Introduction
In this post I'll present an easy way to convert text in ASCII to Hex. This is useful to save data in memory, pass through data in a particular communication protocol, a data to be displayed on an LCD, etc..
Procedure
The VHDL standard has defined several type of conversion's functions in its standard libraries. Some of this functions will be used for this conversion.
The necessary steps for conversion are as follows:
1 - Declaration of the string, constant and signal counter in the declarative part of the architecture:
1 architecture beh of test is
2 .......
3 constant N : natural := 16;
4 type tstring is array(natural range<>) of character;
5 constant msje1 : tstring(0 to N-1) := "Vuelvo en 5 ... ";
6 .......
7 -- declaracion de la senal para asignar el Hex correspondiente
8 signal byte_to_Tx: std_logic_vector(7 downto 0);
9
10 -- declaracion de contador
11 signal char_cont: natural range 0 to N-1;
12 .......
2 .......
3 constant N : natural := 16;
4 type tstring is array(natural range<>) of character;
5 constant msje1 : tstring(0 to N-1) := "Vuelvo en 5 ... ";
6 .......
7 -- declaracion de la senal para asignar el Hex correspondiente
8 signal byte_to_Tx: std_logic_vector(7 downto 0);
9
10 -- declaracion de contador
11 signal char_cont: natural range 0 to N-1;
12 .......
2 - Using conversion functions to get the Hexadeciaml byte for each character in the string:
byte_to_tx<=std_logic_vector(to_unsigned(character'pos(msje1(char_cont)),8));
Let's consider this last statement piece by piece:
a-
msje1(char_cont);
what makes this part of the instruction is to position in a specific character of the msje1. The position is given by the counter's value char_cont. Of course, this statement must be inside a loop where the counter is incremented once is sent the respective character.
b-
character'pos('character')
in this part 'character' represents the character of msje1 specified by char_cnt. On the other hand, character'pos ('V') (I write 'V' as an example of a character from msje1), what it does is first to return the position number value for the 'V' character in the array defined in the VHDL standard. To refresh a little bit something that your surely saw some time ago, I detail the type character as it's defined in the VHDL standard:
1 type character is (
2 NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL,
3 BS, HT, LF, VT, FF, CR, SO, SI,
4 DEL, DC1, DC2, DC3, DC4, NAK, SYN, ETB,
5 CAN, EM, SUB, ESC, FSP, GSP, RSP, USP,
6 ‘ ’,’!’, “”,’#’,’$’,’%’,’&’,’’’,
7 ‘(‘,’)’,’*’, ‘+’, ‘,’,’-‘,’.’,’/’,
8 ‘0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,
9 ’8’,’9’,’:’,’;’,’<’,’=’,’>’,’?’,
10 ‘@’,’A’,’B’,’C’,’D’,’E’,’F’,’G’,
11 ‘H’,’’I’,’J’,’K’,’L’,’M’,’N’,’O’,
12 ‘P’,’Q’,’R’,’S’,’T’,’U’,’V’,’W’,
13 ‘X’,’Y’,’Z’,’[‘,’\’,’]’,’^’,’_’,
14 ‘`’,’a’,’b’,’c’,’d’,’e’,’f’,’g’,
15 ‘h’,’i’,’j’,’k’,’l’,’m’,’n’,’o’,
16 ‘p’,’q’,’r’,’s’,’t’,’u’,’v’,’w’,
17 ‘x’,’y’,’z’,’{‘,’|’,’}’,’~’,DEL);
18
2 NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL,
3 BS, HT, LF, VT, FF, CR, SO, SI,
4 DEL, DC1, DC2, DC3, DC4, NAK, SYN, ETB,
5 CAN, EM, SUB, ESC, FSP, GSP, RSP, USP,
6 ‘ ’,’!’, “”,’#’,’$’,’%’,’&’,’’’,
7 ‘(‘,’)’,’*’, ‘+’, ‘,’,’-‘,’.’,’/’,
8 ‘0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,
9 ’8’,’9’,’:’,’;’,’<’,’=’,’>’,’?’,
10 ‘@’,’A’,’B’,’C’,’D’,’E’,’F’,’G’,
11 ‘H’,’’I’,’J’,’K’,’L’,’M’,’N’,’O’,
12 ‘P’,’Q’,’R’,’S’,’T’,’U’,’V’,’W’,
13 ‘X’,’Y’,’Z’,’[‘,’\’,’]’,’^’,’_’,
14 ‘`’,’a’,’b’,’c’,’d’,’e’,’f’,’g’,
15 ‘h’,’i’,’j’,’k’,’l’,’m’,’n’,’o’,
16 ‘p’,’q’,’r’,’s’,’t’,’u’,’v’,’w’,
17 ‘x’,’y’,’z’,’{‘,’|’,’}’,’~’,DEL);
18
as you can see, the character 'V' is positioned in 86th place in the array, so the character'pos ('V') returns the number 86 (as an integer).
c-
So now we have to convert an integer, 86, (which is giving me the position) to std_logic_vector. Using the now 'famous' conversion functions table we know that we must first pass the integer to unsigned and then to std_logic_vector. That is done by the next part of the statement:
So now we have to convert an integer, 86, (which is giving me the position) to std_logic_vector. Using the now 'famous' conversion functions table we know that we must first pass the integer to unsigned and then to std_logic_vector. That is done by the next part of the statement:
std_logic_vector(to_unsigned(86,8));
where 8 is the number of bits needed to represent the maximum number estimated to be converted (in this case 256).
d-
finally the binary corresponding to the character specified by char_cont signal is assigned to byte_to_Tx
Final ...
I hope you find it useful ... and if you ever use NOTIFY ....
See you soon ....
Thanks a lot for your article :) helped me a lot for my project !
ReplyDeleteAny experience from using the extended character set? When using synplify, character'pos(',') works fine and returns 44. However, character'pos(' ¬') also returns 44 instead of 172 as expected. Any ideas/thoughts about that?
ReplyDeleteHi Eson,
ReplyDeletethanks for your comment. As you can see from the post in the VHDL, the tpye character is defined as an array of 128 characters, therefore you can only access to these 'defined' characters. Hence, if you like to use the extended character set, I think the best way is to declare a new type, something like character_ext where you define all the 256 characters, and then use the same functions used in the example above but replacing character by character_ext.
Hope this helps !
Regards,
Hi,
ReplyDeleteThanks for the answer. The character set in VHDL’87 is 128 characters, but in VHDL’93 it is supposed to be 256 characters. Looking in standard.vhd confirms that I'm using the entire 256 character set. I suspect that I've come across a bug in Synplify.
Regards
ReplyDeleteThank you so much for sharing. Your content was very helpful. You are a marvelous writer. Good work!
Click Here : 2005 Cat 140H (1312) w/7895 Hrs For Sale at $108k