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:
- Bit assignment
- Array slice assignment
- 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
)