VHDL의 구성
1. VHDL의 구성
VHDL에 의한 설계의 기본적인 구성은 PACKAGE, ENTITY, ARCHITECTURE, CONFIGURATION 이다. 그림 1은 VHDL의 기본적인 구성을 나타내었다.
그림 1. VHDL에 의한 설계의 구조
package 는 VHDL 설계에서 반드시 필요한 사항이 아닌 선택적으로 사용하는 것이다. entity는 설계의 입출력을 기술한다. 그리고 architecture는 설계의 실제 내용을 담고 있다. 한 설계에는 다수의 package와 entity, architecture 가 있을 수 있으나 설계와 합성을 위해서는 한개의 entity에 한개의 architecture가 짝을 이루는 것으로 하였다. 만일 다수의 architecture를 갖는 entity가 있을 경우 configuration에 의하여 그 연결관계(entity-architecture mapping)를 설정해 주어야 한다. 실제로 configuration의 사용은 VHDL의 합성후 post-simupation 혹은 gate-simulation과정에서 많이 이용된다.
architecture에는 병렬 구문 (concurrent statement)을 갖는다. 병렬구문은 다른 PLD 언어 혹은 네트리스트와 같은 의미로서 디자인 내에서 구문이 놓인 위치는 시뮬레이션의 실행시, 혹은 회로의 합성시 의미가 없다(프로그래밍 언어에서는 구문이 놓인 순서대로 실행된다.). signal들에 의하여 각 구문에 값이 전달되며 signal로 값의 할당(assignment, <= )은 구동(driver)을 의미한다(프로그래밍 언어에서는 저장을 의미한다.). 하드웨어를 기술하는 언어임에도 불구하고 VHDL은 무엇 보다도 순차구문(sequential statement)이 있다는것이 가장 돋보이는 점이다. 순차 구문은 process 블럭 내, 혹은 function, procedure 내에서만 기술될수 있다. (보통 PLD언어나 네트리스트는 병렬구문만 있으며, 프로그래밍 언어는 모두 순차구문이다.)
순차구문(sequential statement)은 프로그래밍 언어의 문장들과 같다. 이런 순차 구문들은 프로그램 내에서 놓여진 순서에 의거하여 실행된다. 순차구문내의 모든 값들은 변수(variable)와 상수(constant)에 의하여 유지된다. process블럭 내의 값을 병렬 구문으로 전달 할때에는 signal을 통하여 이루어 진다.
VHDL의 병렬구문과 순차구문의 차이를 이해하는 것은 매우 중요하다. 또한 이들 두가지 구문에서 값들의 전달 방법을 이해하여야 한다. 병렬구문에서 값의 전달은 signal에 의하며 순차구문 내에서는 variable을 이용한다. 메모리(memory)나 플립-플롭(flip-flop)같은 순차논리회로(sequential logic)에 대하여 다시 자세히 논의하기로 한다. VHDL에서 순차구문(sequential statement)은 문장의 놓여진 순서에 의미를 두는 형태의 기술방법을 뜻할 뿐이며 실제로 순차논리회로(sequential logic)를 구성한다고 볼수는 없다. 순차구문(sequential statement)은 기술하는 방법에 따라 조합회로 혹은 순차논리회로를 만들수 있다. (모든 순차구문이 바로 순차회로를 의미하는 것이 아니다! VHDL에서 순차구문과 순차 논리회로와는 의미하는 바가 다르다!)
2. ENTITY
시스템을 구성하는 부분품으로서 이들 사이의 상호 연결을 위한 통로 역활(interface)을 하는 것이 ENTITY이다. 말하자면 내부 설게에 대한 입출력 등을 기술하는 “포장”인 셈이다. 시스템의 입장에서 보면 내부 설계에 대한것은 가려져 있고 다만 ENTITY에 기술된 입출력 포트만을 보게되는데 이런 의미에서 ENTITY를 “암흑상자”(Black Box)라고 하기도 한다. ENTITY 선언의 예는 다음과 같다.
ENTITY counter IS PORT ( clk, reset : IN std_logic; datain : IN std_logic_vector(3 DOWNTO 0); buff : BUFFER std_logic_vector(3 DOWNTO 0); output : OUT std_logic_vector(3 DOWNTO 0); inpouput : INOUT std_logic_vector(3 DOWNTO 0) ); END counter; |
이 설계의 이름은 "counter" 이고, 입출력들은 PORT(....)에 나열한 것과 같다. 입출력의 이름과 모드, 그리고 타입을 지정 되어야 한다. 입출력 모드에는 IN, OUT, INOUT, BUFFER가 있다.
IN 은 입력 포트로서 signal assign의 소스(source)측 ( Signal일경우 '<=', Variable일경우 ':=' 의 오른쪽, R-Value )에만 쓸수 있다. OUT은 출력 포트로서 signal asign의 목적지(destination) ('<=' 또는 ':='의 왼쪽, L-Value)에만 쓸수 있다. INOUT은 입출력 포트로 사용 되므로 소스(source) 또는 목적지(destination)에 모두 쓸수 있다. 그러나 한개의 문장에 모두 쓸수 없다. 입출력 모드가 정해진 경우 할당문(assign statement)에서의 엄격한 규정은 하드웨어를 다루기 때문이다. 하드웨어를 기술할때 assign 이란 연결관계를 표현한것(netlist)으로서 프로그래밍 언어에서와 같은 오퍼레이션(move operation)이 아니다. BUFFER는 INOUT과 같은 입출력 포트로서 assign의 소스(source)측 또는 목적지(destination)측에 쓸수 있다. INOUT 모드와 다른점은 단일 할당문 내에서 소스와 목적지측 모두 동시에 사용할수 있다는 것이다. 이는 BUFFER 모드에 이미 F/F을 내포하고 있다는 의미를 갖는다.
다음과 같은 비동기 리셋을 갖는 카운터의 예를 통해서 포트 모드의 사용방법에 대하셔 살펴보기로 하자. 그림 2는 입출력 포트의 모드에 따른 합성의 결과이다. 모두 양방향성 모드이지만 BUFFER 모드인 경우 재귀적인(recursive) 형태의 네트리스트가 형성된 것을 볼 수 있다.
LIBRARY ieee; ENTITY count IS clk, reset : IN std_logic; ); ARCHITECTURE behave OF count IS PROCESS ( clk,reset ) IF reset='0' THEN buff <= "0000"; ELSIF clk = '1' AND clk'EVENT THEN buff <= buff + "0001"; END IF; END PROCESS; END behave; |
그림 2. 입출력 모드에 따른 합성결과
3. 입출력 포트의 타입과 VHDL의 객체형(Object Types)
입출력 포트의 타입을 지정한다. 디지탈 신호가 '1' 과 '0' 만으로 회로를 다룰 것인지 아니면 하이 임피던스(Z)도있고 풀업(H), 풀다운(L), 그리고 합성과 시뮬레이션의 상태를 나타내기 위해서 Don’t care(-), Unknown(U), 버스 충돌등에 의한 에러상태(X) 등도 구분할 것인지 결정해야 한다. 전자의 경우 bit 타입이라고 하고 후자의 경우 std_logic 이라고 하기로 규정했다. VHDL 언어 자체적으로는 std_logic에 대한 규정은 없다. 다만 IEEE 1076을 정할때 std_logic_1164 라는 것을 정해 놓고 이곳에 bit라는 것은 1 과 0으로 규정한다거나 std_logic은 1,0,Z,H,L,X 등등으로 규정한다고 정했다.
- VHDL의 객체형 (Object Types)
VHDL의 객체 형(Object Types)에 대해서 살펴 보기로 하자. VHDL도 다른 언어와 같이 다음과 같은 자료 형(data types)을 가지고 있다.
boolean (논리형)
character (문자형)
integer (정수형)
real (실수형)
string (문자열)
이외에 디지탈 하드웨어를 다루는 언어로서 VHDL은 다음과 같은 자료 형(data type)을 가진다.
bit
bit_vector
bit 형은 디지탈 신호 ‘1’ 또는 ‘0’ 값을 갖는다. bit_vector는 bit의 1차원 배열형이다. 즉, N-bit 버스를 기술하는 것이다. 대부분의 경우 디지탈 데이타 타입은 bit 혹은 bit_vector 대신, IEEE 1164-standard-logic에서 정해놓은 객체 형을 사용한다.
std_logic
std_logic_vector
이들은 IEEE 라이브러리의 std_logic_1164 패키지에 선언되어 있다. 이러한 외부에서 작성된 라이브러리들을 사용하려면, library 와 use 문으로 라이브러리를 지정하고 사용한다.
library ieee; |
Boolean, character, integer, real, string, bit, bit_vector 와 같은 미리정의된 VHDL의 데이타 형은 standard 패키지(package)에 선언되어 있다.
variable, signal, constant등으로 선언된 객체들은 선언된 타입에 따라 사용할수 있는 연산자들이 정해진다. (즉, 객체들에 의하여 연산자가 결정되는 것인데, 흔히 객체 지향적이라는 의미이다. 나중에 언급 되겠지만 VHDL은 객체에 따라 연산자의 오버로딩도 가능하다.) 또한 디지탈 하드웨어 디자인에서 객체의 선언은 사용될 하드웨어의 비트 폭도 함께 포함된다. (소프트웨어적인 프로그래밍 언어에서는 선언하는 객체의 형에 따라 일정한 비트폭이 정해져 있음을 기억해보라!)
VHDL은 컴파일 하는동안 자료 형에대한 형-검사(type-checking)가 매우 엄격하게 이루어 진다. 심지어 bit 와 std_logic 사이에서도 전혀 호환이 이루어지지 않는데 그 이유에 대해서는 std_logic_1164 패키지를 설명할때 자세히 살펴 보도록 한다. 그리고, 서브 프로그램의 오버로딩(over-loading)을 결정한다. 설계자는 사용할 타입 정의(type define)를 할수 있다. 사용자 정의 형선언은 scalar, array, record 등을 이용할수 있다. VHDL은 파생 형(subtype)도 지원한다. 이와 같이 VHDL은 객체의 선언과 사용데 대해서 많은 융통성을 부여한 객체 지향적인 언어라 하겠다.
이번엔 몇비트 짜리인지 기술한다. 버스일 경우 bit 혹은 std_logic 뒤에 _vector라고 덧붇인다.
- 1 비트 짜리 : bit, std_logic
- 여러비트 짜리 : bit_vector, std_logic_vector
그리고 여러비트 짜리인경우 왼쪽부터 MSB일때 'downto', LSB 가먼저 일때 'to' 라고 표현한다.
- MSB 우선 : std_logic_vector( 3 DOWNTO 0 )
- LSB 우선 : std_logic_vector( 0 TO 3 )
정수형(integer)의 경우 기본적으로 16 혹은 32비트의 폭을 갖는다. 또한 실수형(real)의 경우 합성 가능한 연산이 지원 돼지 않으나 정수형의 경우 산술 연산자의 이용과 이에 따른 합성이 지원되고 있다. 합성 가능한 산술연산에 대해서는 나중에 다루어 보기로 하고 간단한 예를 보면 다음과 같다. 정수형의 경우에도 사용하려는 수의 범위를 성정할수 있는데, 아래의 예는 정수형의 범위를 -128~127 로 정해서 선언한 경우 이다. 합성 결과는 그림 3과 같다. 합성기는 수의 범위에 맞게 비트폭으로 합성해 낸다.
LIBRARY ieee; ENTITY integer_test IS a : IN integer range -128 to 127; END integer_test; ARCHITECTURE behave OF integer_test IS mul_ab <= a * b; END behave; |
그림 3. 정수형(integer)연산의 합성결과
4. Architecture
ENTITY로 설계의 겉모양이 준비 되었으면 이제 설계내용을 ARCHITECTURE 에 기술 한다. 이제 본격적으로 설계가 시작되는 것이다. C와 같은 프로그래밍 언어에서 독립 모듈로서 함수는 함수의 이름과 파라메터 리스트 그리고 함수의 몸통부분이 일체형으로 이루어진 것과는 다르게 VHDL에서 ENTITY와 ARCHITECTURE는 각각 독립적인 구성요소라는 점은 생각해 볼 필요가 있다.
VHDL에서 ARCHITECTURE는 독립적인 요소로서 이름을 갖게되며 몸통부분은 BEGIN ~ END 로 이루어 진다. 예를들면,
ARCHITECTURE behave OF count IS BEGIN ............... END behave; |
"ARCHITECTURE behave OF counter IS"는 "counter"라는 이름의 ENTITY용으로 만들어진 "behave"라는 이름을 갖는 ARCHITECTURE 설계라는 뜻이다. 그러면 ARCHITECTURE 마다 이름이 붇는다는 것인데, 이는 다른말로 하면 하나의 ENTITY에 여러개의 몸통이 존재할수도 있다는 것이다. 그러나 여러개의 ARCHITECTURE가 존재 하더라도 각각의 설계는 "1개의 ENTITY 와 1개의 ARCHITECTURE가 짝을 이루어 구성" 되어져야 한다.
예를들어 RS Flip-Flop을 하나 만든다고 하자. RS F/F의 이름을 "rs_ff" 라고 하고 ENTITY를 다음과 같이 기술하였다.
ENTITY rs_ff IS r : IN std_logic; END rs_ff; |
그리고 "rs_ff"의 몸통을 "behave"라는 이름으로 ARCHITECTURE를 다음과 같이 기술 한다.
ARCHITECTURE behave OF rs_ff IS q <= q_s; END behave; |
그림 4. 기능적인 수준의 RS_FF의 기술 및 합성결과
이번에는 미리 구성되어 있는 gate의 라이브러리에서 AND와 NOT 를 불러다가(instanciation) 구조적으로 기술한 경우를 살펴 보기로 하자.
그래서 이번에는 이들 두개의 라이브러리를 참조하여 적당한 AND 와 NOT를 골라 이를 이용하여 "rs_ff"를 설계하도록 하였읍니다.
ARCHITECTURE struct OF rs_ff IS COMPONENT and00 i0 : IN std_logic; END COMPONENT; COMPONENT inv01 i : IN std_logic; END COMPONENT; SIGNAL q_s, qb_s : std_logic; BEGIN q <= q_s; u1 : and00 u2 : and00 u3 : inv01 u4 : inv01 END struct; |
그림 5. 구조적 형태로 기술한 RS_FF와 합성 결과
"struct"라는 이름의 ARCHITECTURE에는 두개의 실제 부품(COMPONENT)이 사용되었다. 이들 두가지 부품을 이용하여 구조적인 형태로 기술한 ARCHITECTURE가 “struct”이다. 이렇게 하여 "rs_ff"에는 기능을 기술한 "behave" 와 부품을 사용한 "struct"라는 이름의 두개의 ARCHITECTURE가 만들어 졌다.
5. Configuration
앞에서 미리 살펴 보았듯이 한개의 ENTITY에는 다수의 ARCHITECTURE가 존재할 수 있다. 이런 상황에서 시뮬레이션이나 합성을 수행할 때 한 ENTITY에 ARCHITECTURE를 결합시켜 주어야 하는데 이때 사용하는 것이 CONFIGURATION이다.
CONFIGURATION conf1 OF rs_ff IS END FOR; END conf1; |
위의 예는 CONFIGURATION 이름이 "conf1" 이고 이는 "rs_ff"라는 ENTITY에 구성할 ARCHITECTURE를 "behave"로 한다는 것을 나타낸 것이다.
CONFIGURATION conf2 OF rs_ff IS FOR struct FOR u1, u2 : and00 USE ENTITY work.and00(behave); END FOR; FOR u3, u4 : inv01 USE ENTITY work.inv01(behave); END FOR; END FOR END conf2; |
위의 예는 CONFIGURATION 이름이 "conf2"이고 이는 "rs_ff"라는 ENTITY에 구성할 ARCHITECTURE를 "struct"로 한다는 것을 나타낸다. "struct"라는 ARCHITECTURE에는 다시 사용된 부품들이 있는데 그이름이 u1, u2, u3 ,u4이고 이들 모델링되어 라이브러리로 존재하는 곳을 지정 하고 있다.
6. WORK 라이브러리
VHDL 에서 "."는 디자인 라이브러리의 계층구조를 표현 한다. VHDL에서는 사용할 라이브러리는 LIBRARY 키워드를 이용하여 지정해 주는데 다음과 같다.
LIBRARY ieee;
실제로 이 라이브러리가 존재하는 디렉토리는 시뮬레이션 또는 합성툴의 환경 변수로 지정되어 있게 된다. Compass Tool의 경우 Manager 윈도우를 띄우면 라이브러리 패스 (library path)를 지정하는 것을 볼수 있을 것이다. MaxPlus 에도 User Library를 지정하는 메뉴가 있고 V-System/VHDL 에도 역시 라이브러리 패스를 지정하는 메뉴가 있읍니다. 대개 라이브러리 이름과 디렉토리 패스를 연결 시키도록 되어 있는데, 라이브러리 명(library name)과 패스(directory path)를 매핑(mapping) 시킨다고 한다.
USE ieee.std_logic_1164.ALL;
이는 ieee라는 라이브러리에서 std_logic_1164 라는 이름의 패키지(package)를 가져다가 그안에 있는 함수(function)들을 모두 사용한다는 뜻으로 ALL 이라고 한 것이다. ALL은 VHDL 의 키워드 이다. 물론 ALL 대신 패키지 내에서 사용할 함수를 지정할 수도 있다.
USE ENTITY work.and00(behave);
위의 경우는 CONFIGURATION에서 라이브러리 및 ENTITY, ARCHITECTURE를 지정한 것 이다. "work" 라는 라이브러리에 "and00" 이라는 ENTITY 와 "behave"라는ARCHITECTURE를 지정해 준 것이다. VHDL을 보면 "work" 라는 library 명이 많이 등장하는데 이는 현재 작업중인 설계의 기본(default) 작업 라이브러리(working library)로 정해진 이름이다. 툴에따라 현재 작업중인 설계의 라이브러리 이름 “work”를 꼭 지정해 주어야 하기도 하지만 대개 지정하지 않으면 자동으로 "work" 라고 인식한다. 작업 라이브러리의 지정 은 다음과 같다.
LIBRARY work;
USE work.ALL;
작업 라이브러리에 패키지가 없으므로 패키지명은 생략한다.
7. VHDL 기술의 추상화 수준
VHDL은 크게 structural, data flow, behavioral 등 3가지 수준의 추상화(abstraction) 및 이들의 혼합한 기술도 가능하다. (추상화란 어떤 구체적인 내용을 약속된 의미로 나타내는 행위를 말한다. 한 예로 대수 계산의 덧셈을 “+”라는 기호로 나타내는 것도 추상화 이다. 프로그래밍 언어에서 추상화란 함수를 들수 있다. 서브 프로그램내의 일련의 계산 절차 과정을 함수 이름으로 대표하여 나타내는 행위등이다.)
다음은 간단한 예로서 VHDL로 하드웨어 뿐만 아니라 다양한 이용이 가능함을 보여준다. 이 예제 ‘Hello World’는 이어서 설명할 세가지 추상화의 예제로도 사용될 것이다.
entity hello is port (clock, reset : in boolean; char : out character) ; end hello; architecture behavioral of hello is constant char_sequence : string := "hello world"; signal step : integer range 1 to char_sequence'high := 1; begin -- Counter if reset then step <= 1; elsif clock and clock'event then if step = char_sequence'high then step <= 1; else step <= step + 1; end if; end if; end process ;
-- Output Decoder end behavioral ; |
이 예에서는 두개의 입력 신호를 받아서 문자열을 출력한다. clock 신호의 rising-edge에서 1개의 문자가 출력된다. reset은 비동기적으로 걸리며 문자열 출력 순서를 초기화 한다. 다음 그림은 예제 ‘Hello World’의 시뮬레이션 결과이다.
그림 6. ‘Hello World’ 시뮬레이션 결과
7-1. Structural VHDL
Structural VHDL은 병렬구문(concurrent statement)에 부품(component)을 불러낸후(instantiation) 이들의 연결(netlist)을 표현한 것이다. 말하자면 Structural VHDL은 네트리스트(netlist)수준의 기술이라 하겠다. 대부분 도면에 의한 회로 설계(schematic capture) 툴에서 쉽게 회로를 구문으로 추출(extract)해내는 방법이다. 또한 부품의 상호연결구조를 계층적(hierachy)으로 나타내는 것으로 하위 부품의 기능에 대한 기술이 data flow, behavioral 수준으로 가능하다. 이와 같이 하위 부품을 이용한 계층적 설계는 자원 재사용 기법(reusablity)과 설계 통합(integrating design) 과정에서 유용하다.
다음은 ‘Hello World’ 예제를 두개의 부품(component)으로 나누어 작성한 것이다. 각각 작성된 두 부품은 상위 설계에서 불려진후 상호 연결 형태로 기술된다. 두개의 부품 counter 와 decoder은 각각 entity/architecture로 기술되어야 한다.
entity hello is port( clock, reset : in boolean; char : out character ) ; end hello; architecture structural of hello is constant char_sequence : string := "hello world"; subtype short is integer range 1 to char_sequence'high; signal step : short; component counter port ( clock , reset : in boolean; num : out short ) ; end component; component decoder port ( num : in short ; res : out character) ; end component; begin U0 : counter port map (clock,reset,step); U1 : decoder port map (step,char); end structural; |
이와 같이 부품(components)으로 나누어 기술하는 방법의 또다른 잇점은 단일 소자(Programmable device)에 프로그램해 넣을 수 없을 정도의 큰 설계의 경우 다수의 소자에 나눌때 유용하다. 각각의 소자에 두 부분을 나누어 프로그램해 넣을 수 있다. 이때 각소자에 들어갈 내용은 독립된 entity/architecture로 기술되어야 한다. 큰 설계를 합성해서 단일 소자에 프로그램해 넣을수 없을경우 다수의 소자로 나누어 합성하는 자동 분할(fitting & partition)기능이 있는 툴도 있다. 그러나 이와 같은 자동 분할 기능(auto-partition)이 않되는 툴이 더많다. 또한 가능하면 툴에 의한 자동 분할하는 것은 신뢰도가 떨어지는 것으로 보이며, 합성후 post-simulation이 매우 복잡해진다.
7-2. Data Flow VHDL
병렬구문에 의한 신호 할당(concurrent signal assignment, <=)문으로 기술된 경우이다. 이러한 경우를 RTL (register-transfer-level) 기술이라고 말하기도 한다. ‘Hello World’의 예제를 data flow VHDL로 기술하면 다음과 같다.
entity hello is port ( clock , reset: in boolean; char : out character ) ; end hello; architecture data_flow of hello is constant char_sequence : string := "hello world"; begin -- Output decoder -- Counter logic -- Counter flip flops step1 when clock and clock'event; end data_flow; |
dataflow VHDL에서 조합논리회로(combinational logic)는 신호 할당(signal assignment, <=)구문으로 간단하게 기술될 수 있다. 그러나 counter는 순차논리회로(sequential logic)이며 신호할당(signal assignment) 구문에서 조합논리회로를 특별히 따로 다루지 않는다. 따라서 when~else~ 에서 else가 없는 미결된 when 문장은 순차논리회로로 간주한다 (infered as sequential logic). 위의 예에서, step1 이 else 가 없는 when 구문으로 기술된 것을 볼 수 있다. 앞서 언급했지만 VHDL의 병렬구문(concurrent statement)과 순차구문(sequential statement)이 논리회로의 조합회로와 순차회로를 직접 의미하는 것은 아니다. 다만 코딩 스타일에 따라 VHDL 순차 구문으로도 조합논리 회로가 될수 있고 혹은 플립플롭(Flip-Flop)과 같은 순차논리회로를 기술해 낼수 있다.
7-3. Behavioral VHDL
PROCESS 구문은 VHDL의 가장 강력한 병렬구문의 하나이다. PROCESS는 순차구문들로 구성된 블럭 으로서 PROCESS 블럭 자체를 1개의 병렬구문으로 간주한다. 따라서 PROCESS 구문에 의한 VHDL의 기술은 behavioral 수준의 추상화 기법이다. 예를 들면,
process (insig) variable var1: integer; -- variable declaration begin var1:= insig; -- variable assignment var1:= function_name(var1 + 1); -- function call end process; |
하드웨어 설계에 있어서 process 구문을 사용하는 방법은 조합논리회로를 기술하는 방법과 순차논리회로를 기술하는 방법등 두가지가 있다. Process 구문으로 조합회로를 기술하는 일반적인 형태는 다음과 같다.
process (signal_name, signal_name, signal_name,......) begin ..... end process; |
순차논리회로를 기술하는 방법은 다음과 같다.
process (clock_signal) begin if (clock_signal and clock_signal'event) then .... end if; end process; |
조합논리회로(combinational logic)인경우 할당문(assignment statement)의 오른쪽(R-value)에 쓰는 입력 signal 들은 process의 감응 리스트(sensitive list)에 모두 나열되어야 한다. 그러나 순차논리회로(sequential logic)를 구성하고자 할경우 wait문을 이용한다면 감응리스트를 나열하지 않는반면 if 문장으로 클럭 신호를 쓸경우 감응리스트에 클럭신호를 반드시 나열해야한다. VHDL에서 동시에 감응리스트와 wait구문을 사용할수는 없다. (process 에 감응 리스트를 쓰는 이유는 process 블럭은 감응리스트에 나열된 신호선들의 변화(event)에 의하여 한개의 병렬구문(concurrent statement)으로서 동작한다(evaluate). 따라서 할당문 오른쪽 signal 들은 모두 감응 리스트에 써줌으로서 이들 signal의 변화에 의한 할당 동작을 분명히 할수 있다. 감응리스트를 제대로 나열하지 않는 것은 VHDL 구문의 에러가 아니다. 만일 이를 제대로 하지 않을경우 시뮬레이션 결과를 예측할수 없는경우도 발생한다. 그러나 대부분 합성기는 감응 리스트의 signal을 검사한다. 이경우 VHDL 동작 시뮬레이션과 합성후 논리 게이트 시뮬레이션의 결과를 보장할수 없게된다. VHDL은 event-drive 한다!)
(VHDL의 언어로서 기술하는 구문의 종류로 병렬구문과 순차구문이 있고, 디지탈 하드웨어의 논리회로를 구분 하는 것으로서 조합회로와 순차회로가 있다. 병렬구문 만으로도 조합회로와 순차회로의 기술이 가능하며 process 구문 내의 순차구문으로도 조합회로와 순차회로의 기술이 가능하다는 점을 기억해야 한다. VHDL의 구문을 사용하여 디지탈 회로를 기술할때 기술된 형태에 따라 조합 혹은 순차 논리회로가 된다.)
두개의 process 구문을 써서 ‘Hello World’ 예제를 기술하면 다음과 같다.
entity hello is port ( clock, reset : in boolean; char : out character) ; end hello; architecture behavioral of hello is constant char_sequence : string := "hello world"; signal step : integer range 1 to char_sequence'high := 1; begin counter : process (reset, clock) begin if reset then step <= 1; elsif clock and clockevent then if step = char_sequence'high then step <= 1; else step <= step + 1; end if; end if; end process ; decoder :process (step) begin char <= char_sequence(step); end process ; end behavioral ; |
8. 시뮬레이션이 되었다고 해서...
이번에는 VHDL 시뮬레이터를 이용해서 원하는 결과가 얻어졌다고해서 안심할일이 아니라는 점을 말하고자 한다. 설계가 하드웨어로 이루어지기 까진 아직 합성(synthesis)이 남았다. 아직 VHDL이라는 언어로 부터 회로를 얻어내기 위한 합성기들은 아직 모든 VHDL 모델을 지원하지 못한다. 특히 고수준의 VHDL 모델, 테스트를 위한 입/출력 파형, 시스템 기술등은 합성 불가능 하다. (after 문에 의한 지연(delay)모델 등을 어떻게 합성해낼수 있을까?)
합성은 적절한 논리회로의 기술이 이루어졌을때 가능하며 모든 설계가 합성가능하지 않다. VHDL 설계자들은 이러한 합성기의 제약사항(constraints)을 반드시 숙지하고 있어야 한다.
아무리 이론적으로 완벽하고 잘 표현 되었더라도 실제로 구현되기 어려운 것들이 많은 법이다. VHDL이 비록 하드웨어를 기술하기 위한 것이라지만 곧바로 하드웨어를 의미하는것은 아니다.
다음에는 VHDL구문을 살펴보고 합성가능한 코딩 스타일과 실제로 합성기 툴에서 얻어진 결과를 비교해 보기로 하겠다.
mailto:goodkook@csvlsi.kyunghee.ac.kr
CSA & VLSI Design Lab. Kyunghee Univ