我正在寻找Systemverilog中"自动"的好处.我一直在看"自动"阶乘的例子.但我无法理解他们.有谁知道为什么我们使用"自动"?
小智 8
传统上,Verilog已用于RTL和门级抽象的硬件建模.由于RTL和门级抽象都是静态/固定(非动态),因此Verilog仅支持静态变量.因此,例如,Verilog中的任何reg或wire将在模拟开始时被实例化/映射,并且将保持映射到模拟存储器中直到模拟结束.因此,您可以将任何wire/reg转储为波形,并且reg/wire将具有从开始到结束的值,因为它始终被映射.从程序员的角度来看,这些变量被称为静态变量.在C/C++世界中,要声明这样的变量,您将不得不使用存储类说明符 static.在Verilog中,每个变量都是隐式静态的.
请注意,在SystemVerilog出现之前,Verilog仅支持静态变量.尽管Verilog还支持一些用于行为抽象建模的构造,但由于缺少自动存储类,因此支持受到限制.
自动(在软件世界中称为auto)存储类变量映射在堆栈上.调用函数时,函数中声明的所有本地(非静态)变量都映射到堆栈中的各个位置.由于这些变量仅存在于堆栈中,因此只要函数的执行完成并且堆栈相应地收缩,它们就不再存在.
除了其他优点之外,此存储类启用的一种可能性是递归函数.在Verilog世界中,一个函数不能重入.在自动存储类不可用的世界中,递归(或重入)函数不起任何有用的作用.要理解这一点,您可以将重入函数想象为一个动态地对其自身进行多次递归实例化的函数.每个实例都会将其自动变量映射到堆栈中.随着我们进入递归,堆栈增长,每个函数都使用自己的变量集进行计算.当函数调用返回时,将整理计算值并使最终结果可用.只使用静态变量,每个函数调用都会将变量值存储在相同的公共位置,从而消除了多次调用(实例化)的任何好处.
进入阶乘算法,将阶乘概念化为递归算法相对容易.在数学中我们写factorial(n)= n(factial(n-1))*.所以你需要计算阶乘(n-1)才能知道阶乘(n).请注意,如果没有终止案例,则无法完成递归,在基数为n = 1的情况下.
function automatic int factorial;
input int n;
if (n > 1)
factorial = factorial (n - 1) * n;
else
factorial = 1;
endfunction
Run Code Online (Sandbox Code Playgroud)
没有自动存储类,因为函数中的所有变量都将映射到固定位置,当我们从factorial(n)内部调用factorial(n-1)时,递归调用将覆盖调用者上下文中的任何变量.在上面代码片段中定义的阶乘函数中,如果我们没有将存储类指定为自动,则n和结果阶乘将被对factorial(n-1)的递归调用覆盖.结果,变量n将被连续地重写为n-1,n-2,n-3等,直到我们达到n = 1的终止条件.终止递归调用阶乘将具有分配给值1 Ñ并且当递归解绕,阶乘(N-1)*N将在每个级中评估为1.
使用自动存储类,每个递归函数调用在内存中(实际上在堆栈上)都有自己的位置来存储变量n.因此,对factorial的连续调用不会覆盖调用者的变量n.因此,当递归展开时,我们将factorial(n)的正确值作为n*(n-1)(n-2) ..*1.
请注意,也可以使用迭代定义阶乘.这可以在不使用自动存储类的情况下完成.但在许多情况下,递归使用户可以以更直观的方式编码算法.