개발/SystemVerilog

[SystemVerilog] 데이터 타입 3 enum

개발과 공부 사이 2022. 1. 15. 20:10

구조체, 열거형 데이터와 user type definition 타입에 대해 정리

 

 

이전글에서 데이터타입을 다루었다.

reg, wire, int, logic, bit 등은 primitive 타입이라고 한다.

 

유저가 데이터 타입을 정의할 수 있는데, user defined 타입이라고 한다.

c언어 처럼 typedef 키워드로 정의한다.

 

c언와 똑같이 enum, struct, union 키워드가 있다.

 

typedef bit [7:0] byte_t;

byte_t a, b;

byte_t [0:15] c;

input byte_t d;

function byte_t parity_check();

 

 

enum 타입 선언

enum {RED, GREEN, BLUE} color_e;


// RED = 0, GREEN = 1, BLUE = 2
typedef enum {RED, GREEN, BLUE} color;


// logic type
typedef enum logic [1:0] {RED, GREEN, BLUE} color;

따로 정의하지 않으면 int 타입으로 정의된다

기본적으로 REG, GREEN, BLUE 의 이름들은 0부터 2 까지 차례대로 값이 할당된다.

 

// logic type
typedef enum logic [1:0] {RED, GREEN, BLUE} color;

color state;
state = RED;
state = color'(2)

// violation
state = 2'b10;
state = 1;

enum 타입으로 정의된 변수에 값을 할당할 때 원칙은, enum 안에 정의된 name으로 할당해야한다.

또는 color'(2) 처럼 type casting을 해줘야한다.

변수에 값을 할당하지 않으면 초기값은 base type의 default 값이다.

 

module test();
  
  typedef enum logic [1:0] {RED, GREEN, BLUE} color_t;
  
  color_t color;
  
  initial begin
    color = RED;
    $display("%d, %s", color, color.name);
  
    color = 2'b10;
    $display("%d, %s", color, color.name);
    
    color = 1;
    $display("%d, %s", color, color.name);
    
    color = color - 1;
    $display("%d, %s", color, color.name);
    
    ++color;
    $display("%d, %s", color, color.name);
  end
  
  
endmodule

하지만 시뮬레이션 해보면 해당 문장들은 경고가 뜨고 시뮬레이션은 정상 동작한다.

시뮬레이터에서 알아서 캐스팅 해준다.

 

 

 

 

열거형타입의 열거된 변수들의 값을 각각 지정할 수 있다.

// 0 부터 차례대로 1씩 증가
typedef enum {a, b, c, d, e, f} state;


// 숫자를 마음대로 지정 가능
typedef enum {a=1, b=3, c=5, d=7, e=10, f=14} state;


// a=3 부터 1씩증가, d=9 부터 1씩 증가
// a=3, b=4, c=5, d=9, e=10, f=11
typedef enum {a=3, b, c, d=9, e, f} state;


// c=5, d=5 중복값이 할당되어 에러발생
typedef enum {a=3, b, c, d=5, e, f} state;

 

데이터 타입으로 선언하고 값을 지정할 수 있다.

// one hot encoding
typedef bit[2:0] {idle=3'b000, start=3'b001, pause=3'b010, done=3'b100} state_t;

 

 

범위지정으로 간단하게 name들을 선언할 수 있다.

typedef enum {s[3]} state;
// equivalent
typedef enum {s0, s1, s2} state;


typedef enum {t[2:4]} state;
// equivalent
typedef enum {t2, t3, t4} state;

// 혼용 가능하다
typedef enum {a, b, s[2], t[1:3], k} state;

[ ] 안에 숫자 하나만 쓰면 0 ~ num-1 까지 이름이 생성된다.

[a : b] 형식으로 쓰면 a ~ b 까지 이름이 생성된다.

 

 

method description
first() enum 타입의 첫번째 값 리턴
last() 마지막값 리턴
next(N) 다음 N번째 값 리턴
prev(N) 이전 N번째 값 리턴
num() 값들의 갯수
name() 값의 이름 string 리턴
module test();
  
  typedef enum logic [1:0] {RED, GREEN, BLUE} color_t;
  
  color_t color;
  
  initial begin
    color = GREEN;
    $display("%d, %s", color, color.name);
  
    color = color.next();
    $display("%d, %s", color, color.name);
    
    color = color.prev();
    $display("%d, %s", color, color.name);
    
    color = color.first();
    $display("%d, %s", color, color.name);
    
    $display("%d ", color.num());
  end
  
endmodule

각 메서드 사용 결과이다.

 

만약에 next , prev 메서드에 범위를 넘어가는 수를 넣으면 어떻게 될까.

module test();
  
  typedef enum logic [1:0] {RED, GREEN, BLUE} color_t;
  
  color_t color;
  
  initial begin
    color = GREEN;
    $display("%d, %s", color, color.name);
  
    color = color.next(2);
    $display("%d, %s", color, color.name);
    
    color = color.next(-2);
    $display("%d, %s", color, color.name);
    
  end
  
endmodule

큰 수를 넣으면 enum 타입 안에서 순환한다.

음수를 넣으면 절댓값에서 1을 뺀 만큼 반대방향으로 값을 찾는다.