VHDL: Is there a convenient way to assign ascii values to std_logic_vector?
Asked Answered
W

4

9
  • In verilog, I can assign a string to a vector like:

    wire [39:0] hello;
    assign hello = "hello"; 
    
  • In VHDL, I'm having difficulty finding a method like this:

    SIGNAL hello : OUT std_logic_vector (39 DOWNTO 0);
    ...
    hello <= "hello";
    

I've been using:

hello <= X"65_68_6c_6c_6f";

which is unclear and time consuming for large strings.

I've looked at the textio package and thetxt_util package, but neither seem to be very clear on how to interpret a string and convert it to std_logic.

Is there a simple method of assigning ascii codes to std_logic in VHDL?

Here's a minimal example:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY test IS
PORT(
   ctrl : IN std_logic;
   stdout : OUT std_logic_vector (39 DOWNTO 0)
);
END ENTITY;

ARCHITECTURE rtl OF test IS
   SIGNAL temp : std_logic_vector (39 DOWNTO 0);
BEGIN
   stdout <= temp;
   PROCESS(ctrl)
   BEGIN
      IF (ctrl = '0') THEN
         temp <= "hello"; -- X"68_65_6C_6C_6F";
      ELSE
         temp <= "world";
      END IF;
   END PROCESS;

END rtl;
Worried answered 6/4, 2014 at 22:43 Comment(0)
F
7

This one varies little for Morten's answer - it only uses one multiply, it copies the string instead of creating an alias, it uses an additional variable and it returns a standard logic vector with an ascending index range.

From a package called string_utils:

library ieee; 
use ieee.numeric_std.all;
-- ...
    function to_slv(s: string) return std_logic_vector is 
        constant ss: string(1 to s'length) := s; 
        variable answer: std_logic_vector(1 to 8 * s'length); 
        variable p: integer; 
        variable c: integer; 
    begin 
        for i in ss'range loop
            p := 8 * i;
            c := character'pos(ss(i));
            answer(p - 7 to p) := std_logic_vector(to_unsigned(c,8)); 
        end loop; 
        return answer; 
    end function; 

You could add an argument with a default specifying ascending/descending index range for the return value. You'd only need to provided the argument for the non default.

Finalist answered 7/4, 2014 at 10:39 Comment(2)
Where is the package "string_utils" available?Mulish
@Morten www-eng.lbl.gov/~jmjoseph/for-JW/CIN-CFG-FPGA/…Finalist
M
6

A small general function is one way to do it, with a suggestion below:

library ieee;
use ieee.numeric_std.all;
...
-- String to std_logic_vector convert in 8-bit format using character'pos(c)
--
-- Argument(s):
-- - str: String to convert
--
-- Result: std_logic_vector(8 * str'length - 1 downto 0) with left-most
-- character at MSBs.
function to_slv(str : string) return std_logic_vector is
  alias str_norm : string(str'length downto 1) is str;
  variable res_v : std_logic_vector(8 * str'length - 1 downto 0);
begin
  for idx in str_norm'range loop
    res_v(8 * idx - 1 downto 8 * idx - 8) := 
      std_logic_vector(to_unsigned(character'pos(str_norm(idx)), 8));
  end loop;
  return res_v;
end function;
Mulish answered 7/4, 2014 at 7:21 Comment(0)
B
3

To return an ascii value of a character, use this code:

some_variable <= character'pos('a'); --returns the 'a' ascii value
Blunder answered 23/6, 2021 at 21:2 Comment(0)
A
0

In your example you are trying to assign a string type to a std_logic_vector type. That is simply not allowed. VHDL is strongly typed.

SIGNAL hello : OUT std_logic_vector (39 DOWNTO 0); ... hello <= "hello";

If your goal is to convert from hexa to ascii for printing simulation result you can simply do that:

character'val(to_integer(unsigned(my_std_logic_vector)))

Acetometer answered 20/9, 2019 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.