但是这段代码有错误,我该如何将它们连接起来?对于多个数组类型,没有隐式声明的连接运算符(&)。您需要声明一个重载运算符,允许不同类型具有相同元素类型进行连接(这很繁琐,需要至少三个函数来处理每种可能的组合),或者通过使用类型转换或像这两个答案中声明单个未绑定数组类型来使数组值成为相同类型。数组类型可以进行类型转换,其索引范围与类型S3兼容,并且具有相同的元素类型。
“Array types”应该被声明为“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 Objects,6.3 Subtype declarations,5.3.2 Array types(mychararray是一个无界数组类型)和9.2.5 Adding operators(& concatenation operator)。
Mycharacters类型是标量枚举字符类型(离散值),mychararray是数组类型(元素为标量类型Mycharacters)。
Renaud Pacalet询问了字符串类型的使用,你的36个值的MyCharacters类型在综合后需要6位二进制值来表示,离std.STANDARD字符类型(需要8位二进制值)只差四分之三。另一方面,如果在
A
之前包含
:
、
;
、
<
、
=
、
>
、
?
和
@
字符,则可以通过将MyCharacters的位置值添加到“110000”(16#30#或48,注意数组类型的左索引位置为'0')来转换为ASCII值。
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);
将其捆绑成一个最小、完整且可验证的示例:
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:
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)声明后会被隐式声明。