有时情况出现在参数化代码中,我想检查数组切片,如果该切片的宽度不为零。我可能写这样的东西:
parameter SLICE_WIDTH;
parameter SLICE_BASE;
logic [my_array_size : 0] my_array;
//...
always_ff @ (posedge clk) begin
if (SLICE_WIDTH==0 || my_array[SLICE_BASE+:SLICE_WIDTH]==0) begin
//alternately "if (SLICE_WIDTH==0 || my_array[SLICE_WIDTH+SLICE_BASE-1:SLICE_BASE]==0) begin"
//do something
end
else begin
//do something else
end
end
这是我在编写VHDL时处理这些情况的方式;在常量评估中依赖于短路以防止无效的阵列范围被评估。在编写的系统verilog中,这会在QuestaSim中引发“部分选择范围被反转”错误和“范围宽度不能为零”错误。
有没有办法干净地处理大多数工具接受的空范围而不将//do something
的内容复制到几个if-generate结构中?
答案 0 :(得分:0)
您可以做的是创建一个掩蔽参数
parameter SLICE_WIDTH;
parameter SLICE_BASE;
localparam logic [my_array_size : 0] MASK) = 2**SLICE_WIDTH - 1 << SLICE_BASE;
logic [my_array_size : 0] my_array;
//...
always_ff @ (posedge clk)
if (my_array&MASK) begin
//do something
end
else begin
//do something else
end
当MASK为0时,综合工具将优化逻辑。
没有测试过这个,所以你可能不得不玩我的等式。
答案 1 :(得分:0)
在verilog中处理它的常用方法是生成&#39;块。
parameter SLICE_WIDTH;
parameter SLICE_BASE;
logic [my_array_size : 0] my_array;
//...
// generate
if (SLICE_WIDTH==0) begin
// do something here
end
else begin
always_ff @ (posedge clk) begin
if ( my_array[SLICE_BASE+:SLICE_WIDTH]==0) begin
//do something
end
else begin
//do something else
end
end
end // endgenerate
使用SV,您不需要使用generate / endgenerate关键字。