2024년 7월 29일 월요일

"Verilog-Verilator-SystemC 방법론 기초" [2] 설계 언어 Verilog 와 검증 언어 SystemC

"Verilog-Verilator-SystemC 방법론 기초"
[2] 설계 언어 Verilog 와 검증 언어 SystemC

[알림] 아래 내용중 질문, 지적, 보강 등 어떤 사항도 환영 합니다.

"Verilog-Verilator-SystemC 방법론 기초"는 "내 칩(My Chip) MPW 서비스": 오픈-소스 도구 활용 반도체 설계 특별과정 중 두번째 강좌로서 베릴로그(Verilog)와 오픈-소스 시뮬레이션 도구 Verilator 그리고 시스템 수준 검증 방법론 SystemC의 입문 과정이다. 컴퓨팅 언어를 활용한 디지털 회로의 설계와 검증을 다룬다(Quantative approach to digital circuit design using computing language and Open-Source EDA tools).

강의 내용은 아래와 같다.

[1] 도구 설치 [링크]
[2] 설계 언어 Verilog 와 검증 언어 SystemC/C++[링크]
[3] 하드웨어 기술 언어의 코딩 스타일[링크]
[4] 실습: 쉬프트 레지스터 [링크]
[5] 실습: FIR 필터 [링크]
[6] "내 칩 MPW" 요건에 맞춘 FIR 필터의 PE 설계[링크]

[부록] FIR 필터 PE의 "내 칩MPW" 제출용 GDS 생성[링크]


------------------------------------------------------

목차

I. 설계의 언어와 검증의 언어

II. 설계 언어 Verilog
    II-1. 플립-플롭을 언어로 묘사하기
    II-2. 프로그래밍 언어로 표현하는 논리식과 논리회로
    II-3. 하드웨어 기술 언어의 최소 요건
        a. 순차 구문
        b. 병렬구문
        c. 하드웨어 객체
        d. 두가지 할당 연산자

III. 검증 언어 SystemC/C++
    III-1. C++ 크래스 이해의 최소선
    III-2. SystemC에 대한 다른 견해

IV. 맺음말

--------------------------------------------------------

I. 설계의 언어와 검증의 언어

설계 방법의 추상성(abstraction level)을 높이는 목적은 생산성을 위해서다. 짧은 시간에 적은 인력으로 더 큰 규모의 설계를 완성하려는 것이다. 인간의 언어에 가까우면서 자동 번역이 가능한 형식을 갖춘 컴퓨팅 언어를 도입하므로써 높은 설계 생산성을 이뤘다. 소프트웨어의 개발 뿐만 아니라 하드웨어 설계에도 높은 추상화 수준을 갖춘 컴퓨팅 언어의 사용이 자리잡았다.

디지털 전자회로의 동작은 논리식(logical expression)으로 표현 할 수 있다. 컴퓨팅 언어로 묘사된 높은 추상화 수준의 행위(알고리즘)는 전자회로로 자동변환이 가능하다. Verilog(베릴로그)는 하드웨어의 행위를 묘사하기 위해 채택된 컴퓨팅 언어다.

하드웨어 기술 언어 HDL(Hardware Description Language)의 최종 목표는 전자회로의 제조를 위한 도면의 생성이다. 큰 비용이 드는 전자회로 반도체는 제작 이전에 충분히 검토되어야 한다. 제조도면의 생성을 목표로 하는 하드웨어 행위의 묘사를 설계(design)라 한다면 검증(verification)은 이 하드웨어가 목적하는 사양서(specification) 대로 기능하는지 확인하는 절차다.

설계와 검증은 동일한 언어(방법론)를 사용하는 것이 보통이었다. 설계 규모가 증가하고 내용이 복잡해 지면서 높은 추상화 수준의 검증 방법론이 필요해졌고 기존의 언어를 차용한 HVL (hardware verification language)이 등장 했다. 현재 사용되고 있는 HVL로 SystemVerilog, OpenVera, e, SystemC 들이 있으며 HDL과 더블어 표준으로 등재되었다[1]. 이들은 프로그래밍 언어에 임의 비트(bit manipulation)와 사건처리(event process)등 하드웨어 객체 표현 방법과 시스템 모델링의 요건으로 병렬실행 구문(concurrent execution statement)을 추가하였다. 그에 덧붙여 공유 객체(SO, shared object), 동적 라이브러리(DLL, dynamic linking library)는 물론 프로세스간 통신(IPC, inter-process communication) 기법을 활용하여 다른 방법론에서 축적된 자원을 재활용 하거나 이종 언어를 통합하기도 한다.

Verilog 언어는 하드웨어의 기술을 목적으로 발명된 언어다. 테스트벤치의 작성을 위해 추상성을 높이며 발전되었다. Verilog로도 시스템 수준 테스트벤치의 작성이 가능하지만 C++에 비하면 엄청난 수고가 든다.

SystemC는 새로운 언어가 아니다. 하드웨어 객체를 표현 할 수 있는 C++의 크래스로서 병렬실행 시뮬레이터를 라이브러리로 제공한다. SystemC로 작성된 모델은 C++ 컴파일러로 실행 파일을 생성한다.

이번 학습은 Verilog로 레지스터 트랜스퍼 수준(RTL, Register-Trasfer Level)에서 디지털 논리회로를 기술하고 SystemC로 테스트벤치를 작성하여 검증하는 방법론을 소개한다. Verilog와 SystemC가 담고 있는 방대한 내용을 단숨에 배우기는 불가능하다. 전자 설계 자동화 도구(EDA Tools)를 활용한 반도체 설계의 필요 최소한 내용을 학습한다.

II. 설계 언어 Verilog

컴퓨팅 언어를 단숨에 배워보자는 동영상이 넘친다. 그러면서 몇시간짜리 동영상을 내밀곤 한다. 다보기 전에 지친다. 체계적인 학습이라 하면서 수백 페이지 교과서를 가지고 몇달을 보낸다. 그러다 지친다. 몇번을 시도하다 결국 처음 몇장 만 훤하다. "체계적 학습"이라는 교실에서 나와 길 위에서 배워보자.

II-1. 플립-플롭을 언어로 묘사하기

논리회로는 이미 배워 알고 있다. 굳이 Verilog 라는 언어를 쓰지 않고 디지털 회로를 표현 할 수 있을지 스스로 질문해 보자. 예를 들어 D 플립 플롭(D-FlipFlop)을 일상 언어로 기술해보자. 그리고 C 언어로 옮겨보자. 언어로 표현하기 곤란 하면 그림은 어떤가?

언어로 디지털 회로를 설계하려고 나선 참인데, 왜? 말로는 어려웠을까? 적당한 용어(jargon)를 찾기 어려웠을 지도 모른다. 다시 D 플립플롭의 '동작'(또는 '행동' 또는 '행위')을 말로 표현해보자.

"클럭으로 지정된 입력 CLK 에 상승 엣지(positive edge)가 감지되면 입력 D 를 Q에 전송한다. 그 이외의 경우 Q는 변화 없다(또는 이전 값을 유지한다)."

위의 문장에서 등장하는 '클럭', '엣지', '전송', '변화' 라는 단어의 이해는 논리회로를 배우기 이전과 이후로 갈린다. 이에 더하여 '이전'이라는 표현이 시간의 흐름을 내포하고 있다. 이번에는 C 언어로 표현해보자.

    if (CLK==1)
        Q = D;

이 문장이 D 플립 플롭을 제대로 표현하고 있을까? 플립플롭의 가장 중요한 동작 요인인 '엣지'의 표현이 없다.

II-2. 프로그래밍 언어로 표현하는 논리식과 논리회로

이번에는 논리식(logical expression)이다. 아래와 같은 간단한 논리회로가 있다.

논리식은 어떤 컴퓨팅 언어로도 쉽게 표현 할 수 있다.

    X = B & A;
    D = X | C;

C 언어라면 위의 두 문장의 순서를 바꿔도 좋을까? SPICE 네트리스트를 떠올려보자. 전자회로를 기술하는 경우라면 두 문장의 순서를 바꿔도 좋다.

II-3. 하드웨어 기술 언어의 최소 요건

위의 간단한 두가지 예를 보더라도 프로그래밍 언어 C 로 하드웨어를 묘사하기 곤란하겠다는 짐작이 간다. 그래서 하드웨어 기술 언어 HDL이 제안되었다.

a. 순차 구문

하드웨어 기술 언어 Verilog는 플립-플롭을 어떻게 기술하는지 보자.

    always @(posedge CLK)
    begin
        Q <= D;
    end

always @()는 소괄호 안에 나열된 신호의 조건이 맞으면 그 아래 딸린 구문을들 실행한다는 뜻이다. 소괄호 안에 나열된 신호들을 감응 신호들(sensitivity list)이라고 한다. 괄호안의 posedge는 신호의 상태를 평가해주는 연산자다. clk가 상승 엣지인지 평가하여 참일 경우 D의 값을 Q 로 전송한다는 의미라는 것은 쉽게 짐작할 수 있다. 그리고 그 짐작이 맞다. 만일 평가 조건이 맞지 않으면(CLK가 0 또는 1 을 유지하고 있을 때는 물론 하강 엣지일 때)는 전송은 실행되지 않게 되므로 Q 는 이전 값을 계속 유지한다. D 플립 플롭의 전형적인 묘사다. 굳이 영어 단어 'always'의 뜻을 적용하여 표현 하면 이렇다.

