无法访问的评估中的 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 关键字。