Menu

Verilog 주석: 한 줄, 여러 줄, 그리고 문서화 스타일

Verilog에서 한 줄과 여러 줄 주석을 쓰는 방법, 그리고 모듈이 커져도 가독성을 유지하기 위해 디지털 설계자들이 사용하는 문서화 패턴.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

두 가지 형태

Verilog은 C에서 베껴 온 정확히 두 가지 주석 문법을 지원합니다.

문법은 이게 전부입니다. Python의 #도, VHDL의 --도, Lisp 스타일도 없습니다. 그저 ///* ... */뿐입니다.

각각을 언제 쓰나

//은 거의 항상 손에 잡히는 선택입니다. 더 짧고, 실수로 닫히지 않은 채로 남을 일이 없으며, Verilog의 작성 스타일(한 줄에 한 선언, 같은 줄이나 인접한 줄에 주석)과 잘 어울립니다.

output reg [7:0] data,  // tx_serial로 시프트해 나가는 바이트
output reg       valid, // data가 전송 중일 때 high
input  wire      ready  // 다운스트림 컨슈머가 수신 준비됨

/* ... */는 주로 두 가지에 씁니다. 파일 맨 위의 큰 header block, 그리고 디버깅 중 일시적으로 코드 덩어리를 비활성화하기. 후자는 위험합니다 - 계속 읽어 보세요.

"중첩 안 됨" 함정

블록 주석은 중첩되지 않습니다. 이미 블록 주석을 포함하는 영역을 주석 처리하려고 하면, 첫 */가 바깥 블록을 닫아 버립니다.

/* 바깥
   /* 안쪽 */    // <-- 여기서 */가 바깥 주석을 닫음
   파서 입장에서는 여전히 살아 있는 소스 코드
*/

결과: 예상치 못한 어딘가에서 syntax error가 나는데, 문제의 줄은 정상으로 보입니다.

영역을 비활성화해야 한다면 다음 중 하나를 선호하세요.

  1. 줄마다 //를 붙이기. 대부분의 에디터가 단축키 한 번에 처리해 줍니다.

  2. preprocessor guard 사용하기:

    `ifdef DISABLED
        // 컴파일되지 않아야 할 코드
    `endif
    

두 번째 패턴은 한 파일에 여러 빌드 구성을 유지하는 방법이기도 합니다.

Synthesis Pragma: 주석이 아닌 주석

벤더 도구는 특수 형식의 주석을 채널 외부 지시문으로 사용합니다. 시뮬레이터는 여전히 그것들을 무시하지만 synthesis 도구는 그것을 읽습니다.

// synthesis translate_off
initial begin
    $display("simulator-only setup");
end
// synthesis translate_on

이 두 pragma는 synthesis 도구에게 "이 마커 사이의 모든 것을 건너뛰라"고 알립니다. 정확한 표기는 벤더마다 다릅니다(synthesis, synopsys, pragma, xilinx 등) - 사용 도구 문서를 확인하세요. 기억할 점은 Verilog 주석이 때로는 의미를 짊어진다는 것입니다.

Header 블록 관행

오래 유지되는 Verilog 파일은 거의 항상 header block으로 시작합니다. 정확한 포맷은 팀 정책에 따르지만 전형적인 예시는 다음과 같습니다.

// -----------------------------------------------------------------------------
// Module      : uart_tx
// Description : 8-N-1 UART transmitter. `valid`가 assert되면 `data`로 한 바이트를
//               받아 `serial_out`으로 시프트해 내보냅니다. `baud_tick`은 매 baud
//               주기마다 한 번씩 pulse해야 합니다.
// Ports       : clk        - 시스템 클럭
//               reset_n    - 동기 active-low reset
//               baud_tick  - 각 baud 간격마다 1-cycle pulse
//               data       - 전송할 바이트
//               valid      - 전송 시작 시 assert
//               serial_out - FPGA를 떠나는 wire
//               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

장식이 핵심이 아닙니다. 일 년 뒤(아마도 본인이) 이 파일을 여는 사람이 네 줄만 읽고도 무엇을 하고, 무엇을 기대하며, 무엇을 만들어 내는지를 알 수 있다는 점이 핵심입니다. 그 보상은 프로젝트 규모에 비례해 커집니다.

값어치 하는 인라인 주석

흔한 실수는 코드가 이미 보여 주는 무엇을 하는지를 주석으로 다시 적는 것입니다.

// 나쁨 - 주석이 코드를 재진술
count <= count + 1;   // count 증가

// 더 나음 - 왜 이 줄이 여기 있는지를 설명
count <= count + 1;   // 타임스탬프용 free-running cycle counter

주석이 유일하게 잘하는 일은 코드 자체로는 보여 줄 수 없는 를 설명하는 것입니다. 어떤 사양 절을 따른 특이한 인코딩인지, register가 왜 한 비트 더 넓은지, default가 왜 '0이 아니라 'x로 설정되어 있는지. 그런 일에 주석을 활용하세요. 명백한 것은 코드에 맡기세요.

직접 해 보기

아래 블록에는 모든 주석 형태가 들어 있습니다. 실행해 보세요 - 출력은 놀랍지 않겠지만 파일 구조에 주목해 주세요.

이제 Verilog이 지원하는 모든 주석 형태를 봤습니다. 이 문서의 나머지에서도 기대하시는 대로 사용됩니다 - 긴 모듈의 맨 위에는 header block, 포트 옆에는 한 줄 //, 그리고 단락 정도 분량의 추론을 담아야 할 때만 block 주석.

자주 묻는 질문

Verilog에서 주석은 어떻게 쓰나요?

Verilog은 C에서 물려받은 두 가지 주석 스타일을 지원합니다. //는 줄 끝까지 가는 주석을 시작합니다. /* ... */는 여러 줄 블록을 감쌉니다. 컴파일러는 마커 사이의 모든 것을 무시합니다. 두 스타일 모두 synthesis 가능 코드든 시뮬레이션 전용 파일이든 똑같이 유효합니다.

Verilog 주석은 synthesis 대상인가요?

주석은 파싱 이후에는 존재하지 않습니다 - 시뮬레이터처럼 synthesis 도구도 주석을 버립니다. 유일한 예외는 synthesis pragma입니다. // synthesis translate_off 같은 특수 형식의 주석을 벤더 도구가 지시문으로 인식합니다. pragma 문법은 도구마다 다르며 표준 Verilog의 일부가 아닙니다.

Verilog 주석은 중첩될 수 있나요?

아니요 - 그래서 이미 /* ... */를 포함하는 블록을 통째로 주석 처리하려는 초보자가 잘 걸려 넘어집니다. 안쪽의 첫 */가 바깥쪽 주석을 닫아 버려, 나머지 부분은 살아 있는 코드로 남게 됩니다. 줄마다 //를 붙이거나, 정말 큰 영역을 비활성화해야 한다면 \ifdef SOMETHING_FALSE/`endif`로 감싸세요.

Verilog header 주석에는 무엇이 들어가야 하나요?

대부분의 팀은 모든 파일의 맨 위에 작은 header를 둡니다. 모듈 이름, 한 문장 목적 설명, 포트 요약, 작성자/날짜, 그리고 수정 이력. 정확한 포맷은 다양하지만 중요한 건 파일을 여는 누구든 본문을 읽지 않고도 그게 뭘 하는지 알 수 있다는 점입니다. 큰 설계에서는 모든 포트 선언 옆에 신호별 주석을 덧붙입니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기