System verilog 重写长xor语句

System verilog 重写长xor语句,system-verilog,hdl,System Verilog,Hdl,请看下面的陈述c\u r被分配一个所有c[k]的xor版本 always_ff @ (posedge clk_i) begin for(k = 0; k < 16; k++) c_r[k*8 +: 8] <= c[k][0] ^ c[k][1] ^ c[k][2] ^ c[k][3] ^ c[k][4] ^ c[k][5] ^ c[k][6] ^ c[k][7] ^ c[k][8] ^ c[k][9] ^ c[k][10] ^ c[k][11] ^ c[k][12] ^

请看下面的陈述
c\u r
被分配一个所有
c[k]
的xor版本

always_ff @ (posedge clk_i)
begin
  for(k = 0; k < 16; k++)
    c_r[k*8 +: 8] <= c[k][0] ^ c[k][1] ^ c[k][2] ^ c[k][3] ^ c[k][4] ^ c[k][5] ^ c[k][6] ^ c[k][7] ^ c[k][8] ^ c[k][9] ^ c[k][10] ^ c[k][11] ^ c[k][12] ^ c[k][13] ^ c[k][14] ^ c[k][15];
end
everys_ff@(posedge clk_i)
开始
对于(k=0;k<16;k++)

c_r[k*8+:8]归约运算符对此很有用,举个简单的例子:

wire result;
wire [3:0] bus;

//assign result = bus[0] ^ bus[1] ^ bus[2] ^ bus[3];
assign result = ^bus;
因此一元
^
将总线折叠为一个位,这也适用于
&
|

在你的情况下,我认为这应该是可行的:

always_ff @ (posedge clk_i)
begin
  for(k = 0; k < 16; k++)
    c_r[k*8 +: 8] <= ^c[k];
end
everys_ff@(posedge clk_i)
开始
对于(k=0;k<16;k++)

c_r[k*8+:8]您可以尝试在内部使用
for
循环来计算异或结果,并将其分配给
c_r
切片:

  always_ff @ (posedge clk_i)
  begin
    for(int k = 0; k < 16; k++) begin
      logic [7:0] xor_result;
      for (int i = 0; i < 16; i++)
        xor_result ^= c[k][i];
      c_r[k*8 +: 8] <= xor_result;
    end
  end
everys_ff@(posedge clk_i)
开始
对于(int k=0;k<16;k++)开始
逻辑[7:0]xor_结果;
对于(int i=0;i<16;i++)
xor_result^=c[k][i];

我提议如下:

logic [16*8-1:0] c_r, next_c_r;
logic [7:0] c[16][16];

always_comb begin
  next_c_r = '0;
  foreach(c[idx0,idx1]) begin
    next_c_r[idx0*8 +: 8] ^= c[idx0][idx1];
  end
end

always_ff @ (posedge clk_i)
begin
  c_r <= next_c_r;
end
logic[16*8-1:0]c\r,下一个c\r;
逻辑[7:0]c[16][16];
总是从梳子开始
next_c_r='0;
foreach(c[idx0,idx1])开始
下一步是[idx0*8+:8]^=c[idx0][idx1];
结束
结束
始终_ff@(posedge clk_i)
开始

谢谢你。不幸的是,这还不起作用
c
定义为
logic[7:0]c[16][16]。使用建议的解决方案,我得到以下错误消息:
error-[IMEMCT]无效内存使用率design.sv,17内存或内存片不允许在以下上下文中使用:1。if/case/while语句中的条件表达式等2。赋值语句的源或目标表达式3。相等运算符表达式的操作数:(^c[k])
这样的循环会是什么样子?我很困惑,因为这会像是
c\uxor[k]=c\uxor[k]^c[k][l]
对吧?我们来这里不是为了简单的事情;-)。我不明白内环。这不是一个组合循环吗?是的。这是一种可能性。但是,我认为这不会提高可读性。此解决方案实现了更易于维护的目标,因为c[k][0]到c[k][15]没有手动列出,因此将来如果需要,更容易更改数字“16”。然而,我认为一些合成工具不知道如何最好地重新排列xor链以减少逻辑深度,而使用reduce xor操作符,该工具在选择xor拓扑时具有更大的灵活性。在过去的这些类型的场景中,我使用循环来重新排列数组索引,这样就可以使用归约运算符。@Morgan这在IEEE 1800-2012标准的第11.3节运算符中。与问题无关,因此我将此作为一个注释:我更喜欢将顺序逻辑作为简单的赋值。这样,所有计算代码都被分组在一起。我发现这有助于提高代码的可读性,因为我不必跳转到另一个always块来查看最终的计算结果。拥有一个
next.*
是一个稍微多的输入,但在调试时非常值得。
logic [16*8-1:0] c_r, next_c_r;
logic [7:0] c[16][16];

always_comb begin
  next_c_r = '0;
  foreach(c[idx0,idx1]) begin
    next_c_r[idx0*8 +: 8] ^= c[idx0][idx1];
  end
end

always_ff @ (posedge clk_i)
begin
  c_r <= next_c_r;
end