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
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.
traffic_generatorfolder contains the file
traffic_generator.vand the testbench for the same
traffic_generator_tb.v. These are the top level codes.
pulse_generatorfolder contains the include file
pulse_generator.v. I am aware that this code is not yet synthesizable, but I can get a synthesizable code with the same behaviour (Right?).
my_fifofolder contains yet another include file
my_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.
output_fifo_empty. I have a feeling
output_fifo_emptyare assigned with blocking assignments and changing at the same timestep as
output_fifo_empty, it is assigned with blocking assignment. As of now,
tx_busyis kept low (for simulation purposes). But when connected to the uart, tx_busy will also be assigned with a blocking assignment. \$\endgroup\$
g. Also, in this configuration, I don't know whether
wr_fullis generated by a blocking or non-blocking assignment (since it is a signal generated by the memory controller). How does this change things ? \$\endgroup\$
@(posedge clk)instead of
#delays to gate transitions that should be in sync with the clock. \$\endgroup\$