简体   繁体   中英

Can the VHDL image attribute be invoked on a generic type?

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) S TANDARD.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 <>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM