Forum Discussion
Altera_Forum
Honored Contributor
11 years agoSimulation Problem about a D filp flop by modelsim ALTERA 10.1d
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.4 Replies
- Altera_Forum
Honored Contributor
No desciption in this thread?
- Altera_Forum
Honored Contributor
--- 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
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.`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 - Altera_Forum
Honored Contributor
There is no difference between doing:
andwire out; assign 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:reg out; always @ (*) out = in1 ^ in2; - Altera_Forum
Honored Contributor
--- Quote Start --- There is no difference between doing:
andwire out; assign 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.reg out; always @ (*) out = in1 ^ in2;