1
\$\begingroup\$

If we assign something to a register ( or do anything else ) in a specific clock cycle, is this assignment performed in the current clock cycle or the next cycle?

(Setting: Xilinx , Spartan-3. coded by Verilog via ISE Webpack)

Example:

always @(negedge GCLK)
   foo<= bar; // foo is equal to bar in this cycle or next?
\$\endgroup\$

3 Answers 3

2
\$\begingroup\$
always @(negedge GCLK)
   foo<= bar; // foo is equal to bar in this cycle or next?

For simple cases where there is nothing going on elsewhere in your code to cause bar to change simultaneously with GCLK, this block says, when a negative-going edge is seen on GCLK, "immediately" change the value of foo to whatever bar is at that instant.

"Immediately" means something like one simulation tick after the negative edge arrived.

This means that any other tranisitions that happen on the same negative edge of GCLK and depend on the value of foo will see the old value of foo. But foo will have the new value starting right away until the next negative edge of GCLK.

Edit in reply to comments,

If "any other transitions" see the old value of foo, can we assume that foo is "is available in next clock"?

In the simulator, yes. In real life you need to check propagation delays and setup and hold times to be sure.

what if we put always code with begin...end ? All of them will be immediate ? as: always@(negedge GCLK) begin .. foo<=bar; x<= foo+1; end In this example x will be bar+1 in the same cycle as foo assignment ?

No, as mentioned before, any other tranisitions that happen on the same negative edge of GCLK and depend on the value of foo will see the old value of foo.

If you want the other behavior you can use blocking assignment:

...
foo = bar; 
x = foo+1; 
...

Modern synthesis tools should be able to compile this correctly but old tools might not be able to. What the modern tool will do is simply translate this to

foo <= bar;
x <= bar+1;

and compile that. Since I learned Verilog before this behavior was reliable I find it less familiar to read the code with blocking assignments.

Can we use blocking assignments for immediate and non-blocking for "delayed" assignments?

I'm not quite clear what you mean by this. What a blocking assignment does (in the simulator) is prevent the next statement from executing until after it is complete. Both types of assignment are immediate, but the blocking assingment causes the next statement to be delayed.

If so, it can be a very useful approach for making small delays in the code

For small delays in simulation you can just use delay events

always @(event) begin
   foo <= x;
   #5 
   bar <= foo;
end

For small delays in synthesized code, you'd better be sure the hardware can actually do what you're asking for.

\$\endgroup\$
9
  • \$\begingroup\$ If "any other transitions" see the old value of foo, can we assume that foo is "is available in next clock"? I mean when writing the code, can we assume foo changes in next cycle? for example if foo is to be sent to an output pin, this change will be seen in next ? \$\endgroup\$
    – Aug
    Nov 19, 2013 at 21:37
  • \$\begingroup\$ And something else: what if we put always code with begin...end ? All of them will be immediate ? as: always@(negedge GCLK) begin .. foo<=bar; x<= foo+1; end In this example x will be bar+1 in the same cycle as foo assignment ? \$\endgroup\$
    – Aug
    Nov 19, 2013 at 21:41
  • 1
    \$\begingroup\$ No, "any other tranisitions that happen on the same negative edge of GCLK and depend on the value of foo will see the old value of foo." If you want the other behavior you can use blocking assignment: ... foo = bar; x = foo+1; .... Modern synthesis tools should be able to compile this correctly but old tools might not be able to. \$\endgroup\$
    – The Photon
    Nov 19, 2013 at 21:55
  • 1
    \$\begingroup\$ " can we assume that foo is "is available in next clock"?" --- In the simulator, yes. In real life you need to check propagation delays and setup and hold times to be sure. \$\endgroup\$
    – The Photon
    Nov 19, 2013 at 21:56
  • \$\begingroup\$ I use last version of Webpack (v14.7)that can compile this code. The answer is nice but I think your comment is even better. Can we use blocking assignments for immediate and non-blocking for "delayed" assignments? If so, it can be a very useful approach for making small delays in the code without using a counter/timer for just one cycle. \$\endgroup\$
    – Aug
    Nov 19, 2013 at 22:14
3
\$\begingroup\$

The answer to this question is strongly related to Verilog concepts I described in my answer to another question about Verilog non-blocking assignment (NBA).

The straightway answer to your question is very simple: all assignments are performed at the same simulation time slot, i.e. both blocking and non-blocking assignments will be evaluated and assigned before the following time slot (which starts with negedge GCLK in your case).

The details, however, are important!

NBAs are not assigned at evaluation time, but at the end of the time slot. This means that if you use foo for evaluation of other expressions (for example assign blocking = foo; or always @( negedge GCLK ) non_blocking <= foo;), the value used will be the value foo had at the beginning of the time slot. The net result of this behavior is that it seems like foo gets its new value only on the next clock cycle.

However, the above description is just a simplification. I strongly recommend that you read this SNUG paper thoroughly and make sure you understand the fine details - this will make you much more comfortable with Verilog and may prevent many nasty bugs and mismatches between RTL and FPGA simulations. Specifically, section 2.0 (Verilog Event Queue) contains the information directly related to your question.

Hope this helps.

\$\endgroup\$
0
1
\$\begingroup\$

Verilog has bunch of different assignment statements with subtle differences

1) 'a = b' assigns something right now

2) 'a <= b' takes a copy of b right now and assigns it at what is essentially the end of the current time tick (just before time is about to advance)

3) 'a = #N b' takes a copy of b, stops simulation of this block for N seconds and then assigns a then continues executing the rest of the block

4) 'a <= #N b' takes a copy of b and continues simulating this block (in the same clock tick) N seconds later a will be assigned the value copied from b

So any of these four will safely swap a and b

always @(posedge clk) { a <= b; b <= a; }

always @(posedge clk) { a <= #1 b; b <= #1 a; }

always @(posedge clk) a <= b; always @(posedge clk) b <= a;

always @(posedge clk) a = #1 b; always @(posedge clk) b = #1 a;

While all of these are unsafe for simulation:

always @(posedge clk) { a = b; b = a; }

always @(posedge clk) { a = #1 b; b = #1 a; }

always @(posedge clk) a = b; always @(posedge clk) b = a;

\$\endgroup\$

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.

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