[카테고리:] 미분류

  • SystemVerilog 기본 문법 가이드 (1부)

    SystemVerilog는 하드웨어 설계 및 검증을 위한 강력한 언어입니다. 기본 문법부터 차근차근 알아보겠습니다.

    1. 모듈 정의

    SystemVerilog의 기본 구성 요소는 모듈(module)입니다. 모듈은 하드웨어 설계의 기능적 단위를 나타냅니다.

    module counter(
        input  logic        clk,    // 클록 입력
        input  logic        reset,  // 리셋 입력
        output logic [7:0]  count   // 8비트 카운터 출력
    );
        // 모듈 내부 로직 구현
        
    endmodule : counter  // 모듈 이름으로 종료 가능
    

    2. 데이터 타입

    SystemVerilog는 Verilog의 reg, wire 보다 더 명확한 데이터 타입을 제공합니다.

    logic [7:0] counter;      // 8비트 논리 신호 (reg/wire 대체)
    bit         flag;         // 단일 비트 (0,1만 가능)
    byte        value;        // 8비트 부호 있는 정수
    shortint    short_val;    // 16비트 부호 있는 정수
    int         int_val;      // 32비트 부호 있는 정수
    longint     long_val;     // 64비트 부호 있는 정수
    
    // 부호 없는 정수형
    bit [7:0]   unsigned_byte;
    logic [15:0] unsigned_short;
    

    3. 항상 블록 (Always Blocks)

    SystemVerilog에서는 목적에 따라 세 가지 항상 블록을 사용합니다.

    // 순차 로직(플립플롭)을 위한 always_ff
    always_ff @(posedge clk or posedge reset) begin
        if (reset)
            counter <= 8'h00;
        else
            counter <= counter + 1;
    end
    
    // 조합 로직을 위한 always_comb
    always_comb begin
        if (counter == 8'hFF)
            overflow = 1'b1;
        else
            overflow = 1'b0;
    end
    
    // 래치를 위한 always_latch (일반적으로 피해야 함)
    always_latch begin
        if (enable)
            latch_data <= data_in;
    end
    

    4. 할당 연산자

    SystemVerilog에서는 두 가지 할당 유형을 사용합니다.

    // 블로킹 할당 (=): 순차적으로 즉시 실행, 주로 조합 로직에 사용
    always_comb begin
        temp = a + b;  // 이 할당은 즉시 발생
        sum = temp;    // temp 값이 먼저 계산된 후 할당됨
    end
    
    // 논블로킹 할당 (<=): 병렬로 사이클 끝에 실행, 주로 순차 로직에 사용
    always_ff @(posedge clk) begin
        a <= b;        // 모든 우변이 계산된 후
        b <= a;        // 모든 좌변에 동시에 할당됨
    end
    

    5. 매개변수 (Parameters)

    매개변수를 사용하여 재사용 가능한 모듈을 만들 수 있습니다.

    module counter #(
        parameter WIDTH = 8,           // 기본값이 8인 매개변수
        parameter [WIDTH-1:0] INIT = 0 // 매개변수는 다른 매개변수를 참조할 수 있음
    )(
        input  logic clk, reset,
        output logic [WIDTH-1:0] count
    );
    
        // 모듈 내부에서 매개변수 사용
        always_ff @(posedge clk or posedge reset) begin
            if (reset)
                count <= INIT;
            else
                count <= count + 1;
        end
        
    endmodule
    

    6. 인터페이스 (Interfaces)

    인터페이스는 관련 신호를 그룹화하고 모듈 간 통신을 단순화합니다.

    // 인터페이스 정의
    interface bus_if;
        logic [7:0] data;
        logic       valid;
        logic       ready;
        
        // 인터페이스 내에 모듈러 태스크 정의 가능
        task automatic transfer(input logic [7:0] d);
            valid = 1'b1;
            data = d;
            wait(ready);
            #1 valid = 1'b0;
        endtask
    endinterface
    
    // 인터페이스 사용
    module sender(bus_if bus);
        // 인터페이스의 신호에 접근
        always_ff @(posedge clk) begin
            bus.valid <= data_ready;
            bus.data <= transmit_data;
        end
    endmodule
    
    module receiver(bus_if bus);
        always_ff @(posedge clk) begin
            if (bus.valid && bus.ready)
                received_data <= bus.data;
        end
    endmodule