blob: 889796eae534ae26a36a28a234c06d4d7028b675 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Testbench module for prim_fifo_sram_async
module prim_fifo_async_sram_adapter_tb #(
parameter int unsigned Width = 32,
parameter int unsigned Depth = 16,
parameter int unsigned FpgaSram = 0 // Use FF based
) (
input clk_wr_i,
input clk_rd_i,
input rst_ni,
input wvalid_i,
output logic wready_o,
input [Width-1:0] wdata_i,
output logic rvalid_o,
input rready_i,
output logic [Width-1:0] rdata_o
);
localparam int unsigned SramAw = 7;
localparam int unsigned SramDw = 32;
localparam logic [SramAw-1:0] SramBaseAddr = 'h 30;
logic w_sram_req;
logic w_sram_gnt;
logic w_sram_write;
logic [SramAw-1:0] w_sram_addr;
logic [SramDw-1:0] w_sram_wdata;
logic [SramDw-1:0] w_sram_wmask;
logic w_sram_rvalid; // not used
logic [SramDw-1:0] w_sram_rdata; // not used
logic [1:0] w_sram_rerror; // not used
logic r_sram_req;
logic r_sram_gnt;
logic r_sram_write;
logic [SramAw-1:0] r_sram_addr;
logic [SramDw-1:0] r_sram_wdata; // not used
logic [SramDw-1:0] r_sram_wmask; // not used
logic r_sram_rvalid;
logic [SramDw-1:0] r_sram_rdata;
logic [1:0] r_sram_rerror;
prim_fifo_async_sram_adapter #(
.Width (Width),
.Depth (Depth),
.SramAw (SramAw), // TODO: random with constraint
.SramDw (SramDw), // TODO: random with constraint
.SramBaseAddr(SramBaseAddr) // TODO: random?
) dut (
.clk_wr_i,
.rst_wr_ni (rst_ni),
.clk_rd_i,
.rst_rd_ni (rst_ni),
.wvalid_i,
.wready_o,
.wdata_i,
.wdepth_o (),
.rvalid_o,
.rready_i,
.rdata_o,
.rdepth_o (),
// Sram Interface
.w_sram_req_o (w_sram_req ),
.w_sram_gnt_i (w_sram_gnt ),
.w_sram_write_o (w_sram_write ),
.w_sram_addr_o (w_sram_addr ),
.w_sram_wdata_o (w_sram_wdata ),
.w_sram_wmask_o (w_sram_wmask ),
.w_sram_rvalid_i(w_sram_rvalid), // not used
.w_sram_rdata_i (w_sram_rdata ), // not used
.w_sram_rerror_i(w_sram_rerror), // not used
// Read SRAM port
.r_sram_req_o (r_sram_req ),
.r_sram_gnt_i (r_sram_gnt ),
.r_sram_write_o (r_sram_write ),
.r_sram_addr_o (r_sram_addr ),
.r_sram_wdata_o (r_sram_wdata ), // not used
.r_sram_wmask_o (r_sram_wmask ), // not used
.r_sram_rvalid_i(r_sram_rvalid),
.r_sram_rdata_i (r_sram_rdata ),
.r_sram_rerror_i(r_sram_rerror),
.r_full_o(),
.r_notempty_o(),
.w_full_o()
);
if (FpgaSram == 1) begin : g_sram_fpga
// FPV looks like does not like the style of ram_2p.
prim_ram_2p #(
.Depth (2**SramAw),
.Width (SramDw),
.DataBitsPerMask (1)
) u_sram (
.clk_a_i (clk_wr_i),
.clk_b_i (clk_rd_i),
.a_req_i (w_sram_req ),
.a_write_i (w_sram_write ),
.a_addr_i (w_sram_addr ),
.a_wdata_i (w_sram_wdata ),
.a_wmask_i (w_sram_wmask ),
.a_rdata_o (w_sram_rdata ),
.b_req_i (r_sram_req ),
.b_write_i (r_sram_write ),
.b_addr_i (r_sram_addr ),
.b_wdata_i (r_sram_wdata ),
.b_wmask_i (r_sram_wmask ),
.b_rdata_o (r_sram_rdata ),
.cfg_i ('0)
);
end else begin : g_sram_ff
logic [SramDw-1:0] mem [2**SramAw];
always_ff @(posedge clk_wr_i) begin
if (w_sram_req && w_sram_write) begin
for (int unsigned i = 0; i < SramDw ; i++) begin
if (w_sram_wmask[i]) mem[w_sram_addr][i] <= w_sram_wdata[i];
end // for
end // if
end
always_ff @(posedge clk_rd_i) begin
if (r_sram_req && !r_sram_write) begin
r_sram_rdata <= mem[r_sram_addr];
end
end
end // !FpgaSram
assign w_sram_gnt = w_sram_req;
always_ff @(posedge clk_wr_i) begin
w_sram_rvalid <= w_sram_req && !w_sram_write;
end
assign w_sram_rerror = '0;
assign r_sram_gnt = r_sram_req;
always_ff @(posedge clk_rd_i) begin
r_sram_rvalid <= r_sram_req && !r_sram_write;
end
assign r_sram_rerror = '0;
`ASSUME_FPV(WdataBins_M,
wvalid_i |-> wdata_i inside {
32'h DEAD_BEEF, 32'h5A5A_A5A5, 32'h 1234_5678
},
clk_wr_i, !rst_ni)
`ifdef FPV_ON
logic [Width-1:0] storage [Depth];
logic [Width-1:0] rdata;
logic [$clog2(Depth)-1:0] wptr, rptr;
logic wack, rack;
assign wack = wvalid_i && wready_o;
assign rack = rvalid_o && rready_i;
always_ff @(posedge clk_wr_i or negedge rst_ni) begin
if (!rst_ni) wptr <= '0;
else if (wack) wptr <= wptr+1;
end
always_ff @(posedge clk_rd_i or negedge rst_ni) begin
if (!rst_ni) rptr <= '0;
else if (rack) rptr <= rptr+1;
end
always_ff @(posedge clk_wr_i or negedge rst_ni) begin
if (!rst_ni) storage <= '{default:'0};
else if (wack) begin
storage[wptr] <= wdata_i;
end
end
assign rdata = storage[rptr];
`ASSERT(DataIntegrityCheck_A,
rack |-> rdata_o == rdata,
clk_rd_i, !rst_ni)
`endif // FPV_ON
endmodule : prim_fifo_async_sram_adapter_tb