"소괄호 안에 나열된 신호를 평가하여 참(true)일 때 항상 아래에 딸린 구문들을 순차적으로 실행 한다"

 always 구역 내의 구문들은 모두 순차적인 행위를 묘사한다는 점에 유의한다.

b. 병렬구문

산술 연산과 논리 연산은 모두 C 언어의 그것과 같은 표현 방식을 따른다. 다만 하드웨어 언어의 모든 문장은 병렬실행(concurrent statement)으로 문장이 놓인 순서는 실행 결과에 영향을 주지 않는다. 병렬 할당문을 명시하기 위해 assign 키 워드(key word)로 명시한다. 위의 조합회로 예를 Verilog 병렬 할당 문으로 표현하면 다음과 같다.

    assign X = B & A;
    assign D = X | C;

병렬 할당문에서 할당 대상은 중복(multiple drive)될 수 없다.

    assign X = B & A;
    assign D = X | C;
    assign X = E ^ F;

하드웨어를 기술한다는 점을 감안하면 전기적인 충돌을 허용할 수 없으므로 이의 금지는 당연하다. 컴퓨팅 언어를 사용한 알고리즘의 기술에 문법적 오류는 당연하며 논리적 오류가 없어야 함은 물론이다. 하드웨어 언어를 사용할 때는 이에 더하여 전기전자 회로의 위반(violation)이 없어야 한다.

c. 하드웨어 객체

하드웨어 언어에서 객체는 기본적으로 1비트 전선(net)이다. 단 병렬 할당과 순차 할당을 구별해 선언 한다.

    reg x;
    wire x;

다수의 비트를 가진 객체를 선언하기 위해 대괄호를 사용한다.

    wire [7:0] z;

객체 z 는 8비트 폭의 전선으로 상위 비트의 위치가 [7]이다. 레지스터 reg 로 선언 되었다고 해서 반드시 디지털 회로의 D 플립플롭을 의미하는 것은 아니다. 기술된 행위에 따라 디지털 데이터의 저장용 플립플롭으로 해석된다. 아래와 같은 기술은 비록 c 가 reg 로 선언 되었어도 조합회로 멀티플렉서(multi-plexer)다.

    always @(s, a, b)
    begin
        if (s)
            c <= a;
        else
            c <= b;
    end

감응으로 지정한 신호 s, a, b에 상승(0->1)과 하강(1->0)의 구분 없이 사건(event, 변화)가 발생하면 if ~ else 문이 실행된다. s의 모든 경우에 할당이 이뤄지고 있다. 이에 반해 아래의 예에서 s 가 0일 경우 할당 문이 없다. 즉, s 가 0 일때 c 는 이전 값을 유지하고 있으라는 의미다. 디지털 회로의 래치(latch)를 묘사한 것이다.

    always @(s, a)
    begin
        if (s)
            c <= a;
    end

always 구역 내의 할당은 reg로 선언되어야 한다. 순차실행 할당 연산자는 <= 다.

d. 두가지 할당 연산자

Verilog는 C 언어를 많이 닮았다고 한다. 따로 설명 할 것도 없이 C 언어의 연산자와 동일하다. 다만 할당 연산자(assignment operator)의 경우 순차구문의 연산자 <= 와 병렬구문의 연산자 = 를 별도로 두고 있다.  각각 즉시할당(immediate assign)과 지연할당(deferred assign)이라고 한다.

순차구문에서 할당은 프로그래밍 언어의 할당과 같은 방식으로 일어난다. 할당 연산자 <= 의 오른편 rhs(right hand side)의 수식이 평가되어 즉시 왼편 lhs로 전송된다.

병렬구문에서 할당은 오른편의 수식의 평가, 이전 값과 비교 후 사건고지, 시뮬레이터에 의한 일률 갱신으로 할당이 이뤄진다.

두 할당으로 구분하는 이유는 시뮬레이션 소프트웨어로 병렬 구문을 모의실행하기 위한 방법이다. 아래 그림은 SystemC 1.x 의 시뮬레이터네서 병렬 구문의 할당과 사건처리 후 갱신을 설명하는 개념도다.

"내 칩 MPW" 지원에 당면하여 알아야할 Verilog는 최소한을 살펴봤다. Verilog는 C 언어를 많이 닮았다며 쉽게 시작 했다가 병렬성에 이르러 곤란을 격는다. 하드웨어를 다룬다는 점을 염두에 두고 상식으로 생각하면 이해되지 않을 것은 없다.

III. 검증 언어 SystemC/C++

검증은 설계물이 목표한 동작을 하는지 확인하는 절차다. 설계 언어는 레지스터 트랜스퍼 수준 RTL에서 디지털 논리회로를 기술한다. 순서에 따라 입력을 주고 출력을 검사하는 검증 환경(테스트벤치, testbench)의 구축에 RTL은 매우 불리하다. 알고리즘을 기술하는 컴퓨팅 언어로 가장 탁월한 C++를 사용하기로 한다. 엄청나게 쌓인 자원(라이브러리)들은 물론 현존하는 컴퓨터와 운영체제를 반도체 설계 검증에 즉시 활용할 수 있다.

RTL에서 기술된 하드웨어를 검증 하기 위해 C++ 언어를 활용 하려면 부족한 부분을 채워야한다. 객체들은 비트 단위로 선언할 수 있어야 하며 입출력의 방향이 지정되어야 한다. 사건에 의해 구동되는 병렬실행을 모의 할 수 있어야 한다. SystemC 는 C++로 하드웨어를 모의할 수 있도록의 크래스와 템플릿 라이브러리를 제공한다.

C 를 배웠다 하더라도 C++를 받아들이기 쉽지 않다. 하물며 그 확장인 SystemC를 단숨에 익히기는 더욱 어렵다. 반도체 설계를 위해 Verilog를 배우려고 디지털 논리 회로의 이해를 기반으로 접근 했었다. SystemC를 배우기 전에 C 프로그래밍 언어를 배운 이유를 상기하기 바란다. Verilog 뿐만 아니라 그 확장 판인 SystemVerilog에서도 C/C++의 함수를 연계시키기 위한 표준이 마련되어 있다. 하드웨어 언어에서 그토록 C/C++를 들여오려고 애쓰는 까닭이 있을 것이다. Verilog 로 테스트 벤치를 작성할 수 있지만 C/C++를 활용하면 매우 수월하기 때문이다.

III-1. C++ 크래스 이해의 최소선

C와 C++의 가장 두드러진 차이를 든다면 단연 크래스와 템플릿이다. C++의 크래스(class)는 C의 구조체(struct)의 확장이다. 구조체는 복합 객체들을 담는 용기(container)다. 크레스는 객체뿐만 아니라 객체를 다루는 방법도 함께 담을 수 있다. 이 방법을 소속함수(member function)라고 한다. 템플릿은 크래스의 자료형을 유연하게 정의한다.

C++의 크래스는 매우 방대하고 추상적 개념들이 가득하다. 그 개념들이 필요한 이유를 모르고 이해하려면 고단해진다. 크래스와 템플릿의 기초만 알고 시작하자. 가장 기초적인 예제는 아래와 같다. 반도체 설계의 검증에 SystemC를 활용하기 위한 C++ 이해의 최소한이다.

    template <typename T>
    class complex_t
    {
        T image;
        T real;

    public:
        complex_t(int x, int y)    // Constructor
        {
            image = x;
            real = y;
        }

        T get_real()   { return real;  }

        T get_image()  { return image; }

    };


    int main()
    {
        complex_t<float> x( 1.0, 2.0);
        complex_t<int> y( 3, 4);

        //printf("%f %d\n", x.real, y.image);    // Error
        printf("%f %d\n", x.get_real(), y.get_image());

        return 0;
    }

III-2. SystemC에 대한 다른 견해

SystemC의 구문을 보면 Verilog와 상당히 닮아있다. 특히 사건에 구동되어 순차구문을 실행하는 모듈 크래스의 소속함수로 지정한 방식은 베릴로그의 always @()와 일치한다. 그외 #define 매크로를 사용하여 C++의 구문을 숨기고 새로운 언어처럼 보이게 한 부분은 억지스럽다며 베릴로그를 써도 될 것을 굳이 어렵게 C++를 도입해야 할 필요성에 의문을 가진 견해도 있다. 참고 [8]을 읽어보기 바란다. SystemC의 구성과 크래스 사용법등을 설명하면서 그 필요성에 대한 다른 견해를 표하고 있다.


IV. 맺음말

이 강좌 글을 읽는 독자는 "내 칩 MPW"에 지원하려고 반도체 설계를 배우기로 했을 것이다. 기왕 설계 방법을 익히려고 했다면 그동안 쌓아온 지식을 모두 활용해보자. 논리회로와 C 언어(C++의 경험이 있다면 큰 도움이 되겠지만)에서 시작해 보자. 만일 새로운 도구가 생소하다면 알고있는 지식을 동원하고 논리적 사고로 이해하도록 노력해보자.

반도체 설계 도구와 프로그래밍 언어는 긴 역사를 가지고 수많은 요구에 맞춰 발달해 왔다. 그런만큼 그 내용은 복잡하고 개념들은 매우 추상적이다. 이제 막 시작하는 입문자에게 방대한 개념들을 이해하기를 요구하는 것은 무리다. 다행히 도구들의 사용수준은 매우 넓다. 초보자도 기본 개념만 이해하면 충분히 활용할 수 있다. 높은 수준의 사용법은 생산성 향상을 위한 기법일 뿐이지 최종 목표의 수준을 뜻하는 것은 아니다. 종종 목적을 잊고 수단에 집착하는 경우를 본다. 컴퓨팅 언어는 디지털 반도체를 얻기 위한 수단에 불과하다.

