hw/ip/prim/rtl/prim_sram_arbiter.sv Cov: 84%

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