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.