Menu

Комментарии в Verilog: однострочные, многострочные и стиль документации

Как писать однострочные и многострочные комментарии в Verilog, плюс паттерны документирования, которые цифровые разработчики используют, чтобы модули оставались читаемыми по мере роста.

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

Две формы

Verilog поддерживает ровно два синтаксиса комментариев, оба скопированы из C:

Это весь синтаксис. Никаких # как в Python, никаких -- как в VHDL, никакого Lisp-стиля. Только // и /* ... */.

Когда какой использовать

// - то, к чему тянешься почти всегда. Короче, не может остаться случайно незакрытым и натурально парится с тем, как ты пишешь Verilog (одно объявление на строку, с комментарием на той же или соседней):

output reg [7:0] data,  // байт, который мы выдвигаем на tx_serial
output reg       valid, // high, пока data передаётся
input  wire      ready  // потребитель ниже по потоку готов принимать

/* ... */ - в основном для двух вещей: больших header-блоков наверху файла и временного отключения куска кода при отладке. Случай с отключением опасен - читай дальше.

Засада "без вложенности"

Блочные комментарии не вкладываются. Если попытаешься закомментировать регион, в котором уже есть блочный комментарий, первый */ закроет внешний блок, а не внутренний:

/* внешний
   /* внутренний */    // <-- это */ закрывает внешний комментарий
   остаётся активным в исходнике с точки зрения парсера
*/

Результат: синтаксическая ошибка где-то неожиданно, на строке, которая выглядит правильно.

Когда нужно отключить регион, предпочитай:

  1. Поставь // в начале каждой строки. Большинство редакторов делают это одной горячей клавишей.

  2. Используй preprocessor guard:

    `ifdef DISABLED
        // код, который не должен компилироваться
    `endif
    

Второй паттерн - ещё и то, как держать несколько конфигураций сборки в одном файле.

Synthesis pragmas: комментарии, которые не комментарии

Вендорские тулы используют специально отформатированные комментарии как директивы вне стандарта. Симулятор их всё равно игнорирует, а синтезатор читает:

// synthesis translate_off
initial begin
    $display("симулятор-only сетап");
end
// synthesis translate_on

Две прагмы говорят синтезатору "пропусти всё между этими маркерами". Точные написания зависят от вендора (synthesis, synopsys, pragma, xilinx и т.д.) - сверяйся с документацией своего тула. Главное помнить: комментарии в Verilog иногда несут смысл.

Соглашения по header-блокам

Долгоживущие файлы Verilog почти всегда начинаются с header-блока. Точный формат - политика команды, но типичный пример:

// -----------------------------------------------------------------------------
// Module      : uart_tx
// Description : UART-передатчик 8-N-1. Принимает байт на `data`, когда `valid`
//               выставлен, и выдвигает его на `serial_out`. `baud_tick`
//               должен пульсировать раз в baud-период.
// Ports       : clk        - системный clock
//               reset_n    - синхронный reset, активный low
//               baud_tick  - 1-тактовый импульс на каждом baud-интервале
//               data       - байт для передачи
//               valid      - выставлен, чтобы начать передачу
//               serial_out - провод, уходящий из FPGA
//               busy       - high, пока кадр летит
// Author      : example@team
// Revision    : 2026-05-26 - первая версия
// -----------------------------------------------------------------------------

module uart_tx (
    input  wire       clk,
    input  wire       reset_n,
    input  wire       baud_tick,
    input  wire [7:0] data,
    input  wire       valid,
    output reg        serial_out,
    output reg        busy
);
    // ... тело ...
endmodule

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

Inline-комментарии, которые окупаются

Распространённая ошибка - комментировать что делает строка, когда код уже это показывает:

// плохо - комментарий пересказывает код
count <= count + 1;   // инкрементируем count

// лучше - комментарий объясняет, зачем эта строка тут
count <= count + 1;   // free-running счётчик циклов для timestamping

Что комментарии умеют уникально хорошо - это объяснять почему, чего код сам показать не может: какой раздел спеки описывает странную кодировку, почему регистр на один бит шире, чем кажется, почему default поставлен в 'x вместо '0. Опирайся на них для этого. Очевидное оставляй коду.

Попробуй

Блок ниже содержит каждую форму комментария. Запусти - вывод тебя не удивит, а вот структура файла должна:

Ты увидел все формы комментариев, которые Verilog поддерживает. Остальные документы используют их так, как ожидаешь: header-блоки наверху длинных модулей, однострочные // рядом с ports и блочные комментарии только когда есть абзац рассуждений, который стоит зафиксировать.

Часто задаваемые вопросы

Как написать комментарий в Verilog?

Verilog поддерживает два стиля комментариев, оба унаследованы от C. // начинает комментарий, который идёт до конца строки. /* ... */ оборачивает многострочный блок. Компилятор игнорирует всё между маркерами; оба стиля одинаково валидны в синтезируемом или симуляционном файле.

Комментарии в Verilog синтезируемые?

Комментариев не существует после парсинга - инструмент синтеза выкидывает их, как и симулятор. Единственное исключение - synthesis pragmas: специально отформатированные комментарии вроде // synthesis translate_off, которые вендорские тулы распознают как директивы. Синтаксис прагм зависит от тула и не является частью стандартного Verilog.

Можно ли вкладывать комментарии в Verilog?

Нет - и это ловит новичков, которые пытаются закомментировать блок, уже содержащий /* ... */. Первый */ внутри закрывает внешний комментарий, оставляя остальной блок как живой код. Используй // на каждой строке, или оборачивай весь регион в \ifdef SOMETHING_FALSE/`endif`, если действительно нужно отключить кусок.

Что должен включать header-комментарий в Verilog?

Большинство команд кладёт небольшой заголовок наверху каждого файла: имя module, одно предложение про назначение, краткое описание ports, автор/дата и история ревизий. Точный формат меняется; главное - чтобы любой, кто откроет файл, мог понять, что он делает, не читая тело. Большие проекты добавляют комментарии к каждому port.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