Sharathraj M
Sharathraj M

Reputation: 29

Why the memory elements are not initialized?

I am designing a fifo. While writing data in to memory, the elements in the memory are not updating and showing output as below.

Design: Designing an 8*8 memory, want to write the data into the memory

module fifo #(parameter width=8,depth=8)(
input clk,rst,WrEn,RdEn,
input reg [$clog2(depth)-1:0] WrPtr,RdPtr,
input reg [width-1:0] InData,
output reg empty,full,
output reg [width-1:0] OutData
);

reg [width-1:0] mem[depth-1:0];
reg [$clog2(depth):0] counter= 4'b000;

// write block
always @(posedge clk)
begin
if(rst)
begin

empty <= 0;
full <= 0;
end

      else   if(WrEn && !full)
            begin
               mem[WrPtr] <= InData;
              if(counter < depth)
                begin
                   
                    counter <= counter + 1;
                    
                  $display("At %0t counter value is %0d",$time,counter);
                  $monitor("the value in the mem[%0d] = %0b and indata = %0d",WrPtr,mem[WrPtr],InData);
                end
              else 
                full <= 1;
            end
      
    end

endmodule

TestBench: , using for loop to generate the elements to write in to memory

module tb #(parameter width=8,depth=8)();
reg clk=0,rst,WrEn,RdEn,empty,full;
reg [$clog2(depth)-1:0] WrPtr,RdPtr;
reg [width-1:0] InData,OutData;
fifo f1(.clk(clk),
.rst(rst),
.WrEn(WrEn),
.RdEn(RdEn),
.WrPtr(WrPtr),
.RdPtr(RdPtr),
.InData(InData),
.OutData(OutData),
.empty(empty),
.full(full));

integer i;
always #2 clk = ~ clk;

initial begin
#3 rst = 1;
#5 rst = 0;
WrEn <= 1;

// write 8 data & counter width
for (i = 0 ; i< depth ; i =i+1 )
begin
@(posedge clk)
begin
WrPtr <= i;
InData <=i;
$display("At %0t  value is wrptr %0d and Indata = %0d",$time,WrPtr,InData);
end
end

end

endmodule

Here the contents of mem[addr] is not being updated, only the last one mem[7] is updated. Help me to understand why the contents of the memory is not updating.

Output

# KERNEL: At 10  value is wrptr x and Indata = x
# KERNEL: At 10 counter value is 0
# KERNEL: the value in the mem[0] = xxxxxxxx and indata = 0
# KERNEL: At 14  value is wrptr 0 and Indata = 0
# KERNEL: At 14 counter value is 1
# KERNEL: the value in the mem[1] = xxxxxxxx and indata = 1
# KERNEL: At 18  value is wrptr 1 and Indata = 1
# KERNEL: At 18 counter value is 2
# KERNEL: the value in the mem[2] = xxxxxxxx and indata = 2
# KERNEL: At 22  value is wrptr 2 and Indata = 2
# KERNEL: At 22 counter value is 3
# KERNEL: the value in the mem[3] = xxxxxxxx and indata = 3
# KERNEL: At 26  value is wrptr 3 and Indata = 3
# KERNEL: At 26 counter value is 4
# KERNEL: the value in the mem[4] = xxxxxxxx and indata = 4
# KERNEL: At 30  value is wrptr 4 and Indata = 4
# KERNEL: At 30 counter value is 5
# KERNEL: the value in the mem[5] = xxxxxxxx and indata = 5
# KERNEL: At 34  value is wrptr 5 and Indata = 5
# KERNEL: At 34 counter value is 6
# KERNEL: the value in the mem[6] = xxxxxxxx and indata = 6
# KERNEL: At 38  value is wrptr 6 and Indata = 6
# KERNEL: At 38 counter value is 7
# KERNEL: the value in the mem[7] = xxxxxxxx and indata = 7
# KERNEL: the value in the mem[7] = 111 and indata = 7

Upvotes: 1

Views: 101

Answers (1)

toolic
toolic

Reputation: 62037

The contents of mem are being updated, but you are not using an efficient tool for seeing the updates. You are only looking at specific locations in the memory at specific times with $display/$monitor. You should dump waveforms and use a waveform viewer instead. Then you will see this:

enter image description here

Here you see that every memory location is filled after 8 clock cycles.

Since you did not reset the memory, it initializes all locations to x (the unknown value). The write pointer also initializes to x. After reset is released, and after the input data and pointer take on known values, then each memory location gets written with known values.

Since you properly used nonblocking assignments and posedge clk to model sequential logic (flip-flops), there is a 1 cycle delay after you see Indata change to when you see mem change. This is all working as expected.

Upvotes: 1

Related Questions