[카테고리:] 미분류

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

    이어서 SystemVerilog의 기본 문법을 살펴보겠습니다.

    7. 열거형 (Enumeration)

    열거형을 사용하면 상태 기계(state machine)와 같은 용도에 읽기 쉬운 이름을 부여할 수 있습니다.

    // 기본 열거형 정의
    typedef enum logic [1:0] {
        IDLE  = 2'b00,
        START = 2'b01,
        BUSY  = 2'b10,
        DONE  = 2'b11
    } state_t;
    
    // 열거형 사용
    state_t current_state, next_state;
    
    always_ff @(posedge clk or posedge reset) begin
        if (reset)
            current_state <= IDLE;
        else
            current_state <= next_state;
    end
    
    always_comb begin
        case (current_state)
            IDLE:  next_state = start_signal ? START : IDLE;
            START: next_state = BUSY;
            BUSY:  next_state = process_done ? DONE : BUSY;
            DONE:  next_state = IDLE;
            default: next_state = IDLE;
        endcase
    end
    

    8. 구조체 (Structures)

    구조체는 관련 데이터를 그룹화하는 데 사용됩니다.

    // 패킷 구조체 정의
    typedef struct packed {
        logic [7:0]  addr;      // 주소 필드
        logic [31:0] data;      // 데이터 필드
        logic [2:0]  cmd;       // 명령 필드
        logic        parity;    // 패리티 비트
    } packet_t;
    
    // 구조체 사용
    packet_t tx_packet, rx_packet;
    
    // 구조체 초기화
    initial begin
        tx_packet.addr   = 8'h42;
        tx_packet.data   = 32'hA5A5_5A5A;
        tx_packet.cmd    = 3'b010;
        tx_packet.parity = 1'b0;
        
        // 또는 한 번에 초기화
        tx_packet = '{addr: 8'h42, data: 32'hA5A5_5A5A, cmd: 3'b010, parity: 1'b0};
    end
    
    // 구조체 필드 접근
    always_comb begin
        if (tx_packet.cmd == 3'b010)
            // 명령에 따른 처리...
    end
    

    9. 배열 (Arrays)

    SystemVerilog는 다양한 유형의 배열을 지원합니다.

    // 1차원 배열
    logic [7:0] mem [0:255];    // 256개의 8비트 메모리 배열
    
    // 다차원 배열
    logic [7:0] matrix [0:3][0:3];  // 4x4 매트릭스
    
    // 배열 초기화
    initial begin
        for (int i = 0; i < 256; i++)
            mem[i] = 8'h00;
            
        // 또는 한 번에 초기화
        mem = '{default: 8'h00};
    end
    
    // 동적 배열
    int dyn_array[];  // 크기가 정해지지 않은 동적 배열
    
    initial begin
        // 동적 배열 크기 할당
        dyn_array = new[100];
        
        // 배열 크기 변경
        dyn_array = new[200](dyn_array);  // 기존 값 유지
    end
    
    // 연관 배열(해시 맵)
    int addr_map[string];  // 문자열 키를 가진 연관 배열
    
    initial begin
        addr_map["PC"] = 32'h0000_1000;
        addr_map["SP"] = 32'h0000_2000;
        
        // 연관 배열 접근
        if (addr_map.exists("PC"))
            $display("PC address: %h", addr_map["PC"]);
    end
    
    // 큐(Queue)
    int fifo[$];  // 첫 번째 입력, 첫 번째 출력 큐
    
    initial begin
        fifo.push_back(10);  // 큐 뒤에 추가
        fifo.push_front(5);  // 큐 앞에 추가
        
        int val = fifo.pop_front();  // 큐에서 값 꺼내기
    end
    

    10. 패키지 (Packages)

    패키지는 재사용 가능한 코드를 그룹화하는 데 사용됩니다.

    // 패키지 정의
    package my_pkg;
        // 타입 정의
        typedef enum {RED, GREEN, BLUE} color_t;
        typedef struct {
            int x, y;
        } point_t;
        
        // 상수 정의
        localparam int MAX_COUNT = 100;
        
        // 함수 정의
        function automatic int max(int a, int b);
            return (a > b) ? a : b;
        endfunction
    endpackage
    
    // 패키지 사용
    module top_module;
        // 패키지 가져오기
        import my_pkg::*;  // 모든 심볼 가져오기
        // 또는
        import my_pkg::color_t;  // 특정 심볼만 가져오기
        
        color_t my_color;
        point_t my_point;
        
        initial begin
            my_color = GREEN;
            my_point.x = 10;
            my_point.y = 20;
            
            $display("Max: %d", max(my_point.x, my_point.y));
        end
    endmodule
    

    11. 클래스 (Classes)

    SystemVerilog는 객체지향 프로그래밍을 지원합니다.

    // 클래스 정의
    class Packet;
        // 속성(멤버 변수)
        logic [7:0] addr;
        logic [31:0] data;
        static int packet_count = 0;
        
        // 생성자
        function new(logic [7:0] a = 0, logic [31:0] d = 0);
            addr = a;
            data = d;
            packet_count++;
        endfunction
        
        // 메소드
        function void display();
            $display("Packet: addr=0x%h, data=0x%h", addr, data);
        endfunction
        
        // 정적 메소드
        static function int get_count();
            return packet_count;
        endfunction
    endclass
    
    // 클래스 사용
    module test;
        Packet p1, p2;
        
        initial begin
            p1 = new(8'h42, 32'h1234_5678);
            p2 = new();
            p2.addr = 8'h55;
            p2.data = 32'h9ABC_DEF0;
            
            p1.display();
            p2.display();
            
            $display("Total packets: %d", Packet::get_count());
        end
    endmodule
    

    12. 인터페이스 클래스 (Interface Classes)

    인터페이스 클래스는 추상화 레벨을 높여 코드 재사용성을 향상시킵니다.

    // 인터페이스 클래스 정의
    interface class IDisplay;
        // 가상 메소드 선언
        pure virtual function void display();
    endclass
    
    // 구현 클래스
    class Packet implements IDisplay;
        logic [7:0] addr;
        logic [31:0] data;
        
        // 인터페이스 메소드 구현
        virtual function void display();
            $display("Packet: addr=0x%h, data=0x%h", addr, data);
        endfunction
    endclass
    
    class Status implements IDisplay;
        bit [3:0] status_code;
        
        // 인터페이스 메소드 다른 방식으로 구현
        virtual function void display();
            $display("Status: code=0x%h", status_code);
        endfunction
    endclass
    
    // 다형성 활용
    module test;
        IDisplay disp_arr[2];
        Packet p;
        Status s;
        
        initial begin
            p = new();
            p.addr = 8'h42;
            p.data = 32'h1234_5678;
            
            s = new();
            s.status_code = 4'h7;
            
            disp_arr[0] = p;
            disp_arr[1] = s;
            
            // 인터페이스를 통한 다형성 호출
            foreach (disp_arr[i])
                disp_arr[i].display();
        end
    endmodule