0
\$\begingroup\$

String contains hex value that can fit within 32 bits. There is no "0x" or "x" at the start, just the hex value.

Does VHDL have a built in method to convert this into an integer or I need to write my own custom function to do this?

EDIT:

A file contains data that is read into a line and then part of it is assigned to a VHDL string data type. Here is an example:

 variable my_string : string(1 to 8);

Now assume that the my_string contains the hex value that has been read from file which could be something like e.g "A57E01AC". It could be upper or lower case, I cannot guarantee the case. It is also possible that instead of 8 characters in the string there be less but it will still fit into 32 bit integer anyway. And yes, the value is signed. The file is generated by some other program. The data in the file is not uniform since it contains ASCII form of packets of data and a data has different fields inside it. However, I will know when the characters 13 to 18 (for example) contain the hex string that must be converted to integer.

Now, with the my_string containing "A57E01AC", how do I convert this into an integer? I could write a function myself but am wondering if VHDL has built in functions for this sort of thing.

And yes, this is for testbench only.

asked Dec 16, 2024 at 23:40
\$\endgroup\$
5
  • 1
    \$\begingroup\$ We need to know what value you are converting, is this a wire or a variable in a test bench \$\endgroup\$ Commented Dec 17, 2024 at 2:02
  • 3
    \$\begingroup\$ Beside the feeling that this is the wrong SE site (you might want to ask this on Stack Overflow), what does your research of the widely available VHDL common libraries' documentation reveal? What did you find, and why does it not help you? \$\endgroup\$ Commented Dec 17, 2024 at 8:10
  • \$\begingroup\$ see also: this post \$\endgroup\$ Commented Dec 17, 2024 at 14:56
  • \$\begingroup\$ @SnappyRiffs Sadly I looked at your referenced post - had to fix the errors in it. \$\endgroup\$ Commented Dec 17, 2024 at 22:27
  • \$\begingroup\$ I have added details so it should now be possible to open the question again. \$\endgroup\$ Commented Dec 19, 2024 at 2:04

2 Answers 2

1
\$\begingroup\$

You cannot currently read integers as hex. You can read signed, unsigned, and std_logic_vector as hex and convert them to integer. If you can, read the characters using hread. With VHDL-2008, hread for signed and unsigned is in package numeric_std - similarly hread for std_logic_vector is in std_logic_1164.

library IEEE ; 
use std.textio.all ; 
use ieee.numeric_std.all ; -- with VHDL-2008 has hread for signed and unsigned
. . .
hread(buf, b_signed) ; 
b_int := to_integer(b_signed) ; 

If you are parsing an input and as a result, you have an 8 bit hex value in a string, it gets more interesting. The easiest thing you can do is put it back into an object of type line and read it. You can do this by doing:

process 
 variable StrPtr: line ; 
 variable b_signed : signed(31 downto 0) ; 
 variable b_int : integer ; 
begin 
 . . .
 StrPtr := new string'(my_string) ; 
 hread(StrPtr , b_signed) ; 
 b_int := to_integer(b_signed) ;
 -- at this point StrPtr is null, but you can deallocate it if you want
 deallocate(StrPtr) ; 

If you poke around in std_logic_1164 you will find a Char2QuadBits in the package body. This will character by character convert your string to std_logic_vector. Unfortunately it is not visible so you would have to copy it. There may also be some open source utilities the provide this capability.

answered Dec 19, 2024 at 4:39
\$\endgroup\$
4
  • \$\begingroup\$ VHDL seems quite weak in its string capabilities. Often the stimulus and expected results are stored in an external file that has been generated through some other C program or Python or TCL script. VHDL is severly lagging behind in basic string processing capabilities it seems. There are workarounds for many things and some open source packages but it does beg the question why these things are not part of the language itself yet so they can be optimized by the simulation tools. \$\endgroup\$ Commented Dec 19, 2024 at 21:43
  • \$\begingroup\$ I do get somewhat confused why the functions that work with line type are not defined for string type as well when line is basically a pointer to a string. \$\endgroup\$ Commented Dec 20, 2024 at 0:13
  • \$\begingroup\$ I have posted an answer, this is the code that I intend to use as given in the answer \$\endgroup\$ Commented Dec 20, 2024 at 2:34
  • \$\begingroup\$ Perhaps even more frustrating that the language implements Char2QuadBits, but does not make it visible. It would be appropriate to add them to the IEEE VHDL standard. See gitlab.com/IEEE-P1076/VHDL-Issues/-/issues to add an issue. It is volunteer based, so you can come and do the implementations too. That will insure the work gets done. \$\endgroup\$ Commented Dec 20, 2024 at 17:11
