0
\$\begingroup\$

I have a vector that contains 15 elements of 8 bits each. I want to XOR each element: $$ out = f_0 \oplus f_1 \oplus \dots \oplus f_{15} $$ where each \$f_i\$ has 8 bits (it's declared as logic [7:0] f1 [0:15];). I know how to do it with one dimensional vector, I'd just do out = ^vector; How do I do with this two dimensional vector? I tried:

out = ^f;

and

out = ^f[7:0];

None of them seem to have a correct syntax.

\$\endgroup\$
  • \$\begingroup\$ You have an 1D array of 15 U8 values to be XOR'd in sequence (bitwise) to give a final value. Where is this confusing you? This is not 2 dimensional unless you need to XOR the result to just a single bit. \$\endgroup\$ – Sparky256 May 5 '19 at 3:41
  • 1
    \$\begingroup\$ If have declared it as logic [7:0] f1 [0:15]; you should at least use out = ^f1; but you can't do that as f1 is not a packed array. So you have to use a loop in which you use ^f1[i]. \$\endgroup\$ – Oldfart May 5 '19 at 8:07
0
\$\begingroup\$

I interpret your question to that you want an 8-bit output. I would do this as follows:

always_comb begin
  out = '0;
  for (int i = 0; i < 16; i++)
    out ^= f[i];
end

If you want a single-bit output (i.e., xoring everything together), you can do this by defining your array with two packed dimensions, then use the reduction operator. E.g.,:

logic [15:0][7:0] f;

assign out = ^f;
\$\endgroup\$
  • \$\begingroup\$ Beware that for (int i = 0; ... is system Verilog. In standard Verilog use integer i; for (i=0; i<16; i=i+1) \$\endgroup\$ – Oldfart May 5 '19 at 14:01
  • \$\begingroup\$ packed dimensions are a nice solution if the are supported. They are actually part of system verilog but some "standard" verilog tool recognizes them as well. Just be aware that something like "Multiple packed dimensions are not allowed in this mode of verilog" can occur. \$\endgroup\$ – Christian B. May 5 '19 at 14:56
  • \$\begingroup\$ This question was tagged with system-verilog though. \$\endgroup\$ – pc3e May 6 '19 at 15:14
1
\$\begingroup\$

To the best of my knowledge 2D arrays in verilog are actually not "really" two dimensional coherent blocks but m "instances" of an n element 1D array. So long story short: there is no way to do it as shortcut version afaik and one has to loop over the second dimension:

integer i;
for (i = 0; i < 16; i = i +1) begin
   out <= out ^ (^f[i]);
end

Alternatively you can try to replace the 2D array with a 1D array by remapping:

[8*16-1:0] logic;

wire [7:0] first_byte = [0+:8] logic; //synonym to [7:0] logic
wire [7:0] second_byte = [8+:8] logic; //synonym to [15:8] logic
...

Then you can XOR the whole array at once as you are used to.

\$\endgroup\$
0
\$\begingroup\$

You can use the xor() reduction method.

out = f.xor()

See Section 7.12.3 Array reduction methods in the IEEE 1800-2017 LRM.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.