Verilog 치트시트
마지막 업데이트
모듈 구조 및 포트
모듈은 기본 구성 요소입니다 - 이름과 포트 목록을 가집니다.
| 문법 | 의미 |
|---|---|
module adder(...); ... endmodule | 모듈과 그 본문을 정의 |
input clk; | 입력 포트 |
output q; | 출력 포트 |
output reg q; | always 블록에서 구동되는 출력 |
input [7:0] data; | 8비트 입력 버스 (벡터) |
inout sda; | 양방향 포트 |
adder u1 (.a(x), .b(y), .sum(s)); | 이름 있는 포트로 모듈 인스턴스화 |
자료형
wire는 연결을 모델링하고, reg는 절차적 코드가 할당하는 값을 담습니다.
| 요소 | 기능 |
|---|---|
wire w; | assign이나 모듈 출력으로 구동되는 네트 |
reg r; | always/initial 블록 안에서 할당된 값을 담음 |
wire [3:0] bus; | 4비트 벡터 (비트 3부터 0까지) |
reg [7:0] count; | 8비트 레지스터 |
bus[2] | 단일 비트 선택 |
bus[3:1] | 비트 슬라이스 선택 (부분 선택) |
reg mem [0:255]; | 메모리: 레지스터의 배열 |
parameter WIDTH = 8; | 모듈을 위한 이름 있는 상수 |
숫자 리터럴
형식은 <size>'<base><value>입니다 - 크기는 비트 단위, 진법은 b/o/d/h.
| 문법 | 의미 |
|---|---|
4'b1010 | 4비트 2진수, 값 10 |
8'hFF | 8비트 16진수, 값 255 |
8'hff | 동일 - 16진수 숫자는 대소문자 구분 없음 |
16'd255 | 16비트 10진수, 값 255 |
3'o7 | 3비트 8진수, 값 7 |
8'b1010_1100 | 밑줄은 가독성을 위해 자릿수를 묶음 |
1'bx | 알 수 없는(x) 비트 값 |
1'bz | 고임피던스(z) 비트 값 |
연산자
비트, 논리, 비교, 축약 연산자.
| 연산자 | 기능 |
|---|---|
& | ^ ~ | 비트 AND, OR, XOR, NOT |
&& || ! | 논리 AND, OR, NOT (1비트 반환) |
== != < > <= >= | 비교 연산자 |
<< >> | 왼쪽 및 오른쪽 시프트 |
+ - * / % | 산술 연산자 |
&bus | 축약 AND (모든 비트의 AND) |
|bus | 축약 OR (모든 비트의 OR) |
^bus | 축약 XOR (모든 비트의 패리티) |
{a, b} | 연결(concatenation); {4{1'b1}}은 4'b1111로 복제 |
연속 할당
assign은 wire를 연속적으로 구동합니다 - 조합 논리에 사용하세요.
| 문법 | 의미 |
|---|---|
assign y = a & b; | a와 b의 AND로 y를 구동 |
assign sum = a + b; | 합을 연속적으로 계산 |
assign y = sel ? a : b; | 삼항 연산자 - 2-to-1 멀티플렉서 |
assign {c, s} = a + b; | 캐리와 합을 함께 취득 |
assign y = ~en; | 반전된 신호로 wire 구동 |
절차적 블록
always와 initial은 문을 실행하며, 감도 리스트가 실행 시점을 제어합니다.
| 문법 | 의미 |
|---|---|
always @(*) begin ... end | 조합 논리 (입력이 바뀔 때마다) |
always @(posedge clk) | 클록 상승 에지마다 실행 (순차) |
always @(negedge clk) | 클록 하강 에지마다 실행 |
always @(posedge clk or posedge rst) | 비동기 리셋이 있는 클록 블록 |
initial begin ... end | 시간 0에 한 번 실행 (테스트벤치, 시뮬레이션 전용) |
begin ... end | 여러 문을 묶음 |
#10 | 10 시간 단위 지연 (시뮬레이션 전용) |
블로킹 vs 논블로킹
조합 논리에는 =를, 클록 순차 논리에는 <=를 사용하세요.
| 문법 | 의미 |
|---|---|
a = b; | 블로킹 - 순서대로 즉시 실행 |
a <= b; | 논블로킹 - 모든 우변을 먼저 읽은 후 할당 |
always @(*) y = a & b; | 조합: 블로킹 = 사용 |
always @(posedge clk) q <= d; | 플립플롭: 논블로킹 <= 사용 |
한 블록에서 =와 <= 혼용 | 피하세요 - 흔한 버그의 원인 |
제어 흐름
절차적 블록 안의 조건문과 다중 분기.
| 문법 | 의미 |
|---|---|
if (cond) ... else ... | 조건문 |
if (a) x = 1; else x = 0; | 한 줄 if/else |
case (sel) ... endcase | 값에 대한 다중 분기 |
2'b00: y = a; | case 항목 |
default: y = 0; | 대체 case 항목 |
for (i = 0; i < 8; i = i + 1) | 반복문 (흔히 generate나 시뮬레이션 안) |
repeat (4) @(posedge clk); | 문을 N번 반복 |
자주 쓰는 패턴
거듭 작성하는 구성 요소와 테스트벤치 작업.
| 패턴 | 문법 |
|---|---|
| D 플립플롭 | always @(posedge clk) q <= d; |
| 리셋이 있는 레지스터 | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| 카운터 | always @(posedge clk) count <= count + 1; |
| FSM 상태 레지스터 | always @(posedge clk) state <= next_state; |
| FSM 다음 상태 논리 | always @(*) case (state) ... endcase |
| 값 출력 | $display("q = %b", q); |
| 변경 시 출력 | $monitor("t=%0t q=%b", $time, q); |
| 시뮬레이션 종료 | $finish; |
자주 쓰는 모든 Verilog 문법을 한 페이지에 담았습니다. 이 Verilog 치트시트는 하드웨어 기술 언어를 위한 빠른 참조 자료입니다 - 모듈과 포트 선언, 자료형 선택, 조합 논리와 순차 논리 작성, 그리고 실제 회로를 기술하는 always 블록 패턴을 다룹니다.
여기 나오는 문법은 표준 Verilog(IEEE 1364)이며 Icarus Verilog, Verilator 같은 일반적인 시뮬레이터에서 동작합니다. 필요한 것을 복사하거나, Verilog 플레이그라운드에서 바로 시험해 보세요 - 모듈을 작성하고 시뮬레이션해 브라우저에서 출력을 확인할 수 있습니다.
Verilog 치트시트 자주 묻는 질문
이 Verilog 치트시트는 무료인가요?
wire와 reg의 차이는 무엇인가요?
wire는 물리적 연결을 모델링하며 연속적으로 구동되어야 합니다 - assign 문이나 모듈 출력으로 - 그래서 조합 네트에 사용합니다. reg는 절차적 코드가 값을 바꿀 때까지 값을 유지하므로, always나 initial 블록 안에서 할당되는 것에 사용합니다. 이름과 달리 reg이 항상 하드웨어 레지스터가 되는 것은 아닙니다. 그저 값이 절차적으로 설정된다는 의미입니다.블로킹 할당과 논블로킹 할당의 차이는 무엇인가요?
=)은 일반 프로그래밍 문처럼 순서대로 즉시 실행되므로, always @(*) 블록의 조합 논리에 사용합니다. 논블로킹 할당(<=)은 모든 우변을 먼저 평가한 다음 좌변을 함께 갱신하는데, 이것이 플립플롭을 올바르게 모델링합니다 - 그래서 클록이 있는 always @(posedge clk) 블록에 사용합니다. 한 블록에서 둘을 혼용하는 것은 시뮬레이션 버그의 전형적인 원인입니다.