0

I have a vector like this

wire [N:0] Vector[M:0];

and I want to convert it into an array of size M*N. A pseudocode could be:

Array={Vector[M],Vector[M-1],Vector[M-2],...,Vector[0]}

So I want to concatenate the elements of the vector in an array. I tried to do it using a loop, but when I try to simulate it gives a fatal error without description. Is there a simpler way of doing it? Thanks!!!

1 Answers1

3

I guessing you tried something like this: Array[N*(index+1) : N*index ] = Vector[index]; in an always block. This will not work because Verilog requires both sides of the range to be constants (during simulation).

There are three Verilog approaches to get the desired assignment:

  1. Bit assignment
  2. Array slice assignment
  3. Generate loop assignment

Bit assignment
In Verilog-95 (IEEE1364-1995), the only ways achieve this was bit assignments with a double for-loop:
Array[N*index_m+index_n] = Vector[index_m][index_n];

reg [M*N:0] Array;
integer index_m, index_n;
always @(Vector) begin // Verilog-95 style sensitivity list
  for(index_m=0; index_m <= M; index_m = index_m + 1) begin
    for(index_n=0; index_n <= N; index_n = index_n + 1) begin
      Array[N*index_m+index_n] = Vector[index_m][index_n];
end
endgenerate

Array slice assignment
Another approach is vector slicing with +: (A feature added in IEEE1364-2001. Refer to Indexing vectors and arrays with +:). This allows one variable starting index and a constant offset for the range.
Array[N*index +: N ] = Vector[index];

reg [M*N:0] Array;
integer index;
always @* begin // Verilog-2001 style sensitivity list
  for(index=0; index <= M; index = index + 1) begin
    Array[index*N +: N ] = Vector[index];
end
endgenerate

Generate loop assignment
A third approach would be to use a generate block (also added in IEEE1364-2001). A generate blocks for-loop unravels at elaboration. There form you could use Array[N*(index+1) : N*index ] = Vector[index];, provided that index is a genvar: Or with a generate block

wire [M*N:0] Array; // note 'wire'
generate
genvar g_index; // The 'g_' prefix is suggested coding style to identified genvars
for(g_index=0; g_index <= M; g_index = g_index + 1) begin
  assign Array[(g_index+1)*N] : g_index*N] = Vector[g_index];
  //assign Array[g_index*N +: N ] = Vector[g_index]; // +: also works
end
endgenerate

SytemVerilog (IEEE1800) added bit streaming which can do the operation in one step Array = {>>{Vector}};, but I am unaware how common it is supported for synthesis. (I typically use array slicing (+:) with SystemVerilog's foreach in an always_comb)

Greg
  • 18,111
  • 5
  • 46
  • 68