로그인회원가입장바구니고객센터마이페이지회사소개
kangcom
전체
서평보기
실습으로 배우는 VHDL(증보판)
이강 외 | 도서출판 아진 | 국내서 | 2004-03-05
종합평점
도서수준
그나마 접근하기 쉬운 VHDL 2008-01-05 오후 11:30:10 
평점
도서수준
조회수 (3115)
공감 (0)
임은천 님의 블로그
VHDL 관련 서적을 몇 권을 샀었지만, 아직 읽어 본 적은 없었습니다. 하드웨어 공부를 어디에서 시작할 것인지 여전히 고민거리 이지만, 어차피 초보일 때는 아무리 봐도 이해가 안되기 때문에 어떤 흐름으로 하드웨어가 구현되는 가 아는 것이 제일 중요했습니다.그런 와중에 찾은 것이 VHDL 이었습니다.
이해한 것보다 이해 안되는 부분이 더 많았지만, 이 책을 먼저 본 것은 탁월한 선택이었습니다. 물론 실습으로 배우는에서 보이듯이 실습을 해봐야 머리에 쏙쏙 들어 오기 때문에.. 책을 모두 읽고 나서 실습을 시작했습니다. 이 책은 중간 정도까지는 내용이 쉬운 편입니다.
 
0장 1절에서는 XILINX ISE라는 툴을 사용하는 방법에 대해서 다룹니다. 툴은 툴인데, 처음에 봤을 때는 도대체 이게 뭐하는 것인가? 라는 생각을 더 많이 했습니다. 지금은 대강 어떤 역할을 하는 지는 알 것 같습니다. 이 툴로 하드웨어를 구현한다고 하니, 신기한 생각이 더 많이 들었습니다. 처음에 의욕이 앞서서 23p에 있는 코드를 열심히 쳐봤지만, 아쉽게도 밑의 소스 내용은 보이지 않았습니다. 저는 이 시점에서 코드를 쳐야 하는 건 줄 알고 쳤는데, 이 장은 그냥 흐름만 보는 장입니다. 괜히 쳐봐야 완전한 코드가 없기 때문에 흐름만 보고 그냥 넘어가기 바랍니다.
 
2절에서는 Quartus라는 툴이 나오는데, 이 책의 내용을 보고 나니 XILINX ISE가 훨씬 더 좋은 것 같습니다. 이제야 조금 매칭이 되는데, Synthesis가 Compile 과정과 비슷합니다.
 
3절에서는 이 책이 쓰인 충남 대학교의 Logic Analyzer and Pattern injector(CLAP Logic Analyzer)라는 도구에 대해서 설명해 줍니다. 다만, 저는 이걸 봤을 때, 무엇을 하는 용도인지 도통 감이 잡히지 않더군요.
 
1장부터는 VHDL 기초에 대해서 다룹니다. 이제 부터 본격적으로 코딩의 세계(?)로 들어가나 싶었습니다. 92p를 보면 찾고 헤맸던 하드웨어 설계 흐름이 나옵니다. 98p에서는 코드에서 꽤나 자주 보게 되는 Entity와 Architecture에 대해서 깔끔한 정의를 내려줍니다.
Circuit Module = Entity Declaration + Architecture body
99p에는 바로 예제를 보여 줍니다. 사실 이 시점에서는 잘 설명 되었지만, 단어 자체가 너무 익숙하지 않아서 상당히 헷갈렸습니다.
100p 아래의 하단에 모든 object가 type과 클래스를 가진다는 중요한 내용이 다뤄집니다. 이 단락의 내용은 계속 접하게 됩니다. 타입은 primitive 타입 같은 것이고, class는 일종의 예약어와 같습니다. 하드웨어 wire의 개념과 유사하다는 signal은 여기에서 처음 봤습니다.
101p에는 std_logic 타입이 0과 1 외에도 좀 더 세밀한 모델링을 위해서 9가지의 다른 값을 가지는 것에 대해서 설명합니다. 이 std_logic은 std_ulogic의 subtype 이라고 합니다.
그 뒤에 113p에서 VHDL의 design unit는 눈여겨 보면 좋습니다.
 
