module tryfact;
// define the function
function automatic integer factorial (input [31:0] operand);
if (operand >= 2)
factorial = factorial (operand - 1) * operand;
else
factorial = 1;
endfunction: factorial
// test the function
integer result;
initial begin
for (int n = 0; n <= 7; n++) begin
result = factorial(n);
$display("%0d factorial=%0d", n, result);
end
end
endmodule: tryfact
Dave's explanation should clear your confusion between automatic and static.
For calculating the factorial, the function should be automatic so that there will be multiple memory allocations for the variable “factorial” which is a property of recursive function. If the function is static, then memory for the variable ‘factorial’ will be only once and finally factorial value is becoming ‘1’ in the recursive calls.
Consider the following example also for understanding the difference between static and automatic.
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
In the above example, the task add is static. So, memory for the variables a & b will be allocated only once. Hence, output for the program will be as follows (which will be definitely different from your prediction).
the sum is 7
the sum is 7.
make the task as automatic and see the difference.
In reply to Have_A_Doubt:
Declaring any function or task with an explicit static lifetime is something you should never need to do in either Verilog or SystemVerilog. If it were not for the mandate to be 100% backward compatibility with Verilog-2001, it could have been eliminated from SystemVerilog.
Because the
class is a new construct in SystemVerilog, we had the opportunity to change the default lifetime and eliminate the confusion between ‘static function’ and ‘function static’. Anyone declaring a function with a static lifetime in a class would most likely be making a mistake thinking they were declaring a static method. By making it illegal, their mistake is caught much earlier.
Hi puttasatish,
If I give the same code with no delay. I’m getting below results
the sum is 5
the sum is 7.
Do you know what could be the reason?
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
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