설계한 부품을 배치하고 연결하는 것
아래는 상위 모듈에서 하위 모듈을 사용하는 문법에 대한 설명이다.
하위 모듈을 설계하고, 상위 모듈에서 하위 모듈의 객체(인스턴스)를 생성하여 사용한다.
// 하위 모듈 정의 (부품 설계도)
module adder (
input [7:0] a,
input [7:0] b,
output [8:0] sum
);
assign sum = a + b;
endmodule
// 상위 모듈에서 인스턴스화 (부품 배치)
module top (
input [7:0] x, y,
output [8:0] result
);
// 모듈명 인스턴스명 포트연결
adder u_adder (
.a(x), // 포트 a에 신호 x 연결
.b(y), // 포트 b에 신호 y 연결
.sum(result) // 포트 sum에 신호 result 연결
);
endmodule
위에서 adder는 앞서 설계한 하위 모듈이고, u_adder은 adder의 객체이다.
이렇게 상위 모듈의 포트를 하위 모듈의 포트에 연결해줌으로써 상위 모듈에서 하위 모듈을 사용할 수 있다.
adder u_adder (
.a(x),
.b(y),
.sum(result)
);
위와 같이 .하위_모듈_포트명(상위_모듈_변수명) 형식으로 연결하는 방법이다.
위 방법의 특징은
과 같은 특징이 존재한다.
권장되는 방식이다.
adder u_adder (x, y, result);
// ↑ ↑ ↑
// a b sum (선언 순서대로)
위와 같이 하위 모듈의 포트 선언 순서대로 상위 모듈의 변수를 하위 모듈의 포트로 연결해주는 방
식이다.
위 방법의 특징은
과 같은 특징이 존재한다.
비권장되는 방식이다.
// 출력 포트 미연결 (허용됨)
alu u_alu (
.a(x),
.b(y),
.op(2'b00),
.result(res),
.carry(), // 빈 괄호 - 연결 안 함
.zero() // 빈 괄호 - 연결 안 함
);
// 입력 포트 미연결 (위험! ⚠️)
alu u_alu (
.a(x),
.b(y),
// .op 생략 → op는 불확정(X) 상태!
.result(res)
);
위의 코드와 같이 출력 포트의 미연결은 결과를 버릴뿐, 연산은 정상적으로 수행이 가능하다.
반면, 입력 포트의 미연결은 연산의 정상적인 수행이 불가능하다.
따라서 Verilog에서는
Verilog 에서는 관례적으로 규칙성있고, 가독성 높은 코드를 위해
인스턴스 명명 규칙이 존재한다.
// 좋은 예 ✅
adder u_adder (.a(x), ...); // u_ 접두사
counter u_cnt (.clk(clk), ...);
uart_tx u_uart_tx (.data(tx_data), ...);
// 나쁜 예 ❌
adder adder1 (...); // 모듈명과 혼동
counter a (...); // 의미 없는 이름
관례는 위와 같이 모듈명에 접두사 u_ 또는 i_ 를 붙이는 것이다. (권장되는 방법)
그냥 대충 adder, adder1, adder2, ... 이런식으로 하는 것은 코드의 가독성을 떨어뜨리므로
권장되지 않는다.