Verilog 모듈 기초: 구조, 문법, 계층적 설계의 핵심
module은 특정 기능을 구현하는 Verilog 코드 블록입니다. 모듈은 다른 모듈 안에 중첩될 수 있으며, 상위 모듈은 하위 모듈의 입출력 포트를 통해 통신합니다.
모듈 문법
module ([port_list]);
// 모듈 내용: 변수 선언, 데이터플로 문장, 함수/태스크, 하위 모듈 인스턴스
endmodule
// 포트 리스트가 비어도 됨
module name;
// 내용
endmodule
module~endmodule 사이에 모든 선언/문장 위치
- 포트 리스트에 선언된 포트는 모듈 본문에서 재선언 불가
- 한 파일에 여러 모듈 정의 가능, 순서 무관
예시: D 플립플롭 (DFF)
module dff (
input wire d,
input wire clk,
input wire rstn,
output reg q
);
always @(posedge clk or negedge rstn) begin
if (!rstn) q <= 0;
else q <= d;
end
endmodule
입력: d(데이터), clk(클럭), rstn(액티브 로우 리셋). 출력: q(상태). 양의 에지에서 d를 q로 래치, 리셋 시 0 클리어.
합성 후 하드웨어 회로도
DFF 심볼: 클럭, 리셋, 데이터 입력 → 상태 저장 플립플롭 → Q 출력.
주의: 모듈 밖에 어떤 코드도 작성할 수 없습니다!
모듈의 목적: 재사용과 계층화
모듈은 합성 시 디지털 회로로 변환되는 설계 단위입니다. 같은 모듈을 여러 번 인스턴스화해 더 큰 회로 구성 가능.
예: DFF 4개로 시프트 레지스터 만들기
module shift_reg (
input wire d,
input wire clk,
input wire rstn,
output wire q
);
wire [2:0] q_net;
dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q(q_net[1]));
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q(q_net[2]));
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
각 DFF 인스턴스는 와이어로 연결되어 4비트 시프트 레지스터 형성.
역방향 분해: GPU 엔진을 서브 블록으로 분해
복잡한 블록(예: GPU)을 버스 인터페이스, 인스트럭션 페치, 디코드, 실행, 라이트백 등 5개 서브 모듈로 분해. 각 서브 모듈은 입출력 포트로 통신하며 필요시 더 세분화 가능.
최상위 모듈 (Top-Level Module)
다른 모든 모듈을 포함하며, 어떤 모듈에도 인스턴스화되지 않는 모듈.
설계 관점의 탑레벨
module mod3 (...); ... endmodule
module mod4 (...); ... endmodule
module mod1 (...); mod3 mod_inst1(...); mod3 mod_inst2(...); endmodule
module mod2 (...); mod4 mod_inst1(...); mod4 mod_inst2(...); endmodule
// 설계 탑레벨: 모든 서브 모듈 포함
module design (...); mod1 mod_inst1(...); mod2 mod_inst2(...); endmodule
테스트벤치 관점의 탑레벨
module testbench;
design d0 (...); // 설계 모듈 인스턴스화
// 자극 생성, 검증 로직
endmodule
시뮬레이터 관점에서는 테스트벤치가 최상위.
계층적 이름 (Hierarchical Names)
모듈 인스턴스 트리에서 점(.)으로 구분해 경로 표현. 모든 신호에 계층 경로로 접근 가능.
design.mod_inst1 // mod_inst1 모듈 인스턴스 접근
design.mod_inst1.y // mod_inst1 내 신호 y 접근
design.mod_inst2.mod_inst2.a // mod_inst2 내 mod4 인스턴스의 a 접근
testbench.d0._net // 테스트벤치에서 설계 내부 넷 접근
이 기능은 디버깅, 프로빙, 계층적 제약 정의 등에 필수적입니다.