123p에서는 갑자기 실습 1이라는 제목으로 뭔가 내용이 나옵니다. 자세히 봤더니 문제더군요. 처음에 아는 것이 없는데 일단 답을 했지만, 정답이 뭔지 궁금해서 책에 있는 주소로 갔더니 없는 주소더군요. 주소가 어떻게 바뀌었는지 책을 읽는 내내 계속 궁금했습니다. 읽어봐도 초보에겐 답이 안나오는 문제가 많습니다. 문제 + 사용법 설명의 구조는 별로 좋은 생각이 아니었다고 생각합니다. 처음에는 사용법을 읽히는 것 위주로 반복 숙달 하게 한 후에 문제를 냈으면 이해도 빠르고 쉬웠을 텐데 왜 먼저 문제가 나온 것인지 다 읽고난 지금도 이상합니다.
 
149p에서는 또 다른 중요한 3가지 기술(description) 개념이 나옵니다. 바로 behavioral, dataflow, structural 입니다. 그냥 딱 봐도 중요한 것 같습니다. 같은 논리라도 3가지 방식으로 다르게 생각할 수 있다는 것입니다.
 
behavioral은 sensitivity list라는 것을 매개 변수와 비슷하게 사용하여 process 문 내의 문장들을 sequential statement로 간주하고 실행되는 것으로 생각합니다. 이것은 소프트웨어에서 잠자다가 깨어나서 이벤트 방식으로 제어 권한을 얻는 것과 비슷합니다. 160p의 wait 구문과 관련이 있고, 서로 연관시켜서 기억을 합니다.
dataflow는 151p에 보이듯이 불린 수식으로 표현합니다. 문서화 관점에서야 꽤 간결하긴 하겠지만, 이해하기엔 좀 머리 아플 것 같습니다.
structural은 계층적 설계의 관점입니다. UML에서 Component Diagram 그리는 것과 비슷합니다.
 
164p에서는 variable, signal 그리고 delta 시간 개념에 대해서 다룹니다. 사실 지금도 delta 시간 개념이라는 것이 잘 이해는 안 되는데, 논리적 최소 시간이라고 합니다. signal에 걸리는 지연 할당을 스케줄링 할 때 쓰이는 논리적 시간인 듯 한데, 정확히 어떤 목적으로 쓰는 것인지는 잘 모르겠습니다. 168p에 보이듯이 signal 할당은 소프트웨어의 할당 개념과는 전혀 다르게 비순차적으로 내용이 실행되는 것을 여실히 보여줍니다.
172에서는 개개의 concurrent signal assignment statement마다 개별적인 driver가 생성된다고 합니다. signal driver가 하는 일은 signal의 값을 할당하는 것이며, signal의 원본의 내용이 변경되면 이런 변경을 수행합니다. 172p 하단에 보이듯이 process() 로 묶이지 않은 부분에서 A에 대해 다른 신호의 값이 할당될 수 있을 경우 값이 충돌되며 이 경우에 resolved type인 경우에만 multiple driver가 허용된다고 합니다. resolved type은 이런 충돌을 해결해 주는 resolution function이 있기 때문입니다. 그 다음 process로 묶인 경우에 concurrent 하게 문장이 동작하게 되므로 차례로 스케줄이 일어나고 앞의 것은 overwrite 되어 delta 논리 시간 후에 A 값에는 C의 signal이 할당 되게 된다고 합니다. 그래서 이런 overwrite가 발생하는 것을 막기 위해서 173p에서는 if 문을 썼습니다.
175p에서부터는 entity 사용, configuration에 대해서 나옵니다. 이미 존재하는 엔티티의 특정 입출력 포트에 매핑하는 내용, 이전에 잠깐 다뤄진 generic overwrite, generate 사용법, 그리고 특정 component에 configuration specification(185p)을 적용하는 방법 등을 다룹니다. 그 뒤로 또 한 동안 연습 문제가 나오지만, 역시 초보자를 위한 내용은 아닌 것 같더군요.
 
247p에서 package = 패키지 선언 + 패키지 몸체라고 설명합니다. 하는 일은 subprogram, type 등을 하나로 모아서 공유해주는 라이브러리 개념입니다. Java로 따지면, 인터페이스와 비슷합니다. 250p에서는 Attributes라는 것이 나옵니다. 마치 멤버 필드 처럼 사용됩니다. 252p에서는 파일 처리에 대해서 다뤄집니다. 그리고 258p에는 코딩 실수를 줄여줄 만한 alias라는 구문이 나오고, 언젠가는 쓰게될 Type Casting과 Type Qualification에 대해서 다뤄집니다. 차이점은 Type Qualification 같은 경우엔 변환이 아니라 해당 타입이 명확히 무엇이다라고 명시하는 것입니다. 사실 이런 게 왜 나온 줄 몰랐는데, 곰곰히 살펴 보니 type에서 downto, to와 같은 것을 쓰거나 "000", "0000" 이렇게 아무렇게나 비트 개수를 써서 표현할 수 있다 보니 정형화된 타입이라기 보다 해당 개수에 대한 alias 처럼 타입이 쓰여서 중복이 일어날 수 있고, 그래서 컴파일러가 인식하기 위해선 그런 방식이 필요한 것이었습니다.
4절에서는 다시 한 번 구문에 대해서 정리를 해줍니다. 이전 절에서 자세히 살펴 본 것을 정리하는 기분으로 읽어보면 됩니다.
 
