Search code examples
verilogsystem-verilog

Concatenate arrays of bytes into one array


Can I concatenate these byte banks:

logic [7:0] bank3[0 : 255];
logic [7:0] bank2[0 : 255];
logic [7:0] bank1[0 : 255];
logic [7:0] bank0[0 : 255];

To something like;

logic [32:0] address_array [0:255];
assign address_array = {bank3, bank2, bank1, bank0}; //!This is pseudocode!

The resulting array's size is 256 x 32bits.

Example:

If I want to read addresses 0x0,0x1,0x2,0x3 then I will access address_array[0]. Array's index should range from 0 to 255 and be 32bits wide.


Solution

  • No need to use generates a standard for loop will do:

    reg [7:0] bank3[0 : 255];
    reg [7:0] bank2[0 : 255];
    reg [7:0] bank1[0 : 255];
    reg [7:0] bank0[0 : 255];
    reg [31:0] address_array[0:255];
    integer i;
    
    always @* begin
      for (i=0;i<256;i=i+1) begin
        address_array[i] = {bank3[i],bank2[i],bank1[i],bank0[i]};
      end
    end
    

    In SystemVerilog:

    logic [7:0] bank3[0 : 255];
    logic [7:0] bank2[0 : 255];
    logic [7:0] bank1[0 : 255];
    logic [7:0] bank0[0 : 255];
    logic [31:0] address_array[0:255];
    
    always_comb begin
      for (int i=0;i<256;i++) begin
        address_array[i] = {bank3[i],bank2[i],bank1[i],bank0[i]};
      end
    end
    

    As Greg has mention this could also utilise a foreach:

    always_comb begin
      foreach ( bank_all[i] ) begin
        bank_all[i]= { bank_stack3[i], bank_stack2[i], bank_stack1[i], bank_stack0[i]};
      end
    end
    

    Solution 2

    The question actually specified that instead of all of the banks to be 'stacked' vertically next to each other that bank0 would be reshaped to utilise the 32bit width. bank0 would be fully read before reaching bank1.

    localparam DEPTH = 8;
    logic [7:0] bank0[0 : DEPTH-1];
    logic [7:0] bank1[0 : DEPTH-1];
    logic [7:0] bank2[0 : DEPTH-1];
    logic [7:0] bank3[0 : DEPTH-1];
    
    logic [7:0]       bank_stack [(DEPTH*4) -1];
    logic [(8*4)-1:0]   bank_all  [0 : DEPTH-1];
    
    always_comb begin
      //First reshape vertically stack banks
      // IEEE 1800-2012 Section 11.4.14 Streaming operators
      {>>{bank_stack}} = {>>{bank0, bank1, bank2, bank3}};
    
      //Second reshape, flatten to 4 bytes wide.
       foreach ( bank_all[i] ) begin
        bank_all[i]= { bank_stack[i], bank_stack[i+1], bank_stack[i+2], bank_stack[i+3]};
      end
    end
    

    Short example on EDA Playground.

    Thanks to Greg for the insight into IEEE 1800-2012 Section 11.4.14 Streaming operators.