SystemVerilog中可变宽度的位切片



我正试图使用+:运算符访问数组的某些部分,但却出现了臭名昭著的[variable] is not a constant错误。唯一的问题是,我希望从数组中获得的宽度也在变化。

这是我的循环:

logic [N-1:0] a;
logic [2**N-2:0] b;
for (i = 0; i < N; i++)
a[i] = b[(2**i)-1 +: 2**i] == {(2**i){1'b1}};

换句话说,如果N = 4,我想让这个循环这样做:

a[0] = b[0:0] == 1'b1;
a[1] = b[2:1] == 2'b11;
a[2] = b[6:3] == 4'b1111;
a[3] = b[14:7] == 8'b11111111;

从逻辑上讲,我非常确信我提供的循环是有效的,但是SystemVerilog不允许使用非常量来设置宽度(在a:之后(。当我的起始索引和宽度都依赖于一个非常量变量时,我如何使用+:运算符?或者考虑到CCD_ 6可以是一个大的数字,是否存在另一种实现这一点的方法。

谢谢!

编辑:

这可以通过轮班来完成,这里有一个工作代码:

for (i = 0; i < N; i++)
a[i] <= ((b >> (2**i)-1) << ((2**N) - (2**i) - 1)) == 
{(2**N-1){1'b1}} << ((2**N) - (2**i) - 1);

不能使用宽度可变的+:。实际上,这只是换班和戴口罩的捷径。例如,以下内容应该适用于您的情况:

logic [N-1:0] a;
logic [2**N-2:0] b;
always_comb begin
for (int i = 0; i < N; i++) begin
logic [2**N-2:0] tmpb, tmp1;
tmpb = b >> ((2**i)+1);
tmp1 = ((2**N)'(1) <<  (2**i)) - 1;
a[i] = (tmpb & tmp1) == 0;
end
end

你只需要计算出偏移和宽度的确切数字。

您可以将'+:'运算符与掩码组合使用

parameter N  = 8; localparam N2 = 2**(N-1);
logic [N-1:0] a;
logic [2**N-1:0] b;
initial begin
b       ={8'b000001,4'b1111,2'b01,1'b1};
for (int i = 0; i < N; i++)
a[i]  = (b[(2**i)-1 +: N2] | ~N2'((1 << 2**i)- 1)) == '1;
$displayb(a,,b);
end

如果右手边是常数或genvar,则可以使用+:

logic [N-1:0] a;
logic [2**N-2:0] b;
for (genvar i = 0; i < N; i++) begin : gen_a
assign a[i] = b[(2**i)-1 +: 2**i] == {(2**i){1'b1}};
end

注意,这个for循环是一个不在过程块(即begin-end(内的生成for循环

最新更新