重写长xor语句

问题描述 投票:3回答:3

请看以下声明。 c_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

然而,设计是否有可能重构声明以便于维护和可读性?

注意:c定义为logic [7:0] c[16][16];

system-verilog hdl
3个回答
2
投票

我建议如下:

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

foreach将遍历所有选定的索引。请参阅IEEE Std 1800-2012§12.7.3foreach-loop以获取完整的语法用法和功能。 ^=是一个二进制位运算符,参考IEEE Std 1800-2012§11.4运算符描述。整个foreach^=LRM的各种代码示例。


1
投票

您可以尝试在里面使用for循环来计算XOR结果并将其分配给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

我不确定这将如何与你的工具合成,但我看到我的同事一直使用这些技巧(用VHDL)。


0
投票

减少运算符对此很有用,一个简短的例子:

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

如果无法嵌入第二个循环(将其提取到组合部分):

logic [15:0] parity_bus;

always_comb begin
  for(k = 0; k < 16; k++) begin
  parity_bus[k] = 1'b0;
    for(int i = 0; i < 16; i++) begin
      parity_bus[k] = parity_bus[k] ^c[k][i];
    end
  end
end

always_ff @ (posedge clk_i) begin     
  for(k = 0; k < 16; k++) begin
    c_r[k*8 +: 8] <= parity_bus[k];
  end
end

您有效地并行描述了16组XOR逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.