2
\$\begingroup\$

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) :

enter image description here

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 file traffic_generator.v and the testbench for the same traffic_generator_tb.v. These are the top level codes.

  • The pulse_generator folder 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?).

  • The my_fifo folder 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.

\$\endgroup\$
14
  • \$\begingroup\$ Can you show how you are driving clk, tx_busy, and output_fifo_empty. I have a feeling tx_busy and output_fifo_empty are assigned with blocking assignments and changing at the same timestep as clk \$\endgroup\$
    – Greg
    Mar 17, 2016 at 4:56
  • \$\begingroup\$ @Greg you are right about output_fifo_empty, it is assigned with blocking assignment. As of now, tx_busy is kept low (for simulation purposes). But when connected to the uart, tx_busy will also be assigned with a blocking assignment. \$\endgroup\$
    – ironstein
    Mar 17, 2016 at 5:05
  • \$\begingroup\$ @Greg and by the way, I edited the question to replace tx_busy with wr_full, output_fifo_empty with fifo_empty, and generate_output_fifo_pop_pulse with g. Also, in this configuration, I don't know whether wr_full is generated by a blocking or non-blocking assignment (since it is a signal generated by the memory controller). How does this change things ? \$\endgroup\$
    – ironstein
    Mar 17, 2016 at 5:08
  • \$\begingroup\$ Signals that are the output of a flop or latch should use non-blocking assignment, this includes signals in your test bench driving the dut. In the test bench, use @(posedge clk) instead of # delays to gate transitions that should be in sync with the clock. \$\endgroup\$
    – Greg
    Mar 17, 2016 at 5:35
  • 1
    \$\begingroup\$ Post your testbench! This could well be an issue with blocking/nonblocking statements in the testbench. \$\endgroup\$ Mar 17, 2016 at 8:06

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.