When I run this I get sig value = 3 from both the displays Why does the $display within the task take the global variable sig = 3 instead of the local variable sig declared within the task signal = 2? Can someone please help me understand?
module tb;
reg[1:0] sig;
task task1(sig);
reg[1:0] sig = 2;
$display("signal = %0b", sig);
endtask
initial begin
sig = 3;
task1(sig);
$display("signal after running display() task = %0b", sig);
end
endmodule
The code you wrote is illegal in SystemVerilog. If fact, this is probably the only backward incompatible language feature of Verilog not allowed in SystemVerilog that I can think of.
The problem is you think task1.sig
is being initialized to 2 every time the task gets called. But it is a static variable that gets initialized once at time 0 before any initial or always blocks have started their processes. If you had declared the task with an automatic lifetime, or used an explicit automatic
lifetime in the declaration on the variable, then it would get initialized upon each activation of the task. SystemVerilog requires variable declarations inside procedural blocks of code with initializations to either have an automatic lifetime, or an explciit static
keyword.
But in any case, you have declared sig
as an input to the task (which is the implicit direction). So the actual argument tb.sig
gets copied to the formal argument task1.sig
.
Reusing the same name for the actual and formal arguments is a poor programming practice. Also, you should be using the Verilog-2001 style of argument declarations.
task task1(input reg [1:0] sig);
Now if you add an initialization
task task1(input reg [1:0] sig = 2);
This gets interpreted in SystemVerilog as a optional argument whose default value is 2.