2장 부터는 슬슬 어려워지기 시작합니다. 최초 조합회로 빌딩 블록 설계라는 제목으로 작은 엔티티(회로)를 코드와 회로 다이어그램과 함께 보여줍니다. 어떻게 변화되는 구나 하는 것을 알 수 있어서 꽤 유익했습니다. 물론 아직 코드 짜라고 하면 짤 자신이 없지만 말입니다.
2절은 순차 회로 빌딩 블록 설계라는 제목을 가집니다. 언젠가 조합회로, 순차회로의 차이점을 배운 기억이 약간 있긴 하지만, 지금은 어떻게 구분하는 지 생각하는 것 보다 어떻게 구현되는 구나에 더 민감하게 보았습니다. 337p 레지스터 파일 부터는 점점 더 어려워 집니다.
338p의 내용은 매우 중요합니다. 이는 메모리가 어떻게 동작하는 지 VHDL 코드로 보여줍니다. 스키마틱을 확인해 보면 RAM이라고 나오는 것을 알 수 있습니다.

3절 부터는 FSM 설계에 대해서 다뤄집니다. 이 절 이후부터는 거의 항상 FSM이 나옵니다. 그래서 이 장에서 정신을 차리고 보면 좋겠지만, 막상 이 FSM이 점점 복잡해져 가면서, 함께 다이어그램과 코드가 복잡해지기 때문에 점점 더 어려워 집니다.
Moore, Mealy 두 가지 방식에 대해서 다루는데, 왜 이렇게 다루는지는 368p에 나옵니다. Moore는 출력과 클럭이 동기되고, Mealy는 클럭에 관계없이 입력에 따라 출력이 변하는 형태라고 합니다. Moore는 동기, Mealy는 비동기라고 이해를 해야 하는 것이 맞는 것인지
 
371p 4절에서는 피가 되고 살이 되는 코딩 스타일 조언을 줍니다. 말하자면, 노하우이기 때문에 따로 출력을 해두고 싶은 부분이기도 합니다. 그런데 380p에서 말하는 스키메틱 수준의 설계도를 머리에 넣을 정도가 되면, 이 책을 보고 있을까요? 하는 생각도 들지요..
 
3장에서는 더욱더 복잡해져 가기 시작합니다. 1절 parallelsorter에서는 하드웨어 정렬기를 구현해 봅니다. 405p 수식은 조금만 더 설명해 주면 안될까요? 하는 생각이 모락모락 떠올랐습니다. 물론 이산 수학 시간에 제대로 안 들은 제 잘못이겠지만 말입니다.
415p에서는 순차 회로 방식으로 같은 내용을 설계해 봅니다. 416p에서는 뜬금없이 MUX가 나옵니다만, 그냥 선택하는 역할을 하는가 보다? 하고 넘어갔습니다. 417p에서 가장 앞의 입력 부분이 왜 A - R1, R1, B - R3, R4, C - R2, R2, D - R4, R3인지 도통알 수가 없었습니다. 설명 좀 해줬으면 하는 바램이지만.. 설명은 없더군요.
 
3절에서는 조합회로 곱셈기를 구현합니다. 다만 BCD로 변환하는 것은 426p에 잘 설명되어 있습니다. 6을 더하여 판단하는 것은 10 이상의 수는 6을 더하게 되면 4비트로 표현하지 못하게 되어 carry out이 되기 때문입니다. 6을 더했을 때 캐리가 있을 때와 없을 때를 다르게 처리해야 합니다. 두 자리수가 될 수도 있고 안 될 수도 있는데, 안 될 경우 6을 더한 값을 넘겨주면 안되는 게 당연하죠. 427p에 진리표는 이 회로가 곱셈기라는 것을 생각하면서 보면 이상하지 않습니다. 처음에는 단순히 BCD Code 출력으로 보아 헷갈렸으나 그게 아니지요. 곱셈기 입니다~
 
