reg a[4:0];
reg inv_a[4:0];
assign inv_a = ~a; //This doesn't work.
当我尝试使用带有上述语句的modelsim时,它会抛出:"对解压缩类型的非法操作"
有人可以指出如何正确否定Verilog中的数组吗?
编辑:提供更多信息,这是否会改变任何建议?
module router_main(
input bustorouter_ready[4:0],
);
wire inv_bustorouter_ready[4:0];
assign inv_bustorouter_ready = ~bustorouter_ready; //Still doesn't work.
答案 0 :(得分:4)
一种单线解决方案,用于反转通过比特流实现的解压缩阵列(请参阅IEEE Std 1800-2012& sect; 11.4.14 流媒体运营商(打包/解压缩)以获取完整详细信息)
logic a[4:0];
logic inv_a[4:0];
assign {<<{inv_a}} = ~{<<{a}}; // bit streaming
比特流仅适用于SystemVerilog。如果您仅限于Verilog,则必须使用for循环或generate-for-loop(请参阅Tudor&#39; s answer)。
另一件需要考虑的事情是,是否需要解包数组。打包的阵列允许整体访问阵列。 Verilog不允许通过端口连接传递解压缩的数组,允许打包数组。 SystemVerilog支持将打包的数组打包为端口。
reg [4:0] a;
reg [4:0] inv_a;
assign inv_a = ~a; // pack array
一般来说,它取决于您希望如何访问阵列。如果您希望被视为一个数字,请使用压缩数组;仍然允许单个元素访问。如果您只想访问数组中的各个元素,请使用unpacked。有关打包和解压缩的更多信息,请参阅前面已回答的问题:
答案 1 :(得分:3)
尝试在组合过程中使用for
循环:
always_comb
for (int i = 0; i <= 4; i++)
inv_a[i] = ~a[i];
由于我猜你正在做设计,你需要检查你的综合工具是否支持这种结构。
或者您可以使用generate
:
genvar i;
for (i = 0; i <= 4; i++)
always_comb
inv_a[i] = ~a[i];
答案 2 :(得分:2)
更改reg
的{{1}},因为wire
需要:{/ p>
assign
或者,如果您使用reg [4:0] a;
wire [4:0] inv_a;
assign inv_a = ~a; //This should work.
块,则可以将inv_a
保留为reg
:
always
reg [4:0] a;
reg [4:0] inv_a;
always @*
inv_a = ~a; //This should work.
似乎与reg a[4:0]
;
reg [4:0] a
与reg a[4:0]
相同:一个包含5个寄存器的数组,每个寄存器为1位。
reg [0:0] a[4:0]
是一个5位寄存器。
减少运算符以及一元逆变器运算符(这是逐位运算的)仅在单个向量(寄存器)上运行。你的第一个声明声明了5个向量。
答案 3 :(得分:2)
您只能对压缩数组(位向量)执行逻辑运算。整个解压缩阵列允许的唯一操作是复制和比较。
如果必须在一行中执行此操作,则可以将解压缩的数组转换为打包数组并返回。
typedef logic ua5[5];
typedef logic bit [4:0] pa5;
ua5 a; // same as reg a[4:0]
ua5 inv_a;
assign inv_a = ua5'(pa'(~a));
否则,我会推荐一个foreach循环
always_comb foreach (a[i]) inv_a[i] = ~a;
答案 4 :(得分:0)
你可以用一系列的x来对它进行xor:
assign inv_a = a ^ {WIDTH{1'b1}};
答案 5 :(得分:-1)
您可以通过对打包数组使用逻辑运算来进行反转。
assign inverted_a = ((a)^(4'b1111));
X (XOR) 1 = ~X
然后,您可以将二进制数编辑为输入或寄存器的宽度
例如7'b11111111
或3'b111
。