Стандартная компоновка и синтаксис VHDL для файла" header"


IDE: Quartus 15

Я новичок в программировании на VHDL, поэтому есть некоторые нюансы, к которым я не привык (перевод с C++). В то время как я нашел ресурсы для программирования "исходных" файлов, я изо всех сил пытался найти что-нибудь для "заголовочных" файлов.

Короче говоря, какова стандартная компоновка / синтаксис файла VHDL "header"?

Чтобы все было просто, случаи использования, которые меня интересуют, объявляют subtype и ссылки на функции для использования между "исходными" файлами.

Я нашел следующий фрагмент кода здесь , который немного помог, но я все еще не уверен в том, в чем разница между package и package body. Я также не уверен, откуда берется слово "работа".

"заголовок":

    package DEFS is
        CONSTANT MAJOR_VERSION: INTEGER := 0;
        CONSTANT MINOR_VERSION: INTEGER := 22;
        CONSTANT MAXREG: integer := 52;
        TYPE REGS_TYPE is array (0 to MAXREG) of STD_LOGIC_VECTOR(15 downto 0);
        FUNCTION opndrn(inp: std_logic) return std_logic;
    end package DEFS;

    package body DEFS is
        FUNCTION opndrn(inp: std_logic) return std_logic IS
        begin
            CASE INP is
                WHEN '0' => return '0';
                WHEN OTHERS => return 'Z';
            END CASE;    
        end;
    end package body DEFS;

"Источник":

    LIBRARY work;
    USE work.defs.all;

Любая и вся помощь ценится.

1 2

1 ответ:

К счастью, в VHDL нет заголовочных файлов.

То, что у вас есть, - это пакет, который никогда ни во что не "включает"d.

В отличие от заголовочного файла, пакет отдельно компилируется - в библиотеку, которую вы можете затем "использовать", как вы это делаете.

В отличие от заголовочного файла, пакет создает собственное пространство имен. USE work.defs.all; импортирует все пространство имен, как using namespace defs в C++. Иногда лучше написать USE work.defs; , что позволит вам выборочно использовать это пространство имен, и обратитесь к defs.Major_Version в вашем источнике, таким образом (а) сохраняя ваше глобальное пространство имен незагроможденным, и (Б) документируя, где Major_Version определено.

В отличие от заголовочного файла, пакет поощряет правильное разделение интерфейса и реализации. Ваш источник может получить доступ только к вещам, экспортируемым пакетом, то есть объявленным в пакете, а не в теле пакета. Это позволяет скрывать информацию, непрозрачные типы и, как правило, лучшие абстракции.

Например, вы можете объявить Major_Version в пакете, но скрыть его фактическое значение в теле (см. "отложенные константы")

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

Затем вы можете изменить тело пакета (реализацию) и перекомпилировать его : ничто, использующее пакет, не нуждается в перекомпиляции (если вы также не изменили интерфейс.

Любой клиент пакета нужно только посмотреть на файл пакета, а не на тело пакета.


Короче говоря, то, что вы делаете, выглядит довольно хорошо. Но вы можете пойти дальше в сокрытии информации. И одна вещь, которой следует остерегаться, - это создание одного универсального пакета Бога : гораздо лучше разделить константы шины, функции и т. д. В пакет "шины", типы регистров (и, возможно, перечисление всех их имен) в пакете" регистров", инструкции в пакете" инструкций " и т. д.