VHDL의 자료형(data types)
VHDL의 자료형은 스칼라 형 (scalar type)과 복합 형(composite type)으로 나뉘어 진다. VHDL에서 사용하는 자료형은 그림 1에서 나타내었다.
VHDL에서 자료형 검사는 매우 엄격하며 정의된 자료형에 따라 사용할 수 있는 연산자 또한 각각 정의 되어야 한다. 합성기(synthesizer)에 따라 서로 지원하는 데이터형이 다를 경우 VHDL 소스 사이의 호환성에 심각한 문제를 일으키며 많은 자료형 변환 함수와 타입 캐스팅 방법이 존재하게 된다. 이러한 문제를 해결하기 위하여 87년 IEEE 1076 VHDL의 표준에 이어 1991년에 IEEE 1164로서 디지털 회로의 합성 가능한 자료형에 대한 표준이 제정되기에 이르렀다. IEEE 1164는 디지털 회로에 대하여 9 가지 값(standard 9-valued logic)을 갖는 데이터 형 “std_logic”을 정의하였고 이는 IEEE 1076 의 “bit” 형을 확장한 것이다. IEEE 1076에는 VHDL의 언어에 대한 표준과 아울러 데이터 타입 및 각종 연산에 대한 표준이 정해져 있다. IEEE 1076에는 디지털 회로의 비트(bit) 형과 정수 및 실수형 문자형 등이 있으며 이중 bit와 정수형이 합성 가능하다. IEEE 1164의 “std_logic”은 bit의 ‘1’과 ‘0’이외에 Pull-up, Pull-down에 해당하는 ‘H’ (Weak-High), ‘L’ (Weak-Low)와 ‘Z’(high-impedance), ‘U’(uninitialize), ‘X’ (unknown), ‘-‘(Don’t care)등을 정의해 놓음으로써 디지털 회로의 합성뿐만 아니라 시스템 인터페이스에 대한 배려를 해두었다.
1-1. 열거형 (Enumeration type )
기본적으로 VHDL에서 사용하는 대부분의 자료형은 대부분 열거형 (enumeration type) 이다. IEEE 1076의 stanandard package에 정의되어 있는 열거형의 예를 들면 다음과 같다.
type boolean is (false,true);
type bit is ('0', '1');
IEEE 1164에 std_ulogic은 다음과 같이 열거형으로 정의 되어 있다.
TYPE std_ulogic IS ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' );
'U'는 초기화 되지 않은 상태(Uninitialized)를 의미하며 'X'는 Unknown으로서 디지털 값의 충돌등과 같은 에러상태를 나타낸다. '0' 과 '1'은 디지털 값에 해당하며 'Z'은 High Impedance, 'W', ‘L’, ‘H’는 각각 Weak Unknown, Weak 0, Weak 1로서 Pull-up혹은 Pull-down된 디지털 값을 나타낸다. 끝으로 ‘-‘은 합성 시 논리 최적화에 Don't care로서 이용된다.
열거형을 이용하면 사용자는 언재든지 자료형의 정의가 가능하다. 또한 열거형으로 정의된 경우 인 코딩(encoding) 방법을 지정할 수 있다. 인 코딩 방법으로는 2진 코드에 의한 방법(binary)과 One-Hot Encoding이 있다. One-Hot encoding 방법은 유한상태 머신(FSM : Finite State Machine)에서 상태를 나타내는 경우에 많이 이용되는 방법이다. 다음과 같은 예를 살펴보자.
type state is (IDLC, RECEIVE, SEND);
와 같이 정의된 자료형 “state”의 경우 binary와 One-Hot encoding 되었을 때 차이는 그림 2와 같다.
예제에서와 같이 열거형 “state”는 3개의 요소를 가지므로 Binary encoding하면 2비트가 필요한 반면 On-Hot encoding하는 경우 각 요소마다 1개의 비트를 할당하여 3비트로 표현된다.
VHDL에서 형 검사(type checking)가 치밀한 이유 중 하나가 위와 같은 열거형을 주로 다루기 때문이라고 할 수 있다. 각종 연산자 혹은 할당(assignment)의 경우 기본적으로 열거형으로 이루어진 서로 다른 두 타입은 비트 폭에서부터 다르기 때문이다. 다음과 같이 bit 형과 std_logic형의 할당문의 경우 예를 살펴보자.
Type bit is (‘0’, ‘1’);
Type std_logic is ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' );
와 같이 정의된 두개의 시그널,
Signal A : bit;
Signal B : std_logic;
을 사용한 할당문,
A <= B;
은 하드웨어적인 연결의 의미를 고려해 볼 때 할당문은 성립할 수 없는 것이 당연하다.
1-2 정수형 (Integer Type)
IEEE 1076에 정의된 정수형의 기본적인 비트 폭(bit-width)은 32비트로 되어 있다.
type integer is range -2147483648 to 2147483647;
정수형은 산술연산이 가능하며 2의 보수형태로 이루어진다. 또한 정수형은 합성이 가능하며 범위를 지정하지 않을 경우 32비트가 된다. 따라서 과도한 비트 폭을 갖는 연산기의 합성을 피하려면 정수의 범위를 지정해서 사용하도록 한다. 다음의 예는 4비트 시그널을 선언한 예이다.
Signal count : integer range 0 to 15;
디지털 회로로 합성 되었을 때 정수형의 비트맵 형태는 그림 3과 같다.
1-3 실수형 (Real, Floating-Point Type)
실수형(real type)은 합성가능하지 않다. 시스템 모델링 이나 아날로그 회로의 모델링 등에 사용될 수 있다. IEEE 1076의 실수형의 정의는 다음과 같다.
type real is range -1.0E308 to 1.0E308;
다음은 실수형으로 아날로그 회로의 한예로서 A/D 변환기를 기술한 예이다.
function ADC_8b_10v_bipolar ( analog_in : in real ) return byte is if (analog_in < 0.0) then digitized_signal := 0; else digitized_signal := integer(analog_in * ( real(max_digital_value) / max_analog_value) ); if (digitized_signal > (max_digital_value - 1)) then digitized_signal := max_digital_value - 1; end if; end if; digital_out := byte(to_std_logic_vector(digitized_signal,8)); return digital_out; end |
아날로그 입력 값을 실수형으로 입력 받은후 디지털 변환을 수행한다.
digitized_signal := integer(analog_in * ( real(max_digital_value) / max_analog_value) );
이때 계산된 값은 정수형 데이터이며 이를 디지털 시스템으로 인터페이스 하기 위하여 정수형을 “std_logic”형으로 변환하기위한 함수를 이용한다. 정수로부터 “std_logic_vector”로 형 변환 (type conversion)을 수행하기 위한 함수 “to_std_logic_vector”는 다음과 같다.
function to_std_logic_vector ( a : integer; width : integer ) return std_logic_vector is y := a; if (a >= 0) then y_ref := a_threshold; for i in y_length-1 downto 0 loop if (y < y_ref) then y_std_logic_vector(i) := '0'; else y := y - y_ref; y_std_logic_vector(i) := '1'; end if; y_ref := y_ref / 2; end loop; else for i in y_length-1 downto 0 loop y_std_logic_vector(i) := '0'; end loop; end if; return y_std_logic_vector; end to_std_logic_vector; |
A/D변환 값을 반환하기 위하여 “byte” 형을 std_logic 형으로부터 정의하여 사용하였다.
type byte is array (7 downto 0) of std_logic;
1-4. Physical Type
물리량의 단위(unit)와 배수 관계를 정의한 것이며 합성 가능하지 않다. IEEE 1076에는 시간에 대한 정의가 있는데 다음과 같다.
type time is range -2147483647 to 2147483647 fs; end units; |
위에서 볼 수 있듯이 VHDL의 최소시간 단위는 fs (femto second, 10E-15) 이다.
1-5 배열형 (Array Type)
VHDL에서 배열형을 사용할 수 있다. 일 차원 배열형의 경우 대부분 합성기에서 지원 하지만 2차원 배열을 지원하지 않는 합성기도 많다. 디지털 회로의 기본 데이터 단위는 “bit” 이다. 이를 버스형태로 정의하기 위해서 “bit_vector”형을 사용한다. 즉 버스를 정의하는 것은 “bit”의 일 차원 배열이다. 배열형을 정의 할 때 그 크기를 지정하는 경우가 있고 임의의 배열 크기를 지정할 수도 있다.
type byte is array ( 7 downto 0) of bit;
일 차원 배열로 8-비트 크기의 데이터 타입 “byte” 을 정의한 것이다.
TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_logic;
"std_logic" 형으로 일 차원 배열형 “std_logic_vector”를 선언한 것이다. 이때 배열의 크기를 제한 시키지 않은 것으로서 시그널을 선언할 때 그 크기를 정하여 사용할 수 있다. 배열형의 선언한 예는 다음과 같다.
Signal byte_a : byte;
Signal count : std_logic_vector( 7 downto 0);
1-6 레코드 형(Record Type)
VHDL에서는 레코드형을 지원한다. 디지털 회로에서의 레코드형 사용 예는 기계어 명령의 비트맵 표현 등에 이용될 수 있다. 다음은 레코드 형의 사용 예이다.
type month_name is (jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dev); type date is day : integer range 1 to 31; end record; constant my_birthday : date := (21, nov, 1963); SIGNAL my_birthday : date;
my_birthday.year <= 1963; |
VHDL에서의 파생형(subtype)을 정의할 수 있으며 다음의 예는 정수로부터 일정한 크기를 갖는 파생 정수형을 정의한 예이다.
type big_integer is range 0 to 1023;
subtype small_integer is big_integer range 0 to 7;
“small_integer”는 “big_integer”의 파생형으로 정의되었다. 이 경우 파생형 “small_integer”의 의미는 10-비트 크기의 “big_integer”의 하위 4-비트를 차지하도록 정렬된다는 의미로서 두 데이터 형의 호환됨을 나타낸다. 다음의 예는 VHDL에서 자료형 검사(type checking)의 엄격함을 보여준다.
type big_integer is range 0 to 1000;
type small_integer is range 0 to 7;
signal intermediate : small_integer;
signal final : big_integer;
final <= intermediate * 5; -- type mismatch error
위의 예에서 “big_integer”와 “small_integer” 형은 비록 서로 정수형 이긴 하지만 서로 호환 돼지 않는다. 이러한 경우 “small_integer”를 파생형으로 정의 함으로서 형 불일치(type mismatch) 에러를 해결할 수 있다.
type big_integer is range 0 to 1000;
subtype small_integer is big_integer range 0 to 7;
signal intermediate : small_integer;
signal final : big_integer;
final <= intermediate * 5;
또 다른 방법으로 type casting을 이용할 수 있는데 이 경우는 기본적으로 두 형의 기본형이 같아야 한다.
type big_integer is range 0 to 1000;
type small_integer is big_integer range 0 to 7;
signal intermediate : small_integer;
signal final : big_integer;
final <= big_integer(intermediate * 5);
만일 정수형과 “std_logic_vector”형으로 변환하기 위해서는 두 데이터 타이의 기본형이 전혀 다르므로 형 변환 함수(type conversion function)를 사용하여야 한다. 형 변환 함수는 사용자가 임의로 만들어 쓸 수 있으나 IEEE 1164의 산술 패키지(numeric_std, numeric_bit)에는 정수와 “std_logic_vector”, “bit” 사이의 형 변환을 위한 함수를 다수 가지고 있으므로 가급적 이를 이용하도록 권장한다. IEEE 1164 라이브러리의 산술연산과 형 변환 함수는 합성 가능한 산술 연산을 다루면서 자세히 살펴 보기로 한다. 다음의 예는 산술연산과 형 변환 함수의 이용에 대한 것이다.
package my_type is type big_integer is range 0 to 1023; end package; library ieee; entity subtype_test is port ( a : in small_integer; end subtype_test; architecture behave of subtype_test is t_int <= a + b; end; |
위의 예는 정수 입력을 받아서 연산을 수행한 후 이를 10 비트 크기의 “std_logic_vector” 로 출력하는 경우이다. 입력된 2개의 정수형(“small_integer”) a,b를 계산하여 “big_integer”로 할당한다.
t_int <= a + b;
사용자 정의형 “big_integer”인 “t_int”로 부터 std_logic_vector”로 변환하는 과정은 약간 복잡하게 보이지만 이러한 변환과정이 시스템 설계와 서로 다른 모듈사이의 인터페이스 할 때 자주 직면하게 되는 문제이므로 잘 이해해둘 필요가 있다.
c <= std_logic_vector(to_unsigned(natural(t_int), 10));
Numeric_std package에 정수-unsigned 변환 함수가 to_unsigned()로 제공되고 있다. 이 함수의 argument가 natural이므로 사용자 정의형으로부터 정수형(natural)으로 type-casting 한다. Unsigned 형으로 변환할 것이므로 integer가 아닌 natural로 type-casting 한 것이다. 정수형을 std_logic_vector로 직접 변환하는 함수를 가지고 있지 않다. 따라서 to_unsigned() 함수를 사용하여 정수를 10비트 unsigned로 변환 한후 다시 type-casting 하여 “std_logic_vector”인 출력 포트에 연결한 것이다. unsigned는 IEEE 1164의 numeric_std에 다음과 같이 정의 되어 있으므로 type-casting이 가능하다.
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;
이 변환 과정을 보면 알 수 있듯이 같은 기본형으로부터 파생된 자료형은 type-casting 할 수 있지만 기본형이 다른 경우 형 변환 함수를 써야 한다. 그러나 “t_int <= a + b;” 에서와 같이 기본형이 같은 파생형(subtype)의 경우에는 변환을 수행할 필요가 없다. 위의 예를 합성한 결과는 그림 4와 같다. 0~7까지의 범위를 갖는 두개의 “small-integer”형 입력이 4비트로 연산기로 합성된 후 10비트 출력의 하위 4비트로 출력 되는 것을 볼 수 있다.
3. 끝으로..
VHDL의 자료형(data type)과 형 변환에 대하여 살펴보았다. 다음에는 VHDL 의 객체(Objects)와 SIGNAL-VARIABLE의 차이, 합성 가능한 구문들에 대해서 살펴보고 합성 결과를 비교해 보기로 한다.
mailto:goodkook@csvlsi.kyunghee.ac.kr
CSA & VLSI Design Lab. Kyunghee Univ.