../src/lowrisc_prim_all_0.1/rtl/prim_sram_arbiter.sv Cov: 84.7%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // N:1 SRAM arbiter
6: //
7: // Parameter
8: // N: Number of requst port
9: // DW: Data width (SECDED is not included)
10: // Aw: Address width
11: // ArbiterImpl: can be either PPC or BINTREE.
12: `include "prim_assert.sv"
13:
14: module prim_sram_arbiter #(
15: parameter int N = 4,
16: parameter int SramDw = 32,
17: parameter int SramAw = 12,
18: parameter ArbiterImpl = "PPC"
19: ) (
20: input clk_i,
21: input rst_ni,
22:
23: input [ N-1:0] req,
24: input [SramAw-1:0] req_addr [N],
25: input req_write [N],
26: input [SramDw-1:0] req_wdata [N],
27: output logic [ N-1:0] gnt,
28:
29: output logic [ N-1:0] rsp_rvalid, // Pulse
30: output logic [SramDw-1:0] rsp_rdata [N],
31: output logic [ 1:0] rsp_error [N],
32:
33: // SRAM Interface
34: output logic sram_req,
35: output logic [SramAw-1:0] sram_addr,
36: output logic sram_write,
37: output logic [SramDw-1:0] sram_wdata,
38: input sram_rvalid,
39: input [SramDw-1:0] sram_rdata,
40: input [1:0] sram_rerror
41: );
42:
43:
44: typedef struct packed {
45: logic write;
46: logic [SramAw-1:0] addr;
47: logic [SramDw-1:0] wdata;
48: } req_t;
49:
50: localparam int ARB_DW = $bits(req_t);
51:
52: req_t req_packed [N];
53:
54: for (genvar i = 0 ; i < N ; i++) begin : gen_reqs
55: assign req_packed[i] = {req_write[i], req_addr[i], req_wdata[i]};
56: end
57:
58: req_t sram_packed;
59: assign sram_write = sram_packed.write;
60: assign sram_addr = sram_packed.addr;
61: assign sram_wdata = sram_packed.wdata;
62:
63: if (ArbiterImpl == "PPC") begin : gen_arb_ppc
64: prim_arbiter_ppc #(
65: .N (N),
66: .DW(ARB_DW)
67: ) u_reqarb (
68: .clk_i,
69: .rst_ni,
70: .req_i ( req ),
71: .data_i ( req_packed ),
72: .gnt_o ( gnt ),
73: .idx_o ( ),
74: .valid_o ( sram_req ),
75: .data_o ( sram_packed ),
76: .ready_i ( 1'b1 )
77: );
78: end else if (ArbiterImpl == "BINTREE") begin : gen_tree_arb
79: prim_arbiter_arb #(
80: .N (N),
81: .DW(ARB_DW)
82: ) u_reqarb (
83: .clk_i,
84: .rst_ni,
85: .req_i ( req ),
86: .data_i ( req_packed ),
87: .gnt_o ( gnt ),
88: .idx_o ( ),
89: .valid_o ( sram_req ),
90: .data_o ( sram_packed ),
91: .ready_i ( 1'b1 )
92: );
93: end else begin : gen_unknown
94: `ASSERT_INIT(UnknownArbImpl_A, 0)
95: end
96:
97:
98: logic [N-1:0] steer; // Steering sram_rvalid
99: logic sram_ack; // Ack for rvalid. |sram_rvalid
100:
101: assign sram_ack = sram_rvalid & (|steer);
102:
103: // Request FIFO
104: prim_fifo_sync #(
105: .Width (N),
106: .Pass (1'b0),
107: .Depth (4) // Assume at most 4 pipelined
108: ) u_req_fifo (
109: .clk_i,
110: .rst_ni,
111: .clr_i (1'b0),
112: .wvalid (sram_req && !sram_write), // Push only for read
113: .wready (), // TODO: Generate Error
114: .wdata (gnt),
115: .depth (), // Not used
116: .rvalid (), // TODO; Generate error if sram_rvalid but rvalid==0
117: .rready (sram_ack),
118: .rdata (steer)
119: );
120:
121: assign rsp_rvalid = steer & {N{sram_rvalid}};
122:
123: for (genvar i = 0 ; i < N ; i++) begin : gen_rsp
124: assign rsp_rdata[i] = sram_rdata;
125: assign rsp_error[i] = sram_rerror; // No SECDED yet
126: end
127:
128: endmodule
129: