- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why reg and wire have different behaviors in RTL simulation?
The module is pasted below.
module FIFO# (parameter WIDTH = 8, DEPTH = 16)
(
input DataIn,
input RdReq,
input WtReq,
input Clk,
input Reset,
output reg DataOut,
output reg Full,
output reg Empty);
reg writep;
reg readp;
reg memory;
reg tempwp;
reg temprp;
reg almostfull;
reg almostempty;
reg rdreqbuffer;
reg rd;
reg wtreqbuffer;
reg wtreqbuffer3;
reg wt;
integer fifo_i;
always@(*) rd = (~rdreqbuffer) & RdReq;
always@(*) wt = (~wtreqbuffer) & WtReq;
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
rdreqbuffer <= 1;
else
rdreqbuffer <= RdReq;
end
always@(WtReq) wtreqbuffer3 = WtReq;
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
wtreqbuffer <= 1;
else
wtreqbuffer <= wtreqbuffer3;
end
always@(writep)
tempwp = writep + 1'b1;
always@(readp)
temprp = readp + 1'b1;
always@(tempwp,temprp,writep,readp)
begin
almostfull = (tempwp == readp)?1'b1:1'b0;
almostempty = (temprp == writep)?1'b1:1'b0;
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
for(fifo_i = 0; fifo_i < DEPTH; fifo_i = fifo_i + 1)
begin
memory <= 0;
end
else if(wt == 1 && Full == 0)
for(fifo_i = 0; fifo_i < DEPTH; fifo_i = fifo_i + 1)
begin
memory <= (writep == fifo_i)?DataIn:memory;
end
else
for(fifo_i = 0; fifo_i < DEPTH; fifo_i = fifo_i + 1)
begin
memory <= memory;
end
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
DataOut <= 0;
else if(rd == 1 && Empty == 0)
DataOut <= memory;
else
DataOut <= DataOut;
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
writep <= 0;
else if(wt == 1 && Full == 0)
writep <= writep + 1'b1;
else
writep <= writep;
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
readp <= 0;
else if(rd == 1 && Empty == 0)
readp <= readp + 1'b1;
else
readp <= readp;
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
Empty <= 1;
else if((almostempty == 1 && rd == 1 && wt == 0) || (Empty == 1 && wt == 0))
Empty <= 1;
else
Empty <= 0;
end
always@(posedge Clk or negedge Reset)
begin
if(Reset == 0)
Full <= 0;
else if((almostfull == 1 && wt == 1 && rd == 0) || (Full == 1 && rd ==0))
Full <= 1;
else
Full <= 0;
end
function integer widthOf;
input integer num;
if(num == 0)
widthOf = 1;
else
for(widthOf = 0; num != 0; widthOf = widthOf + 1) num = num>>1;
endfunction
endmodule
And the testbanch is as follows.
`timescale 10ps/1ps
module FIFO_tb ;
parameter WIDTH = 8 ;
parameter DEPTH = 16 ;
reg DataIn ;
wire DataOut ;
reg Clk;
reg RdReq ;
wire Empty ;
wire Full ;
reg Reset ;
reg WtReq ;
FIFO # ( WIDTH , DEPTH)
DUT (
.DataIn (DataIn ) ,
.DataOut (DataOut ) ,
.Clk (Clk ) ,
.RdReq (RdReq ) ,
.Empty (Empty ) ,
.Full (Full ) ,
.Reset (Reset ) ,
.WtReq (WtReq ) );
initial
begin
Clk <= 1'b1;
forever# 10 Clk <= !Clk;
end
integer i,j;
initial
begin
# 80
for ( i = 1 ; i < 9; i = i + 1)
begin
# 20 DataIn <= i;
end
end
initial
begin
WtReq <= 0;
# 100 WtReq <= 1;
# 160 WtReq <= 0;
end
initial
begin
RdReq <= 0;
# 12 //RdReq = 1;
for ( j = 1 ; j < 18; j = j + 1)
begin
# 20 RdReq <= j%2;
end
end
initial
begin
Reset <= 0;
# 5 Reset <= 1;
end
endmodule
What puzzles me is claiming the wt is reg or wire(always@(*) wt = XXXX or assign wt = XXXX) is quite different! Claiming as wire type the modelsim will fetch 1 at which time Wtreq and Clk rise or fall at the same time, but claiming as reg type will make it behave more like a D flip flop.
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No desciption in this thread?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- No desciption in this thread? --- Quote End --- I just find this problem when I do RTL simulation with upper code. It's easy to find the same problem use the following code.
module test(
input Clock,
input Reset,
input Signal,
output SignalPosEdge
);
//reg signal;
//always@(*) signal = Signal;
reg signalbuffer1;
clkctrl gclk(
.inclk(Clock),
.outclk(gclock)
);
always@(posedge gclock or negedge Reset)
begin
if(Reset == 0)
signalbuffer1 <= 0;
else
signalbuffer1 <= Signal;
// signalbuffer1 <= signal;
end
assign SignalPosEdge = (~signalbuffer1)&Signal;
endmodule
`timescale 1ns/100ps
module test_tb ;
reg Clock ;
wire SignalPosEdge ;
reg Signal ;
reg Reset ;
test
DUT (
.Clock (Clock ) ,
.SignalPosEdge (SignalPosEdge ) ,
.Signal (Signal ) ,
.Reset (Reset ) );
initial
begin
Clock = 1;
forever# 10 Clock = ~Clock;
end
initial
begin
Reset = 0;
# 40 Reset = 1;
end
initial
begin
Signal = 0;
# 40 Signal = 1;
end
endmodule
In the module, test, I want to synchronize Signal's posedge to a cycle of Clock. So I user a D filp-flop to buffer Signal, and use "SignalPosEdge = (~signalbuffer1)&Signal" to get the synchronized pulse. But if using my testbanch, you will only find SignalPosEdge have a risk issue at# 40, being 1 and getting down immediately. While I hope there is one cycle Clock pulse to indicate the posedge of Signal. And if you use the comment sentences in the module, test and the same testbanch, you will find that RTL simulation result is quite different. There is a cycle long pulse in SignalPosEdge. Thank you for your reading. Please forgive my poor English.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is no difference between doing:wire out;
assign out = in1 ^ in2;
andreg out;
always @ (*)
out = in1 ^ in2;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- There is no difference between doing:
wire out;
assign out = in1 ^ in2;
andreg out;
always @ (*)
out = in1 ^ in2;
If you put either into a device you will get the same result. If you simulate these you will also see the same result. However, what you are doing is a little different and you need to understand the way in which ModelSim (or any other simulator) works. When you generate stimulus that occurs at the same point in time (in your case @ 40ns both 'clock' & 'Signal' change) the simulator needs to decide how to evaluate the new state of each signal. Whereas your hardware (your FPGA) does this simultaneously (in parallel, albeit with propagation delays), the simulator does this sequentially over a number of simulation cycles. These cycles aren't 1ns, or 1ps. They don't have any time associated with them they are simply passes of the code. ModelSim will then display this as having occurred simultaneously. This is why you often see glitches that have no time duration associated with them. This is where ModelSim has evaluated a signal in one state (e.g. your 'SignalPosEdge' signal is evaluated HIGH) but on the next simulation cycle to simulator determines it actually needs to be in the other state ('SignalPosEdge' is re-assessed LOW). So, ModelSim displays that as what appears to be a glitch. So, I suggest you change the point at which events occur in your simulation. Change "#40 Signal = 1;" to "#35 Signal = 1;" or "#45 Signal = 1;". You will give the simulator an easier job of analysing your puzzle and, I think you'll learn a little more about your code and ModelSim. If you don't think that appropriately represents your real system then you will need to rethink how your code and how to stimulate your simulation. Cheers, Alex PS. Sorry if this is a little difficult to understand but you are asking about something a little complex... :eek: --- Quote End --- Thank you anyway! I'm really agreed with you. There is no difference between the two xxxx.vo files and in gate-level simulation. Even a D flip flop have setup and hold time for input signal corresponding to clock edge . Furthermore, ModelSim simulate the wave in a special compiled sequence. So, in a word, not using that clock edge, I should change the signal after it to make the RTL simulation right, vise-versa. Did I comprehend it right? Regards, Hubert PS. You explained it in a quite understandable way with simple language.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page