이번 강좌는 베릴로그 HDL과 SystemC/C++를 사용한 설계 방법론에 따라 반도체 설계를 시작하기 위한 필요 최소한 수준을 제시하였다. 앞으로 연습을 통해 실전으로 설계능력을 쌓도록 하겠다. 도구 사용이 서툴다고 "반도체 설계"라는 목표를 져버리지 않길 바란다.

주] 아래 참고목록 중 Verilog[4], SystemC[3] 그리고 C++[5]의 간단 참조 문서를 인쇄하여 연습시 지참 할 것.

-----------------------------------------------------------------------

[1] Hardware Verification Language, https://en.wikipedia.org/wiki/Hardware_verification_language
[2] e Verification Language, https://en.wikipedia.org/wiki/E_(verification_language)
[3] SystemC Quick Reference card, http://www.eis.cs.tu-bs.de/klingauf/systemc/systemc_quickreference.pdf
[4] Verilog Quick Reference, https://web.stanford.edu/class/ee183/handouts_win2003/VerilogQuickRef.pdf
[5] C++ Quick Reference, https://www.hoomanb.com/cs/quickref/CppQuickRef.pdf
[6] SystemC를 이용한 시스템 설계, http://acornpub.co.kr/book/systemc
[7] SystemC와 기본 형식, https://gtrfx.github.io/2020/02/16/systemc-basics.html










2024년 7월 28일 일요일

"Verilog-Verilator-SystemC 방법론 기초" [1] 오픈-소스 도구 Verilator 와 SystemC 설치

"Verilog-Verilator-SystemC 방법론 기초"
[1] 오픈-소스 도구 Verilator 와 SystemC 설치

[알림] 아래 내용중 질문, 지적, 보강 등 어떤 사항도 환영 합니다.

"Verilog-Verilator-SystemC 방법론 기초"는 "내 칩(My Chip) MPW 서비스": 오픈-소스 도구 활용 반도체 설계 특별과정 중 두번째 강좌로서 베릴로그(Verilog)와 오픈-소스 시뮬레이션 도구 Verilator 그리고 시스템 수준 검증 방법론 SystemC의 입문 과정이다. 컴퓨팅 언어를 활용한 디지털 회로의 설계와 검증을 다룬다(Quantative approach to digital circuit design using computing language and Open-Source EDA tools).

강의 내용은 아래와 같다.

[1] 도구 설치 [링크]
[2] 설계 언어 Verilog 와 검증 언어 SystemC/C++[링크]
[3] 하드웨어 기술 언어의 코딩 스타일[링크]
[4] 실습: 쉬프트 레지스터 [링크]
[5] 실습: FIR 필터 [링크]
[6] "내 칩 MPW" 요건에 맞춘 FIR 필터의 PE 설계[링크]

[부록] FIR 필터 PE의 "내 칩MPW" 제출용 GDS 생성[링크]


----------------------------------------------------------------------

목차

I. 시작하기 전에,

II. 하드웨어 설계 도구 설치
    II-1. 리눅스 설치
    II-2. ICARUS/iverilog 설치
    II-3. Verilator 설치
    II-4. SystemC 설치

III. 일러두기

------------------------------------------------------------------------

I. 시작하기 전에,

정보산업이 일상화 되었다. 덩달아 컴퓨터 다루기는 이미 상식이다. 그중 호기심이 발동한 이들은 코딩을 배운다. 심지어 초등학교 방과후 활동으로 코딩을 배운다니 컴퓨터 언어를 더이상 꺼내 설명하지는 않겠다. 컴퓨터는 반도체 부품의 집합체다. 코딩으로 반도체 집합체에게 일을 시킨다는 것은 이미 반도체를 설계하고 있었다는 점은 말해두어야 겠다.

이 글을 읽는 독자는 코딩의 수단인 C 언어와 디지털 논리 회로 정도는 이미 익혔다고 본다. 그리하여 "내 칩 MPW" 시비스를 통해 자신만의 반도체 부품을 설계하려는 의지를 가졌으리라. 그런 독자들을 위해 디지털 하드웨어를 설계하는 방법론 중 하나를 소개 하려고 한다. 여기에서 소개하는 방법은 여러 설계 방법론 중 하나일 뿐이라는 점을 밝혀둔다.

"내 칩 MPW" 서비스의 반도체 제조공장에서 다루는 전선의 굵기는 500 나노메터(0.0000005m)로 매우 가늘다. 사람은 운영만 할 뿐 반도체는 기계(컴퓨터)가 만든다. 기계가 수행할 일(반도체 제조)을 컴퓨터 언어로 코딩을 해주어야 한다. 그래서 채택한 언어가 Verilog(베릴로그)다.

디지털 논리회로(logic circuits)를 익혔고 C 언어의 맛을 봤다면 베릴로그는 어렵지 않다. 당장 나의 알고리즘을 디지털 반도체로 구현할 만큼만 배운다. Verilog라는 색다른 컴퓨팅 언어가 C 와 어느 면에서 다른지 그 차이를 알고 논리회로(조합회로, 순차회로 그리고 유한 상태 머신)의 행동을 표현하는 연습을 해본다. 그 이상은 학습자의 노력에 달렸다.

언어는 매우 추상적인 표현이 가능하다. 논리회로를 학습할 때 단위 객체의 비트 폭을 명확히 하고 순차회로의 행동을 클럭마다 묘사 했었다. 이를 레지스터 트랜스퍼 수준 RTL(Register-Transfer Level)이라고 한다. 베릴로그 언어는 논리회로의 RTL 설계를 할 수 있을 만큼 배운다. SystemC 로는 알고리즘과 시스템 수준의 테스트벤치 모델링을 배운다.

C/C++ 좀 한다는 사람도 그 언어를 속속 들이 알지 못한다. 쓰다가 아쉬우면 사전을 찾아보고 다른이의 예문을 보면서 언어의 실력이 느는 법이다. 언어 실력은 연습으로 길러진다.

II. 하드웨어 설계 도구 설치

베릴로그는 컴퓨터 용 언어의 하나다. 목표가 다를 뿐이다. C 언어는 컴퓨터가 할일을 표현하지만 베릴로그는 논리회로 제조장비가 할일을 기술한다. 무턱대고 제조장비에게 일을 시켜서 잘못되면 큰 손해가 나므로 미리 시험을 해본다. 검증을 위한 시뮬레이션이다. 원하는 대로 만들어 질 것인지 가상으로 확인해보는 절차다.

원시 코드(source code)는 사람이 읽고 쓸수 있는 문서다. 컴파일러는 C 언어로 작성된 원시 문서를 컴퓨터의 2진 코드(binary code)로 바꿔주는 소프트웨어(자동화 도구)다. 시뮬레이터는 베릴로그로 작성된 원시 문서를 컴퓨터의 코드로 바꿔 주고 마치 하드웨어가 만들어진 것처럼 작동 시켜주는 소프트웨어다. 논리회로를 배우면서 작동하는 모습을 파형으로 나타냈었다. 시뮬레이터는 베릴로그로 기술된 하드웨어를 2진 코드로 바꿔놓고 작동 시켜 디지털 회로의 결과를 보여준다.

몇년전 까지만 해도 C 컴파일러는 큰돈을 들여 구입해야 했지만 지금은 자유 소프트웨어 운동 덕에 표준이나 다름없는 GNU의 C/C++ 컴파일러가 무료다. 베릴로그 시뮬레이터는 여전히 고가다. 다행히 하드웨어 설계용 도구에도 오픈-소스 운동에 힘입어 신뢰도 있는 시뮬레이터가 등장했다. 본 강좌는 상용 도구는 피하고 오픈-소스 베릴로그 시뮬레이터로 ICARUS와 Verilator를 사용한다.

II-1. 리눅스 설치

개발의 과정은 워낙 변수가 많고 이에 따라 도구(컴파일러)에 주는 옵션이 매우 다양하기 때문에 Make를 포함한 스크립트 기반의 명령줄 환경에서 이뤄진다. 전자회로 설계에서 그림 기반의 도구를 사용하는 모습을 자주 보게 되지만 취급할 수 있는 한계가 있다. 자동화에 이르면 그림 화면은 입출력 데이터의 시각화(data visualization)와 진행을 감시(process monitoring)할 참고일 뿐이다. 반도체 설계에 컴퓨팅 언어를 채택한 이상 명령줄 사용은 피할 수 없다. 반도체 설계 강좌의 개발환경은 리눅스 운영체제의 명령줄과 스크립트를 활용한다.

윈도우즈 운영체제 하에 리눅스 운영체제와 관련도구의 설치 방법은 "VLSI 레이아웃 설계 기초" 강좌의 "[1] 리눅스 및 VLSI 레이아웃 오픈-소스 도구 설치"편을 참고한다.

    https://fun-teaching-goodkook.blogspot.com/2024/07/vlsi-magic.html


II-2. ICARUS/iverilog 설치

원작자 조차 시작된 연도를 모를 만큼 매우 역사가 깊은 오픈-소스 베릴로그 시뮬레이터다. 오랜 시간동안 꾸준한 갱신이 이뤄진 지금 매우 높은 신뢰를 얻고 있으며 원작자에 의해 여전히 관리되고 있다. PLI/VPI는 물론 SystemVerilog의 DPI 도 지원한다. Icarus Verilog 의 홈페이지는 아래와 같다.

    https://steveicarus.github.io/iverilog/

