How Verilog decides upon simultaneous events

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:

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?

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.

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

• It would be useful to explain why this is the case and what it changes. Apr 11 '15 at 9:38