使用for循环在Verilog中指定变量范围

typ*_*pon 6 hardware verilog system-verilog

我正在尝试编写此代码:

 for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
                    begin : loop_inst

                        if (i < 3)
                        begin
                            if (changed[i] & !done_q[i])
                            begin
                                writedata[3-i] = en[i];
                                writedata[2-i:0] = readdata[2-i:0];
                                writedata[15:4-i] = readdata[15:4-i];
                            end
                        end
                        else
                        ...
Run Code Online (Sandbox Code Playgroud)

基本上,我试图写入(en)的位的位置根据我正在谈论的地址而变化,具体取决于i.此代码不可合成,因为i它不是常量.

还有其他解决方法吗?我知道的唯一解决方法是写出CONST时间的这三个语句.我希望我最终不必那样做.还有其他解决方案吗?

Mar*_*rty 5

看起来您一直在尝试复制readdata到,但如果满足某些特殊情况条件,writedata请填写 LSB 。en我还将假设for您的循环位于一个always块中,并且您打算构建组合逻辑。

从硬件角度来看,您编写的循环for对我来说没有多大意义。循环for用于构建逻辑数组,正如您编写的那样,您将至少有 3 个逻辑锥尝试在整个writedata总线上设置值。(如果它生成任何东西,那将是一些奇怪的优先级结构)。

也就是说,编译器抱怨的可能是范围选择,即 thewritedata[2-i:0]而不是 the writedata[3-i] = en[i];:部分选择中包含的任何内容)。如果您想按照这些思路做一些事情,您可以使用“索引部分选择”(+:-:),但在这种情况下有更好的解决方案。

我将其重写如下 - 假设我假设正确:)

always @( /*whatever*/ ) begin

    // default assignment
    writedata = readdata;

    // overwrite some bits in writedata for special cases
    for(i=0; i<3; i++) begin
        if( changed[i] & !done_q[i] )
             writedata[3-i] = en[i];
    end
end
Run Code Online (Sandbox Code Playgroud)

在此代码中,我设置writedatareaddata,然后调整writedata特殊情况下的结果值。该for循环正在构建 3 个逻辑锥,每个逻辑锥对应 中的每一位writedata[3:1]。我会仔细检查位映射是否是您想要的 - 即映射en[2:0]writedata[1:3].

  • 多谢!我真是个白痴,没有想到这一点......当然,这是显而易见的解决方案!我只是仔细检查了一下,Quartus 编译器只给出了范围赋值的错误,而不是 [3-i] 的错误。而且你确实假设一切都是正确的:) (2认同)