경희대학교 디자인 킷[1]에 설치 스크립트가 준비되어 있다.

    https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/Tools/iverilog_build.sh


II-3. Verilator 설치

Verilator는 엄밀히 말하면 시뮬레이터는 아니다. Verilog를 SystemC/C++의 쓰레딩 함수로 변환해 주는 도구다. 변환된 C++ 소스는 GCC/clang을 사용해 컴파일된 후 시뮬레이션 엔진과 링크하여 실행 가능 파일을 생성한다. Verilog 2005의 대부분 구문과 SystemVerilog 2017의 일부 기능을 지원한다. 단, 트라이 스테이트 MOS 게이트 프리미티브와 사용자 정의 테이블은 지원 하지 않는다. (합성 후 시뮬레이션 모델에 사용 불가) Veripools 의 홈 페이지 링크는 아래와 같다.

    https://www.veripool.org/verilator/

경희대학교 디자인 킷[1]에 설치 스크립트가 준비되어 있다.

    https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/Tools/verilator_build.sh


II-4. SystemC 설치

베릴로그는 하드웨어의 행동을 묘사하기 위한 언어다. 하드웨어를 제작하기 전에 컴퓨터에서 마치 하드웨어 인양 가상으로 작동 시켜본다. 어찌 되었든 소프트웨어다. 하드웨어가 작동 하려면 입력을 넣어주고 그 출력을 받아와야 한다. 입출력의 동작은 컴퓨터 상에서 이뤄 지므로 프로그래밍 언어의 지원을 받도록 한다. 프로그래밍 언어로 최상의 위치에 있는 C++를 하드웨어 언어와 맞물리도록 각종 크래스 라이브러리 묶음이 SystemC 다. 고도의 알고리즘 개발용 C++ 크래스와 템플릿 라이브러리로 STL(Standard Template Library)가 있듯이 SystemC는 하드웨어 모델링용 크래스와 템플릿 라이브러리다. SystemC 는 IEEE 1666으로 표준으로 등재되어 있다. SystemC 의 홈 페이지는 아래와 같다.

    https://systemc.org/
    https://accellera.org/

경희대학교 디자인 킷[1]에 설치 스크립트가 준비되어 있다.

    https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/Tools/systemc_build.sh

III. 일러두기

본 강좌의 Verilog-Verilator-SystemC 방법론은 여러 반도체 설계 방법론 중 하나다. 전통적인 상용 시뮬레이터를 채택한 방법과 다른 점이 많을 것이다. 저마다 장단점을 가지고 있으므로 방법론에 대해 우열을 다툴일은 아니다. 특히 SystemC 에 대해서는 다른 견해도 있다는 점을 밝혀둔다.

    https://gtrfx.github.io/2020/02/16/systemc-basics.html

본 강좌에서 채택한 방법론의 우월성을 강변하지는 않겠다. 이미 익숙한 방법론이 있다면 그를 따르기 바란다. 그럴 경우 이번 강좌는 지나쳐도 좋다. 단, 실습 과제는 다음 강좌에서도 적용 될 것이다. 예제 소스를 익숙한 설계 방법론에 적용 시켜보면 좋을 것이다.







2024년 7월 23일 화요일

"VLSI 레이아웃 설계 기초" [8] Std-Cell 제작 실습: DFF-SR

"VLSI 레이아웃 설계 기초"
[8] Std-Cell 제작 실습: DFF-SR

"VLSI 레이아웃 설계 기초"는 "내 칩(My Chip) MPW 서비스": 오픈-소스 도구 활용 반도체 설계 특별과정 중 첫번째 강좌다. 오픈 소스 도구의 기초적인 사용법과 레이아웃 설계와 검증을 정성적으로 다룬다(Quantative approach to VLSI layout design using Open-Source EDA tools).

강의 내용은 아래와 같다.

[1] 리눅스 및 VLSI 레이아웃 도구 설치 [링크]
[2] XSchem, CMOS 인버터 회로도 작성과 시뮬레이션 [링크]
[3] Magic, CMOS 인버터 레이아웃 작성과 회로추출 [링크]
[4] Netgen, 추출한 회로 비교(LVS) [링크]
[5] XSchem 실습: 인버터 회로도 (Schematic Design) [링크]
[6] Magic 실습: 인버터 레이아웃 (Layout Design) [링크]
[7] Netgen 실습: 네트리스트 비교 및 회로 시뮬레이션 [링크]
[8] Std-Cell 제작 실습: DFF-SR [링크]

-----------------------------------------------------------

목차

I. 표준 셀(Standard Cell) 개요

II. 표준 셀(Standard Cell) 그리기 규칙

III. 표준 셀 D-플립 플롭 기능

    III-1. D 플립 플롭의 기능 사양

    III-2. 회로도 작성

    III-3. 시뮬레이션

IV. 표준 셀 D-플립 플롭의 레이아웃

    IV-1. 표준 셀 INVX1

    IV-2. 표준 셀 NAND2X1

    IV-3. 계층적 D 플립-플롭 레이아웃

    IV-4. LVS

V. 표준 셀 D-플립 플롭 레이아웃 평가

-----------------------------------------------------------


I. 표준 셀(Standard Cell) 개요

표준 셀은 IC 설계에서 사용되는 반도체 설계 방법론(특히 디지털)의 일환이다. 모든 설계를 트랜지스터 수준에서 설계 하기에는 너무나 많은 수고가 든다. 이보다 한단계 높은 논리회로 수준에서 설계하는 경우 자동화 도구의 조력을 받을 수 있다. 기본적으로 논리회로는 식(logic expression)으로 표현할 수 있고 수학적으로 알고리즘을 동원하여 최적화 할 수 있다. 뿐만 아니라 배치와 배선의 자동화(Place & Route Automation)를 꾀할 수 있다.

배선(routing)은 부품의 내부 설계에는 간여하지 않고 오직 금속 층을 사용하여 부품사이의 기하학적 연결을 수행한다. 이때 사용될 부품은 자동 배선을 감안하여 크기와 핀의 간격과 같은 기준이 필요하다. 자동 배선 도구는 금속층을 활용하게 되는데 금속층의 두께(width)와 이격거리(separation) 그리고 비아(via)의 그리기 규칙(layout desifn rule)을 따른다.

II. 표준 셀(Standard Cell) 그리기 규칙

"내 칩(My Chip) MPW" 서비스[1]를 통해 제공하는 공정의 사용 가능한 금속층은 3개에 불과하며 금속의 두께와 비아의 크기 그리고 겹친 비아(stacked via) 금지등 제한 규정이 있다. 자동 배선 도구가 이 규정을 따라야 함은 물론이다. 자동화 배선 도구에서 사용 가능하도록 아래와 같이 셀 그리기 규칙을 수립하였다. 표준 셀 사이의 배선 자동화 규칙은 LEF(Library Exchange Format)[10]에 규정되어있다. 경희대학교 디자인 킷은 표준 셀과 자동 배치배선용 LEF를 제공한다[2].

[주] 표준 셀은 RTL 합성과 자동 배치 배선을 위한 것이다. 추상화 수준을 높일 목적이 아니라면 단지 레이아웃 만으로는 아무런 실용적 의미를 갖지 못한다. 경희대학교 디자인 킷[2]은 합성용 리버티(Liberty)와 합성후 네트 시뮬레이션용 베릴로그 모델 그리고 자동배선용 LEF 를 표준 셀과 함께 제공한다.

    Liberty*: https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/digital_ETRI050_m2d/khu_etri05_stdcells.lib
    Std-Cell Verilog Model: https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/digital_ETRI050_m2d/khu_etri05_stdcells.v
    LEF: https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK/blob/main/digital_ETRI050_m2d/etri050_stdcells.lef

[*] 표준셀의 타이밍 자료는 무효다.


1. 금속 층의 활용

금속1 층(metal 1 layer)은 단위 셀 내의 지역 배선(cell internal route)에 사용한다. 자동 배선에서 금속1 층의 사용은 수평 배선에 사용할 수 있으나 극히 제한적이다. 안테나 룰에 민감하다. 금속 2와 3층(metal 1 and metal 3 layer)은 셀 사이의 전역 배선(inter-cell global route)에 활용한다. 금속 2층은 수직(horizontal route), 금속 3층은 수평 배선(vertical route)에 사용한다.

2. 금속 배선의 간격(Pitch or Tracks)

레이아웃 그리기 규칙의 배선용 금속 2와 3층의 두께, 비아의 크기를 감안하여 배선이 지날 경로(track)의 간격은 수평과 수직 공히 3um 로 한다.


3. 표준 셀의 높이

셀의 높이는 자동 배선 도구의 성능에 영향을 받지만 이를 일률적으로 장담하기는 어렵다. 셀을 조밀하게 그릴 경우 배선에 실패할 수 있고 넓게 그릴 경우 유휴공간이 늘어난다. 일반적으로 표준셀은 9 또는 12 트랙(Track)이지만 경희대학교 디자인 킷[2]의 표준 셀은 몇가지 베릴로그 설계를 활용하여 자동 배치와 배선을 시도한 끝에 셀의 높이는 13개 트랙이 지나는 것으로 확정했다.

4. 트랜지스터의 채널 크기

트랜지스터의 채널 크기는 최소 권장 보다 큰 폭 3um, 길이 0.6um 로 하였다. 

