1
\$\begingroup\$

Say we have a function, simple as f(x) = x. Say we have a clock that ticks every 20 nanoseconds, and say we change x as we wish.

Say there is a clock tick to come, at t = 20ns exactly (whatever that means). Say x had been 0 from the t = 0ns since, and we somehow change the x into 1 at again exactly t = 20ns.

Now describe this scenario in Verilog. The question is, what would f be at t = 21ns?

Here are the Verilog codes I had written, along with the screenshot from Xilinx ISim simulation window.

The circuit.v

module circuit(f, x, clk, rst);

    output f;
    input x, clk, rst;

    wire d, q;

    d_flip_flop flipper (q, d, clk, rst);

    assign f = q;
    assign d = x;

endmodule

The d_flip_flop.v

module d_flip_flop(q, d, clk, rst);

    output reg q;
    input d, clk, rst;

    always @(posedge clk, posedge rst)
    begin
        if (rst)
            q <= 1'b0;
        else
            q <= d;
    end

endmodule

And I test these with this tester.v

module tester;

    reg x, clk, rst;
    wire f;

    circuit uut (f, x, clk, rst);

    initial clk <= 0;
    always #10 clk <= ~clk;

    initial
    begin
        x <= 0;
        rst <= 0;

        rst <= #2 1;
        rst <= #4 0;

        #10 x <= 1;
    end

endmodule

And here's the waveform I get:

waveform

Is this a defined behaviour of Verilog to perform so? If yes, how does it decide upon what should come first in such circumstances?

I have been told by the assistants of the course that what I should really be seeing is actually the opposite, for sure, and I must be doing something wrong if I am seeing otherwise. I would like to know what I am doing wrong, I need help, and they don't provide me this particular help. Could anybody here maybe help?

\$\endgroup\$
2
2
\$\begingroup\$

The Verilog standard guarantees that all events within a begin..end block scheduled for the same simulation time will be processed in the order they are declared. Other than in this specific scenario every other event may be taken out of the queue in any order.

With this said, any behavior can be expected because both events are scheduled for the same simulation time in different code blocks. Nevertheless, the behavior you have is what is generally accepted as correct, because data is not sampled in the same simulation time where it is generated.

Things you could do to improve predictability:

  1. Generate your clock using a blocking assignment.

    always #10 clk = ~clk;
    
  2. Generate stimuli on clock events.

    initial
    begin
        repeat (2) @(posedge clk)
            x <= 1;
    end
    

This coding will, in general, guarantee that the RTL simulation will behave as the final gatelevel netlist without requiring data delays. In an RTL simulation, data must not be generated and sampled in the same simulation time.

\$\endgroup\$
-1
\$\begingroup\$

Instead of using d_flip_flop flipper (q, d, clk, rst); use d_flip_flop flipper (q, x, clk, rst); in toplevel module.

\$\endgroup\$
1
  • 5
    \$\begingroup\$ It would be useful to explain why this is the case and what it changes. \$\endgroup\$
    – David
    Apr 11 '15 at 9:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.