-
[SystemVerilog] 클래스 1개발/SystemVerilog 2022. 1. 17. 23:33
시스템베릴로그에서는 클래스 도입으로 객체지향 프로그래밍이 가능해졌다.
객체지향을 100퍼 지원하는건 아니고 일부분을 지원한다.
1. 추상적 데이터 모델링 (Abstract data modeling)
2. 상속 (Inheritance)
3. 데이터 은닉 (Encapsulation)
4. 다형성 (Polymorphism)
클래스 정의는 class .. endclass 키워드로 할 수 있다.
class myclass; bit [31:0] word; endclass // create class handle myclass c1; // handle points to null myclass c2 = new; // points to object myclass c3 = new c2; // shallow copy
클래스를 정의한 이름 사용하여 클래스 핸들을 선언한다.
클래스 핸들을 선언하고 난 뒤에 new 생성자 함수를 사용하여 오브젝트를 생성해야 한다.
new함수로 오브젝트를 생성하지 않은 c1은 클래스 핸들일뿐, 클래스가 아니다. c1은 null을 가르킨다.
c2는 myclass 오브젝트가 생성이 되었다.
시스템베릴로그는 소멸자가 따로 없다. 클래스 핸들에 null 또는 다른 클래스가 할당되면 기존에 지정되었던 클래스는
시뮬레이터에서 알아서 없애준다.
C언어에서는 포인터 자체를 직접 조작할 수 있지만, 시스템베릴로그의 클래스 핸들은 사용자에 의한 오류를 줄이기 위해서 이러한 기능을 제한한다.
클래스 핸들에 어떤 수를 더하는것, 임의의 데이터타입을 가르키는것 등은 할 수 없다.
클래스를 정의할 때 내부에 데이터와 메서드를 정의할 수 있다.
class myclass int num; task set (input int i); num = i; endtask function int get(); return num; endfunction endclass initial begin int number; myclass c1 = new; c1.num = 1; c1.set(4); number = c1.get(); end
클래스 내부에 정의된 데이터들을 속성(Property)이라고 한다.
클래스 내부에 정의된 함수, 태스크를 메서드(Method)라고 한다.
클래스의 속성과 메서드들은 . 기호로 접근할 수 있다.
클래스 내부에 메서드를 정의하려는데 메서드의 코드가 너무 길면 클래스 밖에 정의를 할 수 있다.
이 때, 클래스 내부에서 extern 키워드를 사용한다. 그리고 클래스 내부에 메서드의 프로토타입을 정의한다.
class myclass; int num; // methods prototype definition extern function int get; extern task set(int number); endclass // method implementation function int myclass::get; return num; endfunction task myclass::set(int number); num = number; endtask
클래스 밖에서 메서드를 구현하려면 메서드 이름 앞에 해당 클래스 이름을 먼저 적어야 한다.
그리고 :: (스코프 연산자)를 사용해야한다.
중요한것은 클래스 내부에 정의된 프로토타입과 형식(메서드 이름, 종류, 입출력 인자 등)이 일치해야한다.
생성자 new 함수는 모든 클래스에 기본적으로 정의된 메서드이다.
이 함수를 다시 정의할 수 있다.
class myclass int num; function new(int number); num = number; endfunction endclass initial begin myclass c1 = new(10) // num = 10 end
new 함수를 사용할때, 인자를 같이 넣으면 해당 값으로 속성값이 할당된다.
클래스 오브젝트를 생성과 동시에 초기값을 설정할 때 유용하다.
클래스를 파라미터화 하여 정의할수 있다.
class packet #(paramter int ADDR_WIDTH = 32, DATA_WIDTH = 32); bit [ADDR_WIDTH-1:0] addr; bit [DATA_WIDTH-1:0] addr; ... endclass initial begin packet pkt; // default ADDR_WIDTH=32, DATA_WIDTH=32 packet #(16, 64) pkt; // ADDR_WIDTH=16, DATA_WIDTH=64 packet #(.DATA_WIDTH(16), .ADDR_WIDTH(16)) pkt // ADDR_WIDTH=16, DATA_WIDTH=16 end
클래스 오브젝트를 생성할 때 #() 안에 값을 넣으면 된다.
값을 넣는 방법은 by position, by name 2가지 가능하다.
'개발 > SystemVerilog' 카테고리의 다른 글
[SystemVerilog] 클래스 3 다형성 (0) 2022.01.24 [SystemVerilog] 클래스 3 상속 (0) 2022.01.24 [SystemVerilog] 데이터 타입 5 string (0) 2022.01.17 [SystemVerilog] 인터페이스 2 (0) 2022.01.16 [SystemVerilog] 인터페이스 1 (0) 2022.01.16