Reputation: 29
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
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:
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