1

我希望能够使用生成块参数化一些行为级别的 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 个语句。

然而,我的问题是如何使用生成参数化它?显然,如果 '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 总是以参数化的形式阻塞......

4

2 回答 2

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,您将不得不修改它以破坏输入数组,但概念是相同的。

于 2013-04-23T14:33:17.243 回答
1

您不需要生成块。添加一个组合 always 块以计算next_SENSE_ADDR将失败到SENSE_ADDR.

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
于 2013-04-23T17:12:17.603 回答