4절에서는 순차 회로 곱셈기를 구현합니다. 435p의 그림으로 설명을 하고 있습니다. add-and-shift 방식이라고 합니다. 내용은 단순합니다. 더하고 나서 부분곱을 shift 합니다. 그리고 또 더합니다. 다 더한 후에 부분곱을 보면 결과 값이 되어 있습니다. 처음에는 이게 뭔지 몰라서 헷갈렸는데 2번째 보니깐 단순하네요.
 
5절에서는 수정된 Booth 곱셈 알고리즘을 사용해서 곱셈기를 구현하는 것입니다. 마찬가지로 수식과 코드는 잘 매치가 안되었습니다.
 
6절에서는 순차 회로 나눗셈기 입니다. 이전의 순차 곱셈기의 add-and-shift와 반대로 minus-and-shift가 나옵니다. 구현은 그래서 2절과 매우 유사합니다.
 
4장부터는 이제 현실적인 예제가 등장합니다. 그래서 정말 어렵습니다. 상태도도 2가지로 분할됩니다. 타이머 부분과 신호등 상태입니다. 교차로(큰 길, 작은 길)의 우선 순위가 다르기 때문에 더 복잡합니다. 설명은 아주 잘한 것 같습니다. 다만, 제 실력으론 아직 이해하기 어려운 부분이 많았습니다.
 
2절에서는 주사위 게임입니다. 이번 상태도는 이전 신호등에서 나온 타이머가 익숙해져서 더 잘 이해될 줄 알았습니다. 그런데, 501p 상태도를 보니 덜 이해 되더군요. <- 이 표시가 보수 인 것 같고, 설명 보고 이해가 되는 부분도 있었는데, 이해 안되는 상태 전이도 있었습니다.
 
517p에서는 분주기라는 것을 설계합니다. 분주기가 뭔가 했는데, 클럭 분주기의 주파수를 나눠서 Entity 마다 새로운 주파수를 생성하는 것이더군요. 518p에서 기억하고 넘어간 것은 복잡할 수록 동기식 설계가 안정적이고, 검증 하는데 유리하다는 것이었습니다.
 
이렇게 쭈욱 넘어가서 5장에서는 이 책에서 사용하는 키트와의 연동을 위해서 VGA, LCD, 입출력 제어에 대해서 다룹니다. VGA 설명은 잘 되어 있습니다. 그런데 563p에서 한 프레임을 그릴 때 필요한 시간이 왜 16.784ms인지는 안 나와 있었습니다. 그리고 564p에서 hsyncb_gen에서 counter 값이 595가 된 후와 counter의 값이 680라는 내용과 vsyncb_gen에서 counter의 값이 378이 된 후와 380이 될 때까지에서 왜 그런 숫자가 나오는지 처음 보는 저로썬 알 수가 없었습니다.
 
651p의 UART 회로 설계 같은 경우엔 모뎀이 어떤 식으로 동작하는구나 한다는 것을 간접적으로나마 들여다 볼 수 있는 좋은 기회였습니다.
 
대망의 6절 675p에서는 8비트 장난감 마이크로 프로세서 설계를 배웁니다. 목표에서 보이듯이 ISA 개념을 이해하고 컴퓨터 구조를 복습한 후에 RTL 수준의 컴퓨터를 설계할 수 있는 기본 바탕을 마련해 줍니다. 과연 언제쯤이면 혼자 힘으로 저렇게 할 수 있을까요? 라는 의구심은 들었지만 말입니다. 이 절의 내용은 다른 책에서도 볼 수 있는 내용이겠지만, 그것을 총체적으로 이해하고 하드웨어화할 수 있다는 점이 다른 책과의 차별성입니다. 어쨌든, 이 것을 보며 가야할 길이 멀구나 하는 것을 알게 되었습니다.
 
부록 A에서는 ModelSim, XLINX Webpack, ALTERA MAX+PLUS II, QUARTUS II  등의 추가적인 사용법을 설명해 줍니다.
부록 B는 이 책에서 주로 사용한 MP3100 보드 메뉴얼과 HBE-COMBO 보드 메뉴얼이 있습니다.
부록 C는 CD-ROM 내용 설명 입니다.

[실습 중 나타난 문제]
180p의 소스는  struct라는 architecture 이름 때문에 Check Syntax에서 계속 에러를 보게 되었습니다. 그러므로 struct -> sub_struct라는 이름으로 변경해서 Synthesize를 실행하셔야 합니다.
 
