지노랩 /JinoLab

[SystemVerilog] 4.8 객체 사용하기 (Using Objects in SystemVerilog) 본문

SystemVerilog검증/4. 객체지향 OOP 기초

[SystemVerilog] 4.8 객체 사용하기 (Using Objects in SystemVerilog)

지노랩/JinoLab 2025. 2. 25. 12:19

SystemVerilog에서 객체를 생성한 후에는 이를 활용하는 방법을 알아야 한다.
Verilog 모듈에서 변수 및 루틴을 접근하는 방식과 유사하게,
SystemVerilog에서는 객체의 멤버 변수 및 메서드(함수, 태스크)를 접근할 때 .(닷) 연산자를 사용한다.


1. SystemVerilog에서 객체 변수와 메서드 접근 방법

아래 예제는 객체를 생성한 후 변수 값을 설정하고, 메서드를 호출하는 기본적인 사용법을 보여준다.

예제 4-8: 객체의 변수 및 루틴 사용

BusTran b;      // BusTran 객체를 위한 핸들 선언
b = new;        // BusTran 객체 생성
b.addr = 32'h42;  // 객체 변수 addr 값을 설정
b.display();    // 객체의 display() 메서드 호출

동작 방식

  1. 핸들 b 선언:
    • b는 BusTran 객체를 가리킬 핸들로 초기화되며, 기본적으로 null 값을 가진다.
  2. 객체 생성 (new 호출):
    • new를 호출하면 b에 새로운 BusTran 객체의 메모리 주소가 할당된다.
  3. 객체 변수 addr 값 설정:
    • b.addr = 32'h42;를 통해 BusTran 객체 내부의 addr 변수에 값을 할당할 수 있다.
  4. 메서드 호출 (display() 실행):
    • b.display();를 실행하면 BusTran 객체 내부의 display() 함수가 실행된다.

이러한 방식으로, 객체 내부의 변수 및 함수에 접근할 수 있다.


2. 엄격한 OOP(Object-Oriented Programming) 방식과의 차이점

엄격한 OOP에서는 객체의 변수(속성)에 직접 접근하지 않고, 반드시 get() 및 put() 같은 메서드를 통해 조작해야 한다.

b.set_addr(32'h42);  // 값 설정
val = b.get_addr();  // 값 읽기

이 방식은 객체의 내부 구현을 숨기고(encapsulation), 추후 코드 변경 시 유지보수성을 높일 수 있다.
즉, get() 및 put()을 사용하면, 변수 접근 방식이 변경되어도 외부 코드 수정이 최소화될 수 있다.

하지만 SystemVerilog에서는 테스트벤치(Testbench) 목적에 따라 직접 변수에 접근하는 방식을 선호하기도 한다.


3. SystemVerilog 테스트벤치에서의 변수 접근 방식

엄격한 OOP는 수십 년 동안 유지되어야 하는 대형 소프트웨어 프로젝트에 적합하다.
하지만 테스트벤치는 설계 검증을 위한 일시적인 코드이므로,
변수 접근을 제한하는 get() 및 put() 방식이 오히려 불편할 수 있다.

테스트벤치에서 직접 변수 접근이 필요한 이유

  1. 랜덤 자극 생성(Constrained Random Stimulus Generation)
    • get() 및 put() 같은 메서드로 변수를 감싸면 변수 값에 대한 직접적인 랜덤 제약을 설정할 수 없음
    • 랜덤 시뮬레이션(randomization)이 필요한 경우, 직접 변수 접근이 필수적
  2. 변수 값을 쉽게 설정하고 수정 가능
    • b.addr = 32'h42; 방식이 간결하고 직관적
    • b.set_addr(32'h42); 방식보다 코드가 더 짧고 읽기 쉬움
  3. GUI, 컴파일러, API 연동을 위한 OOP 방식 유지 가능
    • get() 및 put() 메서드는 GUI, API, 컴파일러에서 객체를 다룰 때 유용할 수 있음
    • 하지만 테스트벤치에서는 빠른 검증이 중요하므로 public 변수를 사용하는 것이 더 적절

4. 테스트벤치에서 public 변수를 사용하는 것이 유리한 경우

엄격한 OOP를 적용하면 모든 변수는 private이며, get() 및 put()을 통해 접근해야 한다.
하지만 테스트벤치에서는 변수를 public으로 선언하고, 직접 접근하는 것이 일반적이다.

class BusTran;
    rand logic [31:0] addr;  // 랜덤 변수 선언
endclass

BusTran b;
initial begin
    b = new;
    b.addr = $random;  // 직접 변수 값 변경 가능
end
  • 위 코드에서는 변수 addr을 직접 할당할 수 있으며, randomization이 가능하다.
  • 반면, get() 및 put() 방식으로 변수에 접근하면 randomization을 적용하기 어려워진다.

5. 결론

SystemVerilog에서 객체를 사용할 때는 b.addr = value; 방식으로 직접 변수에 접근할 수 있다.
이는 테스트벤치에서 랜덤 자극 생성(randomization)을 수행할 때 더욱 유용하다.

SystemVerilog 테스트벤치에서 변수 접근 방식 정리

접근 방식                                            설명                                     장점                                        단점

직접 접근 (b.addr = 32'h42;) 객체의 변수를 . 연산자로 직접 변경 간결하고 효율적, 랜덤 제약 가능 캡슐화 부족, 유지보수 어려움
Getter / Setter (b.get_addr(), b.set_addr(value)) get() 및 put() 메서드를 사용하여 접근 내부 구현 변경 시 외부 코드 수정 최소화 코드가 길어지고 randomization 불가능

 

SystemVerilog에서 get() 및 put()을 사용할 필요는 없으며,
대부분의 테스트벤치에서는 public 변수로 직접 접근하는 방식이 더 유용하다.
따라서 테스트벤치를 설계할 때 변수를 직접 수정할 수 있도록 설계하는 것이 실용적이다.

 

 

 

 

Chris Spear 저자님의

SystemVerilog For Verification

A Guide to Learning the Testbench Language Features

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