【问题标题】:Why do we use functions in VHDL为什么我们在 VHDL 中使用函数
【发布时间】:2013-01-21 17:22:07
【问题描述】:

函数显然没有实体那么冗长。但这意味着许多缺点,包括:

  • 没有等效的通用关键字
  • 只能输出一个

看来函数可以递归调用。实体可能不是这样吗?如果是这样,除了审美目的之外,还有什么好的理由使用函数吗?

【问题讨论】:

    标签: vhdl


    【解决方案1】:

    函数不能直接创建硬件 - 它们必须存在于架构中才能这样做。没有什么可以阻止您将所有功能放入 function(或 procedure),然后在 process 中调用它。

    关于您的其他一些观点:

    • 通过过程,您可以拥有多个inoutout 参数。

    • 实体可以递归...考虑:

      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;
      

    不是很有用,但合成和模拟就好了。

    • 最后,当然,您只将函数用于审美目的(假设您将可维护性和可读性纳入审美的定义中,根据我的经验,大多数编程类型都会这样做)。您仅出于“审美目的”而使用枚举类型、实体、记录和一大堆其他语言特征。即使是汇编助记符也很美观!也许应该回到切换 DIP 开关 :)

    【讨论】:

    • @zplesivcak:感谢编辑 - 我没有注意到我搞砸了格式!
    【解决方案2】:

    vhdl 中的函数使代码易于维护和阅读。通常架构非常大,在调试时如果出现问题,您可以轻松找到有问题的功能并进行纠正,而无需分析整个架构主体。

    在小代码的情况下它是无用的,但在更大的机器上,如果你认为它功能明智,它会让你更好地理解。

    对此没有规定,因此欢迎所有 cmets。

    简而言之:功能的优势在于

    • 重载
    • 算子定义
    • 因此运算符重载
    • 更好的代码结构

    【讨论】:

    • 亲爱的 Arpit,我明白构建代码的必要性。但是我们不能总是用小架构来代替功能吗?
    • 是的,你可以!一件事可以通过多种方式完成,但是每当我们定义单独的架构时,我们也会考虑将它们与其他实体或不同的配置联系起来,但如果不是这种情况,那么最好使用函数。
    • 亲爱的 Arpit, 我们同意功能总是可以被小型架构取代的事实。它显然没有那么强大,例如只有一个输出并且没有通用关键字。因此,我的问题比以往任何时候都更重要。
    • 等待泛型只能在实体中声明,一个输出?如果您使用程序,您可以返回多个。
    • 功能明显没那么强大*
    【解决方案3】:

    我明白你为什么感到困惑,另一个很好的问题是为什么会有 procedurefunction。 (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。

    虽然我可以在不使用过程和函数的情况下完成所有这些工作,但肯定会更加混乱。

    【讨论】:

      猜你喜欢
      • 2016-10-19
      • 1970-01-01
      • 2011-05-03
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多