无法访问的评估中的 Verilog null/invalid 切片范围
Verilog null/invalid slice ranges in unreachable evaluations
有时在参数化代码中会出现一种情况,我想检查一个数组切片,前提是该切片的宽度不为零。我可能会这样写:
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 中引发 "range of part select is reversed" 错误和 "range width cannot be zero" 错误。
有没有一种方法可以干净地处理大多数工具接受的空范围,而无需将 //do something
的内容复制到多个 if-generate 结构中?
您可以做的是创建一个屏蔽参数
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 时,综合工具将优化逻辑。
没有对此进行测试,因此您可能需要玩一下我的等式。
在 verilog 中处理它的常用方法是 'generate' 块。
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 关键字。
有时在参数化代码中会出现一种情况,我想检查一个数组切片,前提是该切片的宽度不为零。我可能会这样写:
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 中引发 "range of part select is reversed" 错误和 "range width cannot be zero" 错误。
有没有一种方法可以干净地处理大多数工具接受的空范围,而无需将 //do something
的内容复制到多个 if-generate 结构中?
您可以做的是创建一个屏蔽参数
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 时,综合工具将优化逻辑。
没有对此进行测试,因此您可能需要玩一下我的等式。
在 verilog 中处理它的常用方法是 'generate' 块。
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 关键字。