在 "while" 中使用一个非常量值,给我这个错误,我该怎么办?
Using a non-constant value inside "while", gives me this error, what can I do?
我正在尝试进行浮点数的加减法运算。我的指南是 Cavanagh 的一本书 "Computer Arithmetic and Verilog HDL Fundamentals"。在模块内部,他使用代码来对齐指数,如下所示。
always @ (oper_1 or oper_2)
begin
exp_a = oper_1 [31:24];
exp_b = oper_2 [31:24];
fract_a = oper_1 [23:0];
fract_b = oper_2 [23:0];
// bias exponents
exp_a_bias = exp_a + 8'b0111_1111;
exp_b_bias = exp_b + 8'b0111_1111;
// align fractions
if (exp_a_bias < exp_b_bias)
ctrl_align = exp_b_bias - exp_a_bias;
while (ctrl_align)
begin
fract_a = fract_a >> 1;
exp_a_bias = exp_a_bias + 1;
ctrl_align = ctrl_align - 1;
end
if (exp_b_bias < exp_a_bias)
ctrl_align = exp_a_bias - exp_b_bias;
while (ctrl_align) // heres comes the troubles
begin
fract_b = fract_b >> 1;
exp_b_bias = exp_b_bias + 1;
ctrl_align = ctrl_align - 1;
end
Quartus II 报如下错误:
错误 (10119):ADD_SUB_FLO.v(40) 处的 Verilog HDL 循环语句错误:具有非常量循环条件的循环必须在 250 次迭代后终止
我搜索了一下,似乎由于 Quartus 无法确定 "ctrl_align" 结果的大小,所以它不会合成。 Quartus 网站说我可以编辑 .qsf 文件,但我在我的文件中找不到任何
set_global_assignment-名称VERILOG_NON_CONSTANT_LOOP_LIMIT300
此外,这本书用错误的代码教授了那一步,这让我印象深刻,无法合成,我也希望实际解决问题而不是解决方法,我该怎么办?
更新:我尝试更改为 'For' 但出现错误:
错误 (10170):ADD_SUB_FLO.v(44) 文本“>”附近的 Verilog HDL 语法错误;期待“=”
我认为暂时或暂时无关紧要,因为问题似乎是系统需要预先知道界限,但这是为了计算。
for ( i=ctrl_align,i>0,i=i-1)
begin
fract_a = fract_a >> 1;
exp_a_bias = exp_a_bias + 1;
end
正如之前的评论所述,这不是可综合的 Verilog。你陷入了顺序思考。您不需要 for 循环或 while 循环,基本上,您希望 fract_*
移位,exp_*_bias
递增,ctrl_align
在初始加载后递减。
一共有三种状态:
- 一个正在加载状态,其中
ctrl_align = exp_b_bias - exp_a_bias
- 一个计数状态,其中
ctrl_align
递减,正确的fract_
移位
- A 完成 状态,其中
ctr_align
== 0 且输出有效
使用简单的状态机来跟踪这一点,然后使用 case 语句 select 为每个网络正确分配。
例如:
always @(posedge clk) begin
// Should include a reset
case(state):
LOAD:begin
ctr_align <= (exp_a_bias < exp_b_bias)? exp_b_bias - exp_a_bias : exp_a_bias - exp_b_bias;
end
COUNT:begin
ctrl_align <= ctrl_align - 8'd1;
fract_a <= (exp_a_bias < exp_b_bias)? fract_a >> 1 : fract_a;
fract_b <= (exp_b_bias < exp_a_bias)? fract_b >> 1 : fract_b;
end
DONE: ctrl_align <= ctrl_align
default: ctrl_align <= 0; // latches inferred for fract_*
还没有检查语法,并且有一些推断的锁存器,但这应该让您了解它的要点。状态机应该很容易实现,只有几个 if 语句。
希望对您有所帮助!
我正在尝试进行浮点数的加减法运算。我的指南是 Cavanagh 的一本书 "Computer Arithmetic and Verilog HDL Fundamentals"。在模块内部,他使用代码来对齐指数,如下所示。
always @ (oper_1 or oper_2)
begin
exp_a = oper_1 [31:24];
exp_b = oper_2 [31:24];
fract_a = oper_1 [23:0];
fract_b = oper_2 [23:0];
// bias exponents
exp_a_bias = exp_a + 8'b0111_1111;
exp_b_bias = exp_b + 8'b0111_1111;
// align fractions
if (exp_a_bias < exp_b_bias)
ctrl_align = exp_b_bias - exp_a_bias;
while (ctrl_align)
begin
fract_a = fract_a >> 1;
exp_a_bias = exp_a_bias + 1;
ctrl_align = ctrl_align - 1;
end
if (exp_b_bias < exp_a_bias)
ctrl_align = exp_a_bias - exp_b_bias;
while (ctrl_align) // heres comes the troubles
begin
fract_b = fract_b >> 1;
exp_b_bias = exp_b_bias + 1;
ctrl_align = ctrl_align - 1;
end
Quartus II 报如下错误:
错误 (10119):ADD_SUB_FLO.v(40) 处的 Verilog HDL 循环语句错误:具有非常量循环条件的循环必须在 250 次迭代后终止
我搜索了一下,似乎由于 Quartus 无法确定 "ctrl_align" 结果的大小,所以它不会合成。 Quartus 网站说我可以编辑 .qsf 文件,但我在我的文件中找不到任何
set_global_assignment-名称VERILOG_NON_CONSTANT_LOOP_LIMIT300
此外,这本书用错误的代码教授了那一步,这让我印象深刻,无法合成,我也希望实际解决问题而不是解决方法,我该怎么办?
更新:我尝试更改为 'For' 但出现错误: 错误 (10170):ADD_SUB_FLO.v(44) 文本“>”附近的 Verilog HDL 语法错误;期待“=” 我认为暂时或暂时无关紧要,因为问题似乎是系统需要预先知道界限,但这是为了计算。
for ( i=ctrl_align,i>0,i=i-1)
begin
fract_a = fract_a >> 1;
exp_a_bias = exp_a_bias + 1;
end
正如之前的评论所述,这不是可综合的 Verilog。你陷入了顺序思考。您不需要 for 循环或 while 循环,基本上,您希望 fract_*
移位,exp_*_bias
递增,ctrl_align
在初始加载后递减。
一共有三种状态:
- 一个正在加载状态,其中
ctrl_align = exp_b_bias - exp_a_bias
- 一个计数状态,其中
ctrl_align
递减,正确的fract_
移位 - A 完成 状态,其中
ctr_align
== 0 且输出有效
使用简单的状态机来跟踪这一点,然后使用 case 语句 select 为每个网络正确分配。
例如:
always @(posedge clk) begin
// Should include a reset
case(state):
LOAD:begin
ctr_align <= (exp_a_bias < exp_b_bias)? exp_b_bias - exp_a_bias : exp_a_bias - exp_b_bias;
end
COUNT:begin
ctrl_align <= ctrl_align - 8'd1;
fract_a <= (exp_a_bias < exp_b_bias)? fract_a >> 1 : fract_a;
fract_b <= (exp_b_bias < exp_a_bias)? fract_b >> 1 : fract_b;
end
DONE: ctrl_align <= ctrl_align
default: ctrl_align <= 0; // latches inferred for fract_*
还没有检查语法,并且有一些推断的锁存器,但这应该让您了解它的要点。状态机应该很容易实现,只有几个 if 语句。
希望对您有所帮助!