与实体相比,函数显然不那么冗长.但它意味着许多缺点,包括:
似乎可以递归调用函数.可能不是实体的情况吗?如果是这样,除了美学目的之外,还有什么理由使用功能吗?
函数不能直接创建硬件 - 它们必须存在于体系结构中才能这样做.没有什么可以阻止你将所有功能放入function(或procedure)然后只是在一个内部调用它process.
关于你的其他一些观点:
使用过程,您可以拥有多个inout或out参数.
实体可以递归...考虑:
entity recurse is
generic (
depth : integer := 1;
param : integer := 3);
port (
a : in integer;
b : out integer);
end entity recurse;
architecture a1 of recurse is
signal c : integer;
begin
c <= a + 1;
bottom: if depth = param generate
b <= a + 1;
end generate bottom;
mid:if depth /= param generate
recurse_1: entity work.recurse
generic map (
param => param,
depth => depth+1)
port map (
a => c,
b => b);
end generate mid;
end architecture a1;
Run Code Online (Sandbox Code Playgroud)不是很有用,但它合成和模拟就好了.
vhdl中的函数使代码易于维护和读取.通常架构非常大,而在调试时如果某些东西不起作用,您可以轻松找到有问题的功能并更正它,而无需分析整个架构体.
在小代码的情况下,它是无用的,但在更大的机器中,如果你认为它的功能明智,它会让你更好地理解.
这没有规则所以欢迎所有评论.
简而言之:功能的优点是
我可以看出为什么你感到困惑,另一个好问题是为什么有程序和功能.(VHDL有时看起来很不优雅!)
话虽这么说,我一直使用程序和函数,尽管大多数都在测试平台中.例如,对于防火墙系统的测试平台,我做了一段时间后,我编写了一个程序pd_tb_send_udp_packet(),我在主进程中反复使用,例如,
pd_tb_send_udp_packet("10.10.10.2", 1234, false);
pd_tb_send_udp_packet("10.10.10.1", 1234, true);
pd_tb_send_udp_packet("10.10.10.1", 1235, false);
pd_tb_send_udp_packet("ff02:100::1", 1234, false);
pd_tb_send_udp_packet("ff02:101::1", 1234, true);
Run Code Online (Sandbox Code Playgroud)
此过程生成带有给定addr/port的随机UDP数据包,并将其发送到防火墙系统,然后根据最终的布尔参数测试是否转发.以下是它的第一行,我使用库中的函数:
if f_atvtb_is_ipv6_addr(dest_ip_addr) then
v_ipv6 := true;
v_ipv6_addr := f_atvtb_ipv6_addr(dest_ip_addr);
else
v_ipv6 := false;
v_ipv4_addr := f_atvtb_ip_addr(dest_ip_addr);
end if;
Run Code Online (Sandbox Code Playgroud)
后两者分别从字符串输入返回128和32位std_logic_vectors.
虽然我可以在不使用程序和功能的情况下完成所有这些,但它肯定会更加混乱.