# Модули

Основной структурный элемент. Он описывает поведение системы, которая может быть реализована на физическом устройстве. Модуль описывается либо через *описание поведения*, либо через *описание структуры* (например, из каких логических элементов он состоит).

Модули соединяются *проводами*, благодаря чему они могут взаимодействовать друг с другом, образуя более крупные схемы.

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

Порты могут быть *входом* (`input`), *выходом* (`output`) или *входо-выходом* (`inout`) и могут быть представлены *проводами* (`wire`) или *регистрами* (`reg`). Регистры сохраняют значение между тактами синхронизации. Провода не хранят значение между тактами синхронизации.

![](https://1605996681-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkhrUYO4h2JjjaxSLXUTQ%2Fuploads%2Fgit-blob-9e4536abc9824b94c3ef8a2870809f2733073bce%2Fmodule.png?alt=media)

Описание модуля начинается с ключевого слова `module`. Описание модуля заканчивается ключевым словом `endmodule` (без `;` в конце). При составлении модуля порты могут располагаться в любом порядке, подобно аргументам функции в языках программирования.

*Синтаксис*

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```verilog
// Вариант 1: объявление модуля без входных и выходных сигналов 
module <название>;

// Вариант 2: объявление модуля с входными и выходными сигналами
module <название>(<список портов для взаимодействия с остальными модулями>);
  <объявления типов для входов и выходов>
  <объявления внутренних переменных>
  <инстанцирование (создание экземпляра модуля) внутренних модулей>
  <объявления цепей и примитивов структурного моделирования>

// Вариант 3: объявление модуля с входными и выходными сигналами с указанием их типов 
module <название>(<список портов для взаимодействия с остальными модулями с типами портов>);
  <объявления внутренних переменных>
  <инстанцирование (создание экземпляра модуля) внутренних модулей>
  <объявления цепей и примитивов структурного моделирования>
```

{% endcode %}

*Примеры*

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```verilog
/* Пример 1: объявление модуля без входных и выходных сигналов */
module my_module_wo_args;

/* Пример 2: объявление модуля с входными и выходными сигналами */
module my_module_with_args(output[3:0] a, output b, input c, d);
    wire[3:0] a;
    wire b;
    reg c, d;
    …

/* Пример 3: объявление модуля с входными и выходными сигналами с указанием их типов */
module my_module_with_args_and_types(output wire a, output wire b, input reg c, input reg d);
```

{% endcode %}
