지노랩 /JinoLab

[SystemVerilog] 2.11 사용자 정의 구조체 (User-Defined Structures) 본문

SystemVerilog검증/2. Data Type

[SystemVerilog] 2.11 사용자 정의 구조체 (User-Defined Structures)

지노랩/JinoLab 2025. 2. 23. 09:36

 

Verilog의 가장 큰 한계 중 하나는 기본적인 데이터 구조의 부족입니다. SystemVerilog에서는 struct 문법을 사용하여 C 언어의 구조체(struct)와 유사한 구조체를 정의할 수 있습니다. 그러나 struct는 제한적인 클래스 형태이므로, 보다 효율적인 코드 작성을 위해 클래스를 사용하는 것이 권장됩니다.

Verilog에서 모듈이 신호(data)와 코드(always 블록, initial 블록, 루틴 등)를 함께 포함하는 것처럼, SystemVerilog의 클래스는 데이터와 루틴을 결합하여 디버깅과 재사용이 용이한 엔티티를 생성할 수 있습니다. 그러나 typedef 문법을 활용하면 단순히 데이터를 그룹화할 수 있으며, 코드의 가독성을 높이고 유지보수를 쉽게 만들 수 있습니다.

사용자 정의 타입, 유니온, 열거형 타입, 가상 인터페이스를 생성할 때 typedef가 유용하게 활용됩니다.


2.11.1 struct와 새로운 타입 정의

여러 변수를 하나의 구조체로 결합할 수 있습니다. 예를 들어, pixel이라는 구조체를 정의하여 Red, Green, Blue(RGB) 값을 저장하는 변수를 만들 수 있습니다.

예제 2-27: 단일 픽셀 타입 정의

struct {bit [7:0] r, g, b;} pixel;

위 코드에서는 pixel이라는 구조체가 생성되며, 이는 3개의 8비트(bit) 필드(R, G, B)를 포함합니다.

그러나 이 방식으로 선언하면 pixel 타입이 개별적인 하나의 픽셀 데이터만 생성합니다. 만약 여러 픽셀을 공유하고자 할 경우 typedef를 활용하는 것이 좋습니다.

예제 2-28: typedef를 활용한 struct 정의

typedef struct {bit [7:0] r, g, b;} pixel_s;
pixel_s my_pixel;

구조체를 typedef로 선언하면, 여러 곳에서 pixel_s를 재사용할 수 있어 코드의 일관성을 유지하고 유지보수를 쉽게 할 수 있습니다. 관례적으로 struct를 정의할 때는 _s 접미사를 붙여주는 것이 일반적입니다.


2.11.2 여러 데이터 타입을 포함하는 union

하드웨어에서는 레지스터(bit 집합) 값이 다른 비트 값에 따라 다르게 해석될 수 있습니다. 예를 들어, 프로세서의 명령어는 연산 코드(opcode)에 따라 여러 형태의 레이아웃을 가질 수 있으며, 즉시(immediate) 모드에서는 리터럴 값이 피연산자 필드에 저장됩니다. 이러한 값은 정수(Integer)와 부동소수점(Floating Point) 연산이 각각 다르게 처리될 수 있습니다.

SystemVerilog에서는 union을 활용하여 여러 데이터 타입을 하나의 메모리 공간에 저장할 수 있습니다.

예제 2-29: typedef를 활용한 union 정의

typedef union { int i; real f; } num_u;
num_u un;
un.f = 0.0; // 실수 값을 저장

위 예제에서는 union을 사용하여 동일한 메모리 위치에 int와 real 데이터를 저장할 수 있습니다. typedef를 활용하여 num_u라는 사용자 정의 타입을 생성하였으며, 관례적으로 _u 접미사를 붙여 union임을 명확하게 합니다.

하지만 union을 사용할 때는 주의해야 합니다. 메모리를 절약할 수 있는 장점이 있지만, 구조체보다 복잡성이 증가하며 데이터 해석이 어려워질 수 있습니다. 특히, 구조화된 데이터에서는 union 대신 class를 사용하는 것이 더욱 권장됩니다.


2.11.3 패킹된 구조체 (Packed Structures)

SystemVerilog에서는 메모리 레이아웃을 더 세밀하게 제어하기 위해 packed struct를 사용할 수 있습니다. packed struct는 데이터가 메모리에서 연속적인 비트 배열로 저장되도록 합니다. 따라서, 불필요한 공간을 최소화하고 특정 비트 필드를 효율적으로 저장할 수 있습니다.

예제 2-30: typedef를 활용한 패킹된 구조체 정의

typedef struct packed {bit [7:0] r, g, b;} pixel_p_s;
pixel_p_s my_pixel;

위 예제에서 pixel_p_s는 packed struct로 선언되었습니다. 따라서, 메모리에서 r, g, b가 연속적으로 배치되며, 추가적인 패딩 없이 24비트(8비트 x 3)로 저장됩니다.

패킹된 구조체는 다음과 같은 경우에 유용합니다.

  • 숫자 값으로 활용해야 하는 비트 필드를 정의할 때
  • 메모리 사용량을 최소화할 때
  • 레지스터 필드를 조합하여 하나의 값으로 저장할 때

예를 들어, 여러 개의 비트 필드를 결합하여 하나의 레지스터를 만들거나, 연산 코드(opcode)와 피연산자(operand) 필드를 하나로 묶을 때 사용할 수 있습니다.


이와 같이 SystemVerilog에서는 typedef, struct, union, packed struct를 활용하여 보다 유연하고 최적화된 데이터 구조를 설계할 수 있습니다.

 

 

 

Chris Spear 저자님의

SystemVerilog For Verification

A Guide to Learning the Testbench Language Features

내용을 기본으로 작성되었습니다.