我在一个包文件中写了一个函数,我在主vhd文件中调用它。在我看来,一切都正确到位。但Sigasi编辑说"没有找到匹配的子程序。"在我调用函数的行。
这是包文件内容:
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;
这是主要文件内容:
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;
错在哪里?有趣的是,ISE正在给出另一个错误,而不是&#34;没有找到匹配的子程序。&#34;。
是:
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)
感谢您的帮助。
答案 0 :(得分:2)
你有很多微妙的错误。其中一些人已经注意到,其他人则没有让我们从类型开始。 &#34; Y&#34;是单个元素字符串(字符串(1到1))。 char2byte需要一个字符,例如&#39; y&#39;。正如@Brian指出的那样,char2byte返回std_logic_vector而不是t(std_logic_vector数组)。
在char2byte上,您已将字符输入声明为信号。这意味着您需要将信号映射到它而不是文字,例如&#39; y&#39;。您可能希望将其声明为常量(或者只是将该类关闭)。在下面的代码中,请注意对yazi_byte的修复(也由@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;
注意Char2Byte的一个聪明的解决方案可能会使用一个std_logic_vector(7 downto 0)数组,它由类型字符索引(可能是另一天的项目)。请参阅@David的帖子,获取一个想法:Missing EOF at function。索引数组的工作方式类似于子程序调用。
如果你只有char2byte,那么你的测试平台需要收到一个std_logic_vector值(另见@ Brian&#39;修复):
architecture Behavioral of rs232 is
signal slv_byte: std_logic_vector(7 downoto 0) ;
begin
slv_byte<=char2byte('y');
如果你的测试平台确实需要使用字符串并输入t,那么接受类型字符串并返回类型t的函数(例如以下部分构建的函数)会有所帮助:
FUNCTION string2slv (yazi_str : string) RETURN t is
variable result : t (yazi_str'range) ;
begin
. . .
end FUNCTION string2slv ;
答案 1 :(得分:1)
问题是您将std_logic_vector与t
混淆,后者是一个std_logic_vector数组。
signal yazi_byte: t;
begin
yazi_byte<=char2byte("y");
...
现在t
是一个不受约束的数组,它允许您在使用包时声明不同大小的t
。有两种方法可以做到这一点:
t
并在声明中初始化它:初始化器(函数调用或数组聚合)定义它的大小。适用于信号,但对常量非常有用因此第一个例子被限制为4个字节长:
constant deadbeef : t := (X"DE", X"AD", X"BE", X"EF");
你的第二个例子当前是1个字节长:但是你仍然需要在其中解决该字节...这实际上是你得到模糊的错误信息的原因。
signal yazi_byte: t(0 downto 0);
begin
yazi_byte(0) <= char2byte("y");
...
VHDL具有运算符和函数重载,因此编译器正在寻找&#34; char2byte&#34;返回std_logic_vector
数组的函数,因为它是您要分配的变量的类型。它找不到一个(因此&#34;没有匹配的子程序&#34;)因为唯一的&#34; char2byte&#34;你写的只返回一个std_logic_vector,而不是它们的数组。
因此,寻址该数组的单个元素将让它找到你的char2byte - 现在错误信息非常有意义......
答案 2 :(得分:0)
变量yazi_byte
需要明确约束,如错误消息所示。看起来它的范围是8位,所以:
VARIABLE yazi_byte: std_logic_vector(7 downto 0);
会起作用。