3-1. Verilog의 구문 (Statement) - if-else 구문

1. Verilog의 if-else 구문의 이해

if-else 구문은 Verilog에서 조건에 따라 코드의 실행 흐름을 제어하는 기본적인 제어 구조입니다. 이는 디지털 시스템의 동작을 모델링하는 데 있어 매우 중요한 역할을 하며, 조건부로 특정 동작을 수행하도록 합니다. 프로그래밍 언어에서 if-else 구문은 가장 기본적인 제어 구조 중 하나이며, Verilog 역시 예외는 아닙니다. if-else 구문을 통해 하드웨어의 동작을 논리적으로 표현하고, 다양한 조건에 따라 서로 다른 기능을 수행하도록 설계할 수 있습니다.

1) if-else 구문의 기본 구조

if-else 구문의 기본 구조는 다음과 같습니다.

if (condition) begin
    // statement1;
    // statement2;
    ...
end
else begin
    // statementA;
    // statementB;
    ...
end

여기서 condition은 참 또는 거짓으로 평가될 수 있는 표현식입니다. 조건이 참(true)이면 if 블록 안의 문장들이 실행되고, 조건이 거짓(false)이면 else 블록 안의 문장들이 실행됩니다. else 부분은 선택 사항이며, else 블록이 없는 경우 조건이 거짓일 때 아무런 동작도 수행하지 않습니다. beginend 키워드는 여러 문장을 하나의 블록으로 묶는 데 사용됩니다.

2) if-else 구문의 동작 원리

if-else 구문은 조건의 평가 결과에 따라 두 가지 실행 경로 중 하나를 선택합니다. 조건 평가의 결과는 true 또는 false이며, Verilog에서는 0이 아닌 값은 true로, 0false로 간주됩니다.

예를 들어, 두 개의 신호 ab를 비교하여 ab보다 크면 output 신호에 1을 할당하고, 그렇지 않으면 0을 할당하는 간단한 회로를 생각해 봅시다.

module compare (
    input  logic [7:0] a,
    input  logic [7:0] b,
    output logic       output
);

    always_comb begin
        if (a > b) begin
            output = 1;
        end
        else begin
            output = 0;
        end
    end

endmodule

이 예제에서 always_comb 블록은 조합 논리를 나타내며, a > b 조건의 평가 결과에 따라 output 신호의 값이 결정됩니다.

2. if-else 구문의 활용

if-else 구문은 다양한 방식으로 활용될 수 있습니다. 특히, 조건에 따라 서로 다른 동작을 수행해야 하는 경우 유용합니다.

1) 다중 조건 처리

if-else 구문은 else if를 사용하여 여러 조건을 차례대로 검사할 수 있습니다. 이를 통해 여러 가지 경우에 대한 서로 다른 동작을 정의할 수 있습니다.

if (condition1) begin
    // statement1;
end
else if (condition2) begin
    // statement2;
end
else if (condition3) begin
    // statement3;
end
else begin
    // statement4;
end

이 구조는 각 조건을 순차적으로 평가하며, 처음으로 참인 조건을 만나면 해당 블록의 문장들을 실행하고 나머지 조건은 평가하지 않습니다. 마지막 else 블록은 모든 조건이 거짓일 경우 실행됩니다.

2) 상태 머신 (State Machine) 설계

if-else 구문은 유한 상태 머신(FSM, Finite State Machine)을 구현하는 데 매우 중요합니다. FSM은 디지털 시스템의 동작을 모델링하는 데 널리 사용되며, 여러 상태를 가지고 상태 전이를 통해 동작을 제어합니다.

module fsm (
    input  logic clk,
    input  logic reset,
    output logic [1:0] state
);

    enum logic [1:0] {IDLE, STATE1, STATE2} current_state, next_state;

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

    always_comb begin
        next_state = current_state; // Default next state

        case (current_state)
            IDLE: begin
                next_state = STATE1;
            end
            STATE1: begin
                next_state = STATE2;
            end
            STATE2: begin
                next_state = IDLE;
            end
        endcase
    end

    assign state = current_state;

endmodule

이 예제는 3개의 상태를 가진 간단한 FSM을 보여줍니다. always_ff 블록은 클럭의 상승 에지 또는 리셋 신호에 의해 트리거되며, 현재 상태를 업데이트합니다. always_comb 블록은 현재 상태에 따라 다음 상태를 결정합니다. case 구문을 사용하여 각 상태에 대한 상태 전이 로직을 구현합니다. if-else 구문은 이 case 구문 안에서도 사용될 수 있습니다.

3) 제어 신호 생성

if-else 구문은 다양한 제어 신호를 생성하는 데 사용될 수 있습니다. 예를 들어, 메모리 읽기/쓰기 신호, 인터럽트 신호, 데이터 유효 신호 등을 생성하는 데 활용됩니다.

module memory_controller (
    input  logic       read_request,
    input  logic       write_request,
    output logic       read_enable,
    output logic       write_enable
);

    always_comb begin
        read_enable  = 0;
        write_enable = 0;

        if (read_request) begin
            read_enable = 1;
        end
        else if (write_request) begin
            write_enable = 1;
        end
    end

