I'm trying to implement this:

This is my code:
module memory
# (
parameter AWIDTH = 5,
parameter DWIDTH = 8
)
(
input wire [AWIDTH-1:0] addr,
input wire clk, wr, rd,
inout wire [DWIDTH-1:0] data
);
reg [DWIDTH-1:0] mem [AWIDTH-1:0];
assign data = rd ? mem[addr] : {DWIDTH{1'bz}};
always @(posedge clk) begin
if (wr)
mem[addr] <= data;
end
endmodule
Here is the result:
Loading snapshot worklib.memory_test:v .................... Done
xcelium> source /tools/cdnc/xcelium/current/tools/xcelium/files/xmsimrc
xcelium> run
Writing addr=00000 data=11111111
Writing addr=11111 data=00000000
Reading addr=00000 data=11111111
At time 40 addr=00000 data=11111111
Reading addr=11111 data=00000000
TEST FAILED
At time 50 addr=11111 data=xxxxxxxx
data should be 00000000
Simulation complete via $finish(1) at time 50 NS + 0
./memory_test.v:35 $finish;
xcelium> exit
TOOL: xrun(64) 19.09-s010: Exiting on May 23, 2021 at 03:45:50 IDT (total: 00:00:01)
It doesn't save my data (x is uninitialized). What am I doing wrong?
Here is the test bench code:
module memory_test;
localparam integer AWIDTH=5;
localparam integer DWIDTH=8;
reg clk ;
reg wr ;
reg rd ;
reg [AWIDTH-1:0] addr ;
wire [DWIDTH-1:0] data ;
reg [DWIDTH-1:0] rdata ;
assign data=rdata;
memory
#(
.AWIDTH ( AWIDTH ),
.DWIDTH ( DWIDTH )
)
memory_inst
(
.clk ( clk ),
.wr ( wr ),
.rd ( rd ),
.addr ( addr ),
.data ( data )
);
task expect;
input [DWIDTH-1:0] exp_data;
if (data !== exp_data) begin
$display("TEST FAILED");
$display("At time %0d addr=%b data=%b", $time, addr, data);
$display("data should be %b", exp_data);
$finish;
end
else begin
$display("At time %0d addr=%b data=%b", $time, addr, data);
end
endtask
initial repeat (67) begin #5 clk=1; #5 clk=0; end
initial @(negedge clk) begin : TEST
reg [AWIDTH-1:0] addr;
reg [DWIDTH-1:0] data;
addr=0; data=-1;
$display("Writing addr=%b data=%b",addr,data);
wr=1; rd=0; memory_test.addr=addr; rdata=data; @(negedge clk);
addr=-1; data=0;
$display("Writing addr=%b data=%b",addr,data);
wr=1; rd=0; memory_test.addr=addr; rdata=data; @(negedge clk);
addr=0; data=-1;
$display("Reading addr=%b data=%b",addr,data);
wr=0; rd=1; memory_test.addr=addr; rdata='bz; @(negedge clk) expect(data);
addr=-1; data=0;
$display("Reading addr=%b data=%b",addr,data);
wr=0; rd=1; memory_test.addr=addr; rdata='bz; @(negedge clk) expect(data);
$display("Writing ascending data to descending addresses");
addr=-1; data=0;
while ( addr ) begin
wr=1; rd=0; memory_test.addr=addr; rdata=data; @(negedge clk);
addr=addr-1;
data=data+1;
end
$display("Reading ascending data from descending addresses");
addr=-1; data=0;
while ( addr ) begin
wr=0; rd=1; memory_test.addr=addr; rdata='bz; @(negedge clk) expect(data);
addr=addr-1;
data=data+1;
end
$display("TEST PASSED");
$finish;
end
endmodule
You created mem using
reg [DWIDTH-1:0] mem [AWIDTH-1:0];
So you have mem with 5 rows and then you send address 'h 1f (row 32 counting from 1) which is out of your mem.
To fix this problem you have to create mem with 32 rows. I suggest power operator. Example mem with 32 rows:
reg [DWIDTH-1:0] mem [2**AWIDTH-1:0];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With