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 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;
bar <= foo;
For small delays in synthesized code, you'd better be sure the hardware can actually do what you're asking for.