Две формы
Verilog поддерживает ровно два синтаксиса комментариев, оба скопированы из C:
Это весь синтаксис. Никаких # как в Python, никаких -- как в VHDL, никакого Lisp-стиля. Только // и /* ... */.
Когда какой использовать
// - то, к чему тянешься почти всегда. Короче, не может остаться случайно незакрытым и натурально парится с тем, как ты пишешь Verilog (одно объявление на строку, с комментарием на той же или соседней):
output reg [7:0] data, // байт, который мы выдвигаем на tx_serial
output reg valid, // high, пока data передаётся
input wire ready // потребитель ниже по потоку готов принимать
/* ... */ - в основном для двух вещей: больших header-блоков наверху файла и временного отключения куска кода при отладке. Случай с отключением опасен - читай дальше.
Засада "без вложенности"
Блочные комментарии не вкладываются. Если попытаешься закомментировать регион, в котором уже есть блочный комментарий, первый */ закроет внешний блок, а не внутренний:
/* внешний
/* внутренний */ // <-- это */ закрывает внешний комментарий
остаётся активным в исходнике с точки зрения парсера
*/
Результат: синтаксическая ошибка где-то неожиданно, на строке, которая выглядит правильно.
Когда нужно отключить регион, предпочитай:
-
Поставь
//в начале каждой строки. Большинство редакторов делают это одной горячей клавишей. -
Используй 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.