아래 그림은 실제 배선이 이뤄진 레이아웃의 일부 모습이다. 굵은 사각형은 표준 셀 중 복잡도가 높은 D 플립-플롭 이다. 셀 내부의 지역 배선에서 금속 1층(파란색)이 사용 되었고 그 위로 금속 2(보라색)의 수직 배선, 최상층 금속3(분홍색) 배선이 트랙을 따라 지나고 있다. 큰 정사각형 분홍색은 수직과 수평 배선 사이의 비아2(via2), 보라색 정사각형은 금속1과 2 사이의 비아1(via1)이다.

비아1은 셀의 포트를 전역 배선으로 연결한다. 셀 내부의 배선은 가급적 금속1 만을 사용하지만 피치못할 경우 금속 2를 최소한으로 사용한다. 이때 셀의 포트가 자동 배선에 막히지 않도록 수직 배선으로 만 사용하는 것을 원칙으로 한다.

표준 셀 그리기 규칙을 적용한 D 플립-플롭 표준 셀의 모습은 아래와 같다. 폴리 실리콘 컨택과 디퓨젼 컨택은 비교적 자유롭지만 비아1(via1)은 자동 배선 도구와 보조를 맞춰야 하므로 반드시 트랙 선상에 놓도록 한다.

많은 금속층을 가진 공정의 경우 전역 배선을 할 수 있는 여유가 많고 대부분 겹친 비아를 허용하므로 표준 셀을 조밀하게 그릴 수 있다. 5개 금속층을 가진 SkyWater130[3]의 D-FF(dffbbn1)의 내부 모습은 아래와 같다. 셀 내부가 매우 조밀하게 구성된 것을 알 수 있다.

경희대학교 디자인 킷[2]의 LEF에 규정된 배선 규칙은 다음과 같다. 금속 층의 배선 방법과 비아 뚫기 규칙을 정의한다.

    UNITS
      DATABASE MICRONS    1000 ;
    END UNITS

    USEMINSPACING    OBS ON ;
    USEMINSPACING    PIN OFF ;
    CLEARANCEMEASURE EUCLIDEAN ;

    MANUFACTURINGGRID    0.15 ;

    LAYER nwell
      TYPE    MASTERSLICE ;
    END nwell

    LAYER nactive
      TYPE    MASTERSLICE ;
    END nactive

    LAYER pactive
      TYPE    MASTERSLICE ;
    END pactive

    LAYER poly
      TYPE    MASTERSLICE ;
    END poly

    LAYER cc
      TYPE    CUT ;
      SPACING 0.9 ;
    END cc

    LAYER metal1
      TYPE          ROUTING ;
      DIRECTION     HORIZONTAL ;
      PITCH         3.0 ;
      OFFSET        1.5 ;
      WIDTH         0.9 ;   # ETRI050 Rule: WIDTH=0.8
      SPACING       1.05 ;  # ETRI050 Rule: SPACING=1.0
      RESISTANCE    RPERSQ 0.09 ;
      CAPACITANCE    CPERSQDIST 3.2e-05 ;
    END metal1

    LAYER via1
      TYPE       CUT ;
      SPACING    0.9 ;
    END via1

    LAYER metal2
      TYPE         ROUTING ;
      DIRECTION    VERTICAL ;
      PITCH        3.0 ;
      OFFSET       1.5 ;
      WIDTH        1.05 ;  # ETRI050 Rule: WIDTH=1.0
      SPACING      1.05 ;  # ETRI050 Rule: SPACING=1.0
      RESISTANCE   RPERSQ 0.09 ;
      CAPACITANCE  CPERSQDIST 1.6e-05 ;
    END metal2

    LAYER via2
      TYPE        CUT ;
      SPACING     0.9 ;
    END via2

    LAYER metal3
      TYPE         ROUTING ;
      DIRECTION    HORIZONTAL ;
      PITCH        3.0 ;
      OFFSET       1.5 ;
      WIDTH        1.2 ;   # ETRI050 Rule: WIDTH=1.2
      SPACING      1.05 ;  # ETRI050 Rule: SPACING=1.0
      RESISTANCE   RPERSQ 0.05 ;
      CAPACITANCE  CPERSQDIST 1e-05 ;
    END metal3

    VIA M2_M1 DEFAULT
      LAYER metal1 ;
        RECT -1.050 -1.050 1.050 1.050 ;
      LAYER via1 ;
        RECT -0.450 -0.450 0.450 0.450 ;
      LAYER metal2 ;
        RECT -1.050 -1.050 1.050 1.050 ;
    END M2_M1

    VIA M3_M2 DEFAULT
      LAYER metal2 ;
        RECT -1.050 -1.050 1.050 1.050 ;
      LAYER via2 ;
        RECT -0.450 -0.450 0.450 0.450 ;
      LAYER metal3 ;
        RECT -1.050 -1.050 1.050 1.050 ;
    END M3_M2

III. 표준 셀 D-플립 플롭 기능

플립 플롭은 디지털 정보의 저장소로서 순차회로의 핵심이다[4]. 표준 논리회로를 활용하여 D 플립플롭을 설계한다.

III-1. D 플립 플롭의 기능 사양

비동기 셋(async. set)과 리셋(async. re-set)을 가진 상승 엣지 트리거(positive-edge trigger) D-형 플립-플롭을 표준 셀로 작성 한다. 잘알려진 TTL 7474의 CMOS 버젼 74HCT74의 내부 회로구성을 차용하여 기능 사양(functional specification)으로 삼았다. 기능도는 아래와 같다.


[그림출처] D-Type Positive-Edge-Triggered Flip-Flops With Clear and Preset[5]

III-2. 회로도 작성(D-FF Schematic)

XSchem으로 기능 사양서에 따라 회로도를 아래와 같이 작성한다. 이번 실습은 회로도와 레이아웃 폴더를 분리하였다. 실습 디렉토리 구조는 아래와 같다.

회로도 작업 폴더로 이동한 후 XSchem 실행.

    $ cd ~
    $ cd ~/Tutorials/1-4_StdCell_DFFSR/Sch
    $ xschem

하위 회로로 NAND2X1과 INVX1를 별도로 작성하여 계층적 회로로 작성 하였다. 트랜지스터의 폭과 길이는 미리 만들어 둔 표준 셀과 동일하게 주었다.

플립-플롭에서 전자정보는 NAND 게이트의 궤환(feed-back)에 의해 유보된다. 이 궤환의 경로에 외부 영향을 배제 하기 위해 D 입력에 반전 버퍼(inverter)를 달았다. 아울러 출력의 궤환작용이 외부에 영향을 주지 않도록 역시 반전 버퍼가 있다. 입력과 출력에 모두 반전 버퍼를 달고 있지만 전역 신호 리셋 R (/CLEAR)과 셋 S (/PRE)은 반전을 상쇄하기 위해 맞바꿨다.

III-3. 시뮬레이션

트랜시언트 시뮬레이션(transient simulation) 결과는 아래와 같다. 비동기 R(/CLR)과 S(/PRE)의 동작과 클럭의 상승 엣지에 동기된 정보보유(latch)의 동작을 확인 하였다.


IV. 표준 셀 D-플립 플롭의 레이아웃

기능이 검증된 D 플립-플롭의 회로도를 사양으로 레이아웃을 그려보자. 회로도에 NAND 와 INV 게이트 그리고 스위치용 p/n-mos 쌍이 사용되었다. 레이아웃 에서도 이에 대응하는 표준 셀을 준비한다.

IV-1. 표준 셀 INVX1

INVX1는 구동력(driving power)이 1인 인버터(inverter)다. n-mos의 채널(전자 이동한다)과 p-mos의 채널(홀이 이동한다)은 전하 이동도(mobility)가 2배 차이가 나는 것이 실험적으로 알려져 있다[6]. 이동도가 서로다른 채널을 상보적(complementary)으로 사용하는 CMOS 에서 이를 해결하는 방법으로 p-mos 트랜지스터의 채널 폭을 두배로 늘린다. 집적도에서 손해보는 방법이지만 가장 수월하다.

 

트랜시언트 시뮬레이션(Transient Simulation)은 수평축이 시간이다. 입력에 대하여 DUT가 반응하는 시간을 평가한다.

전압 증가 시뮬레이션(V-Sweep Simulation)은 수평축이 전압이다. 입력 전압에 대하여 DUT의 최종 출력 전압을 평가한다.

앞의 실습에서 p와 n-mos의 채널 폭이 동일한 인버터의 입력 전압에 대한 출력의 반응(voltage sweep)과 비교해 보자. 반전 하강하는 출력 곡선이 매우 가파르다. n-mos가 빠르게 반응하기 때문이다.

트랜시언트 시뮬레이션으로 비교해 보면 두 인버터 출력의 상승 반전과 하강 반전되는 시간의 차이가 드러난다. 좌측 그래프는 p-mos와 n-mos의 채널 폭이 동일한 경우다. 우측 그래프는 p-mos 채널 폭이 n-mos 채널 폭의 2배인 경우다.

IV-2. 표준 셀 NAND2X1

표준 셀 NAND 게이트의 회로도와 레이아웃은 아래 그림과 같다.

 

NAND2X1의 트랜시언트 시뮬레이션 결과는 아래와 같다. 두 입력이 모두 p-mos를 켜는 경우 vdd와 출력의 작아져서 반응 시간이 빠르다.

 

