With no delays, you have a race condition. There are many possible outcomes, although you are only likely to see 5,7, or 7,5. That is because most event driven simulators only exec one thread at a time and do not switch to another thread until there is a potential blocking event.
what is potentail blocking event? can you please explain
That is any kind of construct that will block, like Delay or @signal_change, or has a chance of blocking, like wait(true_condition), mailbox.get(Item).
module test();
task add(int a, int b);
#2;
$display("the sum is %0d", a+b);
endtask
initial
fork
begin
add(2,3);
end
begin
#1;
add(3,4);
end
join
endmodule
How do we get sum is 7
Sum is 7
According to me, it should be 5 and 7, but for what reason the sum 7 and 7
I too had the same doubt that answer should be 5 & 7. But is it that since add is a static task, so when fork-join will end, latest value will overlap(/erase any previous value) & hence 7 is displayed twice.
Please correct me if I’m wrong.
Thanks
Since the add is a static task by default, the local variables are allotted only one memory location for all calls to that task.
@t=0 → a=3 , b=2
@t=1 → a=3 , b=4; (second call overwrites the first call values, as no separate memory is allocated for local variables in different calls to the task); The first call hasn’t reached the display statement because of #2 delay.
@t=2 → The first call display statement is executed and the sum is a(3)+b(4)=7
@t=3 → The second call’s display statement is executed and the sum is again a(3)+b(4)=7.
SystemVerilog added a lifetime qualifier for modules and interfaces so that all routines defined in that module would be considered automatic by default so you didn’t have to add the automatic keyword after each function or task declaration.
Hi Dave,
From the quotes is it implied that all the functions in my scoreboard class are automatic by default? And during run_phase all calls made to any task or functions will have an automatic behavior?
Thanks,
DJ
Second question, not exactly. The calling of a task or function does not determine its lifetime, only its declaration. All of the tasks/function in your UVM code will be automatic, but let’s say your driver calls a task/function via a virtual interface, the lifetime of those are static by default unless you declare them otherwise.
SystemVerilog added a lifetime qualifier for modules and interfaces so that all routines defined in that module would be considered automatic by default so you didn’t have to add the automatic keyword after each function or task declaration.
Does that mean, by Default all functions and tasks are Automatic ?
I tried the example
module test();
task add(int a, int b);
#2;
$display("the sum is %0d", a+b);
endtask
initial
fork
begin
add(2,3);
end
begin
#1;
add(3,4);
end
join
endmodule
whose o/p is 7 ,7 which means by default lifetime is static …
SystemVerilog added a lifetime qualifier for modules and interfaces so that all routines defined in that module would be considered automatic by default so you didn’t have to add the automatic keyword after each function or task declaration.
module automatic test();
task add(int a, int b); // the lifetime of this task is now implicitly automatic
#2;
$display("the sum is %0d", a+b);
endtask
initial
fork
begin
add(2,3);
end
begin
#1;
add(3,4);
end
join
endmodule