Search code examples
vhdl

VHDL concatenation of two ARRAYS types std_logic


Hi I'm trying out using ARRAYS for memory. I would like to concatenate 4 smaller ARRAYS into a larger ARRAY. I've tried using the ampersand to do this as so:

MEM_STRING(1) <= MEM_CHAR(3) & MEM_CHAR(3) & MEM_CHAR(0) & MEM_CHAR(1);

But the compiler says that it finds no definitions of the & character. The MEM_STRING(1) is 28 bits and each MEM_CHAR is 7 bits. I could convert each MEM_CHAR to std_logic_vector, assign to a signal and then concatenate, but it seems like a very long way to go about things. Is there any other way to do this?

TYPE SEG7 IS ARRAY (6 DOWNTO 0) OF std_logic; 
TYPE REG_CHAR IS ARRAY (3 DOWNTO 0) OF SEG7; --Array block for characters
TYPE STRINGS IS ARRAY (27 DOWNTO 0) OF std_logic;
TYPE REG_STRINGS IS ARRAY (6 DOWNTO 0) OF STRINGS; --Array block for strings
SIGNAL MEM_CHAR          : REG_CHAR; --Assign character
SIGNAL MEM_STRING        : REG_STRINGS; --Assign String

These are the ARRAY declerations used. Best Regard D


Solution

  • I could convert each MEM_CHAR to std_logic_vector, assign to a signal and then concatenate, but it seems like a very long way to go about things. Is there any other way to do this?

    MEM_CHAR and std_logic_vector aren't closely related. The element type of MEM_CHAR is SEG7 and the element type of std_logic_vector is std_ulogic.

    You should create an aggregate of type REG_CHAR and convert that to type STRINGS:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity memchar is 
    end entity;
    
    architecture foo of memchar is
    
        TYPE SEG7 IS ARRAY (6 DOWNTO 0) OF std_logic; 
        TYPE REG_CHAR IS ARRAY (3 DOWNTO 0) OF SEG7; --Array block for characters
        TYPE STRINGS IS ARRAY (27 DOWNTO 0) OF std_logic;
        TYPE REG_STRINGS IS ARRAY (6 DOWNTO 0) OF STRINGS; --Array block for strings
        SIGNAL MEM_CHAR:           REG_CHAR; --Assign character
        SIGNAL MEM_STRING:         REG_STRINGS; --Assign String
    
        function to_strings (REGC: REG_CHAR) return STRINGS is
            variable retstr: STRINGS;
            subtype strings_range is natural range STRINGS'RANGE;
            variable retptr: strings_range;  -- default value is STRINGS'LEFT
        begin
            for i in REG_CHAR'RANGE loop   -- 3 downto 0
                for k in SEG7'RANGE loop   -- 6 downto 0
                    retstr(retptr) := REGC(i)(k);
                    if retptr /= 0 then      -- quit decrementing at 0
                        retptr := retptr - 1;
                    end if;
                end loop;
            end loop;
            return retstr;
        end function;
    
    begin
        -- MEM_STRING(1) <= MEM_CHAR(3) & MEM_CHAR(3) & MEM_CHAR(0) & MEM_CHAR(1);
        MEM_STRING(1) <=  to_strings(REG_CHAR'(MEM_CHAR(3),
                                               MEM_CHAR(3),
                                               MEM_CHAR(0),
                                               MEM_CHAR(1)
                                               )
                                     );
    
    end architecture;
    

    This example analyzes, elaborates and simulates, which tells us the total of the lengths of the elements of the aggregate matches STRINGS length.

    Notice the left to right order is preserved in the function to_strings.

    And for what it's worth it was painful to wade through all these circuitous definitions, the more so without the question supplying a Minimal, Complete, and Verifiable example.