函数显然不如实体那么冗长。但这意味着许多缺点,包括:
- 没有等效的通用关键字
- 只能输出一种
似乎可以递归调用函数。实体可能不是这样吗?如果是这样,除了审美目的之外,还有什么好的理由使用函数吗?
函数显然不如实体那么冗长。但这意味着许多缺点,包括:
似乎可以递归调用函数。实体可能不是这样吗?如果是这样,除了审美目的之外,还有什么好的理由使用函数吗?
函数不能直接创建硬件——它们必须存在于架构中才能这样做。没有什么可以阻止您将所有功能放入function
(or 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;
不是很有用,但它可以很好地合成和模拟。
我明白你为什么感到困惑,另一个好问题是为什么会有procedure和function。(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);
此过程生成具有给定地址/端口的随机 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;
后两者分别从字符串输入返回 128 位和 32 位 std_logic_vector。
虽然我可以在不使用过程和函数的情况下完成所有这些工作,但肯定会更加混乱。
vhdl 中的函数使代码易于维护和阅读。通常架构非常大,在调试时,如果某些东西不起作用,您可以轻松找到有问题的功能并纠正它,而无需分析整个架构主体。
在小代码的情况下它是无用的,但在更大的机器上,如果你认为它功能明智,它会让你更好地理解。
对此没有规定,因此欢迎所有评论。
简而言之:功能的优点是