0
\$\begingroup\$

Here is the code that I eventually wrote myself and it works:

 function hchar_to_slv(c : character) return std_logic_vector is
 variable slv : std_logic_vector(3 downto 0);
 begin
 case c is
 when '0' => slv := "0000";
 when '1' => slv := "0001";
 when '2' => slv := "0010";
 when '3' => slv := "0011";
 when '4' => slv := "0100";
 when '5' => slv := "0101";
 when '6' => slv := "0110";
 when '7' => slv := "0111";
 when '8' => slv := "1000";
 when '9' => slv := "1001";
 when 'A' | 'a' => slv := "1010";
 when 'B' | 'b' => slv := "1011";
 when 'C' | 'c' => slv := "1100";
 when 'D' | 'd' => slv := "1101";
 when 'E' | 'e' => slv := "1110";
 when 'F' | 'f' => slv := "1111";
 when others =>
 slv := "XXXX";
 report "Invalid value passed into hchar_to_slv: " & c
 severity failure;
 end case;
 return slv;
 end function hchar_to_slv;
 function hstring_to_integer(str : string; is_signed : boolean := FALSE) return integer is
 constant STR_T : string(1 to str'length) := str;
 variable slv : std_logic_vector(4*str'length-1 downto 0) := (others=>'0');
 variable hchar_slv : std_logic_vector(3 downto 0) := (others=>'0');
 begin
 -- validate input parameter
 assert str'length <= 8
 report "Input to hstring_to_integer too large: " & str
 severity failure;
 -- conversion from string to slv
 for i in 0 to STR_T'length - 1 loop
 hchar_slv := hchar_to_slv(STR_T(STR_T'length - i));
 slv(4*i+3 downto 4*i) := hchar_slv;
 end loop;
 -- conversion from slv to integer
 if (is_signed = TRUE) then
 return to_integer(signed(slv));
 else
 if str'length = 8 and slv(slv'left) = '1' then
 report "The input string value is 32 bits " &
 "while its MSb is '1'; Conversion to unsigned " &
 "is not possible so expect warning: NUMERIC_STD.TO_INTEGER not in bounds of subtype NATURAL"
 severity warning;
 end if;
 return to_integer(unsigned(slv));
 end if;
 end function hstring_to_integer;

Going from string to std_logic_vector and then to integer is the simplest route. The code implies that the input parameter has number of bits that are multiple of 4. This is very important for conversion from string to signed integer.

answered Dec 20, 2024 at 2:33
\$\endgroup\$
4
  • \$\begingroup\$ Some day you may wish to support Z as generating "ZZZZ", and likewise for U, X, W, -, L, H. Char2QuadBits has some of these but not all. Other than missing these, your code appears to be identical to Char2QuadBits. \$\endgroup\$ Commented Dec 20, 2024 at 17:09
  • 1
    \$\begingroup\$ Your hstring_to_integer has a bug. Integers are 32 bits when they are signed. Hence, your conversion in the return needs to be to_integer(signed(slv)). Using unsigned will overflow when the left most bit of the slv is a 1. \$\endgroup\$ Commented Dec 23, 2024 at 3:38
  • 1
    \$\begingroup\$ Following on from my comment above, when using type unsigned, you only get 31 bits of integer \$\endgroup\$ Commented Dec 24, 2024 at 19:00
  • \$\begingroup\$ Yes, when doing unsigned with 8 character string, the result will become a negative number when put into an integer; that is, when the MSb is '1'. This is why a severity warning; message is issued. I thought if it should be a fatal instead. I shall look into the bug you have pointed out. \$\endgroup\$ Commented Dec 26, 2024 at 13:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.