String to std_logic_vector

S

Shannon

I've been searching here but all the hits were for converting SLV to
string for testbenches.

I'm looking to convert a string to an array of 8bit SLVs. The idea is
I have a revision string of fixed length- something like:

ver <= "005-0805300908x2"'

and I have an array of registers declared as such:

SUBTYPE hwid_type is STD_LOGIC_VECTOR(7 DOWNTO 0);
TYPE reg_type IS ARRAY (0 TO NUM_REGS-1) OF hwid_type;
SIGNAL regs : reg_type;

What I'm looking for is a loop shown here in psuedo code:

for i in 1 to 16 loop
regs(i) <= to_slv(ver(mid$(i,1)))
end loop

Note this is for synthesis so I don't know if any of this is even
legal. I am trying to create a version register that the
microprocessor can read. An ascii string is prefered - let's pretend
for a moment it is a requirement. This is also a learning exercise
for me to deal with strings in VHDL.

Any ideas?

Shannon
 
K

KJ

I've been searching here but all the hits were for converting SLV to
string for testbenches.

I'm looking to convert a string to an array of 8bit SLVs.  The idea is
I have a revision string of fixed length- something like:

ver <= "005-0805300908x2"'

and I have an array of registers declared as such:

SUBTYPE hwid_type is STD_LOGIC_VECTOR(7 DOWNTO 0);
TYPE reg_type IS ARRAY (0 TO NUM_REGS-1) OF hwid_type;
SIGNAL  regs : reg_type;

What I'm looking for is a loop shown here in psuedo code:

for i in 1 to 16 loop
    regs(i) <= to_slv(ver(mid$(i,1)))
end loop

Note this is for synthesis so I don't know if any of this is even
legal.  I am trying to create a version register that the
microprocessor can read.  An ascii string is prefered - let's pretend
for a moment it is a requirement.  This is also a learning exercise
for me to deal with strings in VHDL.

Any ideas?

Shannon

Since your input string has some non-numeric characters in it that you
presumably want to keep in the string, then the best approach would be
to simply write a function that parses the string however you'd like.

Below is an example that simply adds the 'value' of each input
character to produce an integer output. You should be able to easily
modify this to select out whichever characters you want and perform
whatever calculations you'd like.

function Version_String_To_integer(Some_String: STRING) return integer
is
variable Return_Value: integer := 0;
begin
for i in Some_String'range loop
Some_Char := Some_String(i)
case Some_Char is
when "0" => Return_Value := Return_Value + 0;
when "1" => Return_Value := Return_Value + 1;
...
when others => null;
end case;
end loop;
return(Return_Value);
end function Version_String_To_integer;

KJ
 
S

Shannon

Since your input string has some non-numeric characters in it that you
presumably want to keep in the string, then the best approach would be
to simply write a function that parses the string however you'd like.

Below is an example that simply adds the 'value' of each input
character to produce an integer output.  You should be able to easily
modify this to select out whichever characters you want and perform
whatever calculations you'd like.

function Version_String_To_integer(Some_String: STRING) return integer
is
variable Return_Value: integer := 0;
begin
for i in Some_String'range loop
  Some_Char := Some_String(i)
  case Some_Char is
     when "0" => Return_Value := Return_Value + 0;
     when "1" => Return_Value := Return_Value + 1;
     ...
     when others => null;
  end case;
end loop;
return(Return_Value);
end function Version_String_To_integer;

KJ- Hide quoted text -

- Show quoted text -

As I suspected. So to flesh things out a bit....

function Version_Char_To_slv(Some_Char: character) return slv
is
variable Return_Value: slv(7 downto 0) := (others => 0);
begin
case Some_Char is
when "0" => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(0,8);
when "1" => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(1,8);
...
when "a" => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(97,8);
...
when "-" => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(45,8);
...
when others => null;
end case;
return(Return_Value);
end function Version_Char_To_slv;

and then back in my main process....

for i in 1 upto 16 loop
regs(i) <= Version_Char_To_slv(ver(i));
end loop;


Or something like that?
 
M

Mike Treseler

Shannon said:
Or something like that?

-- or this:

type char2std_t is array(character) of std_ulogic;

constant char2std_c : char2std_t := (
'U' => 'U',
'X' => 'X',
'0' => '0',
'1' => '1',
'Z' => 'Z',
'W' => 'W',
'L' => 'L',
'H' => 'H',
'-' => '-',
others => 'X');

function str2std(arg : string) return std_logic_vector is
variable result : std_logic_vector(arg'length - 1 downto 0);
variable j : integer;
begin
j := arg'length -1;
for i in arg'range loop
result(j) := char2std_c(arg(i));
j := j -1;
end loop;
return result;
end function;



-- Mike Treseler
 
S

Shannon

Except that each character only returns a nibble not a byte.

KJ

My finished version:

FUNCTION char_to_slv (c : CHARACTER) RETURN STD_LOGIC_VECTOR IS
variable Return_Value : STD_LOGIC_VECTOR(7 downto 0);
BEGIN
case c is
when '0' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(0,8));
when '1' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(1,8));
when '2' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(2,8));
when '3' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(3,8));
when '4' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(4,8));
when '5' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(5,8));
when '6' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(6,8));
when '7' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(7,8));
when '8' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(8,8));
when '9' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(9,8));
when '-' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(45,8));
when others => Return_Value := (OTHERS => '1');
end case;

