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

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다