2

How can one assign a multi dimensional array if it is a wire, in a single line?

assign TO[W1:0][W2:0] = cntrl ? FROM1[W1:0][W2:0] : FROM2[W1:0][W2:0];  

I get a syntax error if I use this.

Is there any other way other than using generate or for loops?

3
  • 3
    Can you show your types and your specific error message? Commented Jul 8, 2015 at 13:18
  • In verilog, this is impossible without a loop or without slices. A specific error message for ncvlog is "Memory or an array reference requires an index." In iverilog the message is "Cannot assign to array xxxx. Did you forget a word index?" Commented Mar 13, 2018 at 19:04
  • In other words, an N-dimensional array will require N-1 for loops in Verilog. Commented Mar 13, 2018 at 19:24

3 Answers 3

1

You need to be using SystemVerilog to make aggregate assignments to arrays.

Sign up to request clarification or add additional context in comments.

Comments

0

To assign an unpacked arrays braces with tick '{ and } are used, provided all the values of the array should be assigned.

usage example

module top ( input i);

  wire d [0:1][0:3];
  wire a [0:1][0:3]='{ '{1,1,1,1}, '{1,1,1,1} };
  wire b [0:1][0:3]='{ '{0,0,0,0}, '{0,0,0,0} };

  assign  d = i? (' { '{a[0][0],a[0][1],a[0][2],a[0][3]},'{b[1][0],b[1][1],b[1][2],b[1][3]}}):
                 (' { '{b[1][0],b[1][1],b[1][2],b[1][3]},'{a[0][0],a[0][1],a[0][2],a[0][3]}});
endmodule

Here wire a [0:1][0:3]='{ '{1,1,1,1}, '{1,1,1,1} }; and wire b [0:1][0:3]='{ '{0,0,0,0}, '{0,0,0,0} }; represents

// a[0][0] = 1  b[0][0] = 0
// a[0][1] = 1  b[0][1] = 0
// a[0][2] = 1  b[0][2] = 0
// a[0][3] = 1  b[0][3] = 0
// a[1][0] = 1  b[1][0] = 0
// a[1][1] = 1  b[1][1] = 0
// a[1][2] = 1  b[1][2] = 0
// a[1][3] = 1  b[1][3] = 0

Working example can be found in the eda-playground link

3 Comments

Although legally correct, this syntax is not relevant to the questions
@dave_59 Yes, although it is SV, since it was mentioned without using generate or for loops I took the alternate approach
The problem here is is W1 and W2 MSBs in the OP are module parameters derived from instantiation. In other words, this syntax doesn't work for arbitrarily large arrays. But this answer is interesting if the array sizes are fixed.
0

Two pure verilog solutions: (Assuming W1 and W2 are parameters, not variables)

// 'TO' must be a reg
integer i,j;
always @* begin
  for(i=0; i<=W1; i=i+1) begin
    for(j=0; j<=W2; j=j+1) begin
      TO[i][j] = cntrl ? FROM1[i][j] : FROM2[i][j];
    end
  end
end

 

// 'TO' must be a wire
genvar i,j;
generate
  for(i=0; i<=W1; i=i+1) begin
    for(j=0; j<=W2; j=j+1) begin
      assign TO[i][j] = cntrl ? FROM1[i][j] : FROM2[i][j];
    end
  end
endgenerate

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.