Verilog initial 블록: 용도, 문법, 비합성 가능 특성 이해하기
Verilog에는 두 가지 프로시저럴 블록이 있습니다: initial (한 번 실행)과 always (반복 실행). initial 블록은 시뮬레이션 전용으로 합성되지 않습니다.
문법
initial statement;
initial begin ... end
initial 블록의 용도
- 시뮬레이션 시작 시 변수/신호 초기화
- 테스트벤치 자극(Stimulus) 생성: 입력 신호 시퀀스 구동
$display, $monitor, $finish 등 시스템 태스크 호출
- 메모리/파일 로드:
$readmemb, $readmemh
합성 불가: initial 블록은 하드웨어로 매핑되지 않습니다. 실제 회로에 전원 투자 리셋 회로가 필요하면 RTL에 명시적 리셋 로직 구현해야 함.
실행 시점과 종료
- 시뮬레이션 시간 0에서 시작
- 블록 내 모든 문장 실행 완료 시 종료 (한 번만 실행)
- 지연(
#) 문장 포함 시 시간 경과 후 후속 문장 실행
단일 문장 vs 다중 문장
// 단일 문장: begin/end 불필요
initial a = 2'b10;
// 다중 문장 + 지연
initial begin
a = 2'b10;
#10 b = 0; // 10시간 단위 후 실행
end
다중 initial 블록: 병렬 실행
한 모듈 내 여러 initial 블록은 시간 0에 동시에 시작해 병렬 실행. 각 블록의 지연에 따라 종료 시점 다름.
module test;
initial begin #20 $display("Block 1 done at %0t", $time); end
initial begin #10 $display("Block 2 done at %0t", $time); #40 $display("Block 2 cont at %0t", $time); end
initial begin #60 $finish; end // 가장 늦게 끝나는 블록이 시뮬 종료 결정
endmodule
시뮬레이션은 가장 늦게 끝나는 initial 블록(또는 $finish 호출)까지 진행. $finish가 조기 호출되면 다른 블록도 강제 종료.
테스트벤치에서의 표준 패턴
module tb;
reg clk, rstn, din;
wire dout;
dut u0 (.clk(clk), .rstn(rstn), .din(din), .dout(dout));
// 클럭 생성 (always 블록)
always #5 clk = ~clk;
// 자극 생성 (initial 블록)
initial begin
clk = 0; rstn = 0; din = 0;
#12 rstn = 1; // 리셋 해제
#10 din = 1; // 입력 변경
#20 din = 0;
#50 $finish; // 시뮬레이션 종료
end
// 파형 덤프 (선택)
initial begin
$dumpfile("wave.vcd");
$dumpvars(0, tb);
end
endmodule
initial vs always 요약
| 특성 | initial | always |
| 실행 횟수 | 1회 | 무한 반복 (민감도 리스트/지연 기반) |
| 합성 가능 | 불가 | 가능 (올바른 템플릿 준수 시) |
| 주 용도 | 테스트벤치, 초기화, 시뮬 제어 | RTL 설계 (조합/순차 논리) |
지연(#) | 자유 사용 | 합성 시 무시/경고, 시뮬용만 |