Verilog 我们可以用“初始化变量”吗;网络;,而不是常数,在“内”;首字母“;块

Verilog 我们可以用“初始化变量”吗;网络;,而不是常数,在“内”;首字母“;块,verilog,Verilog,以下代码给出了输出(“事实”)1,与输入无关。错误是什么 module Factorial_calc(n, fact); input [5:0] n; output reg [64:0] fact; reg [5:0] i; initial begin i=n; fact=1; end always @(*) begin while(i>0) begin fact=i*fact; i=i-1; end end Verilog不会阻止您在初始块内为净值分配一个reg,但您极不

以下代码给出了输出(“事实”)1,与输入无关。错误是什么

module Factorial_calc(n, fact);
input [5:0] n;
output reg [64:0] fact;
reg [5:0] i;

initial
begin
i=n;
fact=1;
end

always @(*)
begin
 while(i>0)
 begin
 fact=i*fact;
 i=i-1;
 end
end

Verilog不会阻止您在初始块内为净值分配一个reg,但您极不可能得到预期的结果


初始
块在时间0运行一个。在分配给reg之前,网络可能没有预期值。通过设计,Verilog允许在时间步长的同一阶段内程序块和有争议的分配的评估顺序的非确定性。Verilog的求值顺序可以由事件依赖关系控制<代码>初始块不依赖于事件,因此将始终尽快对其进行评估。网络将具有依赖性(除非它们被分配给常数),因此通常在以后对其进行评估

使代码正常工作的最小更改是将初始块的内容移动到while语句上方的always块内。这将在每次输入
n
更改时更新
i
,并在while循环中更新之前重置
fact

always @(*)
begin
  i = n; // <-- local sample
  fact = 1; // local reset
  while(i>0)
  begin
    fact=i*fact;
    i=i-1;
  end
end
始终@(*)
开始
i=n;//0)
开始
事实=我*事实;
i=i-1;
终止
终止

这将适用于模拟,但它无法合成,因为它使用了while语句。

一个
initial
块在模拟开始时运行一次。我想您希望它在以后的某个时间运行不止一次?你是在设计硬件吗?不,我不是在用硬件。这只是为了模拟。该代码用于查找数字的阶乘。我想递减“n”并与输出变量“fact”相乘。但是由于“n”是一个“net”,我使用的是中间的“reg”“I”。如果它不是硬件,那么把所有这些代码放在一个函数中怎么样?当然可以。可以有更好的方法。但我想知道这种用法有什么问题。我也回答了你的问题——“初始块在模拟开始时运行一次。我想你希望它在以后的某个时间运行不止一次?”。但是,如果你不是在设计硬件,那么你就是在编写软件。因此,将其作为一个函数来实现更为合理,而不是始终作为
块来实现。但是我想知道为什么第一种方法不起作用。我得到了答案。谢谢。@Ssap您的第一次尝试没有成功,因为在计算
i=n
时,
n
没有被赋值。对于您的原始代码,
i
在时间0后将不再更新<无论何时
n
更改值(我的代码就是这样做的),都应该更新code>i