endmodule

이 예제는 읽기/쓰기 요청에 따라 read_enable 또는 write_enable 신호를 활성화합니다.

3. if-else 구문의 주의사항

if-else 구문을 사용할 때 몇 가지 주의해야 할 사항이 있습니다.

1) 래치 (Latch) 생성

if-else 구문은 불완전한 조건으로 인해 의도하지 않은 래치를 생성할 수 있습니다. 래치는 원치 않는 동작을 유발하고, 회로의 성능을 저하시킬 수 있습니다. 특히, always 블록 내부에서 if 구문을 사용할 때, 모든 가능한 입력 조건에 대해 출력 신호의 값을 할당하지 않으면 래치가 생성될 수 있습니다.

module latch_example (
    input  logic  a,
    input  logic  en,
    output logic  q
);

    always_comb begin
        if (en) begin
            q = a;
        end
        // else q is not assigned
    end

endmodule

이 예제에서 en이 참일 때만 qa의 값을 받도록 설정되어 있습니다. en이 거짓일 경우 q의 값은 정의되지 않으며, 시뮬레이터는 이 경우 래치를 추론합니다.

래치 생성에 대한 설명 뒤

래치를 방지하려면 모든 가능한 입력 조건에 대해 출력 신호의 값을 명시적으로 할당해야 합니다.

module no_latch_example (
    input  logic  a,
    input  logic  en,
    output logic  q
);

    always_comb begin
        if (en) begin
            q = a;
        end
        else begin
            q = 0; // 명시적으로 값을 할당
        end
    end

endmodule

위의 수정된 예제에서는 en이 거짓일 경우 q0을 할당하여 래치 생성을 방지합니다.

2) 코드 스타일

가독성을 위해 if-else 구문을 사용할 때는 일관된 코드 스타일을 유지하는 것이 중요합니다. 들여쓰기, 괄호 사용, 주석 추가 등을 통해 코드를 이해하기 쉽게 만들 수 있습니다.

3) 합성 가능성

Verilog 코드는 합성 가능한 부분과 시뮬레이션 전용 부분으로 나눌 수 있습니다. if-else 구문은 일반적으로 합성 가능하지만, if 조건에 변동적인 변수가 사용되는 경우, 즉 시뮬레이션 과정에서 값이 변경될 수 있는 변수가 조건에 사용되는 경우에는 합성에 문제가 발생할 수 있습니다. 따라서, 합성 가능한 코드를 작성하기 위해서는 합성 도구의 가이드라인을 따라야 합니다.

4. if-else 구문의 실습 예제

이 섹션에서는 if-else 구문의 사용법을 보여주는 실습 예제를 제공합니다.

1) 2-to-1 멀티플렉서 (Multiplexer)

2-to-1 멀티플렉서는 두 개의 입력 신호 중 하나를 선택하여 출력하는 회로입니다. 선택 신호(select)의 값에 따라 입력 신호 중 하나가 선택됩니다.

module mux2to1 (
    input  logic       a,
    input  logic       b,
    input  logic       sel,
    output logic       y
);

    always_comb begin
        if (sel == 0) begin
            y = a;
        end
        else begin
            y = b;
        end
    end

endmodule

이 예제에서 sel0이면 ya의 값을 갖고, sel1이면 yb의 값을 갖습니다.

2) 4-bit 비교기

4-bit 비교기는 두 개의 4-bit 입력 값의 크기를 비교하는 회로입니다. 두 입력 값이 같으면 "equal" 신호를, 첫 번째 입력 값이 크면 "greater" 신호를, 첫 번째 입력 값이 작으면 "less" 신호를 활성화합니다.

module comparator4bit (
    input  logic [3:0] a,
    input  logic [3:0] b,
    output logic       equal,
    output logic       greater,
    output logic       less
);

    always_comb begin
        equal   = 0;
        greater = 0;
        less    = 0;

        if (a == b) begin
            equal = 1;
        end
        else if (a > b) begin
            greater = 1;
        end
        else begin
            less = 1;
        end
    end

endmodule

이 예제는 if-else if-else 구조를 사용하여 세 가지 경우를 처리합니다.

5. 결론

if-else 구문은 Verilog에서 조건부 동작을 구현하는 핵심적인 요소입니다. 이 구문을 통해 하드웨어의 복잡한 동작을 모델링하고, 다양한 조건에 따라 서로 다른 기능을 수행하도록 설계할 수 있습니다. 래치 생성에 주의하고, 일관된 코드 스타일을 유지하며, 합성 가능성을 고려하여 코드를 작성하는 것이 중요합니다. 위에 제시된 예제들을 통해 if-else 구문의 활용 방법을 익히고, 실제 회로 설계에 적용해 볼 수 있습니다. if-else 구문에 대한 이해는 Verilog를 이용한 디지털 시스템 설계를 위한 기본적인 단계이며, 숙달될수록 보다 효율적이고 정확한 하드웨어 모델링이 가능해집니다.

비슷한 글 추천

Comments (0)

No comments yet. Be the first to comment!