String to std_logic_vector

Discussion in 'VHDL' started by Shannon, May 30, 2008.

  1. Shannon

    Shannon Guest

    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
     
    Shannon, May 30, 2008
    #1
    1. Advertising

  2. Shannon

    KJ Guest

    On May 30, 12:16 pm, Shannon <> wrote:
    > 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
     
    KJ, May 30, 2008
    #2
    1. Advertising

  3. Shannon

    Shannon Guest

    On May 30, 9:47 am, KJ <> wrote:
    > On May 30, 12:16 pm, Shannon <> wrote:
    >
    >
    >
    >
    >
    > > 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- 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?
     
    Shannon, May 30, 2008
    #3
  4. Shannon wrote:

    > 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
     
    Mike Treseler, May 30, 2008
    #4
  5. Shannon

    KJ Guest

    On May 30, 1:03 pm, Shannon <> wrote:
    > On May 30, 9:47 am, KJ <> wrote:


    >
    > Or something like that?
    >


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

    KJ
     
    KJ, May 30, 2008
    #5
  6. Shannon

    Shannon Guest

    On May 30, 10:31 am, KJ <> wrote:
    > On May 30, 1:03 pm, Shannon <> wrote:
    >
    > > On May 30, 9:47 am, KJ <> wrote:

    >
    > > Or something like that?

    >
    > 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;
     
    Shannon, May 30, 2008
    #6
  7. Shannon wrote:

    > 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
     
    Mike Treseler, May 30, 2008
    #7
  8. Shannon

    Shannon Guest

    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
     
    Shannon, May 30, 2008
    #8
  9. Shannon

    KJ Guest

    "Shannon" <> wrote in message
    news:...
    > 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
     
    KJ, May 30, 2008
    #9
  10. Shannon

    KJ Guest

    "Shannon" <> wrote in message
    news:...
    > 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
     
    KJ, May 30, 2008
    #10
  11. Shannon

    Shannon Guest

    On May 30, 2:06 pm, "KJ" <> wrote:
    > "Shannon" <> wrote in message
    >
    > news:...
    >
    >
    >
    >
    >
    > > 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- Hide quoted text -
    >
    > - Show quoted text -


    Gee That's a bit more simple. Sigh.
     
    Shannon, May 30, 2008
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeremy Pyle
    Replies:
    3
    Views:
    52,756
    Mike Treseler
    Jun 28, 2003
  2. Carson
    Replies:
    4
    Views:
    19,028
    David Bishop
    Sep 1, 2005
  3. Bego
    Replies:
    0
    Views:
    2,044
  4. Thomas Rouam
    Replies:
    6
    Views:
    1,134
  5. Mad I.D.
    Replies:
    6
    Views:
    5,235
    JimLewis
    Sep 16, 2009
Loading...

Share This Page