我创建了一个模块,它接受一个参数,指定模块数据行的字节宽度。它看起来像:
module wrapper#
(
parameter DATA_BYTE_WIDTH = 1
)
(
din, dout, ..
);
localparam DATA_BIT_WIDTH = 8*DATA_BYTE_WIDTH;
input [DATA_BIT_WIDTH-1:0] din;
output [DATA_BIT_WIDTH-1:0] dout;
.....
generate
if( DATA_BYTE_WIDTH == 1 ) begin
// Various modules and interconnects for 1-byte data
else if( DATA_BYTE_WIDTH == 2) begin
// Various modules and interconnects for 2-byte data
else if....
// and so on, for 4, 8, and 16
else
// DATA_BYTE_WIDTH is not a valid value
// HERE is where I want to throw an error
end
endgenerate
// other code
endmodule
问题是唯一有效的宽度是1,2,4,8或16个字节。如果DATA_BYTE_WIDTH使用任何其他值,则根本不会生成互连。但Xilinx似乎并不关心这一点。它会愉快地生成"如果提供了无效值,则不会产生任何结果:生成的设计会合成,但根本不起作用。
有没有办法检查参数的值并在错误时抛出错误?我已经尝试了$error
和assert
(正如所讨论的here),以及$display
(如上所述here)。 Xilinx拒绝使用任何这些函数,而是抛出语法错误并拒绝继续。
理想情况下,我想在else
内的最终generate
内投入一些东西,但此时我会满足于此。
答案 0 :(得分:2)
Verilog没有一个干净的解决方案来验证参数。在任何版本的IEEE Std 1364中都不会提到至少一个。最好的Verilog只能使用不存在的模块。
generate
// ...
else begin // invalid parameter configuration
nonexistent_module_to_throw_a_custom_error_message_for invalid_parameters();
end
endgenerate
false 替代方法是将不存在的模块行替换为:
initial begin
$display("Runtime error for invalid parameter value %b",DATA_BYTE_WIDTH);
$finish(1);
end
这是 false 替代方法,因为大多数综合工具会忽略$display
(我相信它们也会忽略$finish
)。在编译之后,您也不会知道在模拟之前存在参数问题。不存在的模块是优越的,因为它是语法清除参数条件编译错误。它只缺少显示违规参数值的消息。
从IEEE Std 1800-2009开始,SystemVerilog中存在一个干净的解决方案,它添加了精化系统任务。看起来Xilinx ISE不支持SystemVerilog。 Xilinx Vivado确实如此,但我不确定它是否完全投诉LRM。如果可以,请尝试一下。阅读IEEE Std 1800-2012§20.11精化系统任务中的完整说明。 (* - 2012可以免费下载,以促进SV的采用。* -2009更老,仍然在支付墙后面。关于详细系统任务的部分在两个版本之间逐字逐句。)
generate
// ...
else begin // invalid parameter configuration
$error("Elaboration error for invalid parameter value %b in", DATA_BYTE_WIDTH);
/* alternative $fatal. This prevents further elaboration from
happening. $error allows the rest of the design to elaborate.
Both block simulation. */
//$fatal(1,"Fatal elab. error for invalid parameter value %b in", DATA_BYTE_WIDTH);
end
endgenerate