我希望能够使用生成块参数化某些行为级别的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总是以参数化形式阻塞......
答案 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