직렬 연결된 두 n-mos가 켜지는 경우 채널 길이(저항)가 두배가 된다. 이를 보상하기 위해 채널 폭을 늘렸다. 두 p-mos는 병렬 연결이다. 둘 중 하나만 켜지는 경우는 직렬연결된 두 n-mos와 균형을 이루지만 모두 켜지는 경우 빠르게 동작한다. 이를 보상하기 위해 n-mos의 채널 폭을 두배로 늘였다. 표준 셀 INVX1, NAND2X1, NOR2X1, SWITCH2X1의 레이아웃을 비교해 보면 트랜지스터의 채널 폭을 달리하는 이유를 같은 논리로 설명할 수 있다.

   

IV-3. 계층적 D 플립-플롭 레이아웃

미리 구축해 놓은 논리 게이트들의 표준 셀 레이아웃을 활용하여 회로도와 동일한 D-플립 플롭을 그린다.

    cd ~
    $ cd ~/Tutorials/1-4_StdCell_DFFSR/Layout
    $ magic -d XR DFFSR74

표준 게이트를 하위회로로 두고 있는 계층적 레이아웃이다. 레이아웃의 이름은 DFFSR74.mag 다.

회로도의 p와 n-mos 쌍의 스위치를 표준 셀로 만들어 하위회로로 활용 하였다.

IV-4. LVS

회로도와 레이아웃의 동일성 검증을 위해 LVS를 실시한다. Magic 레이아웃의 이름은 DFFSR74 이며 회로도의 D 플립-플롭의 이름은 DFFSR 이다. 회로도의 네트리스트는 시뮬레이션을 위해 미리 생성해둔 DFFSR_TB.spice 다. 이 네트리스트 내에 하위회로로 존재하는 DFFSR와 레이아웃에서 추출한 네트리스트의 하위회로 DFFSR74를 비교한다. LVS의 결과 보고서는 LVS_DFFSR74_DFFSR.txt 로 하였다.

    $ netgen -noc -batch lvs \

        "./DFFSR74.spice DFFSR74" \
        "../Sch/simulation/DFFSR_TB.spice DFFSR" \
        ./netgen_setup.tcl LVS_DFFSR74_DFFSR.txt

주] 설계는 도구의 반복 실행이다. 매번 명령줄에서 긴 명령을 입력하려면 피곤하다. 스크립트를 작성해 두도록 한다. 위의 LVS 실행 스크립트는 run_lvs.sh 다.

    $ ./run_lvs.sh DFFSR74 DFFSR

LVS 수행 후 결과는 두 회로의 네트리스트 불일치(mismatch)로 판명 되었다. 보고서를 열어 원인을 살펴보자. 처음 발견된 불일치는 NAND2X1의 핀 목록(pin list)에 불일치가 있다고 한다.

Netgen은 NAND2X1의 레이아웃과 회로도의 두 입력 순서가 바뀐 것을 찾아내 이를 불일치 판정했다. NAND 게이트의 논리를 따져보면 두 입력의 순서가 바뀌어도 동작과 무관 하다. 하지만 LVS는 매우 민감하다. 회로 전체를 살펴보고 '오류(error)', '경고(warning)', '통보(notice)' 등을 알려 줄 수 있으면 좋겠지만 Netgen은 그정도 지능(intelligence)은 가지고 있지 않다. 최근 상용 반도체 설계 도구에 인공지능(AI) 넣기가 한창이다. 오픈-소스 도구에도 이의 적용이 멀지 않았다.

이어서 두 네트리스트 사이에 하위회로 구성이 다르다는 점을 지적하고 있다. 회로도에 없는 SWITCH2X1이 레이아웃에 존재한다. Netgen은 하위회로 레이아웃을 상위회로로 평활화(flatten) 하여 등가성을 확인해 준다. 두 회로의 전체 구성(사용된 트랜지스터의 수, 네트의 수)은 일치하지만 네트이 연결에 불일치가 발견 되었다는 보고다.

레이아웃 DFFSR74 회로에서 네트 R이 두개의 NAND게이트 모두 B 포트에 연결되었으나 DFFSR의 회로도에서는 각각 B와 A 포트에 연결되어 있다. 네트 S의 경우 DFFSR74에서는 각각 A와 B에 연결되었지만 DFFSR 회로도는 모두 B 포트에 연결 되었다.

NAND 게이트는 A와 B 포트가 바뀌어도 기능상 등가이지만 LVS의 불일치를 바로 잡도록 하자. 레이아웃을 수정하기 보다 회로도를 수정하는 편이 수월하다. 회로도의 수정은 다음과 같다.

- 하위회로 NAND2X1의 A 와 B를 맞바꾼다.
- 네트 R이 X7의 B에, 네트 S는 X8의 A 에 연결 한다.

회로도 수정 후 LVS를 실시하여 두 네트리스트가 일치하는 결과를 얻었다.

회로도를 수정하였으므로 시뮬레이션을 다시 실시하여 반드시 검증해야함은 물론이다.

V. 표준 셀 D-플립 플롭 레이아웃 평가

설계에 사용될 부품을 규격화 해 놓음으로써 얻는 장점이 있다. 배치와 배선을 수행하는 자동화 도구에 의해 활용되려면 부품의 외형 규격화(standarized footprint)는 필수다. 배선 자동화 도구가 사용할 금속층의 규칙으로 금속2층은 수직배선, 금속 3층은 수평배선으로 규정했다고 하자. 전역 배선 규정은 LEF(Library Exchange Format)에 명시된다. 이 규정으로는 위에서 작성한 DFFSR74는 매우 부적절하다. 셀 내부에 유휴공간이 많고 수평배선으로 금속2가 다수 사용되었기 때문에 전역배선의 공간이 없다.

제대로 그린 표준 셀 DFFSR의 레이아웃은 아래와 같다. 약 32개 가량의 트랜지스터를 포함하는 레이아웃은 하위 셀을 불러오지 않고도 충분히 최적화된 셀을 그릴 수 있다.

표준 셀은 레이아웃 뿐만 아니라 자동 배치와 배선 도구를 위한 정보를 제공해햐 한다. 표준 셀의 크기와 배치시 상하 좌우 뒤집힘(flip)의 가능 여부, 핀(포트)의 금속층 좌표와 입출력 방향 그리고 금속 층별 배선을 금지하는 영역(obstruction)을 정의해 주어야 한다. 자동 배선도구는 셀 내부를 들여다 보지 않는다. 따라서 OBS 영역은 셀 내부에서 사용된 금속층의 영역을 표시하여 배선에 사용하지 못하도록 한다. 표준 셀 DFFSR의 LEF 매크로 정의는 아래와 같다.

    MACRO DFFSR
      CLASS CORE ;
      FOREIGN DFFSR ;
      ORIGIN 0.000 0.000 ;
      SIZE 69.000 BY 39.000 ;
      SYMMETRY X Y ;
      SITE core ;

      PIN D
        DIRECTION INPUT ;
        USE SIGNAL ;
        PORT
          LAYER metal2 ;
            RECT 27.900 14.850 29.100 17.100 ;
        END
      END D

      PIN S
        DIRECTION INPUT ;
        USE SIGNAL ;
        .......
      END S

      ......

      PIN Q
        DIRECTION OUTPUT ;
        USE SIGNAL ;
        PORT
          LAYER metal2 ;
            RECT 63.900 15.900 65.100 18.150 ;
        END
      END Q

      PIN vdd
        DIRECTION INOUT ;
        USE POWER ;
        SHAPE ABUTMENT ;
        PORT
          LAYER metal1 ;
            RECT -0.900 37.800 69.900 40.200 ;
        END
      END vdd

      PIN gnd
        DIRECTION INOUT ;
        USE GROUND ;
        SHAPE ABUTMENT ;
        PORT
          LAYER metal1 ;
            RECT -0.900 -1.200 69.900 1.200 ;
        END
      END gnd

      OBS
          LAYER metal1 ;
            RECT 1.200 30.900 3.000 37.500 ;
            RECT 4.200 31.800 6.000 36.900 ;
            ..........
            RECT 66.000 1.500 67.800 5.100 ;

          LAYER via1 ;
            RECT 30.900 27.300 33.000 29.400 ;
            RECT 36.300 28.800 38.400 30.900 ;
            .........

          LAYER metal2 ;
            RECT 15.900 31.800 18.900 33.900 ;
            RECT 19.800 31.800 21.900 33.900 ;
            .........
      END

    END DFFSR

오픈-소스 Magic 도구는 레이아웃으로부터 표준 셀의 라이브러리 정보를 추출해준다. 경희대학교 디자인 킷[2]은 레이아웃에서 LEF 정보의 추출과 통합 수정될 경우 두 레이아웃 사이의 네트리스트 비교(LVL, Layout-vs-Layout)등 일련의 표준 셀 구축용 스크립트를 제공한다. 자신만의 최적화된 표준 셀 라이브러리를 구축해 보자.


-------------------------------------------------------------------------------

