조건문과 로직 흐름 제어 없이는 하드웨어 동작을 구현할 수 없습니다. Verilog는 이를 위한 제어 흐름 블록과 메커니즘을 제공합니다. if-else-if 이 조건문은 특정 문장을 실행할지 여부를 결정하는 데 사용됩니다. C 언어의 if-else-if와 매우 유사합니다. 표현식이 참으로 평가되면 첫 번째 문장이 실행됩니다. 거짓이고 else 부분이 있으면 else 부분이 실행됩니다. 문법 // else 부분 없는 if 문 if (expression) [statement] // else 부분 있는 if 문 if (express
차단 할당 (Blocking Assignment) 차단 할당문은 = 연산자를 사용하며, 절차적 블록 내에서 순차적으로 실행됩니다. 하지만 병렬 블록에서 실행되는 문장들의 실행을 막지는 않습니다. module tb; reg [7:0] a, b, c, d, e; initial begin a = 8hDA; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $time, a, b, c); b = 8hF1; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $
넷(net)과 변수에 값을 할당하는 것을 할당(assignment)이라고 합니다. 기본적으로 세 가지 형태가 있습니다: 절차적 할당 (Procedural) 연속 할당 (Continuous) 절차적 연속 할당 (Procedural continuous) 허용되는 LHS(왼쪽 항) 값 할당문은 오른쪽 항(RHS)과 왼쪽 항(LHS)으로 구성되며, 그 사이에는 등호(=) 또는 비차단 할당 연산자(<=)가 위치합니다. 할당 유형 왼쪽 항 (LHS) 절차적
여러 문장을 하나로 그룹화하는 블록 문장은 begin-end (순차)와 fork-join (병렬) 두 가지가 있습니다. 시뮬레이션 시간 제어와 실행 흐름 이해에 필수적입니다. 순차 블록 (Sequential Block: begin-end) 문장이 순서대로 실행. 지연(#)은 이전 문장 실행 시점 기준 상대적. module design0; reg [31:0] data; initial begin #10 data = 8hfe; // 시간 10에 실행 $display([Time=%0t] dat
앞선 1011 디텍터에 이어 더 긴 패턴 110101 (6비트) 검출기를 구현하고, 오버래핑 패턴 처리까지 다룹니다. 상태 정의 (7개 상태) 상태값매칭된 접두사 IDLE0- S111 S11211 S1103110 S110141101 S11010511010 S1101016110101 (완전 매칭) RTL 구현 (오버래핑 버그 포함 버전) module det_110101 ( input wire clk, input wire rstn, inpu
유한 상태 머신(FSM)의 고전적 예제인 시퀀스 디텍터를 Verilog로 구현합니다. 입력 비트 스트림에서 고정 패턴 1011이 나타날 때 출력을 어서트합니다. 상태 정의 상태값의미 IDLE0초기/매칭 없음 S111 검출 S10210 검출 S1013101 검출 S101141011 완전 매칭 → 출력 1 RTL 구현 (무어 머신) module det_1011 ( input wire clk, input wire rstn, input wire in,
generate 블록은 모듈 인스턴스를 반복 생성하거나 파라미터 기반으로 조건부 인스턴스화를 수행합니다. 정적 엘라보레이션(Elaboration) 단계에서 전개되므로 런타임 오버헤드 제로. generate 블록 제약 포트, 파라미터, specparam, specify 블록 포함 불가 모듈 아이템, 다른 generate 블록, 연속 할당, always/initial, UDP 허용 generate ~ endgenerate 키워드로 감싸기 생성 구조 3가지 Generate for loop Generate if-
Verilog 설계의 모든 행동 코드는 module~endmodule 안에 들어갑니다. 모듈은 입출력 포트로 외부와 통신합니다. 모듈 기본 구조 module testbench; endmodule // 빈 모듈 module dff (input d, clk, rstb, output q); endmodule // 포트 있는 모듈 데이터 타입: reg vs wire 타입비유할당 위치 reg변수 (값 저장)initial, always 블록 내부 wire전선 (연속 구동 필요)assign 문, 포트 연결,
Verilog에는 두 가지 프로시저럴 블록이 있습니다: initial (한 번 실행)과 always (반복 실행). initial 블록은 시뮬레이션 전용으로 합성되지 않습니다. 문법 initial statement; initial begin ... end initial 블록의 용도 시뮬레이션 시작 시 변수/신호 초기화 테스트벤치 자극(Stimulus) 생성: 입력 신호 시퀀스 구동 $display, $monitor, $finish 등 시스템 태스크 호출 메모리/파일 로드: $readmemb, $readmemh
always 블록은 순차 논리(메모리 요소 포함) 구현의 주력 도구입니다. 클럭 에지 기반 상태 업데이트 패턴을 마스터하세요. JK 플립플롭 진리표: J=K=0 유지, J=0/K=1 리셋(0), J=1/K=0 세트(1), J=K=1 토글. module jk_ff (input j, k, rstn, clk, output reg q); always @(posedge clk or negedge rstn) begin if (!rstn) q <= 0; else q <= (j & ~q) | (~k
이전 글에서 assign 문으로 조합 논리를 다뤘다면, 이번엔 always 블록으로 같은 회로들을 구현합니다. always @(*) 패턴이 현대적 표준입니다. 예제 1: 기본 조합 논리 (5입력) module combo (input a, b, c, d, e, output reg z); always @(a or b or c or d or e) begin z = ((a & b) | (c ^ d) & ~e); // 블로킹 할당(=) 사용 end endmodule 중요: 조합 논리 always 블록에서는
always 블록은 Verilog의 프로시저럴(절차적) 블록 중 하나로, 내부 문장들이 순차 실행됩니다. 하드웨어의 동시 동작을 모델링하기 위해 민감도 리스트(sensitivity list) 또는 타이밍 제어로 트리거됩니다. 문법 always @(event) statement; always @(event) begin ... end 민감도 리스트란? @( ... ) 안에 트리거 신호 나열. 나열된 신호 중 값이 변경될 때마다 블록 실행. always @(a or b) begin ... end // a 또는 b 변경 시 실행 (
여러 비트 와이어/변수를 { }로 묶어 더 큰 벡터를 만드는 결합, 같은 표현식을 반복하는 복제 연산자를 마스터하세요. 결합 연산자 { } 피연산자: 와이어, 변수, 표현식, 크기 지정된 상수. 각 피연산자 크기를 알아야 전체 크기 계산 가능. wire a, b; wire [1:0] res; assign res = {a, b}; // res[1]=a, res[0]=b wire [2:0] c; wire [7:0] res1; assign res1 = {b, a, c[1:0], 2b00, c[2]}; // res1[7]=b, [6]
디지털 회로에서 데이터 처리는 필수입니다. 합성 도구가 적절한 하드웨어로 매핑할 수 있는 Verilog 연산자들을 카테고리별로 정리합니다. 산술 연산자 (Arithmetic) 연산자설명비고 a + b덧셈 a - b뺄셈 a * b곱셈DSP 블록 매핑 가능 a / b나눗셈b=0 시 결과 x, 합성 비용 큼 a % b나머지b=0 시 x a ** b거듭제곱피연산자 중 실수 있으면 결과 실수, b=0 시 1 module des; reg [7:0] d1, d2; in
assign 문은 wire 타입 신호를 연속 구동해 조합 논리를 합성하는 표준 방식입니다. 주요 조합 회로 설계 예제를 통해 패턴을 익혀보세요. 예제 1: 기본 조합 논리 (5입력) module combo (input a, b, c, d, e, output z); assign z = ((a & b) | (c ^ d) & ~e); endmodule 합성 시 AND, XOR, NOT, OR 게이트 조합으로 구현. 테스트벤치로 32가지 입력 조합 전수 검증 가능. 예제 2: 반가산기 (Half Adder) module ha
wire 타입 신호는 연속적으로 값을 구동해야 합니다. 브레드보드에서 전선이 배터리 전압을 계속 전달하는 것과 같습니다. Verilog에서 이 개념을 구현하는 것이 assign 문(연속 할당)입니다. assign 문법 assign = [drive_strength] [delay] ; LHS: 스칼라/벡터 넷 또는 넷의 결합 (절대 reg 불가) RHS: 상수, 신호 표현식, 레지스터, 함수 호출 가능 드라이브 강도/지연: 데이터플로 모델링용, 합성 시 대부분 무시 동작: RHS 피연산자 중 하나라도 값 변경 시
복잡한 설계는 여러 모듈을 계층적으로 통합해 만듭니다. 모듈 인스턴스화 시 포트 연결은 순서 기반(Ordered)과 이름 기반(Named) 두 가지 방식이 있습니다. 1. 순서 기반 연결 (Ordered List) 포트 리스트 순서대로 매핑. 설계 모듈의 포트 순서를 알아야 하며, 포트 추가/순서 변경 시 연결이 깨지기 쉽습니다. module mydesign (input x, y, z, output o); endmodule module tb_top; wire [1:0] a; wire b, c; mydesign d0
포트는 모듈과 외부 세상을 연결하는 핀(Pin) 역할을 합니다. 모듈을 PCB 위 칩으로 비유하면 포트는 패키지 핀과 같습니다. 포트 방향 3가지 포트방향설명 input외부 → 내부모듈이 외부에서 값만 수신 output내부 → 외부모듈이 외부로 값만 송신 inout양방향양방향 버스 등에서 송수신 모두 가능 포트 기본 타입은 wire (넷)입니다. 포트 선언 문법 input [net_type] [range] port_names; inout [net_type] [range] port_nam
module은 특정 기능을 구현하는 Verilog 코드 블록입니다. 모듈은 다른 모듈 안에 중첩될 수 있으며, 상위 모듈은 하위 모듈의 입출력 포트를 통해 통신합니다. 모듈 문법 module ([port_list]); // 모듈 내용: 변수 선언, 데이터플로 문장, 함수/태스크, 하위 모듈 인스턴스 endmodule // 포트 리스트가 비어도 됨 module name; // 내용 endmodule module~endmodule 사이에 모든 선언/문장 위치 포트 리스트에 선언된 포트는 모듈 본문에서 재선
Verilog에서 넷이나 변수의 배열 선언은 스칼라/벡터 모두 가능하며, 식별자 뒤에 주소 범위를 추가해 여러 차원을 만들 수 있습니다. reg, wire, integer, real 타입 모두 배열 생성 가능. 배열 선언 예시 reg y1 [11:0]; // 스칼라 reg 배열, 깊이 12, 각 1비트 wire [0:7] y2 [3:0]; // 8비트 벡터 넷 배열, 깊이 4 reg [7:0] y3 [0:1][0:3]; // 2차원 배열: 2행 4열, 각 8비트 배열 요소 접근 및 할당 모든 차원
verilog