Search code examples
arraysstringvectortype-conversionvhdl

vhdl: convert vector to string


How can I convert a std_logic vector, bit_vector or any other vector to string?

Signal a,b          : UNSIGNED(7 DOWNTO 0);
SIGNAL x,y,z    : BIT_VECTOR(7 DOWNTO 0);

...

report "value: " & BIT_VECTOR'Image(x) severity note;
report "and this one: " & to_string(a) severity note;

This does not work, so how can I convert a vector to a string?


Solution

  • As you have discovered, the 'image attribute is only declared for scalar types, not arrays or records : the usual approach is to create one's own library of test utilities including to_string or image functions in a package at the start of a design, and use it throughout.

    It would be perfectly possible to standardise a library of these, and you will probably find many potential "test utility" packages but none has really caught on well enough to deserve becoming a standard.

    That being said, you might find the following package a useful starting point.

    It encapsulates a couple of custom datatypes with operations on them. No generics, but thanks to overloading, you can use the package as though its functions were generic. (You will notice that the function bodies are incomplete though!) Extending it and adding types is easy cut&paste for the most part; and it keeps a lot of clutter out of the main design.

    It may be better to separate out the type declns and the (testbench only) functions into two separate packages; Types and Types_Test_Utils. Then Types is used throughout the design, while the test utilities are only exposed to the testbench.

    library IEEE;
    use IEEE.numeric_std.all;
    
    package Types is
      subtype SmallNum is UNSIGNED(7 DOWNTO 0);
      subtype BiggerNum is UNSIGNED(19 DOWNTO 0);
      subtype Bits is BIT_VECTOR(7 DOWNTO 0);
    
      -- and operations on these types
      -- Simulate generic procedures using overloading
    
      function to_string(N : Unsigned) return String;
      function to_string(N : Bits) return String;  
    
      procedure eq_checker (name : string; sig,should : SmallNum; at : time);
      procedure eq_checker (name : string; sig,should : Bits; at : time);
    
    end Types;
    
    package body Types is
    
    function to_string(N : Unsigned) return String is
    variable temp : string(1 to (N'length + 3)/4) := (others => 'x');
    begin
       -- not finished!
       return temp;
    end to_string;
    
    function to_string(N : Bits) return String is
    begin
       return "hello";
    end to_string;
    
    procedure eq_checker(name : string; sig,should : SmallNum; at : time) is
    begin
      if (at = now) then
        if sig = should then
          report to_string(sig) & "has same value" severity note;
        else
          report to_string(sig) & "has not same value as " & to_string(should) severity note;
        end if;
      end if;
    end procedure eq_checker;
    
    procedure eq_checker(name : string; sig,should : Bits; at : time) is
    begin
       null;
    end procedure eq_checker;
    
    end Types;
    

    And a simple tester for it...

      use Work.Types.all;
    
      ENTITY tester IS
      END tester;
    
      ARCHITECTURE behavior OF tester IS 
    
      Signal a,b      : SmallNum := X"AA";
      Signal c        : BiggerNum := X"ABCDE";
      SIGNAL x,y      : Bits := X"BB";
    
      BEGIN
    
      process(a,x) is
      begin
         report "value: " & to_string(X) severity note;
         report "and this one: " & to_string(a) severity note;
         report "this one too: " & to_string(c) severity note;
      end process;
    
      END;