../src/lowrisc_prim_generic_ram_1p_0/rtl/prim_generic_ram_1p.sv Cov: 79.4%

   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 single-port SRAM model
   6: 
   7: `include "prim_assert.sv"
   8: 
   9: module prim_generic_ram_1p #(
  10:   parameter  int Width           = 32, // bit
  11:   parameter  int Depth           = 128,
  12:   parameter  int DataBitsPerMask = 1, // Number of data bits per bit of write mask
  13:   parameter      MemInitFile     = "", // VMEM file to initialize the memory with
  14: 
  15:   localparam int Aw              = $clog2(Depth)  // derived parameter
  16: ) (
  17:   input  logic             clk_i,
  18: 
  19:   input  logic             req_i,
  20:   input  logic             write_i,
  21:   input  logic [Aw-1:0]    addr_i,
  22:   input  logic [Width-1:0] wdata_i,
  23:   input  logic [Width-1:0] wmask_i,
  24:   output logic [Width-1:0] rdata_o // Read data. Data is returned one cycle after req_i is high.
  25: );
  26: 
  27:   // Width of internal write mask. Note wmask_i input into the module is always assumed
  28:   // to be the full bit mask
  29:   localparam int MaskWidth = Width / DataBitsPerMask;
  30: 
  31:   logic [Width-1:0]     mem [Depth];
  32:   logic [MaskWidth-1:0] wmask;
  33: 
  34:   always_comb begin
  35:     for (int i=0; i < MaskWidth; i = i + 1) begin : create_wmask
  36:       wmask[i] = &wmask_i[i*DataBitsPerMask +: DataBitsPerMask];
  37:     end
  38:   end
  39: 
  40:   // using always instead of always_ff to avoid 'ICPD  - illegal combination of drivers' error
  41:   // thrown when using $readmemh system task to backdoor load an image
  42:   always @(posedge clk_i) begin
  43:     if (req_i) begin
  44:       if (write_i) begin
  45:         for (int i=0; i < MaskWidth; i = i + 1) begin
  46:           if (wmask[i]) begin
  47:             mem[addr_i][i*DataBitsPerMask +: DataBitsPerMask] <=
  48:               wdata_i[i*DataBitsPerMask +: DataBitsPerMask];
  49:           end
  50:         end
  51:       end else begin
  52:         rdata_o <= mem[addr_i];
  53:       end
  54:     end
  55:   end
  56: 
  57:   `include "prim_util_memload.sv"
  58: endmodule
  59: