Verilog case 문 완전 정복: 구문, 예제 및 모범 사례

1. Introduction

Verilog은 디지털 회로 설계에 널리 사용되는 하드웨어 기술 언어(HDL) 중 하나입니다. 그 기능 중 case 문은 조건 분기를 효율적으로 기술하기 위한 필수 구조입니다. 특히 상태 머신(FSM) 및 멀티플렉서 설계에서 흔히 사용됩니다. 이 글에서는 Verilog case 문의 기본, 고급 활용 사례, 그리고 모범 사례를 다룹니다. 단계별로 설명되는 실용적인 코드 예제를 통해 초보자도 쉽게 따라 할 수 있으니, 끝까지 읽어 보시기 바랍니다.

2. Basic Syntax of the Verilog case Statement

What is a case Statement?

Verilog case 문은 주어진 조건(선택자)에 따라 서로 다른 연산을 수행하는 구조입니다. C 언어의 switch-case 문과 비슷하지만 몇 가지 중요한 차이점이 있습니다. 기본 문법은 다음과 같습니다:
case (expression)
    condition1: statement1;
    condition2: statement2;
    condition3: statement3;
    default: statement4;  // Executes if no condition matches
endcase

Basic Usage of case

다음 예시는 2비트 입력 sel에 따라 out에 서로 다른 신호를 할당하는 간단한 case 문을 보여줍니다:
module case_example(input [1:0] sel, output reg [3:0] out);
    always @(*) begin
        case (sel)
            2'b00: out = 4'b0001;
            2'b01: out = 4'b0010;
            2'b10: out = 4'b0100;
            2'b11: out = 4'b1000;
            default: out = 4'b0000;  // Default value for safety
        endcase
    end
endmodule
여기서 outsel 값에 따라 다른 값을 갖게 됩니다. default 케이스를 포함함으로써 예상치 못한 입력을 안전하게 처리할 수 있습니다.

Differences Between case, casex, and casez

Verilog은 확장된 형태의 case를 제공합니다: casexcasez. 이들은 와일드카드처럼 동작하여 특정 비트를 무시할 수 있습니다.
SyntaxCharacteristics
case정확히 일치해야 함(기본 동작)
casexX(알 수 없음)와 Z(고임피던스) 값을 무시
casezZ 값만 무시
casez를 사용한 예시:
casez (sel)
    2'b1?: out = 4'b1111; // Matches if the MSB is 1
    2'b01: out = 4'b0001;
    default: out = 4'b0000;
endcase
여기서 1?는 가장 높은 비트가 1이면 하위 비트와 관계없이 매치된다는 의미입니다.

3. Practical Examples of case

Basic Conditional Branching

다음 예시는 8비트 opcode 값에 따라 서로 다른 연산을 수행하는 간단한 CPU 디코더를 보여줍니다:
module decoder(input [7:0] opcode, output reg [3:0] control_signal);
    always @(*) begin
        case (opcode)
            8'h00: control_signal = 4'b0001; // NOP
            8'h01: control_signal = 4'b0010; // ADD
            8'h02: control_signal = 4'b0100; // SUB
            default: control_signal = 4'b0000; // Undefined instruction
        endcase
    end
endmodule

Using case in State Machines

case 문은 FSM(유한 상태 머신) 에서 널리 사용됩니다:
typedef enum reg [1:0] {IDLE, RUN, STOP} state_t;
state_t current_state, next_state;

always @(posedge clk) begin
    if (reset)
        current_state <= IDLE;
    else
        current_state <= next_state;
end

always @(*) begin
    case (current_state)
        IDLE: next_state = RUN;
        RUN:  next_state = STOP;
        STOP: next_state = IDLE;
        default: next_state = IDLE;
    endcase
end
이는 3상태 FSM을 구현한 예시입니다. 상태 관리가 필요한 회로에서는 case가 로직을 훨씬 명확하게 만들어 줍니다.

4. Best Practices and Caveats

Verilog에서 case 문을 사용할 때는 다음 사항을 유념하십시오:

1. Always Include a default Case

가능한 모든 입력을 포괄하는 것이 중요합니다. FPGA나 ASIC 합성 시 default를 생략하면 예기치 않은 래치 생성이 발생할 수 있습니다.

2. casexcasez를 신중히 사용하기

These constructs can match unintended signals. Always simulate thoroughly when using them.
casez (sel)
    2'b1?: out = 4'b1111; // Matches if MSB = 1
    2'b01: out = 4'b0001;
    default: out = 4'b0000;
endcase

3. case를 과도하게 사용하지 말 것

For small conditional branches, if-else can be more intuitive and readable. Use case mainly when there are multiple options to handle.

5. 결론

In this article, we covered the following about the Verilog case statement: ✅ Basic syntax and behavior ✅ Differences between case, casex, and casez ✅ Practical usage (conditional branching, FSMs) ✅ Key caveats and best practices By using the case statement properly in Verilog, you can improve readability and prevent design errors. Apply these concepts in your future designs!

Verilog에서 다음에 배울 내용

Once you understand the case statement, the next step is to study the always block and the difference between combinational and sequential circuits for deeper insights into Verilog design.