Later I will add the lowercase letters but this gets me through the
day. Thanks for you help everyone.

Mike -- Your answers are always amazing to me. You find super compact
ways of doing clever things. I confess I don't understand your
version this time but as usual, I will synthesize it and look at the
RTL viewer to see how yours does the same thing as mine in a tenth the
number of lines!

Shannon
return(Return_Value);

END char_to_slv;
 
M

Mike Treseler

Shannon said:
Mike -- Your answers are always amazing to me. You find super compact
ways of doing clever things. I confess I don't understand your
version this time but as usual, I will synthesize it and look at the
RTL viewer to see how yours does the same thing as mine in a tenth the
number of lines!

Thanks, but it is just a related example
of how to use a constant array for conversions.
It only covers the std_ulogic bits as is.
Your function looks fine for what you are doing.

-- Mike Treseler
 
S

Shannon

Little mistake there. For clarity those should have been ascii
values:

FUNCTION char_to_slv (c : CHARACTER) RETURN STD_LOGIC_VECTOR IS
variable Return_Value : STD_LOGIC_VECTOR(7 downto 0);
BEGIN
case c is
when '0' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(48,8));
when '1' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(49,8));
when '2' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(50,8));
when '3' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(51,8));
when '4' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(52,8));
when '5' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(53,8));
when '6' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(54,8));
when '7' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(55,8));
when '8' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(56,8));
when '9' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(57,8));
when '-' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(45,8));
when others => Return_Value := (OTHERS => '1');
end case;
return(Return_Value);
END char_to_slv;

And it's working in hardware! yeah! Now...to figure out how to write
a TCL script or something to push my revision number into a constant
in my package. The fun never ends!

Shannon
 
K

KJ

Shannon said:
Little mistake there. For clarity those should have been ascii
values:

FUNCTION char_to_slv (c : CHARACTER) RETURN STD_LOGIC_VECTOR IS
variable Return_Value : STD_LOGIC_VECTOR(7 downto 0);
BEGIN
case c is
when '0' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(48,8));
when '1' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(49,8));
when '2' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(50,8));
when '3' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(51,8));
when '4' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(52,8));
when '5' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(53,8));
when '6' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(54,8));
when '7' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(55,8));
when '8' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(56,8));
when '9' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(57,8));
when '-' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(45,8));
when others => Return_Value := (OTHERS => '1');
end case;
return(Return_Value);
END char_to_slv;

And it's working in hardware! yeah! Now...to figure out how to write
a TCL script or something to push my revision number into a constant
in my package. The fun never ends!

Well if all you wanted was the ASCII value of the charcters in the string
(as it appears from your code that you do) then it's even simpler

for i in 1 to 16 loop
Some_Slv <= std_logic_vector(to_unsigned(character'pos(Some_String(i)),
8));
end loop;

KJ
 
K

KJ

Shannon said:
Little mistake there. For clarity those should have been ascii
values:

FUNCTION char_to_slv (c : CHARACTER) RETURN STD_LOGIC_VECTOR IS
variable Return_Value : STD_LOGIC_VECTOR(7 downto 0);
BEGIN
case c is
when '0' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(48,8));
when '1' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(49,8));
when '2' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(50,8));
when '3' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(51,8));
when '4' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(52,8));
when '5' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(53,8));
when '6' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(54,8));
when '7' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(55,8));
when '8' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(56,8));
when '9' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(57,8));
when '-' => Return_Value := STD_LOGIC_VECTOR(TO_UNSIGNED(45,8));
when others => Return_Value := (OTHERS => '1');
end case;
return(Return_Value);
END char_to_slv;

And it's working in hardware! yeah! Now...to figure out how to write
a TCL script or something to push my revision number into a constant
in my package. The fun never ends!

Shannon

Well if all you wanted was the ASCII value of the charcters in the string
(as it appears from your code that you do) then it's even simpler

for i in 1 to 16 loop
Some_Slv_String(i) <=
std_logic_vector(to_unsigned(character'pos(Some_String(i)),
8));
end loop;

KJ
 
S

Shannon

Well if all you wanted was the ASCII value of the charcters in the string
(as it appears from your code that you do) then it's even simpler

for i in 1 to 16 loop
    Some_Slv_String(i) <=
std_logic_vector(to_unsigned(character'pos(Some_String(i)),
8));
end loop;

KJ- Hide quoted text -

- Show quoted text -

Gee That's a bit more simple. Sigh.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top