- 1 1. Introduction: The Importance and Purpose of “display” in Verilog
- 2 2. Basics of $display: Syntax, Use-Cases, and Precautions
- 3 3. 로그 출력 시스템 태스크 비교: $display, $write, $strobe, $monitor
- 4 4. 포맷 지정자와 고급 디스플레이 기법
- 5 5. 실용 예제: 테스트벤치와 모듈에서 $display 사용하기
- 6 6. 디스플레이 제어 응용 (픽셀/텍스트/이미지 디스플레이)
- 7 7. 적용 시나리오에 따른 적절한 사용법 및 팁
- 8 8. FAQ (자주 묻는 질문)
- 9 9. 결론 및 다음 단계
1. Introduction: The Importance and Purpose of “display” in Verilog
Verilog에서 “display”는 무엇을 의미하나요?
Verilog에서 $display는 시뮬레이션 중 설계의 내부 상태를 “표시”하기 위한 시스템 태스크입니다. C의 printf와 유사하게, 신호, 변수 값, 문자열 등을 터미널이나 콘솔에 출력할 수 있어 디버깅 및 기능 검증에 핵심적인 역할을 합니다.
왜 $display가 Verilog 개발에 필수적인가요?
- 디버깅 효율성 향상 : 복잡한 회로 설계에서는 내부 신호가 올바르게 동작하는지 시각화하는 것이 중요합니다.
$display를 사용하면 시뮬레이션 중 관심 있는 신호의 값을 즉시 확인할 수 있습니다. - 시뮬레이션 가시화 : 특정 시점에서 값 변화를 추적할 때 파형만으로는 부족할 수 있습니다. 디스플레이 로그는 그 정확한 순간을 신뢰성 있게 표시해 줍니다.
- 문서화에도 유용 : 설계 의도나 동작 규칙을 다른 엔지니어에게 전달할 때, 주석이 달린 디스플레이 로그를 삽입하면 코드 이해도를 높일 수 있습니다.
이 글의 목적 및 구성
이 글에서는 다음을 체계적으로 설명합니다.
- 기본 문법 및 사용법 :
$display의 기본 문법과 사용법을 자세히 소개합니다. - 다른 시스템 태스크와의 비교 :
$write,$strobe,$monitor등 디스플레이 관련 태스크와의 차이점을 정리합니다. - 포맷 지정자와 고급 사용 기법 :
%d,%b,%h,%s등 포맷 지정자와 특수 디스플레이 기법을 소개합니다. - 실용적인 사용 예제 : 테스트벤치와 코드에서의 구체적인 사용 예시를 보여주어 바로 적용 가능한 노하우를 제공합니다.
- 디스플레이 제어 응용 : LCD나 모니터 제어와 같은 하드웨어 출력, 텍스트/이미지 출력 예제를 포함합니다.
이와 같은 구성을 통해 초보자와 중급 사용자가 Verilog의 $display를 올바르게 이해하고 실제에 적용할 수 있도록 돕습니다. 이후 각 섹션에서는 가능한 한 예시와 다이어그램을 활용해 명확히 진행합니다.
2. Basics of $display: Syntax, Use-Cases, and Precautions
$display 기본 문법
Verilog에서 $display를 사용할 때 기본 문법은 다음과 같습니다.
$display("string or format specifiers", signal1, signal2, ...);
- 문자열 부분 : 텍스트나 포맷 지정자(예:
%d,%b,%h)를 작성합니다. - 인자 : 해당 포맷에 맞춰 출력할 신호명이나 변수명을 나열합니다.
예시: 클럭 카운트와 신호 값을 표시하기
$display("Time=%0t : clk=%b, reset=%b", $time, clk, reset);
위 예시에서는 시뮬레이션 시간과 클럭/리셋 신호의 값이 출력됩니다.
$display 활용 사례
- 시뮬레이션 진행 상황 파악 : 설계의 특정 지점에
$display를 삽입하면 코드가 어느 부분까지 실행되었는지 확인할 수 있습니다. - 신호 값 검증 : 파형 뷰어만으로는 조건 분기나 상태 전이를 직관적으로 이해하기 어려울 때, 텍스트 출력으로 이해도를 높일 수 있습니다.
- 조건부 메시지 출력 :
if문과 결합해 특정 조건이 만족될 때만 로그를 남길 수 있습니다.if (reset) $display("Reset asserted at %0t", $time);
$display와 $write의 차이점
$display는 출력 끝에 자동으로 개행(newline)을 추가합니다. 반면 $write는 개행 없이 연속해서 출력합니다.
예시:
$display("Hello");
$display("World");
출력:
Hello
World
$write("Hello");
$write("World");
출력:
HelloWorld
줄 단위로 명확한 로그가 필요하면 $display를 사용하고, 한 줄에 여러 값을 포맷팅해서 출력하고 싶다면 $write를 사용하세요.
사용 시 주의사항
- 과도한 출력 방지 매 클럭 사이클마다
$display를 사용하면 로그가 크게 증가하고 가독성이 떨어집니다. → 출력량을 줄이기 위해 조건부 출력을 사용하세요. - 시간 표시 활용
$time이나$realtime을 출력하면 연산의 타이밍을 정확히 파악할 수 있습니다. - 시뮬레이션 전용 태스크
$display는 합성(FPGA/ASIC 구현)에서 사용할 수 없습니다. 순수히 시뮬레이션 디버깅용 도구입니다.
3. 로그 출력 시스템 태스크 비교: $display, $write, $strobe, $monitor
Verilog는 $display 외에도 다양한 시스템 태스크를 제공하여 출력을 제어합니다. 각각의 사용 사례와 타이밍을 이해하면 효율적으로 활용할 수 있습니다.
$display: 표준 디스플레이 태스크
- 특징 자동으로 개행을 추가하고 호출당 한 줄을 기록합니다.
- 사용 사례 가장 기본적인 디버그 방법으로, 언제든지 한 번의 출력이 필요할 때 사용합니다.
$write: 개행 없이 출력
- 특징 개행을 추가하지 않으므로 같은 줄에 계속 출력됩니다.
- 사용 사례 여러 값을 나란히 표시하고 싶을 때 유용합니다.
- 예시
$write("A=%d, ", a); $write("B=%dn", b);→ 출력:A=5, B=10
$strobe: 시뮬레이션 사이클 종료 시 출력
- 특징 현재 단계의 모든 시뮬레이션 평가가 끝난 뒤 값을 출력합니다.
- 사용 사례 레이스 컨디션을 피하고 싶을 때(여러 신호가 동시에 변할 때) 유용합니다.
- 예시
$strobe("Time=%0t, signal=%b", $time, sig);→$display가 중간값을 보여줄 수 있는 반면,$strobe는 안정된 값을 보여줍니다.
$monitor: 자동 추적 출력
- 특징 모니터링 대상 신호가 변할 때마다 자동으로 출력합니다.
- 사용 사례 여러 신호를 지속적으로 감시하고 싶을 때 편리합니다.
- 예시
$monitor("At %0t: a=%b, b=%b", $time, a, b);→a또는b가 변할 때마다 로그가 기록됩니다.
요약 표
| 태스크 | 개행 | 출력 타이밍 | 주요 사용 사례 |
|---|---|---|---|
$display | 예 | 호출 시 | 기본 로그 출력 |
$write | 아니오 | 호출 시 | 나란히 포맷팅 |
$strobe | 예 | 시뮬레이션 사이클 종료 후 | 안정된 값 확인 |
$monitor | 예 | 신호 변동 시 자동 | 지속적인 모니터링 |
효과적인 사용 팁
- 기본적으로
$display사용 : 가독성이 좋고 초보자에게 쉬움. - 한 줄에 결합된 출력을 원한다면
$write사용 . - 변경 후 안정된 값을 보고 싶다면
$strobe사용 . - 신호를 지속적으로 감시해야 한다면
$monitor사용 .
4. 포맷 지정자와 고급 디스플레이 기법
$display나 $write와 같은 태스크에서는 문자열 안에 “포맷 지정자”를 넣어 신호나 변수를 원하는 형식으로 출력할 수 있습니다. C의 printf와 유사하므로 목적에 맞게 올바르게 사용하면 디버깅 효율이 크게 향상됩니다.
기본 포맷 지정자
| 지정자 | 설명 | 출력 예시 |
|---|---|---|
%b | 2진수 | 1010 |
%d | 10진수 | 10 |
%h | 16진수 | A |
%o | 8진수 | 12 |
%c | ASCII 문자 | A |
%s | 문자열 | Hello |
%t | 시뮬레이션 시간 | #100 등 |
%m | 모듈 계층 이름 | top.u1.u2 |
실용 예시
신호를 여러 형식으로 출력
verilog reg [7:0] data = 8'b10101010; $display("data = %b (bin), %d (dec), %h (hex)", data, data, data);
→ 예시 출력:data = 10101010 (bin), 170 (dec), AA (hex)모듈 계층 확인
verilog $display("Current module hierarchy is %m");
→ 예시 출력:Current module hierarchy is top.u1.counter시뮬레이션 시간 출력
verilog $display("Time=%0t: clk=%b", $time, clk);
→ 예시 출력:Time=100: clk=1
고급 디스플레이 기법
- Zero‑padding 및 필드 너비
%0d와 같이 제로 패딩이나 필드 너비를 지정할 수 있습니다. 예시:$display("Count=%04d", count);→ 출력:Count=0012 - Signed vs unsigned 구분
%d는 값을 부호 있는(signed) 것으로,%u는 부호 없는(unsigned) 것으로 처리합니다. 음수 값이 예상대로 표시되지 않으면 지정자를 수정하세요. - 다중 라인 메시지 포맷팅 가독성을 위해
\n을 사용해 줄바꿈합니다. 예시:$display("Start of test\nSignal A=%b\nSignal B=%b", A, B);
주의 사항
- 비트 폭에 유의 : Verilog 신호는 폭이 서로 다를 수 있으며,
%d를 사용하면 트렁케이션이나 부호 확장 문제가 발생할 수 있습니다. - 정의되지 않은 값 (X, Z) 처리 : 정의되지 않은 비트를 포함하면
%b로x혹은z가 직접 표시됩니다.
5. 실용 예제: 테스트벤치와 모듈에서 $display 사용하기
이제 실제 Verilog 코드 예제를 통해 테스트벤치부터 조건부 디버그 로깅까지 $display 의 효과적인 활용 방법을 소개합니다.
기본 예제: 테스트벤치에서 출력하기
테스트벤치에 $display 를 삽입하면 시뮬레이션 중 동작을 관찰할 수 있습니다.
module tb_counter;
reg clk;
reg reset;
wire [3:0] count;
// DUT (Device Under Test)
counter uut (
.clk(clk),
.reset(reset),
.count(count)
);
// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk; // invert every 5 units
end
// Test scenario
initial begin
reset = 1;
#10 reset = 0;
#50 $finish;
end
// Display state
always @(posedge clk) begin
$display("Time=%0t | reset=%b | count=%d", $time, reset, count);
end
endmodule
이 예제에서는 상승하는 클럭마다 reset 과 count 가 출력됩니다. 텍스트 로그와 파형을 동시에 확인할 수 있어 동작 추적이 쉬워집니다.
조건부 디스플레이 예제
if 문과 결합하면 특정 조건이 만족될 때만 로그를 남길 수 있습니다.
always @(posedge clk) begin
if (count == 4'd10) begin
$display("Count has reached 10 (Time=%0t)", $time);
end
end
→ 불필요한 로그를 피하면서 관심 있는 이벤트만 정확히 파악할 수 있습니다.
디버그 메시지 예제
설계 디버깅 시 신호가 “예상치 못한 상태”에 들어갔을 때 이를 포착하는 것이 효과적입니다.
always @(posedge clk) begin
if (count > 4'd12) begin
$display("WARNING: count overflow detected! Time=%0t, value=%d", $time, count);
end
end
→ 설계 결함이나 예상치 못한 시뮬레이션 동작을 빠르게 발견할 수 있습니다.
여러 신호를 동시에 모니터링하기
많은 신호를 출력할 때 $display 로 한 줄에 모아 출력하면 로그 가독성이 향상됩니다.
$display("Time=%0t | clk=%b | reset=%b | A=%h | B=%h | SUM=%h",
$time, clk, reset, A, B, SUM);

실용 팁 요약
- 테스트벤치에
$display를 배치해 진행 상황을 시각화 - 조건문을 활용해 로그를 정제
- 경고 메시지를 생성해 이상 징후를 탐지
- 여러 신호를 한 줄에 통합해 가독성 개선
6. 디스플레이 제어 응용 (픽셀/텍스트/이미지 디스플레이)
지금까지 시뮬레이션 로그용 $display 를 소개했습니다. 한편 Verilog는 하드웨어 구현에서도 “디스플레이 제어”(LCD, VGA, HDMI 출력) 용도로 널리 사용됩니다. 이 섹션에서는 하드웨어 수준에서 화면 디스플레이를 구현하는 방법을 간략히 소개합니다.
디스플레이 제어의 기본 개념
화면에 텍스트나 이미지를 표시하려면 $display 가 아니라 비디오 신호를 생성해야 합니다. 일반적인 제어 신호는 다음과 같습니다:
- HSYNC (Horizontal Sync) : 각 라인의 끝을 나타내는 신호
- VSYNC (Vertical Sync) : 각 프레임의 끝을 나타내는 신호
- RGB Data : 각 픽셀의 색상을 나타내는 신호 (예: 8bit × 3 = 24bit 컬러)
Verilog에서는 카운터와 상태 머신을 이용해 이러한 신호를 타이밍에 맞춰 제어하고 출력함으로써 “스크린 디스플레이”를 구현합니다.
예제 1: 컬러 바 표시하기
가장 기본적인 예는 디스플레이에 색상 막대를 가로로 출력하는 것입니다.
always @(posedge clk) begin
if (h_counter < 100) rgb <= 24'hFF0000; // red
else if (h_counter < 200) rgb <= 24'h00FF00; // green
else if (h_counter < 300) rgb <= 24'h0000FF; // blue
else rgb <= 24'h000000; // black
end
→ 이는 화면을 가로로 정렬된 빨강, 초록, 파랑 색상 막대로 표시합니다.
예제 2: 텍스트 디스플레이
텍스트 디스플레이를 위해 폰트 ROM을 준비하고 각 문자들의 점 패턴을 픽셀로 변환합니다.
// Referencing the pattern of 'A' from the font ROM and displaying
if (font_rom[char_code][y][x] == 1'b1)
rgb <= 24'hFFFFFF; // white for display
else
rgb <= 24'h000000; // black background
→ 이는 특정 문자(예: “A”)를 화면에 그립니다.
예제 3: 이미지 디스플레이
이미지를 표시하려면 미리 저장된 비트맵 데이터(ROM 또는 외부 메모리)를 읽어 픽셀 출력으로 변환합니다.
rgb <= image_rom[addr]; // Retrieve color data from ROM
FPGA를 사용하는 임베디드 시스템에서 이 방법으로 간단한 아이콘이나 로고를 표시할 수 있습니다.
디버그 $display와의 차이점
$display는 텍스트 출력(시뮬레이션 전용)입니다.- 디스플레이 제어는 비디오 신호 생성(하드웨어 구현 가능)입니다.
목적은 다르지만 Verilog 학습자들은 두 가지를 혼동하기 쉽습니다.
- “시뮬레이션 중 동작을 검증하고 싶다” →
$display사용 - “FPGA에서 실제 화면에 출력하고 싶다” → 비디오 신호 로직 설계
응용 분야 확장
- FPGA 보드를 학습할 때 Verilog는 7세그먼트 LED 디스플레이 또는 소형 LCD 디스플레이에 자주 사용됩니다.
- 더 나아가 VGA/HDMI 출력을 지원하는 시스템을 구축하여 게임 개발이나 GUI 디스플레이에 활용할 수 있습니다.
$display에 대한 지식과 디스플레이 제어 로직을 결합하면 시뮬레이션과 실제 하드웨어 모두에서 “디스플레이”를 다룰 수 있습니다.
7. 적용 시나리오에 따른 적절한 사용법 및 팁
Verilog에서 “디스플레이”라고 할 때는 두 가지 측면이 있습니다: 시뮬레이션 전용 $display 작업과 하드웨어 구현 디스플레이 제어. 각각을 적절히 사용하면 효율적인 개발 및 디버깅이 가능합니다.
시뮬레이션에서의 사용
- 디버그 로그로서의
$display$display를 사용해 중요한 변수나 신호를 출력하여 설계가 기대대로 동작하는지 확인합니다.- “특정 조건에서의 값”이나 “카운터가 특정 지점에 도달했는지”를 로그로 검증하는 것이 효율적입니다.
- 과도한 출력 피하기
- 매 클럭 사이클마다 출력하면 로그가 범람하고 가독성이 떨어집니다. 조건을 좁혀 출력합니다.
- 예시:
if (state == ERROR) $display("Error occured at %0t", $time);
- 작업 구분하기
$monitor→ 지속적으로 감시하고 싶은 신호에 사용$strobe→ 안정된 값을 출력하고 싶을 때 사용$write→ 가로형 포맷 출력에 사용
하드웨어 디스플레이 제어에서의 사용
- 학습용 7세그먼트 디스플레이
- FPGA 초급 프로젝트에서 카운터 값을 7세그먼트 LED에 표시하는 것이 일반적입니다.
$display시뮬레이션 출력과 결합하면 디스플레이와 시뮬레이션의 차이를 깊이 이해할 수 있습니다.
- LCD 또는 VGA 모니터 제어
- 폰트 ROM이나 이미지 ROM을 사용해 텍스트나 이미지를 표시합니다.
- 시뮬레이션에서도
$display를 활용하면 비디오 신호 생성이 올바른지 두 번 확인할 수 있습니다.
- 하드웨어 디버그 오버레이
- 실제 비디오 출력에 “카운터 값”, “좌표”, “디버그 메시지” 등을 오버레이할 수 있습니다.
- FPGA 개발에서는 화면 자체를 디버깅 도구로 만드는 것이 일반적입니다.
실용적인 팁
- 시뮬레이션 → 하드웨어 흐름 따라가기 먼저
$display를 사용해 시뮬레이션에서 동작을 검증하고, 이후 하드웨어 구현을 위한 디스플레이 제어 로직으로 이동합니다. - 로그와 파형을 함께 사용
$display의 텍스트 로그는 “이벤트 발생 시점”을 나타내고, 파형은 “세부 전이”를 보여줍니다. 두 가지를 함께 사용하면 디버깅 정밀도가 높아집니다. - 팀 개발에서 메시지 형식 통일
$display메시지 형식(접두사, 시간 표시 등)을 표준화하면 여러 사람이 작업할 때 로그 분석이 쉬워집니다.
요약
$display유형 작업은 시뮬레이션 전용 “관찰 도구”입니다.- 디스플레이 제어는 하드웨어 구현 “디스플레이 방법”을 의미합니다.
- 각각을 적절히 사용하고 결합하면 효율적인 개발이 가능합니다.
8. FAQ (자주 묻는 질문)
Q1. $display와 $monitor의 차이점은 무엇인가요?
A. $display는 호출된 순간에 한 번 출력합니다. 반면 $monitor는 등록된 신호가 변할 때마다 자동으로 출력합니다.
- 일회성 디버깅 →
$display - 지속적인 모니터링 →
$monitor
Q2. 언제 $strobe를 사용해야 하나요?
A. $strobe는 시뮬레이션 사이클이 끝날 때 안정된 값을 출력합니다. 예를 들어 클럭 엣지에서 여러 신호가 동시에 변할 경우 $display는 중간 값을 보여줄 수 있습니다. 이런 경우 최종 값을 표시하기에 $strobe가 편리합니다.
Q3. 포맷 지정자 %m의 용도는 무엇인가요?
A. %m은 현재 모듈 계층 구조 이름을 출력합니다. 큰 설계에서는 “메시지가 어느 계층에서 왔는지”를 로그에 남기는 것이 분석을 훨씬 쉽게 해줍니다.
$display("Current module: %m");
예시 출력:
Current module: top.u1.counter
Q4. $display를 많이 사용해서 로그가 방대해졌어요. 어떻게 해야 하나요?
A. 다음과 같은 방법이 효과적입니다:
if문을 사용해 출력 필터링- 오류 감지나 특정 이벤트만 출력
$monitor를 사용해 최소한의 필수 신호만 감시- 로그 파일에 출력하고 분석 시 필터링 도구 적용
Q5. $display를 합성(FPGA/ASIC)에서 사용할 수 있나요?
A. 아닙니다. $display는 시뮬레이션 전용 작업입니다. 합성 도구는 이를 무시하므로 실제 하드웨어에 반영되지 않습니다. 실제 하드웨어에 출력을 표시하려면 Verilog에서 “7-세그먼트 LED”, “LCD”, “VGA 제어 로직” 등을 설계해야 합니다.
Q6. 실제 하드웨어에 텍스트나 이미지를 어떻게 표시하나요?
A. $display가 아니라 비디오 신호를 생성해서 합니다.
- 7-세그먼트 디스플레이 → 간단한 숫자나 문자 표시용
- VGA/LCD → HSYNC, VSYNC, RGB 신호를 생성하고 제어
- 텍스트 → 폰트 ROM을 사용해 점 패턴 출력
- 이미지 → 비트맵을 ROM이나 외부 메모리에 저장하고 픽셀을 출력
9. 결론 및 다음 단계
이 글의 요약
이 글에서는 Verilog의 “디스플레이”를 기본 개념부터 응용까지 다루었습니다. 주요 내용은 다음과 같습니다:
$display기본- 신호나 변수를 표시하는 시뮬레이션 작업으로, C의
printf와 유사하게 사용할 수 있습니다.
- 신호나 변수를 표시하는 시뮬레이션 작업으로, C의
- 관련 작업과의 차이점
$write→ 줄바꿈 없이 표시$strobe→ 시뮬레이션 사이클 종료 시 안정된 값 출력$monitor→ 신호 변화 자동 감시
- 포맷 지정자 사용
%b,%d,%h,%m,%t등을 사용하면 더 명확하고 실용적인 로그를 출력할 수 있습니다.
- 실용 예제
- 테스트벤치에
$display를 삽입해 진행 상황을 모니터링합니다. - 조건부 메시지를 사용해 효율적인 디버깅을 가능하게 합니다.
- 테스트벤치에
- 디스플레이 제어 적용
$display는 시뮬레이션 전용이며, 하드웨어 구현은 HSYNC, VSYNC, RGB를 사용해 텍스트/이미지를 출력합니다.- 7-세그먼트 디스플레이 학습부터 고급 VGA/HDMI 제어까지 확장이 가능합니다.
다음 단계
- SystemVerilog로 진보 → 후속 언어인 SystemVerilog에서는 더 고급 디버그 기능(어설션, 향상된
$display등)을 사용할 수 있습니다. - 파형 뷰어와 결합 →
$display로그와 파형 데이터를 결합하면 수치값과 전이 모두를 분석할 수 있어 디버깅 정밀도가 향상됩니다. - 하드웨어 디스플레이 출력 학습 → 작은 FPGA 보드 프로젝트에서 7세그먼트나 LCD에 출력해 보면서 “시뮬레이션 디스플레이”와 “하드웨어 디스플레이 제어”의 차이를 체험해 보세요.
- 팀 개발에 적용 →
$display메시지 형식을 표준화함으로써 다인 개발에서 로그 분석 효율을 높일 수 있습니다.
마무리
$display는 단순한 “텍스트 출력” 그 이상입니다. 시뮬레이션 디버깅을 위한 강력한 도구이며, 디스플레이 제어 세계에 들어가면 FPGA를 통해 실제 모니터에 그래픽을 표시하는 즐거움을 경험할 수 있습니다.
이 글이 Verilog 학습자들이 “시뮬레이션 디버깅”과 “하드웨어 디스플레이 출력”을 명확히 이해하는 데 도움이 되길 바랍니다.

