3

I'm trying to implement this:

enter image description here

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

1 Answer 1

2

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];
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.