[SystemVerilog] 데이터 타입 3 enum
구조체, 열거형 데이터와 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을 뺀 만큼 반대방향으로 값을 찾는다.