Verilog always 블록 완벽 가이드: 문법, 민감도 리스트, 조합/순차 설계
always 블록은 Verilog의 프로시저럴(절차적) 블록 중 하나로, 내부 문장들이 순차 실행됩니다. 하드웨어의 동시 동작을 모델링하기 위해 민감도 리스트(sensitivity list) 또는 타이밍 제어로 트리거됩니다.
문법
always @(event) statement;
always @(event) begin ... end
민감도 리스트란?
@( ... ) 안에 트리거 신호 나열. 나열된 신호 중 값이 변경될 때마다 블록 실행.
always @(a or b) begin ... end // a 또는 b 변경 시 실행 (조합 논리)
always @(posedge clk) begin ... end // clk 상승 에지에서 실행 (순차 논리)
always @(posedge clk or negedge rstn) begin ... end // 비동기 리셋 포함
민감도 리스트가 없으면?
always 블록이 0 지연 무한 루프로 시뮬레이션 행(hang). 반드시 타이밍 제어 필요.
always clk = ~clk; // 불법: 0 지연 무한 루프
always #10 clk = ~clk; // 합성 불가하지만 시뮬용 클럭 생성엔 OK
주의: 명시적 지연(#10)은 합성 불가. 실제 설계 코드는 반드시 민감도 리스트 필요.
순차 소자 설계 예: T 플립플롭
module tff (input d, clk, rstn, output reg q);
always @(posedge clk or negedge rstn) begin
if (!rstn) q <= 0;
else if (d) q <= ~q; // d=1일 때 토글
else q <= q;
end
endmodule
posedge clk: 양의 에지에서 상태 업데이트
negedge rstn: 리셋 어서트(하강 에지) 시 비동기 클리어
- 비블로킹 할당(
<=) 사용 — 순차 논리 필수
리셋 에지에서 일어나는 일
negedge rstn 발생 → rstn=0
if (!rstn) 참 → q <= 0 실행
조합 논리 설계 예
module combo (input a, b, c, d, output reg o);
always @(a or b or c or d) begin
o <= ~((a & b) | (c ^ d));
end
endmodule
- 모든 입력을 민감도 리스트에 포함 (Verilog-2001부터
@(*) 또는 @*로 자동 추론 가능)
- 출력 포트는
reg 타입 선언 (프로시저럴 블록에서 할당하므로)
- 조합 논리엔 블로킹 할당(
=) 권장 — 시뮬레이션 경합 방지
할당 유형 비교
| 할당 | 기호 | 용도 | 실행 시점 |
| 블로킹 | = | 조합 논리, 순차적 실행 | 즉시 |
| 비블로킹 | <= | 순차 논리, 병렬 업데이트 | 타임스텝 끝 (NBA 영역) |
황금률: 순차 논리 → <=, 조합 논리 → = (또는 always_comb in SystemVerilog)
민감도 리스트 자동화 (Verilog-2001+)
always @(*) begin ... end // 읽히는 모든 신호 자동 포함
always @* begin ... end // 동일
수동 리스트 누락으로 인한 시뮬레이션/합성 불일치(래치 유도) 방지.