Почему мы используем функции в VHDL

функции, очевидно, менее подробны для записи, чем сущности. Но это подразумевает много недостатков, в том числе:

  • нет эквивалента универсального ключевого слова
  • возможен только один выход

похоже, что функции можно вызывать рекурсивно. Не может ли быть так с сущностями? Если да, то есть ли веские причины использовать функции, кроме эстетических целей?

3 ответов


функции в vhdl делают код легким поддерживать и читать. обычно архитектуры очень большие, и при отладке, если что-то не работает, вы можете легко найти проблемную функцию и исправить ее, и нет необходимости анализировать весь корпус архитектуры.

в случае небольших кодов это бесполезно, но в более больших машинах это заставляет вас лучше понять,если вы считаете, что это разумно.

для этого нет правила, поэтому все комментарии добро пожаловать.

вкратце: преимущество функций

  • перегрузка
  • определение операторов
  • перегрузка операторов
  • лучшая структура кода

функции не могут создавать оборудование напрямую - для этого они должны существовать в архитектуре. Ничто не мешает вам положить все свои функции в 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;
    

не очень полезно, но оно синтезирует и воспроизводит просто отлично.

  • и, наконец, конечно, вы используете функции только для эстетических целей (предполагая, что вы включаете ремонтопригодность и читаемость в определение эстетики, что делает большинство типов программирования в моем опыте). Вы используете только перечисленные типы, сущности, записи и целый ряд других языковых функций для "эстетических целей". Даже на ассемблере мнемоника эстетична! Возможно, следует вернуться к переключению DIP-переключателей:)

Я вижу, почему вы смущены, еще один хороший вопрос, почему есть оба процедура и функции. (VHDL иногда кажется довольно неэлегантным!)

это, как говорится, я использую как процедуры, так и функции все время, хотя в основном на испытательных стендах. Например, для testbench для системы брандмауэра, которую я сделал некоторое время назад, я написал процедуру 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-пакет с заданным addr/портом и отправляет его в систему брандмауэра, а затем проверяет, пересылается ли он или нет на основе конечного логического параметра. Вот первые строки, где я использую функции из библиотеки:

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_vectors из строкового ввода соответственно.

хотя я, вероятно, мог бы сделать все это без использования процедур и функций, это определенно было бы намного грязнее.