如何在 VHDL 中组合传入数据和字符?
How do I combine incoming data and character in VHDL?
我想使用 VHDL 驱动 4x16 LCD 显示器。第一行应该是 "FREQ: 000 RPM",其中零代表传入的 8 位频率数据。对于具有不同数据的下一行也是如此,也是 8 位。我的VHDL代码如下:
-- 16 Characters
subtype string16_type is string(1 to 16);
-- 4 string of 16 characters
type message4x16_type is array(1 to 4) of string16_type;
-- Define messages displayed
constant message_home: message4x16_type := ( --1234567890123456
1 => "FREE MODE ",
2 => "PARCOURS ",
3 => "- - - - - - - - ",
4 => " - - - - - - - -");
constant message_info: message4x16_type := ( --1234567890123456
1 => "FREQ: 000 RPM ",
2 => "SPEED: 000 KM/H ",
3 => "DIST: 000 KM ",
4 => "MORE INFO ");
-- Character amount in line
signal character_counter: integer range 1 to 16;
-- Line amount on LCD
signal line_counter : integer range 1 to 4;
然后是状态机,状态 write_char 部分如下所示:
if msg_select = '0' then
aline := message_home(line_counter);
elsif msg_select = '1' then
aline := message_info(line_counter);
end if;
data <= std_logic_vector(to_unsigned(character'pos(aline(character_counter)),8));
一切都以这种方式顺利进行,但我想不出一种将频率数据实现到消息中的方法,比如在 C 中使用 %i。我知道 'record' 语句但不确定如何实现在这种情况下使用它。非常欢迎任何其他方式来实现数据。
感谢正手。
像以前一样声明类型、常量和信号:
-- 16 characters
type lcd_line_type is array(0 to 15) of character;
-- 4 lines of 16 characters
type message4x16_type is array(0 to 3) of lcd_line_type;
-- Define messages displayed
constant message_home : message4x16_type := (
--1234567890123456
"FREE MODE ",
"PARCOURS ",
"- - - - - - - - ",
" - - - - - - - -"
);
constant message_info : message4x16_type := (
--1234567890123456
"FREQ: 000 RPM ",
"SPEED: 000 KM/H ",
"DIST: 000 KM ",
"MORE INFO "
);
-- Character amount in line
signal character_counter : integer range 0 to 15;
-- Line amount on LCD
signal line_counter : integer range 0 to 3;
subtype rawchar is std_logic_vector(7 downto 0);
type rawstring is array(natural range <>) of rawchar;
signal rpm : rawstring(2 downto 0);
signal kmh : rawstring(2 downto 0);
function to_rawchar(char : character) return rawchar is
begin
return std_logic_vector(to_unsigned(character'pos(char), 8));
end function;
用法示例:
if msg_select = '0' then
data <= to_rawchar(message_home(line_counter)(character_counter));
elsif msg_select = '1' then
case line_counter is
when 0 =>
-- replace 000 by rpm(2:0)
case character_counter is
when 6 => data <= rpm(2);
when 7 => data <= rpm(1);
when 8 => data <= rpm(0);
when others => data <= to_rawchar(message_info(0)(character_counter));
end case;
when 1 =>
-- replace 000 by kmh(2:0)
case character_counter is
when 7 => data <= kmh(2);
when 8 => data <= kmh(1);
when 9 => data <= kmh(0);
when others => data <= to_rawchar(message_info(1)(character_counter));
end case;
-- ...
end case;
end if;
第一个案例测试请求的行。第二种情况覆盖特定位置的常量值。
我另外将 char 到 slv 的转换提取到一个函数中。
我想使用 VHDL 驱动 4x16 LCD 显示器。第一行应该是 "FREQ: 000 RPM",其中零代表传入的 8 位频率数据。对于具有不同数据的下一行也是如此,也是 8 位。我的VHDL代码如下:
-- 16 Characters
subtype string16_type is string(1 to 16);
-- 4 string of 16 characters
type message4x16_type is array(1 to 4) of string16_type;
-- Define messages displayed
constant message_home: message4x16_type := ( --1234567890123456
1 => "FREE MODE ",
2 => "PARCOURS ",
3 => "- - - - - - - - ",
4 => " - - - - - - - -");
constant message_info: message4x16_type := ( --1234567890123456
1 => "FREQ: 000 RPM ",
2 => "SPEED: 000 KM/H ",
3 => "DIST: 000 KM ",
4 => "MORE INFO ");
-- Character amount in line
signal character_counter: integer range 1 to 16;
-- Line amount on LCD
signal line_counter : integer range 1 to 4;
然后是状态机,状态 write_char 部分如下所示:
if msg_select = '0' then
aline := message_home(line_counter);
elsif msg_select = '1' then
aline := message_info(line_counter);
end if;
data <= std_logic_vector(to_unsigned(character'pos(aline(character_counter)),8));
一切都以这种方式顺利进行,但我想不出一种将频率数据实现到消息中的方法,比如在 C 中使用 %i。我知道 'record' 语句但不确定如何实现在这种情况下使用它。非常欢迎任何其他方式来实现数据。
感谢正手。
像以前一样声明类型、常量和信号:
-- 16 characters
type lcd_line_type is array(0 to 15) of character;
-- 4 lines of 16 characters
type message4x16_type is array(0 to 3) of lcd_line_type;
-- Define messages displayed
constant message_home : message4x16_type := (
--1234567890123456
"FREE MODE ",
"PARCOURS ",
"- - - - - - - - ",
" - - - - - - - -"
);
constant message_info : message4x16_type := (
--1234567890123456
"FREQ: 000 RPM ",
"SPEED: 000 KM/H ",
"DIST: 000 KM ",
"MORE INFO "
);
-- Character amount in line
signal character_counter : integer range 0 to 15;
-- Line amount on LCD
signal line_counter : integer range 0 to 3;
subtype rawchar is std_logic_vector(7 downto 0);
type rawstring is array(natural range <>) of rawchar;
signal rpm : rawstring(2 downto 0);
signal kmh : rawstring(2 downto 0);
function to_rawchar(char : character) return rawchar is
begin
return std_logic_vector(to_unsigned(character'pos(char), 8));
end function;
用法示例:
if msg_select = '0' then
data <= to_rawchar(message_home(line_counter)(character_counter));
elsif msg_select = '1' then
case line_counter is
when 0 =>
-- replace 000 by rpm(2:0)
case character_counter is
when 6 => data <= rpm(2);
when 7 => data <= rpm(1);
when 8 => data <= rpm(0);
when others => data <= to_rawchar(message_info(0)(character_counter));
end case;
when 1 =>
-- replace 000 by kmh(2:0)
case character_counter is
when 7 => data <= kmh(2);
when 8 => data <= kmh(1);
when 9 => data <= kmh(0);
when others => data <= to_rawchar(message_info(1)(character_counter));
end case;
-- ...
end case;
end if;
第一个案例测试请求的行。第二种情况覆盖特定位置的常量值。
我另外将 char 到 slv 的转换提取到一个函数中。