219p의 소스는 Design Pattern의 Producer-Consumer Pattern을 보여줍니다. 하지만, 이 장은 문제이죠. 그래서 코드를 짜야 동작하는 것을 볼 수 있습니다. 아무리 ModelSim에 넣고 돌려도 동작이 없죠? 그 코드에는 클럭이 없고, 게다가 넘겨주는 데이터도 없습니다. 그러므로 클럭과 데이터를 생성해 주어야 합니다. 또한 시뮬레이터 상에서는 해당 데이터가 218p 그림처럼 변하는 것을 확인할 수 없습니다. 그러므로 219p 아래에 있는 것처럼 after 구문을 붙여줘야 명시적으로 확인할 수 있습니다.

architecture hand_sim of handshaking is
 signal a : std_logic := 0
 signal cnt : integer range 0 to 10 := 0
 signal input_data, transmit_data : integer
 signal RQ, ACK : std_logic := 0
begin
 clk : process(a) begin
  a <= not a after 3 ns
 end process
 
 makerequest : process(a) begin
  if a[요기 작은 따옴표]event and a = 1 then
   cnt <= cnt + 1
   if cnt = 9 then
    cnt <= 0
   end if
   input_data <= cnt
  end if
 end process
 
 producer : process
 begin
  wait on input_data
  transmit_data <= input_data
  RQ <= 1 after 1 ns
   wait until ACK = 1
   RQ <= 0 after 1 ns
   wait until ACK = 0
 end process
 consumer : process
 variable receive_data : integer
 begin
  wait until RQ = 1
  receive_data := transmit_data
  ACK <= 1 after 1 ns
  wait until RQ = 0
  ACK <= 0 after 1 ns
 end process
end hand_sim
 
위의 코드가 테스트용 코드 입니다. 조금 허접해도 동작은 하니 사용해 보시길.. 그리고 글 올릴 때 세미 콜론이 제거 되므로 세미 콜론과 작은 따옴표는 알아서 넣으세요.

230p에서 y <= 이렇게 되어 있는데 y signal은 선언한 적이 없죠. x로 바꾸시던가 선언된 x signal을 y로 변경하세요. 후자가 더 간단하겠군요.
그리고 아랫줄에 보면 std_ulogic으로 바꾸면 unresolved type이라는 의미가 나오는데, 이것은 자바에서 식별자가 없어서 발생하는 예외와 상관이 없습니다. 이전에 앞 장에 resolution function에 대한 내용이 있었지요. std_ulogic 형은 서로 다른 두 개의 값이 한 signal을 구동하려고 할 때 적절히 처리할 수 없지만, std_logic에서는 resolution function을 통해서 적절한 해석을 통해서 제 3의 값을 자동으로 생성할 수 있다는 뜻입니다.
 
236p의 문제에서 으로 된 부분은 직접 작성해야 하는 부분입니다. 잘 기억이 안나면 component 선언 부분을 다시 참고해서 작성하고 signal은 당연히 타입을 지정해야 하구요. 끝으로 z=>z0이 되어 있으나 z0은 없으니 맞는 signal로 수정해야겠지요.
 
245p의 함수에서 clock라는 것은 정의된 적이 없습니다. 이것은 entity에 있는 CLOCK를 가리키는 것으로 인식되어 오류가 발생하므로 clock => clk로 변경해야 합니다.
 
338p에서 새로운 타입을 정의할 때 ** 뒤에 "4" 대신에 그냥 4를 적어야 되더군요.
344p에서 "is" 이렇게 되어 있는데 그렇게 되면 파일 자체가 인식이 안되므로 큰 따옴표를 제거 합니다.
 
408p~409p에서 코드를 작성하고 난 후에 아무리 테스트 벤치를 돌려봐도 값이 안 나와서 이상해 하던 차에 내용을 보니 compare_chnage 컴포넌트가 없더군요 -_ - 프로젝트 뷰에서 보면 compare_change 가 물음표 아이콘으로 표시되어 있을 것입니다. 그러므로 여러분께서는 저와 같은 삽질을 하지 마시고, 책의 소스를 확인해서 compare_change 코드를 참고하시기 바랍니다. 어째 정렬이 안되더라는..

[점수]
통합성 : 100점/100점
용어 선정 : 80점/100점
독자 이해도 : -/-(아는 만큼)
주석 점수 : 0점/100점
참조 목록 : 0점/100점
 
p.s. 이 책과 관련된 연구실에 계셨던 분 계시면, 연구실 홈페이지 주소 좀 알려 주십시오.
찾았습니다. -_ -
http://eda.cnu.ac.kr/
책에 있었던가요 암튼 위의 주소가 맞는 듯..

 
코멘트 0   공감 0
코멘트작성
 
이메일주소수집거부