2013-04-23 68 views
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”否则,如果块,如果中的语句我对它们进行了硬编码,目前的综合和仿真都适用于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总是阻止在参数化形式的功能...

回答

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

你不需要一个生成块。总是添加一个组合块来计算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