[1] KION My Chip MPW, http://mpw.kion.or.kr/
[2] 경희대학교 디자인 킷, https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK
[3] SkyWater130 Process, https://skywater-pdk.readthedocs.io/en/main/rules/assumptions.html
[4] 플립-플롭, https://ko.wikipedia.org/wiki/%ED%94%8C%EB%A6%BD%ED%94%8C%EB%A1%AD
[5] Flip-Flop, https://en.wikipedia.org/wiki/Flip-flop_(electronics)
[6] CDx4HCT74 Dual D-Type Positive-Edge-Triggered Flip-Flops With Clear and Preset, https://www.ti.com/lit/gpn/CD74HCT74
[7] 장효과 트랜지스터, https://ko.wikipedia.org/wiki/%EC%9E%A5%ED%9A%A8%EA%B3%BC_%ED%8A%B8%EB%9E%9C%EC%A7%80%EC%8A%A4%ED%84%B0
[8] Field Effetc Transistor, https://en.wikipedia.org/wiki/Field-effect_transistor
[9] Predicting CMOS Speed with Gate Oxide and Voltage Scaling and Interconnect Loading Effects, https://www.researchgate.net/publication/3063052_Predicting_CMOS_speed_with_gate_oxide_and_voltage_scaling_and_interconnect_loading_effects
[10] LEF/DEF Reference Manual, https://www.ispd.cc/contests/18/lefdefref.pdf



2024년 7월 21일 일요일

"VLSI 레이아웃 설계 기초" [7] Netgen 실습: 네트리스트 비교(LVS) 및 시뮬레이션

"VLSI 레이아웃 설계 기초"
[7] Netgen 실습: 네트리스트 비교(LVS) 및 시뮬레이션

"VLSI 레이아웃 설계 기초"는 "내 칩(My Chip) MPW 서비스": 오픈-소스 도구 활용 반도체 설계 특별과정 중 첫번째 강좌다. 오픈 소스 도구의 기초적인 사용법과 레이아웃 설계와 검증을 정성적으로 다룬다(Quantative approach to VLSI layout design using Open-Source EDA tools).

강의 내용은 아래와 같다.

[1] 리눅스 및 VLSI 레이아웃 도구 설치 [링크]
[2] XSchem, CMOS 인버터 회로도 작성과 시뮬레이션 [링크]
[3] Magic, CMOS 인버터 레이아웃 작성과 회로추출 [링크]
[4] Netgen, 추출한 회로 비교(LVS) [링크]
[5] XSchem 실습: 인버터 회로도 (Schematic Design) [링크]
[6] Magic 실습: 인버터 레이아웃 (Layout Design) [링크]
[7] Netgen 실습: 네트리스트 비교 및 회로 시뮬레이션 [링크]
[8] 표준 셀 제작 실습: D-Flip Flop [링크]

-----------------------------------------------------------

목차

I. 개요

II. LVS, 네트리스트 비교

    II-1. 작업 폴더

    II-2. 계층적 회로도

    II-3. 계층적 레이아웃

    II-4. 스크립트 사용

    II-5. LVS 실행


III. 시뮬레이션

    III-1. 시뮬레이션용 네트리스트

    III-2. 테스트 벤치

    III-3. 시뮬레이션 결과

-------------------------------------------------------------------


I. 개요

이번 실습편은 상이한 추상화 수준 또는 방법론이 다른 두 설계물을 등가성을 검증한다. 동일한 기능을 상이한 방법으로 설계하는 가장 큰 이유는 생산성 때문이다. 설계는 목표한 사양에 이르기까지 입력과 검증 그리고 수정의 반복이다. 검증을 위한 시뮬레이션은 자동화 되어 있지만 입력과 수정은 인간의 지적 능력에 달렸다. 인간이 다루기 수월한 형식을 취하기 위해 상위 추상화 수준에서 설계하고 검증을 마친 후 하위 수준으로 이전하므로서 생산성을 높인다.

Y 차트는 설계 방법론과 추상화 수준을 잘 설명하고 있다. 그림에서 설계방법을 3가지 영역(domain)으로 나누고 있으며 추상화 수준을 낮춰(refinement) 최종 목표인 설계 도면을 얻는과정을 표현한다.

Y 차트의 중심으로 향하는 과정에서 자동화 도구(EDA Tools)의 조력을 받는다. 영역 사이를 오가면서 사용하는 자동화 도구는 설계 생산성 향상에 큰 기여를 한다.

"VLSI 레이아웃 설계 기초" 과정은 낮은 추상화 수준(회로 수준)에서 두영역을 오가며 최종 레이아웃 얻는 반도체 설계 방법을 다루고 있다.

트랜지스터 회로도(schematic)와 레이아웃(layout) 설계를 Y-차트의 추상화 수준에서 보면 비슷한 수준 "Circuit Level" 이나 방법론은 매우 다르다.

비슷한 추상화 수준이라도 방법론을 달리하는 이유는 역시 생산성 향상을 얻기 위함이다. 추상화 수준은 물론 설계 방법의 전환이 있게 되면 반드시 검증의 절차를 따라야 한다. 회로를 표현하는 방법이 달라도 기능적으로 동일성이 확인 되어야 한다.

LVS(Layout versus Schematic)은 트랜지스터 수준에서 두 회로의 등가성을 확인한다. 다른 방식으로 표현된 회로를 각각 공통의 SPICE 네트리스트로 추출 하여 비교한다. 비교될 항목은 보다 높은 추상화 수준의 회로를 따른다. 회로도 보다 실제 가까운 레이아웃에서 추출된 기생 C 값은 비교 항목에서 제외 된다. 기능적으로 동일한 두 회로의 물리적(시간적) 차이와 특성 파악은 시뮬레이션을 통해 이뤄진다.

II. LVS, 네트리스트 비교

오픈-소스 도구 Netgen 은 SPICE 네트리스트 비교한다. 회로의 연결관계 뿐만 아니라 회로요소의 세부 파라메터 까지 비교해준다. 트랜지스터의 경우 기하학적 모습(채널의 폭과 길이)를 포함한다.

II-1. 작업 폴더

작업 디렉토리로 이동,

    $ cd
    $ mkdir Tutorials/1-3_Inverter_Netgen
    $ cd Tutorials/1-3_Inverter_Netgen

Magic 의 환경 설정 파일 복사,

    $ cp ~/ETRI050_DesignKit/tech/etri050.magicrc .magicrc

Netgen의 환경설정 파일 복사,

    $ cp ~/ETRI050_DesignKit/tech/etri050_setup.tcl netgen_setup.tcl

실습 디렉토리 구조:

II-2. 계층적 회로도

XSchem은 계층적 회로도를 작성할 수 있다. 앞선 실습에서 만들어둔 인버터를 하위회로로 4개를 잇달아 연결한 버퍼 회로를 작성한다.

생성된 네트리스트를 보면 하위회로 inverter 4개가 연속으로 이어진 회로로 기술되었다. SPICE 의 .subckt 는 하위회로를 정의하는 명령이다.

    ** sch_path: /home/goodkook/ETRI050_DesignKit/Tutorials/1-3_Inverter_Netgen/buffer.sch
    **.subckt buffer A Y VDD GND
    *.ipin A
    *.opin Y
    *.iopin VDD
    *.iopin GND
    X6 A net1 VDD GND inverter
    X1 net1 net2 VDD GND inverter
    X5 net2 net3 VDD GND inverter
    X2 net3 Y VDD GND inverter
    **.ends

    * expanding   symbol:  ~/Tutorials/1-1_Inverter_XSchem/inverter.sym # of pins=4
    ** sym_path: ~/Tutorials/1-1_Inverter_XSchem/inverter.sym
    ** sch_path: ~/Tutorials/1-1_Inverter_XSchem/inverter.sch
    .subckt inverter A Y VDD GND
    *.ipin A
    *.opin Y
    *.iopin VDD
    *.iopin GND
    M2 Y A VDD VDD pfet w=2.0u l=0.6u m=1
    M1 Y A GND GND nfet w=2.0u l=0.6u m=1
    .ends

    .end

상위 회로에 .subckt 를 붙이지 않고 있는 점에 유의하자. 정의한 하위회로를 실제로 존재하게 해야(사례화, instantiate) 비로서 회로가 꾸며진다.

II-3. 계층적 레이아웃

Magic은 계층적 레이아웃 설계를 지원한다. 앞서 제작해둔 인버터 레이아웃을 하위 셀(sub-cell)로 불러올 수 있다. 현재 위치의 환경 파일 .magicrc에 하위 셀이 저장된 경로를 추가해 준다. 상대 경로도 가능하다.

    addpath ../1-2_Inverter_Magic

Magic의 명령창에서 앞서 제작해둔 인버터 inverter_x1 을 불러온 후 이를 복사하여 버퍼를 만들고 buffer_x1으로 저장한다.

하위 셀들을 불러오는 명령은 getcell 이다.

    getcell inverter_x1

불러온 하위 셀을 복사하여 배치한 후 metal1 레이어를 이용하여 배선한다. 배선이 완료되면 상위 셀에서 입출력 포트를 붙여 주도록 한다. 상위 설계에서 하위 셀의 내부를 보여주는 명령은 expand (단축키 x) 다. 반대는 unexpand (단축키 'X')다.

II-4. 스크립트 사용

레이아웃에서 네트리스트의 생성은 용도에 따라 차이가 있다. 앞의 실습에서는 회로 시뮬레이션을 위한 용도로 배선으로 인한 기생 커페시턴스까지 추출 하였다. 이를 기생 커페시턴스는 없는 상위 수준의 회로도에서 추출한 네트리스트와 비교할 경우 회로 불일치 오류를 발생한다.

한 레이아웃에서 용도에 따라 다른 네트리스트를 생성하기 위해 편집(수정과 삭제)기능이 있는 도구를 매번 실행 시키면 자칫 실수가 끼어들 수 있다. 특히 단축키들의 사용이 광범위한 그래픽 기반의 편집 도구들은 실수로 인한 설계물의 변경 위험이 너무크다. 이런 위험을 배제하기 위해 스크립트들이 적극 활용되고 있다.

