Search code examples
system-veriloghdl

Rewrite long xor statement


Look at the following statement. c_r gets assigned an xor versioned of all c[k].

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

The design works, however is there a possibility to refactor the statement for easier maintenance and readability?

Note: c is defined as logic [7:0] c[16][16];


Solution

  • I would propose the following:

    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
    

    The foreach will iterate through all selected indexes. See IEEE Std 1800-2012 § 12.7.3 The foreach-loop for full syntax usage and functionality. ^= is a binary bitwise assignment operators, refer to IEEE Std 1800-2012 § 11.4 Operator descriptions. There are various code examples for foreach and ^= throughout the LRM.