如何在 VHDL 中连接两个数组
How to concatenate two arrays in VHDL
我有一些这样的类型:
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;
和 4 个这种类型的信号:
Signal S1, S2 : CharArray_8;
Signal S3 : CharArray_16;
Signal S : CharArray_32;
我想连接 S1、S2 和 S3 并将结果分配给 S,如下所示:
S <= S1 & S2 & S3;
但是这段代码是错误的,有错误,我应该如何连接它们?
是否应将数组类型声明为 MyCharacters 的子类型?
不,您的数组类型不能声明为 MyCharacters
的子类型,它是枚举类型,而不是数组类型。
你的3个数组类型是不同的独立类型。连接运算符 (&
) 未在您使用的它们的组合上定义。您可以针对这种特定情况重载它,但最简单的方法可能是使用通用基类型,即父无约束数组类型并声明其具有固定范围的子类型:
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);
这样,它们都将具有相同的基类型,并且使用 mychararray
类型自动声明的隐式连接运算符将对它们的任意组合起作用(假设结果的大小相同作为分配给它的变量的大小,当然)。
注意:我想你已经知道字符串类型(字符数组)了吧?
but this code is wrong and have error, how I should concatenate them ?
没有为多个数组类型定义隐式声明的串联运算符 (&)。您需要声明一个重载运算符,允许连接具有相同元素类型的不同类型(这很麻烦,每种可能的组合至少需要三个函数),或者通过使用类型转换或在前两个答案声明了一个未绑定的数组类型。数组类型符合类型转换条件,具有与类型 S3 兼容的索引范围和相同的元素类型。
Should Array types be declared as SubType of MyCharacters ?
除了 Renaud Pacalet 显示的命名子类型对象声明之外,还可以通过对象声明中的子类型指示(类型标记和约束)来定义子类型:
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);
&
运算符在类型声明(一维数组类型)之后隐式声明。
参见 IEEE Std 1076-2008 6.4 对象、6.3 子类型声明、5.3.2 数组类型(mychararray 是无界数组类型)和 9.2.5 添加运算符(& 串联运算符)。
Mycharacters类型是标量枚举字符类型(离散值),mychararray是数组类型(元素,这里是标量类型Mycharacters)。
Renaud Pacalet询问string类型的使用,你的36值MyCharacters类型合成后需要6位二进制值来表示,四分之三到std.STANDARD字符类型(需要8位二进制值)。另一方面,如果包含 [ =16=、;
、<
、=
、>
、?
和 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
您可以在对象声明中使用具有适当索引约束的类型字符,而不是声明类型 MyCharacters:
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);
将其捆绑成 Minimal, Complete and Verifiable 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
其中 30H 是“0”,5AH 是 'Z'。另外请参阅 16.2.2 类型和对象的预定义属性。
我们看到我们可以轻松地从 MyCharacters 值中导出 7 位 ASCII 或 8 位 ISO/IEC 8859-1 字符值(请参阅 15.2 字符集)。
在任何一种情况下,串联运算符(数组和数组、元素和数组、数组和元素)都在单维数组类型(此处为 mychararray)的声明之后隐式声明。
我有一些这样的类型:
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;
和 4 个这种类型的信号:
Signal S1, S2 : CharArray_8;
Signal S3 : CharArray_16;
Signal S : CharArray_32;
我想连接 S1、S2 和 S3 并将结果分配给 S,如下所示:
S <= S1 & S2 & S3;
但是这段代码是错误的,有错误,我应该如何连接它们?
是否应将数组类型声明为 MyCharacters 的子类型?
不,您的数组类型不能声明为 MyCharacters
的子类型,它是枚举类型,而不是数组类型。
你的3个数组类型是不同的独立类型。连接运算符 (&
) 未在您使用的它们的组合上定义。您可以针对这种特定情况重载它,但最简单的方法可能是使用通用基类型,即父无约束数组类型并声明其具有固定范围的子类型:
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);
这样,它们都将具有相同的基类型,并且使用 mychararray
类型自动声明的隐式连接运算符将对它们的任意组合起作用(假设结果的大小相同作为分配给它的变量的大小,当然)。
注意:我想你已经知道字符串类型(字符数组)了吧?
but this code is wrong and have error, how I should concatenate them ?
没有为多个数组类型定义隐式声明的串联运算符 (&)。您需要声明一个重载运算符,允许连接具有相同元素类型的不同类型(这很麻烦,每种可能的组合至少需要三个函数),或者通过使用类型转换或在前两个答案声明了一个未绑定的数组类型。数组类型符合类型转换条件,具有与类型 S3 兼容的索引范围和相同的元素类型。
Should Array types be declared as SubType of MyCharacters ?
除了 Renaud Pacalet 显示的命名子类型对象声明之外,还可以通过对象声明中的子类型指示(类型标记和约束)来定义子类型:
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);
&
运算符在类型声明(一维数组类型)之后隐式声明。
参见 IEEE Std 1076-2008 6.4 对象、6.3 子类型声明、5.3.2 数组类型(mychararray 是无界数组类型)和 9.2.5 添加运算符(& 串联运算符)。
Mycharacters类型是标量枚举字符类型(离散值),mychararray是数组类型(元素,这里是标量类型Mycharacters)。
Renaud Pacalet询问string类型的使用,你的36值MyCharacters类型合成后需要6位二进制值来表示,四分之三到std.STANDARD字符类型(需要8位二进制值)。另一方面,如果包含 [ =16=、;
、<
、=
、>
、?
和 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
您可以在对象声明中使用具有适当索引约束的类型字符,而不是声明类型 MyCharacters:
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);
将其捆绑成 Minimal, Complete and Verifiable 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
其中 30H 是“0”,5AH 是 'Z'。另外请参阅 16.2.2 类型和对象的预定义属性。
我们看到我们可以轻松地从 MyCharacters 值中导出 7 位 ASCII 或 8 位 ISO/IEC 8859-1 字符值(请参阅 15.2 字符集)。
在任何一种情况下,串联运算符(数组和数组、元素和数组、数组和元素)都在单维数组类型(此处为 mychararray)的声明之后隐式声明。