Magic 역시 그래픽 도구를 띄우지 않고 명령줄 실행이 가능하다. Tcl 명령 프롬프트 % 에 레이아웃 파일을 불러들여 네트리스트로 추출하는 명령을 줄 수 있다.

    $ magic -dnull -noconsole

    %

리눅스의 쉘 스크립트는 간이형 프로그래밍 언어로서 손색이 없다. 파일의 형식변환, 네트리스트 생성과 같은 일련의 작업이 필요한 경우 쉘 스크립트로 작성해 두면 매우 유용하다. Magic 레이아웃에서 시뮬레이션용 네트리스트를 생성하는 배쉬-쉘 스크립트를 아래와 같이 작성해 놓으면 매우 유용하게 쓸 수 있다.

    #!/usr/bin/bash
    ### filename: extract_spice_sim.sh

    if [ -f ".magicrc" ] ; then
        echo "Magic rc found"
    else
        echo "Magic rc NOT found"
        exit 2
    fi

    if [[ $# -ne 1 ]]; then
        echo "usage: extract <Magic Layout>"
        echo "      Extract spice netlist for simulation"
        exit 2
    fi

    magic -dnull -noconsole << EOF
    drc off
    box 0 0 0 0
    load $1 -force
    drc off
    extract all
    ext2spice default
    ext2spice format ngspice
    ext2spice scale off
    ext2spice subcircuit on
    ext2spice hierarchy on
    ext2spice
    quit -force
    EOF

파이썬(Python) 스크립트는 완전한 프로그래밍 언어로서 설계 자동화 도구에 널리 사용된다.

II-5. LVS 실행

Netgen으로 XSchem 회로도에서 생성한 네트리스트와 Magic 레이아웃에서 생성한 네트리스트를 비교하는 명령은 다음과 같다.

    % netgen -batch lvs \
            "./simulation/buffer_top.spice buffer" \
            "buffer_x1.spice buffer_x1"\
            ./netgen_setup.tcl comp.out


두 SPICE 네트리스트 내에 비교할 하위 회로를 지정하고 있다. 실행은 매우 단순하지만 입력해야 할 명령줄이 너무 길다. LVS 를 수행하는 스크립트를 파이썬으로 작성하면 아래와 같다.

    #!/usr/bin/env python3
    ### filename: run_lvs.py

    import os, sys

    if len(sys.argv) != 3:
        print('lvs: Specify two netlist folder and '
                 'filename to compare.')
        sys.exit(1);

        os.system('netgen -batch lvs \
                        "{}.spice {}"  \
                        "./simulation/{}_top.spice {}" \
                         ./netgen_setup.tcl comp.out' \
                         .format( sys.argv[1], sys.argv[1],  \
                         sys.argv[2], sys.argv[2]))

    sys.exit(0)

명령줄의 첫번째 인수로 Magic에서 생성한 네트리스트, 두번째 인수는 XSchem에서 생성한 네트리스트다. 각 네트리스트가 생성된 경로에 유의한다. 위의 파이썬 스크립트를 실행하여 LVS를 실시한다.

    $ ./run_lvs.py buffer_x1 buffer

두 네트리스트의 비교 결과 불일치의 보고를 받을 경우 결과 보고 파일 comp.out 을 살펴보자.

Flattening unmatched subcell inverter in circuit
    ./simulation/buffer.spice (0)(4 instances)

Subcircuit summary:

Circuit 1: ./simulation/buffer.spice |Circuit 2: buffer_x1.spice
-------------------------------------|-----------------------------
pfet (4)                             |pfet (4)
nfet (4)                             |nfet (4)
(no matching element)                |c (5)
Number of devices: 8 **Mismatch**    |Number of devices: 13
Number of nets: 7                    |Number of nets: 7
-------------------------------------------------------------------

NET mismatches: Class fragments follow (with fanout counts):

불일치의 원인은 XSchem 회로도에서 추출한 네트리스트에 없던 커페시터(c) 5개가 Magic 레이아웃 네트리스트에 포함되었기 때문이다.

레이아웃 네트리스트를 추출할 때 기생 C 가 없는 LVS 용으로 추출하는 스크립트는 아래와 같이 작성한다.

    #!/usr/bin/bash
    ### filename: extract_spice_lvs.sh

    if [ -f ".magicrc" ] ; then
        echo "Magic rc found"
    else
        echo "Magic rc NOT found"
        exit 2
    fi

    if [[ $# -ne 1 ]]; then
        echo "usage: extract <Magic Layout>"
        echo "      Extract spice netlist for simulation"
        exit 2
    fi

    magic -dnull -noconsole << EOF
    drc off
    box 0 0 0 0
    load $1 -force
    drc off
    extract all
    ext2spice default
    ext2spice format ngspice
    ext2spice cthresh infinite
    ext2spice rthresh infinite
    ext2spice scale off
    ext2spice subcircuit on
    ext2spice hierarchy on
    ext2spice
    quit -force
    EOF

시뮬레이션용 네트리스트 추출 스크립트와 다른 점은 기생 C 와 R 의 추출 한계치 cthresh와 rthresh 를 무한대 infinite 로 놓고 있다. LVS용 스크립트를 이용하여 생성한 네트리스트를 가지고 비교를 수행한다.

    $ ./extract_spice_lvs.sh buffer_x1

    $ ./run_lvs.py buffer_x1 buffer

    Contents of circuit 1:  Circuit: './simulation/buffer.spice'
    Circuit ./simulation/buffer.spice contains 8 device instances.
      Class: pfet                  instances:   4
      Class: nfet                  instances:   4
    Circuit contains 7 nets.
    Contents of circuit 2:  Circuit: 'buffer_x1.spice'
    Circuit buffer_x1.spice contains 8 device instances.
      Class: pfet                  instances:   4
      Class: nfet                  instances:   4
    Circuit contains 7 nets.
    Circuit 1 contains 8 devices, Circuit 2 contains 8 devices.
    Circuit 1 contains 7 nets,    Circuit 2 contains 7 nets.
    Final result:
    Circuits match uniquely.
    Logging to file "comp.out" disabled
    LVS Done.

두 회로가 일치한다는 보고를 얻는다.

III. 시뮬레이션

방법론은 물론 추상화 수준이 전환되면 두 설계물의 등가성 확인은 필수 사항이다. 이와 더블어 전환 전후의 회로의 물리적인 변화는 시뮬레이션을 통해 확인 되어야 한다. 전환 전의 시뮬레이션을 Pre-Simulation, 전환된 후의 시뮬레이션을 Post-Simulation 이라 한다. 실물에 가까울 수록 시간 지연을 예상 할 수 있다.

III-1. 시뮬레이션용 네트리스트

레이아웃은 실물에 가깝다. 트랜지스터의 채널은 물론 드레인과 소스 기하학적 모양과 배선으로 인한 기생 성분이 추가된다. 미리 작성해둔 스크립트를 이용하여 레이아웃으로부터 시뮬레이션용 네트리스트를 추출한다.

    $ ./extract_spice_sim.sh buffer_x1

III-2. 테스트 벤치

XSchem을 활용하여 SPICE 시뮬레이션용 테스트 벤치를 작성한다. 회로도와 레이아웃의 심볼을 만든 후 테스트벤치에 사례화 하였다. 두 회로는 기능적으로 동일 하므로 입력에 대한 전압 변화의 관찰(voltage sweep)은 의미없다. 트랜지스터의 기하학적 모양과 배선으로 인한 기생 성분을 반영한 경우 지연을 예상 할 수 있다. 시간축상의 출력 변화를 살펴보기로 한다. 이를 통과시간(transient) 시뮬레이션이라고 한다. 테스트벤치는 아래와 같다.

입력으로 시간상 변화하는 전압을 pulse()로 표현하였다. SPICE는 pulse외에 수학 함수를 포함하여 다양한 방식으로 전압원을 생성할 수 있다[1].

시뮬레이션 명령은 .tran 이다.

    .tran 0.01n 50n

50 나노초까지 시뮬레이션을 진행하며 관찰 간격은 0.01나노초다.

III-3. 시뮬레이션 결과

테스트벤치에 두 설계물을 각각 사례화 한 후 시뮬레이션을 수행하였다. 전류 소모의 비교를 위해 전원 공급원을 따로 두었다. 시뮬레이션 결과는 아래와 같다.

간단한 인버터 회로를 대상으로 대하여 오픈-소스 설계 자동화 도구의 사용법을 살펴봤다. 오픈-소스 반도체 설계 자동화 도구와 상용 도구를 굳이 비교할 필요는 없다. 도구 사용법은 사용자 편의성을 고려했다 뿐이지 다 거기서 거기다. 어떤 도구를 가졌는가 보다 어떤 내용을 담을지 생각하자.

다음 편에서는 좀더 복잡한 회로를 다뤄보기로 한다.

---------------------------------------------------------------------

[1] SPICE 'Quick' Reference Sheet, https://kolegite.com/EE_library/books_and_lectures/%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BD%D0%B0%20%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%B0%D0%BD%D0%B5%D1%82%D0%BE%20%D0%B2%20%D0%95%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%B8%D0%BA%D0%B0%D1%82%D0%B0/spice_ref.pdf

[2] An introduction to the MAGIC VLSI design Layout System, https://terpconnect.umd.edu/~newcomb/vlsi/magic_tut/Magic_x3.pdf