生成块编译时​​间If-Else参数化

时间:2013-04-23 08:52:08

标签: if-statement verilog

我希望能够使用生成块参数化某些行为级别的Verilog。该模块用于可重新配置的读出和FIFO模块,主要是因为我们可以对其进行编码,只需在顶层使用参数。

让我们说:

always @(posedge write_out_clk or posedge RESETN)
 begin
   if (RESETN)          
    SENSE_ADDR <= 0;
   else if (enb[0] == 1)
        SENSE_ADDR <= 1;   // for example but may be some other wire/bus etc
   else if (enb[1] == 2)
        SENSE_ADDR <= 1;   // for example but may be some other wire/bus etc
   else
    SENSE_ADDR <= SENSE_ADDR;
   end
 end

这是行为,因此实现的细节留给编译器,用户给定时序约束等。如果我对它们进行硬编码,这适用于块中的'n'else-if语句,目前合成和模拟都适用于16个陈述。

我的问题是如何使用generate参数化?很明显,如果'n = 8',硬编码并不是什么大不了的事。如果'n = 64'或'n = 128'等,如果模块的其余部分使用'n'的生成完全参数化,那么硬编码似乎是一种耻辱......

我尝试过这样的事情:

genvar elseif_generate;
generate
   for (elseif_generate=0; elseif_generate<FIFO_SUB_BLOCKS; elseif_generate=elseif_generate+1)
   begin: elseif_generate_logic
   always @(posedge write_out_clk or posedge RESETN)
    begin
    if (RESETN)
        SENSE_ADDR <= 0;
    else if (enb[elseif_generate] == 1)
        SENSE_ADDR <= some_wire[elseif_generate];
    else
        SENSE_ADDR <= SENSE_ADDR;
    end
   end
endgenerate

然而,这导致输出线'SENSE_ADDR'的多源错误。这引出了我进一步的问题。显然,生成块不适用于此块,但我将如何为此块实现参数化代码复制?基本上我想要行为的功能,硬编码if-else总是以参数化形式阻塞......

2 个答案:

答案 0 :(得分:1)

这是否符合您的需求?无需生成。

module mux #(
        parameter WIDTH = 5,
        parameter NUM   = 2,
        parameter NUMLG = $clog2(NUM)
    ) (
        input [NUMLG -1:0] sel,
        input [WIDTH - 1:0] in [0:NUM-1],
        output [WIDTH - 1:0] out
    );

    assign out = in[sel];

endmodule

如果你的模拟器不能很好地支持SystemVerilog,你必须修改它以吹灭输入数组,但概念是相同的。

答案 1 :(得分:1)

您不需要生成块。添加一个组合始终阻止计算将next_SENSE_ADDR转换为SENSE_ADDR的{​​{1}}。

always @(posedge write_out_clk or posedge RESETN)
 begin
   if (RESETN)          
    SENSE_ADDR <= 0;
   else
    SENSE_ADDR <= next_SENSE_ADDR;
 end

integer idx;
always @* begin // @(SENSE_ADDR or enb or some_wire)
  next_SENSE_ADDR = SENSE_ADDR; // default, value if enb is all 0
  // count down because lsb has higher priority
  for ( idx=FIFO_SUB_BLOCKS-1; idx>=0; idx-- ) begin
    if ( enb[idx] )
      next_SENSE_ADDR = some_wire[idx];
  end
end