I have a part of Verilog code that is basically trying to synthesize a flip-flop. I have been experimenting and it seems that I can come up with two ways of writing it.
The first way being :
always @(posedge(clk),posedge(reset)) begin
if(reset) begin
g <= 1'b0;
end else begin
if((~wr_full) && (~fifo_empty)) begin
g <= ~ g;
end else begin
g <= g;
end
end
end
And the second way being :
reg g_next;
always @(posedge(clk),posedge(reset)) begin
if(reset) begin
g <= 1'b0;
end else begin
g <= g_next;
end
end
always @* begin
if((~wr_full) && (~fifo_empty)) begin
g_next = ~ g;
end else begin
g_next = g;
end
end
It turns out that both these codes synthesize to become the exact same circuit (which was expected) :
But their behaviour in simulation is different. In the first case, as soon as the condition in the if statement (~tx_busy) && (~output_fifo_empty)
becomes true
, the output of the flip flop changes, but in the second case, the change in output occurs one clock cycle after the condition becomes true
.
So, my questions are :
1) Why are the behavioural simulation results different, even though both the codes synthesize to become the same circuit.
2) Which one of the behaviours is expected as the output of the synthesized circuit, and why? After looking at the synthesized circuit, it seems logical to infer that the behaviour will be that of the second circuit, but why is that (the behaviour I wanted to infer was the first one). And if this is the case, how do I enforce the first behaviour (maybe a latch ?)
3) I have been using these two methods interchangeably to produce the behaviours I wanted, but I have now realized that these two synthesize to be the same circuit. How does this affect my other circuits (do I not understand how they work, but they still work as expected ?)
4) How do I know that the circuit behaviour that I inferred in behavioural simulation will be the one of the synthesized circuit (this experience basically questions all the beliefs I had about the behaviours of simulated and synthesized designs)
EDIT : since the codes are very long, i'd rather not post them here. I have uploaded them here.
There are three floders.
The
traffic_generator
folder contains the filetraffic_generator.v
and the testbench for the sametraffic_generator_tb.v
. These are the top level codes.The
pulse_generator
folder contains the include filepulse_generator.v
. I am aware that this code is not yet synthesizable, but I can get a synthesizable code with the same behaviour (Right?).The
my_fifo
folder contains yet another include filemy_fifo.v
. I suspect there might be some problem due to the way the empty flag is updated, but I can't seem to figure it out.