(발전과정, 변천사)
-
SSI (small scale integration; 소규모 IC)
-
MSI (mediun scale integration; 중규모 IC) : 단일 칩에 수백 개의 gate
-
LSI (large scale integration; 대규모 IC) : 수천개의 게이트, 설계작업이 복잡해짐. 이때까지도 breadboard 위에서 회로들을 검증. 손과 종이를 이용한 레이아웃 작성
=> 자동화의 필요성 대두
=> EDA (electronic design automation) 기술이 발전하기 시작
-
VLSI (very LSI; 초대규모 IC) : 10만개 이상의 Tr.이 들어가는 칩을 설계
=> 회로설계와 검증이 매우 어려워짐.
-
회로 레이아웃의 자동 배치와 배선은 가능
=> 컴퓨터로 게이트 수준의 디지텅 회로를 만들기 시작.
상위레벨의 블록을 만들기 위해 이런 작업을 반복.
=> 하드웨어 기술 언어(hardware description languages; HDL)가 개발.
=> 설계가자 h/w에서 발생하는 반복성을 모델링할 수 있도록 해줌
-
Verilog HDL : 1983년 Gateway Design Automation 사에서 개발
cf) VHDL : DARPA에서 개발
-
HDL 설계를 도식적인 회오오 번역하는 작업은 여전히 수작업으로 진행.
-
논리합성(1987년)의 등장은 설계방법을 급진적으로 바꿈.
$\because$ HDL을 이용하여 RTL(register transfer level)로 표현 -> 게이트 배치와 배선을 구해줌. -
Verilog HDL은 IEEE 1364-1995가 표준으로 채택됨. 기존의 표준에서 중요한 특성을 향상시켜 만든 Verilog HDL이 IEEE 1364-2001
설계자
기존 : 머리 -> 도면 (이를 합성이라고 함)
HDL : 머리 -> 기술(description) -> 수작업 도면
합성 : 머리 -> 기술(description) -> 컴퓨터 도면
(6페이지 그림 1-1 ; 하얀색 부분: 사람이 하는 부분 / 회색 부분: 컴퓨터가 하는 부분, 사람이 확인 불가능)
-
어떤 설계에서든지 그 명세(spec.)가 일차적으로 작성됨/ 디지털 회로의 기능, 인터페이스, 전체구조 등.
-
행위 수준 표현 : 회로 기능, 성능, 표준 준수 여부, 설계 분성, HDL로 기술 가능 (프로그래밍 언어(C)와 비슷한 수준)
-
행위 수준 표현은 수작업을 통해 RTL표현으로 바꿈. 회로를 구현하는 데이터 흐름을 기술.
-
이후의 설계 작업은 설계 도구를 사용
Functional Verification and Testing : 시간 지연 등 물리적인 사항에 대한 고려 없이 논리적 결과만 확인하는 단계
=> 논리 합성 도구는 RTL 표현을 게이트 수준 net-list(회로) 으로 바꾸어줌
-
검증을 거친 게이트 수준 net-list는 자동 배치 도구와 배선 도구의 입력이 되어 레이아웃을 생성
-
레이아웃은 검증과정을 거친 후, 칩 위에 제작
-
현재의 디지털 회로의 설계는 회로의 RTL표현을 최적화하는 것에 집중
=> RTL 표현이 확정되면 EDA 도구 사용
=>설계 주기 단축, 반복 설계 가능, 기존 설계의 재사용 가능, 변경 쉬움.
cf) 행위 수준 합성도구의 등장, 행위 수준 표현에서 RTL 표현으로 변경.
=> 고도의 추상화된 수준 표현으로 부터 최종 ID 칩을 설계 가능할 것
=> 그러나 도구의 작업을 제어하는 것은 설계자의 몫
- 설계가 매우 추상화된 수준에서 표현, 일단 회로를 표형하면 논리합성 도구가 새로운 기술에 알맞도록 회로 면적과 타이밍을 최적화해 줄 것
- 설계의 기능적 검증은 설계 주기의 초반(RTL표현 최적화 시점)에 끝낼 수 있음.
- 배우기 쉽고, 사용하기 쉬움, C 프로그래밍과 유사.
- 하나의 회로 모델 안에서 서로 다른 추상화 레벨을 섞어 사용 가능. 하나의 언어로 설계와 스티물러스(시뮬레이션, 기능적인 검증)를 동시에 해결.
cf) Verilog의 4가지 추상화 레벨 : 스위치(최저레벨), 게이트, RTL(데이터 플로우, 행위(최고레벨) 레벨)
- 대부분의 논리 합성 도구들이 지원.
- 모든 반도체 제조사들이 논리합성을 위한 라이브러리를 제공. 선택의 폭이 넓어짐
- PLI를 이용해 설계자의 필요에 맞도록 시뮬레이터를 조정 가능.
-
현대의 디지털 회로 설계자들은 회로의 기능젓인 측면만 생각하면 됨
=> EDA 도구들이 최적에 가깝게 나머지를 처리해줌
-
현재 RTL설계가 주류임 . 행위 수준 모델링은 아직 널리 사용되지 않음
-
새로운 검증 방법들이 요구에 다라 개발될 것.
= 형식적 검증 기술 : verilog 표현의 정확성을 수학적 기술을
= assertion 검사
-
검사 속도의 향상 : 시간 단축
-
이미 설계 되거나 제공되는 모듈과 블록을 사용한 bottom-up 방법 사용
이 장에서는
- 디지털 설계의 기본개념인 계층적 모델링의 개념을 이해한다
- 전형적인 설계방법과 Verilog에서의 적용방법을 알아본다
- 디지털 시뮬레이션의 요소들 사이의 관계를 알아본다
[목표]
-
Top-down 설계 방법, bottom-up 설계 방법
-
모듈과 모듈 인스턴스(중요한 키워드!)의 차이점
-
4가지 추상화 수준 : 행위, 데이터플로우, 게이트, 스위치 레벨
-
디지털 시뮬레이션을 위한 요소 : 스티뮬러스블록/ 설계 블록/ 스티뮬러스 적용방법
- top-down 설계 : 최상위 블록을 정의하고 최상위 블록을 만드는게 필요한 하위 블록을 확인해감. 하위 블록을 더 이상 나누어지지 않는 리프셀(leaf cell) 까지 나눌 수 있음
(그림 2-1 top-down 설계 방법론)
- bottom-up설계 : 먼저 필요한 블록들을 만들고, 그것을 이용해 더 큰 셀을 만들어 삼. 이런 방법으로 최상위 블록까지 만들어 냄.
(그림 2-2 bottom-up 설계 방법론)
- 일반적으로 top-down 설계와 bottom-up 설계를 같이 사용
- 디자인 설계자는 최상위 블록을 정의하고, 논리 설계자는 기능들을 블록와 하위블록으로 나눔으로써, 설계를 어떻게 구성할 것인지 결정하고, 최적화된 리프셀을 설계
- 스위치 수준 회로 설계자는 스위치를 가지고 리프셀의 라이브러리를 만들고, 논리 수준 설계자는 이 리프셀응 가지고 top-down방법으로 모든 모듈을 만듦
(그림 2-3 리플 캐리 카운터; clock: 컴퓨터의 그 클럭 / reset: 초기화시키는거라고 생각)
-
4비트 리플 캐리 카운터는 4개의 T_FF(T_플립플롭)으로 구성됨
-
T_FF는 하강 모서리-구동 D_FF(D_플립플롭)와 인버터로 구성될 수 있음 (그림 2-4 : T_FF의 내부, ㅡo<lㅡ모양이 인버터)
=> 리플 캐리 카운터도 계층적(hierarchical)인 형태로 만들어짐 (그림 2-5 리플 캐리 카운터 설계 계층)
- Top-down 설계
- 최상위 블록인 리플캐리 카운터의 기능을 정의
- T_FF로 카운터 구현
- D_FF와 인버터로 T_FF구현
- Bottom-up 설계 : 탑다운방법과는 반대의 흐름을 가짐; 하위->상위
ex) D_FF는 and나 or게이트, Tr.을 이용해 만듦
Bottom-up의 흐름과 Top-down의 흐름이 D_FF의 단계에서 만남
- 모듈은 포트 인터페이스를 통해서 상위 수준의 블록에 필요한 기능을 제공해주지만, 내부구현은 숨김
=> 설계자가 다른 부분에 영향을 주지 않고 모듈의 내부를 수정 가능
ex) 그림 2-5에서 리플 캐리 카운터, T_FF, D_FFf는 모듈의 예
- 모듈 : 키워드 module로 시작하여 모듈의 마지막은 반드시 endmodule
-
각 모듈은 모듈이름과 모듈의 입출력 터미널을 나타내는 모듈 터미널 리스트 를 가짐
module <모듈 이름> (<모듈 터미널 리스트>); ... <모듈 내용> ... ... endmodule
=>
module T_FF(q, clock, reset); . . <T_플립플롭의 기능> . . endmodule
- Verilog의 4가지 추상화 수준 : 모듈은 설계의 쓰임에 따라 여러 수준으로 정의
=> 모듈은 추상화 수준과 관계 없이 외부에서는 같게 동작
-
행위 또는 알고리즘 수준(behavioral or algorithmic level)
-
베릴로그에서 제공하는 추상화(abstraction)의 가장 상위 레벨
=> 원하는 디자인 알고리즘을 사용해 모듈 구현, C프로그래밍과 유사
-
-
데이터 플로우 수중
-
데이터의 흐름을 명백히 나타냄으로써 모듈 구현
=> 래지스터 사이의 데이터 흐름과 데이터가 어떻게 처리되는지를 알고 있어야함
=> 1과 2를 합쳐서 RTL이라고 함
-
-
게이트 수준 : 논리회로 지식 요구됨
- 논리 게이트와 게이트 사이의 연결에 의해 모듈을 구현
-
스위치 수준 : 가장 하위 수준의 추상화 레벨
-
스위치와 기억노드를 이용하여 모듈을 구현
=> 스위치 수준에 대한 지식이 요구됨. 잘 사용되지 않음
-
- Verilog는 설계시 4개의 추상화 수준을 혼용하는 것을 허용
-
디지털 설계에서 RTL이란, 행위 수준 구조와 데이터플로우 수준 구조를 섞어서 사용하는 Verilog 표현을 뜻함
-
일반적으로 상위의 추상화 레벨이 더 융통성 있고, h/w 구현에 대하여 독립적이나, 하위의 추상화 레벨 설계는 그 반대임.
=> 작은 수정이 많은 부분의 변경을 요하게 됨 cf) C vs 어셈블리
- Verilog는 템플릿(template)으로 부터 객체를 생성, 각 객체는 이름, 변수, 파라미터, I/O 인터페이스를 가짐. 각 인스턴스는 고유의 이름을 가짐.
=> 템플릿으로부터 객체를 생성하는 것을 파생(instantiation), 객체를 인스턴스라 함.
(instantiation : 파생 중요한 용어!!)
예제2-1) 모듈 파생 (리플 캐리 카운터)
- 최상위 블록은 T_FF 템플릿으로부터 4개의 인스턴스를 생성.
- 각 T_FF는 D_FF과 인버터를 파생.
module ripple_carry_counter(q, clk, reset);
output [3:0] q;
input clk, reset;
T_FF tff0 (q[0], clk, reset);
T_FF tff1 (q[1], q[0], reset);
T_FF tff2 (q[2], q[1], reset);
T_FF tff3 (q[3], q[2] reset);
endmodule
module T_FF(q, clk, reset);
output q
input clk, reset;
wire d;
D_FF dff0(q, d, clk ,reset);
not n1(d, q);
endmodule
- 설계블록이 완성되면 반드시 테스트가 필요함.
- 설계블록의 기능적인 테스트 스티뮬러스()를 적용시킨 결과로 확인
- 스티뮬러스 블록은 보통 테스트 벤치()라고 불리는데, 설계블록과 따로 작성
- 스티뮬러스를 적용하는 방법
- 스티뮬러스 블록에서 설계블록을 파생시텨 설계블록의 신호를 직접받는 방법 (그림2-6)
- 스티뮬러스 블록은 최상위 블록으로 이 블록은 c과 reset신호를 조정하고, 풀력신호q를 출력하여
- 가상의 최상위 모둘에서 스티뮬러스와 설계블록 둘 다를 파생시키는 방법
- 스티뮬러스 블록은 오직
2.6.1 설계블록
top-down 설계방식 사용'
=> 최상위 블록 설계 => T_FF->_D_FF
이 장에서는 - Verilog의 기본적인 구조와 규칙을 알아본다.
- Verilog는 토큰의 스트림을 포함. 토큰 : 주석, dlimiter, 숫자, 문자열, 식별자, 키워드
- Verilog는 대소문자를 구분, 모든 키워드는 소문자
-
화이트 스페이스 : Verilog에서 화이트 스페이스는 토큰들을 분리할 때를 제외하고는 항상 무시됨. 그러나 문자열에서는 포함됨.
-
주석 : 가독성과 문서화를 위해 사용
-
연산자 : 단항, 이항, 삼항연산자 세 가지 형이 있음
- 단항 연산자 : 피연산자 ; 피연산자 앞에 위치
- 항 연산자 : 두개의 피연산자 사이에 위치
- 삼항 연산자 : 각 피연산자 사이에 위치
- 수 표현 : 크기 지정 기능과 크기 지정 불가능 형태의 두가지 수 표현
- 크기 지정 가능 수 : 형식
<크기>'<기본형식><숫자>
- <크기>는 숫자의 비트 수의 개수를 나타냄. 10진수만 가능.
- <기본 형식>은 2/8/10/16 진수
- <숫자>는
- ㄴㅁㅇㄹ
- X, Z값 : 알 수 없는 값(unknown) / 하이 임피던스(high impedence)
- 2진수에서 x 또는 z는 1비트를, 8진수에서는 3비트를, 16진수에서는 4비트를 지정.
- 0, x, z 를 하나만 사용하면 자동으로 나머지 비트를 이 비트로 채움
- 음수 : 숫자의 <크기> 앞에 음수 부호를 붙임
- "_" 와 물음표 : 가독성 향상
- "_"는 맨 처음을 제외하고, <숫자>의 어느 위체이 와도 상관 없음.
- "?"는 < 숫자>에서 x와 같은 역할을 함. casex, casez문에서 사용.
- 문자열 : 큰따옴표 사이에 있는 문자들. 줄 바꿈 없이 한 줄로만 제한됨. 문자열은 일련의 1byte ASCII
6) 식별자와 키워드 (중요!!!! 작명법~!!)
- 식별자 : 설계시 객체들을 참조하기 위해 객체에 주어진 이름
- 알파벳, 숫자, "_" ,$를 사용. 대소문자 구분. 첫문자는 알파벳과 "_"
- 키워드 : 언어 구조를 정의하기 위해 예약된 특별한 식별자. [부록C]
- 에스케이프 식별자 : "\"로 시작해서 화이트 스페이스로 끝남.
-
"\"와 화이트 스페이스 사이에 있는 모든 문자들은 글자 그대로 처리.
-
풀력하기 위한 ASCII 문자는 에스케이프 식별자에 포함
"\"와 화이트 스페이스는 식별자로 구분되지 않음.
<<<<<<< HEAD
- 논리값 집합 : 4개의 논리값(표 3-1)과 8개의 신호강도(표 3-2)를 지원
-
신호강도는 디지철 회로에서 서로 다른 강도를 갖는 신호들의 충돌을 해결하는데 사용.
=> 만약 다른 강도의 두 신호다 동일한 wire로 만나면 결과는 알 수 없음 ("x (언노운)")
- trieg 넷만이 large, medium, samll의 강도를 저장 가능
논리값 수준 | 하드웨어 회로에서의 상태 |
---|---|
0 | 논리값 0, 거짓 상태 |
1 | 논리값 1, 참 상태 |
x | 알 수 없는 논리 값 |
z | 하이 임피던스, 플로팅 상태 |
이 표 중요! 이 다음것도 중요!
- 넷(nets == wire) : h/w 요소 사이의 연결 을 나타냄. 실제 회로에서처럼, 연결되어있는 장히의 출력으로 유도되는 연속적인 값을 가짐.
-
넷 a가 and 게이트 g1의 출력에 연결되어 있음
=> 넷 a는 게이트 g1에 의해 생성된 출력 b&c를 연속적으로 가짐
-
넷은 키워드 wire에 의해 정의. cf) 와이어와 넷은 같은 뜻으로 사용됨.
-
넷의 크기를 정하는 벡처를 지정하지 않으면, 1bit넷으로 사용됨.
-
넷의 기본값은 'z(하이 임피던스)'임. cf) trireg 넷의 기본값은 'x'임.
-
벳은 그것에 유도된 출력값을 갖고, 만약 유도되는 값이 없다면 'z'값
-
넷은 키워드가 아니라, wire, wand, wor, tri, triand, trior, trireg 등의 집합을 나타냄 => 대부분 wire로 선언. [부록A] 참조.
wire a; // 넷 a를 정의
wire b, c; // 넷 b, c를 정의
wire d = 1'b0 // 넷 d를 논리값 0으로 선언
- 레지스터 : Verilog에서 단지 값을 저장할 수 있는 변수를 의미
-
레지스터의 논리값은 시뮬레이션시 레지스터에 새로운 논리값을 대입함으로써 변경할 수 있음
-
키워드 reg에 의해 정의. 기본 논리값은 'x'임.
cf) 클럭이 필요한 h/w 레지스터와 혼동하지 말 것
- 벡터 : 넷과 reg는 벡터로 선언 가능. 비트 폭의 기본값은 스칼라 (1bit)
- 벡터는 [높은 수 : 낮은 수] or [낮은 수 : 높은 수] 로 표현. 왼쪽 값이 최상위 비트(중요!!!)
wire a;
wire [7:0] bus;
wire [31:0] busA, busB, busC;
reg clock;
reg [0:40] virtual_addr;
-
벡터 부분 선택 : 주소 비트 또는 벡터의 일부분을 나타낼 수도 있다.
busA [7] // 벡터 busA의 7번 비트 bus [2:0] // 벡터 bus의 3개의 하위비트
-
가변 벡터 부분 선택 : Verilog는 벡터의 가변 부분 선택을 제공
- [<시작비트+:폭] - 시작비트부처 부분 선택 증가
- [<시작비트-:폭] - 시작비트부처 부분 선택 감소
부분 선택이 시작 비트는 다양하지만, 폭은 일정해야함
- 정수, 실수, 시간 레지스터 데이터형
- 정수 : 양을 다루기 위한 일번것인 범용 레지스터 데이터형. integer
- wjdtndml rlqhs chrdms wlwjdehls rlrPdml dnjem zmrldhk rkxdma
- 적어도 32bit보다 커야
- 레지스터는 음수 불가능 수로 저장되나 정수는 음수 가능수로 저장
- 실수 : 실수는 상수이고, 키워드는 real. 십진표기법 또는 과학적 표기법으로 표현
- 시간 : Verilog 시뮬레이션은 시뮬레이션 시간을 고려하여 동작.
- h/w에 따라 다르니
- 배열 : reg, integer, time, real, realtim 벡터 레지스터 데이처형의 배열읠 제공
-
배열의 형채 : <배열 이름>[<서브 스크립트]
-
넷 또느 레지스터 벡터와 배열을 혼동 유의
=> 벡터는 n-bit의 폭을 가지는 하나의 원소, 배열은 1-bit or n-bit을 가지는 여러 원소!
- 메모리 : Verilog에서 메모리는 단순히 레지스터의 배열로 구성. 배열의 각 원소는 워드. 이 때 각
- n개의 1bit 레지스터와 1개의 n-bit 레지스터를 구분하는 것은 중요
- 메모리에서 부분적인 워드는 주소로 사용.
- 파라미터 : 모듈 내에서 상수를 정의. 변수로 사용 금지. 키워드는 parameter.
- 각 모듈 인스턴스의 파라미터 값은 컴파일 시 개별적으로 대치됨.
- 파라미터의 타입과 크기도 정의 가능.
- 보통, 숫자를 직접 사용하지 않고 파라미터를 사용해서 모듈을 작성.
- 파라미터 값 변경 : 모듈 파생시 또는 defparam 문장을 이용(9장 참고)
- 키워드 localparam은 파라미터 값이 변해서는 안 될 때 사용됨.
( 파라미터 사용 이유 ~~ c에서 define을 통해 상수값을 쓰는 것과 비슷. => 호환성, 유지보수 용이성)
- 문자열 : 레지스터에 저장. 단 reg 변수의 폭은 문자열보다 커야함.
- 문자열의 각 문자는 8bit를 차지.
- reg의 폭이 문자열보다 큰 경우, Verilog는 문자열의 왼쪽 비트들을 0으로 채움 => 문자열 선언시, 필요한 것보다 약간 크게 하는 것이 안전.
- reg의 폭이 문자열보다 작은 경우, 문자열의 왼쪽비트들을 무시함.
-
모듈 정의는 항상 키워드 'module'로 시작함
모듈 정의의 처음에는 모듈이름
-
모듈이 외부환경과 소통할 수 있는 인터페이스
-
외부환경에서는 모듈의 내부를 볼 수 없음
=> 인터페이스가 변하지 않는 한, 외부환경에 영향을 주지 않고 모듈 내부를 수정 가능
-
위치에 의한 연결 : 파생된 모듈의 포트와 정의한 모듈의 포트는 같은 위치에 있는 신호들 끼리 연결
-
이름에 의한 연결 : 포트이름에 의해 외부 신호를 연결. 계층적 이름
-
논리회로는 논리 gate를 사용해서 설계할 수 있음.
-
Verilog는 기본적인 논리 gate를 프리미티브(primitive)로 미리 정의해둠.
=> 모듈 정의를 필요로 하지 않으며, 바로 모듈처럼 파생 가능.
-
기본 gate (프리미티브는 크게 두가지로 나뉨!)
-
And/Or 게이트
하나의 스칼라 출력과 여러 새의 스칼라 입력을 가짐 ( 출력이 하나 )
gate 터미널 리스트의 첫번째 터미널은 출력이고, 나머지는 입력
gate의 출력은 입력값중 하나가 바뀌는 즉시 값을 계산해서 가짐
프리미티브를 지정할 때는 인스턴스 이름이 필요 없음
=> 설계자는 이름이 없는 수백개의 게이트 파생 가능
-
Buf/Not 게이트
하나의 스칼라 입력과 하나 또는 그 이상의 스칼라 출력 (입력이 하나)
포트의 마지막 터미널은 입력과 연결, 나머지 터미널은 출력과 연결.
bufif / notif (3상태 버퍼) : buf와 not gate에 조절(control, ctrl, enable, E) 신호를 추가한 gate
=> 이 게이트는 조절 신호가 인가될 때만 신호를 전달, 조절 신호가 인가되지 않으면 z값이 전달됨
bufif1 b1 (out, in, ctrl);
-
-
인스턴스의 배열 (p72 참고)
nand n_gate [7:0] (OUT, IN1, IN2); // 이는 다음과 같다 nand n_gate0 (OUT[0], IN1[0], IN2[0]); nand n_gate1 (OUT[1], IN1[1], IN2[1]); nand n_gate2 (OUT[2], IN1[2], IN2[2]); ....
상승, 하강, 턴-오프 지연
-
프리미티브 게이트의 입력에서 출력으로 가는 지연의 형태 3가지
-
상승지연 : 다른 값에서 1로 게이트 출력이 변화
-
하강지연 : 다른 값에서 0으로 게이트 출력이 변화
-
턴-오프 지연 : 게이트 출력이 어떤 값에서 'Z'로 변화
-
만약 값이 x로 변했다면, 지연이 가장 작은 것으로 간주
-
-
지연을 표시하는 3가지 형태 : 예제5-10
- 1개의 지연만 지정된 경우 : 모든 변화에 사용
- 2개의 지연이 지정된 경우 : 상승, 하강 지연
- 3개의 지연이 지정된 경우 : 상승, 하강, 턴-오프 지연
-