../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: