hw/ip/prim_generic/rtl/prim_generic_ram_2p.sv Cov: 100%

   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: // Synchronous dual-port SRAM register model
   6: //   This module is for simulation and small size SRAM.
   7: //   Implementing ECC should be done inside wrapper not this model.
   8: 
   9: module prim_generic_ram_2p #(
  10:   parameter  int Width = 32, // bit
  11:   parameter  int Depth = 128,
  12: 
  13:   localparam int Aw    = $clog2(Depth)  // derived parameter
  14: ) (
  15:   input clk_a_i,
  16:   input clk_b_i,
  17: 
  18:   input                    a_req_i,
  19:   input                    a_write_i,
  20:   input        [Aw-1:0]    a_addr_i,
  21:   input        [Width-1:0] a_wdata_i,
  22:   output logic [Width-1:0] a_rdata_o,
  23: 
  24: 
  25:   input                    b_req_i,
  26:   input                    b_write_i,
  27:   input        [Aw-1:0]    b_addr_i,
  28:   input        [Width-1:0] b_wdata_i,
  29:   output logic [Width-1:0] b_rdata_o
  30: );
  31: 
  32:   logic [Width-1:0] mem [Depth];
  33: 
  34:   // Xilinx FPGA specific Dual-port RAM coding style
  35:   // using always instead of always_ff to avoid 'ICPD  - illegal combination of drivers' error
  36:   // thrown due to 'mem' being driven by two always processes below
  37:   always @(posedge clk_a_i) begin
  38:     if (a_req_i) begin
  39:       if (a_write_i) begin
  40:         mem[a_addr_i] <= a_wdata_i;
  41:       end
  42:       a_rdata_o <= mem[a_addr_i];
  43:     end
  44:   end
  45: 
  46:   always @(posedge clk_b_i) begin
  47:     if (b_req_i) begin
  48:       if (b_write_i) begin
  49:         mem[b_addr_i] <= b_wdata_i;
  50:       end
  51:       b_rdata_o <= mem[b_addr_i];
  52:     end
  53:   end
  54: 
  55: endmodule
  56: