If I have a VHDL package or function which takes a generic type, is there some way to invoke the image attribute on the generic type (or achieve the same functionality some other way)?
For example, if I try to compile this package with Modelsim:
package dummy_pkg is
    generic (type pkg_t);
end package;
package body dummy_pkg is
    procedure do_something(x : pkg_t) is
        constant s  : string := pkg_t'image(x);
    begin
    end procedure;
end package body;
then this fails with the following error:
dummy_pkg.vhd(9): Attribute "image" requires a scalar type mark prefix.
In my case, I only ever intend for pkg_t to be scalar type. Is there perhaps some way to tell the compiler this?
I find it interesting that if image were a function (with generic type) instead of an attribute, then the compiler appears to be happy. For example, this package at least compiles without error:
package dummy_pkg is
    generic (type pkg_t);
end package;
package body dummy_pkg is
    -- If "image" were a function...
    function image
        generic (type fun_t)
        parameter(x : fun_t) return string is
    begin
        return "A string representing x";
    end function;
    -- Then I could do this...
    procedure do_something(x : pkg_t) is
        function pkg_t_image is new image
            generic map(fun_t => pkg_t);
        constant s  : string := pkg_t_image(x);
    begin
    end procedure;
end package body;
Is there perhaps some way to get the functionality of the image attribute via a function? Perhaps there is some way using the to_string() function? However, if I just replace the above call to pkg_t_image() with to_string(), the compiler gives this error:
dummy_pkg.vhd(10): (vcom-1600) No feasible entries for subprogram "to_string". Visible subprograms are: (implicit) STANDARD.to_string[BIT_VECTOR return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(79) (implicit) STANDARD.to_string[BOOLEAN return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[BIT return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.CHARACTER return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.SEVERITY_LEVEL return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[universal_integer return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[universal_real return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[INTEGER return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.REAL return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.TIME return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.FILE_OPEN_KIND return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.FILE_OPEN_STATUS return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.REAL, INTEGER return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.REAL, std.STANDARD.STRING return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93) (implicit) STANDARD.to_string[std.STANDARD.TIME, std.STANDARD.TIME return std.STANDARD.STRING] at $MODEL_TECH/../vhdl_src/std/standard.vhd(93)
Because 'image can only be used on a scalar type, the compiler has no way of knowing that pkg_t can only be a scalar. Hence 'image cannot be used directly. Again with to_string, the compiler has no idea where to get it from, so cannot be used.
The only way to do this will be to pass in a to_string(p : pkg_t) function as a generic. If you add the <> value, the compiler will search for function signature that matches the function when the package is instantiated:
generic (
  type pkg_t;
  function to_string(p : pkg_t) return string is <>;
);
so now, the package can be instantiated like this:
library ieee;
use ieee.std_logic_1164.all;
package my_pkg is new dummy_pkg generic map ( pkg_t => std_logic );
-- to_string is already declared in std_logic_1164, hence is connected automatically because of <>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With