Description about both the snippets, you have given, is below :
First Snippet :
When the execution flow comes to the ā@(posedge clk) begin-end statementā, the simulator wait for the triggering event(positive edge) on the clk and when it triggers, the piece of code covered within begin-end block will execute.
Second Snippet :
When the execution flow comes to the ā@(posedge clk) begin-end statementā, the simulator wait for the triggering event(positive edge) on the clk. Until the triggering even happen, it blocks the following code and when it triggers, the execution flow goes to the next statement.
Thank you for the response. :) But anyway, my question is actually for verification codes, not for RTL. :)
So thatās why I donāt need to worry about synthesizable code.
I Think It should work exactly the same from the test bench point of view.
In the first code snippet, the statements inside the beginā¦end will get triggered at the posedge.
While in the second case, they get triggered 0 time units after the posedge which means the same thing.
I think you mean " always @(posedge clk) begin ⦠end "
I think they are different, First code execution depends on whether blocking or non block stmt used inside ābegin-endā.
If ā=ā is used then on the same clk edge all code gets executed inside ābegin-endā.
But in the second code is always blocks the rest of the code following clkā event for a posedge.
An event control like @(ā¦) or #(ā¦) is a prefix to any single procedural statement. It is not considered a statement in itself.
The difference between
@(A) somecode;
and
@(A); somecode;
is that the first line is considered one procedural statement and the second line is considered two procedural statements. The first of the two statements in the second line is the null statement, prefixed by an event control @(A).
You might think there is really no behavioral difference between these two lines, but I havenāt shown you the complete context of where these statements are located (neither did you in your original question).
I can claim there is no behavioral difference between t1 and t2. However tools may differ in their ability to set breakpoints on individual statements, and code coverage tools may report these as one or two statements respectively.
On the there hand, if you had the following code
task t1;
if (X)
@(A) somecode;
endtask
task t2;
if (X)
@(A); somecode;
endtask
Now there is a big difference between the two tasks. In t1, the conditional statement is @(A) somecode;. But in t2, only @A; is the conditional statement-- somecode; is executed unconditionally. Of course, you can always wrap multiple statements in an begin/end block, and use that block where one statement is allowed.
task t1;
if (X)
@(A) somecode;
endtask
task t2;
if (X)
begin @(A); somecode; end
endtask
task t3;
if (X)
@(A) begin somecode; end
endtask
Now t1 and t2 are now behaviorally the same. t3 is also the same. the event control is a prefix to a single statement, which happens to be a begin/end block.
// In the testbench driver #1 signal = 1; #1 signal = 0;
// In the testbench monitor
@(posedge clk) begin
if(signal) $display(āsignal assertedā);
end
In which timestamp does the āsignal assertedā will appear? Is it at the same time with the posedge? Or after 1 clock cycle?
Iām asking this because in RTL a register can only sample the signal after 1 clock cycle, not at exactly the same time with the posedge.
What I want my testbench to do is to report only at the time the RTL registers actually see the signal.
This is a completely different question, but again you have not show enough code to explain. When is the signal written in relation to the time of the posedge clk?
If you have multiple processes where one process is writing to a signal (the driver), and another process is reading the same signal (the monitor) at the same time, then you have a race condition in that you donāt know if you are reading the old value or newly written value of the signal. That is why we use non-blocking assignments (NBA) in Verilog. Search for that.
Yes, that will be a race condition.
What if the non-blocking assignment is inside an if-statement? Will it still not cause a race condition?
For example,
//===== Driver ========
forever begin
@(posedge clk);
if(wr_en) d <= 1;
end
//===== Monitor =======
forever begin
@(posedge clk);
if(d) s = 1;
end
If wr_en asserts at 10us, will s also assert at 10us?
Actually I can try to write this code and simulate it to see the effect but Iām thinking that the result may not be the same for larger codes. This example code is only small so that may not result to a race condition⦠Iām wondering what will happen for larger codes.
Hi Dave,
I have a different Question,
whatās the difference between $monitor and $strobe ?
Since both are on postponed region, right ?
I read somewhere single $monitor gives value whenever variable changes throughout simulation, if itās correct can you show code example or snippet for that ?
It would help if you opened up a new question thread. It helps build the knowledge base when people search for similar issues.
Did you read the definition in the 1800-2017 LRM; there are lots of examples in it. People rarely use $monitor as it only helps with dry simple debugging.