How to combine two arrays in VHDL

I have types like this:

Type MyCharacters is ('0', '1' ... '9', 'A', 'B', ... 'Z');

Type CharArray_8 is array(1 to 8) of MyCharacters;
Type CharArray_16 is array(1 to 16) of MyCharacters;
Type CharArray_32 is array(1 to 32) of MyCharacters;

      

and 4 Signals with these types:

Signal S1, S2 : CharArray_8;
Signal S3 : CharArray_16;
Signal S : CharArray_32;

      

I want to concatenate S1, S2 and S3 and assign the result to S, for example:

S <= S1 & S2 & S3;

      

but this code is wrong and has an error, how should I concatenate them?

Should array types be declared as a subtype of MyCharacters?

+3


source to share


2 answers


but this code is wrong and has an error, how should I concatenate them?

There is an implicitly declared concatenation operator (&) defined for several array types. You need to either declare an overload operator so that different types with the same element types are concatenated (which is cumbersome, requiring at least three functions for every possible combination), or make the array values ​​the same type, either using a type conversion, or as these first two answers declare a single unbound array type. Array types are casted types that have index ranges that are compatible with the S3 type and the same element type.

Should array types be declared as a subtype of MyCharacters?

In addition to the named subtypes, the object declarations shown by the Reno Packalet subtypes can be specified using the subtype hints (type sign and restriction) in the object declarations:

type mychararray is array(natural range <>) of MyCharacters; 
signal S1, S2: mychararray(1 to 8);
signal S3: mychararray(1 to 16);
signal S: mychararray(1 to 32); 

      

The operator is &

implicitly declared after the type declaration (type of one-dimensional array).

See IEEE Std 1076-2008 6.4 Objects, 6.3 Subtype Declarations, 5.3.2 Array Types (mychararray is an unrestricted array type) and 9.2.5 Adding Operators (& Concatenation Operator).

The type Mycharacters is the scalar type of the enumerated character (discrete values), mychararray is the type of the array (elements, here are scalar signed characters).

Reno Pakalet asks about using a string type, your 36-character type MyCharacters requires 6-bit binary values ​​to represent after synthesis, three-quarters of the way to std.STANDARD type (requiring 8-bit binary values). On the other hand, you can convert an ASCII value, adding value MyCharacters position "110000" (16 # 30 # or 48, noting that the position of "LEFT index your type of the array is equal to" 0 "), if you switch to :

, ;

, <

, =

, >

, ?

and @

before A

:



30  0    31  1    32  2    33  3    34  4    35  5    36  6    37  7
38  8    39  9    3a  :    3b  ;    3c  <    3d  =    3e  >    3f  ?
40  @    41  A    42  B    43  C    44  D    45  E    46  F    47  G
48  H    49  I    4a  J    4b  K    4c  L    4d  M    4e  N    4f  O
50  P    51  Q    52  R    53  S    54  T    55  U    56  V    57  W
58  X    59  Y    5a  Z

      

Instead of declaring types MyCharacters, you can use the type symbol with appropriate indices in object declarations:

subtype MyCharacters is character('0' to 'Z');
type mychararray is array(natural range <>) of MyCharacters; 
signal S1, S2: mychararray(1 to 8);
signal S3: mychararray(1 to 16);
signal S: mychararray(1 to 32); 

      

Combine this into a Minimal, Complete and Testable Example :

entity mychar_concat is
end entity;

architecture foo of mychar_concat is

    subtype MyCharacters is character range '0' to 'Z'; -- 16#30# to 16#5A#
    type mychararray is array (natural range <>) of 
              character range '0' to 'Z'; 
    signal S1: mychararray (1 to 8) := "01234567";
    signal S2: mychararray (1 to 8) := "89:;<=>?";
    signal S3: mychararray (1 to 16) := "@ABCDEFGHIJKLMNO";
    signal S: mychararray (1 to 32); 

    function valuehex (inp: MyCharacters) return string is
        variable retval: string (1 to 2);
        variable hexval: integer;
        variable remainder: integer;
    begin
        hexval := character'pos(inp) / 16;
        retval(1) := character'val(hexval + 48); -- where '0' 'pos is 48.
        -- expects inp is less than 'Z', (9 * 16 > 'Z')
        remainder := character'pos(inp) rem 16;
        if remainder < 10 then
            retval(2) := character'val(remainder + 48); -- offset to '0'
        else
            retval(2) := character'val(remainder + 48 + 7); -- offset to 'A'
        end if;
        return retval;
    end function;
begin
    S <= S1 & S2 & S3; -- & implicity declared for mychararray
MONITOR:
    process
    begin
        wait on S;
        wait for 0 ns;  -- skip "00000000000000000000000000000000" default S
        report "S = " & string(S);
        report "valuehex(MyCharacters'LEFT) = " & 
                valuehex(MyCharacters'LEFT) & "H";
        report "valuehex(MyCharacters'RIGHT) = " & 
                valuehex(MyCharacters'RIGHT) & "H";
    end process;
end architecture;

      

ghdl -r mychar_concat
mychar_concat.vhdl:37:9:@0ms:(report note): S = 0123456789:;<=>?@ABCDEFGHIJKLMNO
mychar_concat.vhdl:38:9:@0ms:(report note): valuehex(MyCharacters'LEFT) = 30H
mychar_concat.vhdl:40:9:@0ms:(report note): valuehex(MyCharacters'RIGHT) = 5AH

      

Where 30H is "0" and 5AH is "Z". See also 16.2.2 Predefined Type and Object Attributes.

We can see that we are deriving 7-bit ASCII or 8-bit ISO / IEC 8859-1 character values ​​(see 15.2 Character Set) from MyCharacters values ​​with minimal effort.

In any case, the concatenation operators (array and array, element and array, array and element) are implicitly declared after the one-dimensional array type is declared (mychararray here).

+4


source


No, your array types cannot be declared as subtypes MyCharacters

, which is an enumerated type and not an array type.

Your three types are different and independent. The concatenation operator ( &

) is undefined in the combination of the ones you are using. You can overload it for this specific case, but the simplest might be to use a generic base type, that is, the parent type without constraints and declare its subtypes with fixed ranges:

type mychararray is array(natural range <>) of MyCharacters;
subtype CharArray_8 is mychararray(1 to 8);
subtype CharArray_16 is mychararray(1 to 16);
subtype CharArray_32 is mychararray(1 to 32);

      



Thus, they will all have the same base type, and the implicit concatenation operator, which is automatically declared with the type mychararray

, will work with any combination of them (provided that the size of the result is the same as the size of the variable to which it is assigned, of course).

Note. I'm assuming you already know the string type (character array)?

+1


source







All Articles