Reputation: 201
I wrote a function inside a package file, and I'm calling it inside the main vhd file. It seems to me everything is correctly in place. But the Sigasi editor says "No matching subprogram was found." at the line where I called the function.
This is the package file content:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.numeric_std.ALL;
PACKAGE pkg IS
TYPE t IS ARRAY (positive RANGE <>) OF std_logic_vector(7 DOWNTO 0);
FUNCTION char2byte (SIGNAL yazi_char: character) RETURN std_logic_vector;
END pkg;
PACKAGE BODY pkg IS
FUNCTION char2byte (SIGNAL yazi_char: character) RETURN std_logic_vector IS
VARIABLE yazi_byte: std_logic_vector;
BEGIN
case yazi_char is
when '0' => yazi_byte:=x"30";
when '1' => yazi_byte:=x"31";
when '2' => yazi_byte:=x"32";
....
when others =>
end case;
RETURN yazi_byte;
END char2byte;
END pkg;
And this is the main file content:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use WORK.pkg.ALL;
entity rs232 is
port(
clk:in std_logic;
tx_port:out std_logic
);
end rs232;
architecture Behavioral of rs232 is
signal yazi_byte: t;
begin
yazi_byte<=char2byte("y");
process(clk)
begin
....
end process;
end Behavioral;
Where is the fault? The funny thing is, ISE is giving another error, not a "No matching subprogram was found.".
It is:
ERROR:HDLParsers:522 - "D:/UME/FPGA/ise_projeleri/RS232_TEST/pkg.vhd" Line 16. Variable yazi_byte is not constrained.
ERROR:HDLParsers:3304 - "D:/UME/FPGA/ise_projeleri/RS232_TEST/pkg.vhd" Line 16. Can not determine the "others" values in aggregate. (LRM 7.3.2)
Thanks for helping.
Upvotes: 1
Views: 4474
Reputation: 3983
You have lots of subtle errors. Some of them noted already, others not. Lets start with types. "y" is a single element string (string(1 to 1)). char2byte requires a character, such as 'y'. As @Brian pointed out, char2byte returns std_logic_vector and not type t (an array of std_logic_vector).
On char2byte you have declared the character input to be a signal. This would mean that you need to map a signal to it and not a literal, such as 'y'. You probably want to declare it as a constant instead (or just leave the class off). In the code below, note the fix to yazi_byte (also noted by @Andy).
FUNCTION char2byte (CONSTANT yazi_char: character) RETURN std_logic_vector IS
VARIABLE yazi_byte: std_logic_vector(7 downto 0) ;
BEGIN
case yazi_char is
when '0' => yazi_byte:=x"30";
when '1' => yazi_byte:=x"31";
when '2' => yazi_byte:=x"32";
....
when others =>
end case;
RETURN yazi_byte;
END char2byte;
Note a clever solution to Char2Byte may use an array of std_logic_vector(7 downto 0) that is indexed by type character (perhaps a project for another day). See @David's post here for an idea: Missing EOF at function. Indexing the array would work similar to a subprogram call.
If you only have char2byte, then your testbench needs to receive a std_logic_vector value (also see @Brian's fix):
architecture Behavioral of rs232 is
signal slv_byte: std_logic_vector(7 downoto 0) ;
begin
slv_byte<=char2byte('y');
If your testbench really needs to work with strings and type t, then a function that takes type string and returns type t, such as the following partially built function would be helpful:
FUNCTION string2slv (yazi_str : string) RETURN t is
variable result : t (yazi_str'range) ;
begin
. . .
end FUNCTION string2slv ;
Upvotes: 2
Reputation:
The problem is that you are confusing a std_logic_vector with t
, an array of std_logic_vector.
signal yazi_byte: t;
begin
yazi_byte<=char2byte("y");
...
Now t
is an unconstrained array, which allows you to declare t
s of different sizes when you use the package. There are two ways to do this :
t
and initialise it in the declaration : the initialiser (function call or array aggregate) defines its size. Works for signals but especially useful for constantsThus the first example is constrained to be 4 bytes long:
constant deadbeef : t := (X"DE", X"AD", X"BE", X"EF");
And your second example is currently 1 byte long: however you still need to address that byte within it... This is actually why you get the obscure-looking error message.
signal yazi_byte: t(0 downto 0);
begin
yazi_byte(0) <= char2byte("y");
...
VHDL has operator and function overloading, so the compiler is looking for a "char2byte" function that returns an array of std_logic_vector
because that's the type of the variable you are assigning to. It can't find one (hence "no matching subprogram") because the only "char2byte" you wrote returns a single std_logic_vector, not an array of them.
So addressing a single element of that array will let it find your char2byte - and now the error message makes perfect sense...
Upvotes: 1
Reputation: 644
The variable yazi_byte
needs to be constrained explicitly, as the error message says. It looks like it has a range of eight bit, so:
VARIABLE yazi_byte: std_logic_vector(7 downto 0);
would work.
Upvotes: 0