Verilog 시작하기
Source: Dev.to

이 게시물은 두 가지에 초점을 맞춥니다
- 반드시 이해해야 할 핵심 Verilog 구문
- 실제 설계에서 사용되는 세 가지 주요 모델링 스타일
소프트웨어 배경을 가지고 있다면, Verilog를 시간에 따라 하드웨어 동작을 설명하는 방법으로 생각하세요, 라인‑바이‑라인 실행되는 프로그램이 아닙니다.
Verilog란 무엇인가?
Verilog는 다음과 같은 디지털 시스템을 모델링하는 데 사용됩니다
- 조합 논리
- 순차 논리
- 유한 상태 기계
- 완전한 SoC 및 ASIC 설계
Verilog 코드는 다음과 같이 할 수 있습니다
- 기능 검증을 위한 시뮬레이션
- 실제 하드웨어 생성을 위한 합성
기본 Verilog 프로그램 구조
Every Verilog design is built using modules.
module example_module (
input wire a,
input wire b,
output wire y
);
assign y = a & b;
endmodule
핵심 포인트
module과endmodule는 하드웨어 블록을 정의합니다.- 입력과 출력은 인터페이스를 설명합니다.
- 내부 로직은 출력이 입력에 어떻게 의존하는지를 설명합니다.
Common Data Types
Wire
연속 연결에 사용됩니다.
wire sum;
assign sum = a ^ b;
Reg
절차 블록 내부에서 값을 저장하는 데 사용됩니다.
reg q;
이름과 달리,
reg는 항상 플립‑플롭을 의미하는 것은 아닙니다. 이는 단순히 신호가always블록 내부에서 할당된다는 의미입니다.
자주 사용할 연산자
- Arithmetic : + - * /
- Logical : &&
- Bitwise : &
- Comparison : == !=
- Assignment : = (blocking) <= (non‑blocking)
Source:
Verilog 모델링 스타일
Verilog는 세 가지 주요 모델링 스타일을 지원합니다. 올바른 스타일을 선택하는 것은 설계 대상과 설명을 얼마나 추상화하고 싶은지에 따라 달라집니다.
1. Behavioral Modeling
회로가 무엇을 하는지에 초점을 맞추며, 어떻게 구현되는지는 다루지 않습니다.
예시: 2:1 멀티플렉서
module mux2_behavioral (
input wire a,
input wire b,
input wire sel,
output reg y
);
always @(*) begin
if (sel)
y = b;
else
y = a;
end
endmodule
특징
always블록을 사용합니다.- 읽고 쓰기 쉽습니다.
- 제어 로직 및 FSM에 이상적입니다.
- 신중히 작성하면 합성 가능합니다.
2. Dataflow Modeling
연속 할당과 식을 이용해 논리를 기술합니다.
예시: 전가산기
module full_adder_dataflow (
input wire a,
input wire b,
input wire cin,
output wire sum,
output wire cout
);
assign sum = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
특징
assign문을 사용합니다.- 불 대수식에 매우 가깝습니다.
- 조합 논리에 가장 적합합니다.
- 간단하고 간결합니다.
3. Structural Modeling
하위 모듈들을 연결하여 회로를 구성하며, 회로도와 유사합니다.
예시: 두 개의 반가산기를 이용한 전가산기
module half_adder (
input wire a,
input wire b,
output wire sum,
output wire carry
);
assign sum = a ^ b;
assign carry = a & b;
endmodule
module full_adder_structural (
input wire a,
input wire b,
input wire cin,
output wire sum,
output wire cout
);
wire s1, c1, c2;
half_adder ha1 (a, b, s1, c1);
half_adder ha2 (s1, cin, sum, c2);
assign cout = c1 | c2;
endmodule
특징
- 계층적 설계입니다.
- 실제 하드웨어 연결을 그대로 반영합니다.
- 대형 설계에서 흔히 사용됩니다.
- 재사용성과 가독성을 높여 줍니다.
4. Gate‑level Modeling
Verilog 기본 게이트 프리미티브를 직접 사용합니다.
예시: 반가산기
module half_adder (
input wire a,
input wire b,
output wire sum,
output wire carry
);
xor (sum, a, b);
and (carry, a, b);
endmodule
특징
- 순수 게이트 수준 기술입니다.
- 큰 설계에서는 매우 번거롭습니다.
블로킹 vs 논블로킹 할당
이것은 Verilog에서 매우 중요합니다.
블로킹 (=)
조합 논리용으로 사용됩니다.
always @(*) begin
x = a & b;
y = x | c;
end
논블로킹 (<=)
순차 논리용으로 사용됩니다.
always @(posedge clk) begin
q <= d;
end
일반적인 규칙
- 조합 논리에서는
=를 사용합니다. - 클럭 기반(순차) 논리에서는
<=를 사용합니다.
순차 논리 모델링
예시: 활성‑저(reset) 리셋을 가진 D 플립플롭
module dff (
input wire clk,
input wire rst,
input wire d,
output reg q
);
always @(posedge clk or negedge rst) begin
if (!rst)
q <= 1'b0;
else
q <= d;
end
endmodule
모든 코드 스니펫은 Verilog‑2001 구문으로 작성되었으며, 별도 언급이 없는 한 합성 가능(synthesizable)합니다.
Source: …
Verilog 플립‑플롭 예제
module dff (
input wire clk,
input wire rst,
input wire d,
output reg q
);
always @(posedge clk or negedge rst) begin
if (!rst)
q <= 1'b0;
else
q <= d;
end
endmodule
이 스타일은 합성 가능하며 하드웨어 플립‑플롭에 직접 매핑됩니다.
각 모델링 스타일을 언제 사용할까
- Behavioral modeling – 제어 로직 및 유한 상태 머신에 가장 적합합니다. 회로가 무엇을 하는지에 초점을 맞추며, 어떻게 구현되는지는 신경 쓰지 않습니다. 복잡한 의사결정 로직을 읽고 유지보수하기가 더 쉽습니다.
- Dataflow modeling – 조합 논리에 이상적입니다. 불 대수식과 밀접하게 일치하며, 산술 회로, 멀티플렉서, 입력으로부터 직접 출력이 도출되는 간단한 논리 블록에 흔히 사용됩니다.
- Structural modeling – 크고 계층적인 설계에 사용됩니다. 작은 모듈들을 연결해 큰 시스템을 구성하며 실제 하드웨어 구조를 그대로 반영합니다. 재사용 가능하고 확장 가능한 설계에 적합합니다.
- Gate‑level modeling – 주로 시연 및 학습 목적에 활용됩니다. 현대의 대규모 설계에서는 거의 사용되지 않으며, Verilog 게이트 프리미티브에 의존해 코드가 장황하고 관리하기 어렵기 때문입니다. 따라서 재사용 가능하거나 확장 가능한 설계를 만드는 데는 부적합합니다.
실제 프로젝트에서는 세 가지 스타일(Behavioral, Dataflow, Structural)을 동일한 설계에 혼합해서 사용하는 경우가 많습니다.
Final Thoughts
Verilog는 다양한 추상화 수준에서 하드웨어를 모델링할 수 있기 때문에 강력합니다. 구문을 이해하는 것도 중요하지만, 다양한 모델링 스타일을 마스터하는 것이 설계를 깔끔하고 확장 가능하며 합성 가능하게 만드는 핵심입니다.
