모듈은 Verilog의 기본 설계 단위이다.
모듈의 구조는 아래와 같다.
module 모듈이름 (포트 목록);
// 내부 로직
endmodule
예를들어 AND Gate의 경우 아래와 같이 개념도를 그릴 수 있다.
┌─────────────┐
a ───┤ │
│ and_gate ├─── y
b ───┤ │
└─────────────┘
위의 개념도를 기반으로 아래와 같이 모듈을 설계할 수 있다.
module and_gate(
input a,
input b,
output y
);
assign y = a & b;
endmodule
포트란
모듈을 외부와 연결하는 통로이다.
포트의 방향은 input, output, inout 으로 설정할 수 있다.
예를들어 계산기 모듈을 설계하는 경우, 아래와 같은 개념도를 그릴 수 있다.
┌──────────────────┐
num_a ───►│ │
num_b ───►│ calculator ├───► result
operation ──►│ │
└──────────────────┘
이를 모듈로 설계하면 아래와 같다
module calculator (
input [7:0] num_a, // 숫자 A (입력)
input [7:0] num_b, // 숫자 B (입력)
input [1:0] operation, // 연산 선택 (입력)
output [8:0] result // 계산 결과 (출력)
);
// 내부 계산 로직
endmodule
양방향 통신에서 선 1개로 read/write 모두 하는 경우(=BUS 구조) 사용한다.
예를들어 I2C의 경우 아래와 같이 모듈을 설계할 수 있다.
module i2c_controller (
input clk,
inout sda, // 데이터 라인: 읽기도 하고 쓰기도 함
output scl // 클럭 라인: 출력만
);
wire 는 값을 저장하지 않는 HW적인 연결선을 의미한다.
wire는 연결선으로, 값을 저장하지 않고, 연결된 소스의 값을 그저 그대로 전달만한다.
회로의 전선처럼 연결만 담당한다.
reg는 값을 저장하는 레지스터이다.
module example1 (
input a,
input b,
output y // wire (기본값)
);
assign y = a & b; // assign → wire 사용
endmodule
위의 모듈의 포트 a,b,y는 그냥 input/output만 적혀있다.
이렇게 포트의 방향만 적혀있고, 포트의 타입을 생략하면 기본적으로 wire 타입이된다.
위의 a,b,y는 모두 input wire a, input wire b, output wire b 와 같은 것이다.
module example2 (
input clk,
input d,
output reg q // ⭐ reg로 선언!
);
always @(posedge clk) begin
q <= d; // always → reg 필요
end
endmodule
위의 코드와 같이 always block 안에서 출력(q)을 조작하는 경우,
해당 출력 포트를 무조건 reg 타입으로 설정해야한다.
그 외에는 기본값인 wire 타입의 포트를 그대로 사용하면 된다.