Verilog-2001 函数中的 for 循环问题

问题描述

我在将 SystemVerilog 文件转换为来自 GitHub 项目的 Verilog-2001 文件时遇到问题。似乎在 Verilog-2001 中,不可能在函数中放置一个表的展开循环:

  function [31:0] gen_val;
    input [31:0] old_val;
    input [31:0] new_val;
    input [3:0] be;

    integer n;

    for (n = 0 ; n < 4 ; n = n + 1) 
        gen_val[n*8+8:n*8] = be[n] ? new_val[n*8+8:n*8] : old_val[n*8+8:n*8];

  endfunction

使用 Icarus Verilog (iverilog) 进行编译时,我收到多个错误消息:

./tb_tiny.v:39: error: A reference to a wire or reg (`n') is not allowed in a constant expression.
./tb_tiny.v:39: error: Part select expressions must be constant.
./tb_tiny.v:39:      : This lsb expression violates the rule: (n)*('sd8)
./tb_tiny.v:39: error: A reference to a wire or reg (`n') is not allowed in a constant expression.
./tb_tiny.v:39: error: Part select expressions must be constant.
./tb_tiny.v:39:      : This msb expression violates the rule: ((n)*('sd8))+('sd8)
.....

有人知道如何在 Verilog-2001 中解决这个问题吗?

问候

解决方法

IEEE Verilog HDL 标准 (IEEE Std 1364-2001) 条款 4.2.1 定义了两种类型的部分选择:常量部分选择和索引部分选择。

... 使用以下语法给出向量 reg 或 net 的常量部分选择:

vect[msb_expr:lsb_expr]

两个表达式都应该是常量表达式。 ...

向量网络、向量 reg、整数变量或时间变量的索引部分选择使用以下语法给出:

reg [15:0] big_vect;
reg [0:15] little_vect;

   big_vect[lsb_base_expr +: width_expr]
little_vect[msb_base_expr +: width_expr]

   big_vect[msb_base_expr -: width_expr]
little_vect[lsb_base_expr -: width_expr] 

width_expr 应该是一个常量表达式。它也不受运行时参数分配的影响。 lsb_base_expr 和 msb_base_expr 可以在运行时变化。 ...

您的函数可以使用索引部分选择重写:

function [31:0] gen_val;
    input [31:0] old_val;
    input [31:0] new_val;
    input [3:0] be;

    integer n;

    for (n = 0 ; n < 4 ; n = n + 1) 
        gen_val[n*8 +: 8] = be[n] ? new_val[n*8 +: 8] : old_val[n*8 +: 8];

endfunction

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...