2024년 3월 28일 목요일

ETRI 0.5um CMOS DK 예제: FIR8 / [1] 알고리즘 및 병렬처리 구조 탐색

ETRI 0.5um CMOS DK 예제: FIR8

[1부] 알고리즘 및 병렬처리 구조 탐색

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

목차:

1. 개요

2. FIR 필터 알고리즘

    2-1. FIR 알고리즘의 언-타임드 모형 (Un-Timed C/C++ model)

    2-2. FIR 알고리즘의 타임드 모형(Timed C++/SystemC model)

        2-2-1. 타임드 모형 시뮬레이션 도구

        2-2-2. 언-타임드 모형의 구조 탐색

        2-2-3. 파이프라인 배열 구조 묘사

        2-2-3. 타임드 모형 테스트벤치

        2-2-5. 패드 제한(pad-limit) 검토

3. 예제 따라하기

4. 참고

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

1. 개요

내칩(My Chip) MPW에서 제공하는 칩은 크기는 제한되어 있다. 면적은 1900x1900um이며 패키지까지 제공 받으려면 28핀내에 설계되어야 한다[바로가기]. 디지털 설계의 경우 패드 라이브러리의 크기를 감안하면 코어의 설계 면적은 1000x1000um 이내로 제한된다. 이런 한도 내에서 구현할 수 있는 알고리즘은 많지않다. 경희대학교 반도체 전공 트랙에서 개발한 표준 셀 라이브러리 설계 키트[바로가기]를 사용했을 경우 8비트 가감산및 논리연산기와 3개의 8비트 레지스터, 8비트 곱셈기와 입출력 제어용 FSM을 넣을 수 있는 수준이다[바로가기].

규모있는 알고리즘을 구현하기 위한 방안으로 설계를 분할 하여 다수의 프로젝트를 지원해 보는 것도 한 방법이 될 수 있을 것이다. 또다른 방안은 파이프 라인 배열 구조로 구현하는 방법이다. 디지털 신호처리, 신경망[바로가기] 등의 알고리즘은 벡터 곱셈(콘볼루션)을 기초로 한다. 이 알고리즘들은 전형적인 병렬처리(Parallel Processing)/파이프라인(Pipeline)/배열연산기(Array Processing) 구조를 갖는다. MPW에서 10개 이상의 패키지된(!) 칩이 제공될 것으로 예상되므로 각 칩을 배열의 처리단위(PE, Processing Element)로 사용하는 방법이다.

[출처] https://youtu.be/GVsUOuSjvcg?si=D580dNr1eZ9mojgj&t=319

본 예제는 파이프라인 배열 구조에 적용될 디지털 FIR 필터[바로가기]의 PE다. MPW의 칩 제한 규정에 여유가 없으므로 8비트 부호없는 정수를 입력받아 처리하는 8탭 FIR 필터의 PE를 설계한다. 이렇게 느슨하게 설계된 필터의 용도는 매우 제한적이다. 좁은 대역폭을 갖는 SSB 음성 통신의 저대역 통과 필터로 사용할 수 있을 것이다[바로가기]. 예제의 원시 코드들의 깃-허브 저장소는 아래와 같다.

Git-Hub: https://github.com/GoodKook/ETRI-0.5u-CMOS-MPW-DK-Example--FIR8.git

깃-허브 저장소에서 예제의 소스코드들을 내려 받는 방법은 다음과 같다.

    ~$ cd
    ~$ git clone https://github.com/GoodKook/ETRI-0.5u-CMOS-MPW-DK-Example--FIR8.git
    ~$ cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8

깃-허브 원격 저장소는 원작자(그리고 허용된 참여자)에 의해 수시로 갱신된다. 그때마다 모두 내려받을 필요는 없다. 작업 폴더로 이동 한 후 원격저장소에서 갱신된 파일만을 내려 받는 git 명령은 pull 이다.

    ~$ cd
    ~$ cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8
    ~$ git pull


2. FIR 필터 알고리즘

FIR 필터의 '급수합' 알고리즘은 잘 알려져 있다[바로가기]. 이 알고리즘은 배열 구조 병렬처리에 적용되는 전형적인 예이기도 하다.


[출처] https://en.wikipedia.org/wiki/Finite_impulse_response

필터의 계수는 T-Filter 웹 도구[바로가기]를 통하여 구했다. 필터 탭의 계수가 갖는 수의 범위가 크지 않다.

위의 웹 도구를 통해 얻은 필터 계수를 활용한 C 코드는 다음과 같다.

    fir8.h

    fir8.cpp

필터를 시험하기 위한 테스트 벤치는 다음과 같다.

    fir8_tb.cpp

시험용 입력으로 몇가지 주파수를 갖는 신호에 백색 잡음을 혼합하여 생성하였다. 필터 알고리즘의 시험은 순수 C 프로그램 수준에서 실시한다. 하드웨어의 시간개념이 포함되지 않은 순수 C 코드로 작성된 모델을 "언-타임드(un-timed)" 라고 한다.

2-1. FIR 알고리즘의 언-타임드 모형 (Un-Timed C/C++ model)

개발 중 컴파일과 실행을 반복하게 된다. 그때마다 명령줄에서 매번 복잡한 옵션과 함게 명령입력을 해주려면 짜증나는 일이다. 메이크 유틸리티(make utility)를 사용하면 매우 유용하다[바로가기]. FIR 필터의 알고리즘 시험용 언-타임드 C 모델의 빌드와 실행을 용이하게 해줄 Makefile을 작성하였다.

    Makefile

필터 알고리즘 시험용 테스트 벤치는 한회에 4800개의 시계열 입력 자료를 생성하고 필터를 거친 출력을 얻는다. 수없이 나열된 숫자들을 보고 그 결과를 판단 할 수는 없다. 다양한 가시화 도구(visualization tools)를 갖춘 파이썬(Python)은 알고리즘 분석의 필수 도구다. FIR 필터 알고리즘을 시험한 결과를 시각화하기 위한 파이썬 코드는 아래와 같다.

    plotDFT.py

알고리즘의 언-타임드 시험을 해보자. C 모델이 저장된 폴더로 이동,

    ~$ cd
    ~$ cd cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8
    ~$ cd 0_algorithm/c_untimed

미리 만들어둔 메이크 파일로 컴파일 한다.

    ~$ make

그리고 실행,

    ~$ make run

필터를 거친 4800개의 숫자가 나열된다. 이들 숫자들을 보는 것으로 알고리즘의 결과를 확인해 보기는 불가능하므로 스펙트럼을 보며 필터 결과를 관찰해 보기로 하자. 집단지성의 덕분에 다양한 라이브러리들이 공개적으로 제공되는 파이썬은 알고리즘의 개발과 분석에 매우 효과적이다.  오늘날 컴퓨팅 언어로 가장 활용도가 높다[바로가기]. 파이썬의 도표 그리기 라이브러리는 matplotlib 다. 파이썬의 pip 도구를 사용해 라이브러리 추가 설치할 수 있다.

    ~$ python3 -m pip install -U matplotlib

파이썬 코드를 실행하여 필터링 된 출력 신호들의 주파수 파워 스펙트럼을 살펴보면 저역 필터의 효과를 확인 할 수 있다.


    ~$ make plot_fy

-------

2-2. FIR 알고리즘의 타임드 모형(Timed C++/SystemC model)

알고리즘을 하드웨어로 구현할 목적이라면 그에 맞게 레지스터 전송 수준(RTL, Register-Transfer Level)으로 기술되어야 한다. RTL에서는 클럭 단위로 하드웨어의 작동을 묘사한다. 아울러 각 객체들(신호선, 와이어)은 비트 단위로 상세히(clock/bit-detailed) 기술된다. 합성을 목표로 하는 경우 하드웨어 묘사는 추상화 수준이 낮은 RTL에서 이뤄진다. 하드웨어 언어는 기본적으로 동시작동 원칙에 절차적 행동을 묘사할 수 있는 장치를 갖추고 있지만 알고리즘의 개발과 시험에 사용할 만큼 높은 추상화 수준에 이르지 못한다. 게다가 동시실행성(concurrency)은 알고리즘 개발에 오히려 방해일 뿐이다.

2-2-1. 타임드 모형 시뮬레이션 도구

순수 C/C++ 는 컴퓨터에서 실행될 소프트웨어를 기술하는 언어로 컴퓨팅 언어의 최강자 자리에 있다. 진즉에 기계어(어셈블리어)를 밀어낸 C/C++는 폭넓은 추상화 수준을 수용할 수 있어서 응용 프로그램(application) 뿐만 아니라 운영체제(operating system), 장치 구동기(device driver) 제작에 사용된다. 하지만 하드웨어를 묘사할 수 있는 요소(동시실행과 절차성을 모두 함축한 클럭의 개념)를 갖추고 있지 않다.

최근 인공지능과 함께 연산전용의 (범용 컴퓨터에 비해 낮은 클럭으로 작동하는 저전력) 고성능 컴퓨팅 수요가 증가하고 있다. 대용량 FPGA를 보조 연산장치로 장착한 컴퓨터에서 알고리즘 개발 도구로 C/C++에서 직접 RTL로 변환하는 고위합성(HLS, High-Level Synthesis)이 실용화 단계에 이르럿다[바로가기][고위합성 튜토리얼]. HLS이 생성해내는 RTL 코드는 상당한 여분(redundancy)을 안고 있지만 재구성 가능한 FPGA를 사용하므로 크게 문제되지 않는다. 향후 고성능 컴퓨팅 방법으로 커다란 발전을 기대하고 있다[바로가기].

지난 수십년간 소프트웨어 언어로 기술된 알고리즘을 하드웨어로 구현하기 위해 RTL로 변환하는 방법이 수없이 등장했다 사라졌다[바로가기]. C/C++ 언어에서 부족한 시간의 개념을 도입하기 위해 여러 유사언어가 등장 했으나 2005년 SystemC가 IEEE 1666 [바로가기]으로 표준화된 이후  모두 사라졌다[바로가기]. 표준 C++ 만 남았다. SystemC는 하드웨어의 특성을 묘사하기 위한 C++ 크래스와 동시실행 시뮬레이션 엔진이 포함된 라이브러리다. 개발에 표준 C++ 컴파일러가 필요할 뿐이다.

2-2-2. 언-타임드 모형의 구조 탐색

본 예제는 FIR 필터의 배열형 병렬처리 계산기 구조를 탐색하고 처리단위를 모형화 한다. 하드웨어 구조의 병렬성을 묘사한 후 모의실험의 도구로 SystemC를 활용한다. 언-타임드 순수 C/C++로 작성된 알고리즘을 하드웨어로 구현하는 첫 단계는 변수들 사이의 의존관계를 따져 병렬성을 탐지해 내는 일이다. 이를 근거로 동시처리가 가능한 요소로 분할하고 클럭 단위의 스케쥴링을 수립한다.

FIR 필터 알고리즘의 골자인 for() 반복문을 다루는 방법에 두가지 구조를 고려해 볼 수 있다. 첫째 구조는 반복문의 제어절차를 FSM으로 구현하고 누산기를 두는 방법이다. 두번째는 반복문 for()에서 순환변수 i를 펼쳐 놓고 자료의 의존관계를 살펴보는 것이다. 곱셈과 누적 연산 사이에 순방향 의존만 존재하므로 파이프라인 병렬처리 구조가 가능하다. 

두 구조는 각각 장단점이 있으므로 조건과 용도에 맞게 선택한다. 고위합성기 HLS를 활용하는 경우 원하는 하드웨어의 구조를 지정할 수 있다[HLS예 바로가기]. 본 예제는 HLS를 사용하지 않을 뿐더러 MPW 칩의 제한을 감안하여 배열 계산기 전체가 아닌 PE 만을 설계한다. SystemC로 기술한 PE는 아래와 같다.

    sc_fir_pe.h

배열구조의 한 처리요소 PE를 SystemC의 묘듈로 기술하면 아래와 같다.

SystemC로 기술된 내용을 보면 마치 새로운 언어처럼 보이지만 C++의 #define 매크로를 적극적으로 활용하여 마치 HDL의 외형과 유사해 보인다. 실제로 SC_MODULE()을 정의한 매크로는 다음과 같다.

    #define SC_MODULE(user_module_name)   \
        struct user_module_name : sc_module

따라서 위의 sc_fir_pe 는 아래와 같이 C++의 크래스를 의미한다.

    class sc_fir_pe : public sc_core::sc_module
    {
        public:
            ......
    }

하드웨어 모듈의 행동은 C++ 크래스의 소속함수로 기술한다. SC_CTOR() 매크로는 모듈이 사례화(instantiate) 될 때 처음 실행되는 크래스 구성자(constructor)다. 소속함수를 클럭의 사건에 감응(sensitize)토록 지정하였다.

C++의 추상화 수준은 프로그래밍 언어의 최고 위치에 있을 뿐만 아니라 폭넓은 범위를 수용한다. SystemC는 C++의 크래스와 각종 객체를 유연하게  선언할 수 있도록 허용하는 템플릿(C++ class template, 바로가기)을 매우 폭넓게 활용하고 있다. C++ 언어의 진수를 보여준다고 할만하다. 프로그래밍 언어에 익숙치 않은 하드웨어 기술자에게 매우 낮설 수 있지만 그동안 쌓아온 경험을 가지고 예제들을 읽어보면 상식적인 수준에서 이해될 수 있을 것이다. 위의 PE를 기술한 모듈의 소속함수를 읽어보기 바란다. 베릴로그 HDL에 비하여 어렵지 않을 것이다.

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

주] SystemC는 새로운 설계방법론일까? [바로가기]

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

FIR8의 처리요소 PE는 매 클럭당 계수 곱셈과 누산을 수행한다. 소속함수 pe_thread()는 입력 clk의 변화(사건, event)에 호출되도록 감응이 지정되었고 내부 행동은 clk의 상승 엣지 사건 일때 까지 대기한다.

    wait(clk.posedge_event());

언-타임드 모형에서 함수호출은 프로그래머가 놓아둔 구문의 순서를 따르지만 SystemC로 기술된 쓰레드(또는 메쏘드)함수는 지정된 신호의 사건에 의해 시뮬레이터가 호출한다. 그리고 구문수행에 시간의 개념(클럭 동기)이 포함되어 있다. 이를 '타임드(timed)' 모형이라고 한다. 시간은 병렬실행을 모사하는 기준이다. 사건이 발생하면 시뮬레이터는 시간을 멈춰놓은 후 이에 감응이 지정된 모든 함수를 호출한다(event & call-back). 각 함수의 출력을 검사하여 다음 시간에 일어날 사건들을 수집하고 시간을 진행 시킨다. 시뮬레이터가 하드웨어의 병렬수행을 모의하는 작동 원리다. SystemC는 C++의 크래스(class)와 템플릿(template)를 활용하여 하드웨어 객체(입출력 방향 및 와이어와 레지스터)를 표현하며 병렬 시뮬레이터를 내장한 라이브러리다.

2-2-3. 파이프라인 배열 구조 묘사

파이프라인 처리 배열구조 병렬처리 계산기는 별도의 제어기 없이 데이터의 흐름 만으로 알고리즘을 수행한다. 초기 클럭 지연 이후 매 클럭마다 결과를 내므로 낮은 클럭율(clock rate)의 매우 효율적(고속 및 저전력)인 전용 하드웨어 구조다. 위에서 설계한 8개의 처리요소 PE들을 사용한 배열을 구조를 묘사하면 아래와 같다.

    sc_fir8.h

병렬처리 배열구조에 입력과 출력 그리고 클럭 이외의 다른 제어선은 없다.

    SC_MODULE(sc_fir8)

    {
        sc_in<bool>             clk;
        sc_in<sc_uint<8> >      Xin;
        sc_out<sc_uint<8> >     Xout;
        sc_in<sc_uint<16> >     Yin;
        sc_out<sc_uint<16> >    Yout;

        sc_fir_pe*      u_fir_pe[N_PE_ARRAY];

        sc_signal<sc_uint<8> >  X[N_PE_ARRAY-1];    // X-input
        sc_signal<sc_uint<16> > Y[N_PE_ARRAY-1];    // Accumulated
        sc_signal<sc_uint<8> >  C[N_PE_ARRAY];      // Filter-Tabs Coeff

        SC_CTOR(sc_fir8): clk("clk"),...
        {...}

        .....
    };

모듈 크래스 SC_MODULE 의 구성자 내에서 N_PE_ARRAY=8개의 sc_fir_pe 를 하위 모듈로 생성(사례화, instantiate)하고 이들 사이에 시그널 채널(signal channel)을 통해 연결 한다. SystemC의 채널은 베릴로그의 하드웨어 객체, 레지스터 reg 와 같다.

    SC_CTOR(sc_fir8): clk("clk"), Xin("Xin"), ...... , Yout("Yout")
    {
        char    szPeName[16];
        for (int i=0; i<N_PE_ARRAY; i++)
        {
            sprintf(szPeName, "u_PE_%d", i);
            u_fir_pe[i] = new sc_fir_pe(szPeName); // Instantiate PE

            C[i].write(sc_uint<8>(filter_taps[i])); // Set Coeffs.

            u_fir_pe[i]->Cin(C[i]);    // Bind Coeffs.
            u_fir_pe[i]->clk(clk);     //  and Clock
        }

        // 0-th PE
        u_fir_pe[0]->Xin(Xin);
        u_fir_pe[0]->Xout(X[0]);
        u_fir_pe[0]->Yin(Yin);
        u_fir_pe[0]->Yout(Y[0]);

        // Systolic Array
        for (int i=1; i<N_PE_ARRAY-1; i++)
        {
            u_fir_pe[i]->Xin(X[i-1]);
            u_fir_pe[i]->Xout(X[i]);
            u_fir_pe[i]->Yin(Y[i-1]);
            u_fir_pe[i]->Yout(Y[i]);
        }

        // Last PE
        u_fir_pe[N_PE_ARRAY-1]->Xin(X[N_PE_ARRAY-2]);
        u_fir_pe[N_PE_ARRAY-1]->Xout(Xout);
        u_fir_pe[N_PE_ARRAY-1]->Yin(Y[N_PE_ARRAY-2]);
        u_fir_pe[N_PE_ARRAY-1]->Yout(Yout);

    }


2-2-4. 타임드 모형 테스트벤치

배열구조 sc_fir8를 시험하기위한 테스트 벤치는 다음과 같다.

    sc_fir8_tb.h

피시험 설계물(DUT, Design Under Test) sc_fir8의 입출력에 연결한 시그널 채널 sc_signal<>들을 테스트벤치 크래스 내에 선언하였다. 상위 테스트벤치는 입출력 신호를 갖지 않도록 했다. 테스트 벤치 크래스는 두 소속함수를 가지는데 각각 시험용 신호의 생성과 DUT로부터 출력되는 필터의 결과를 취하여 언-타임드 알고리즘 계산과 비교한다.

    SC_MODULE(sc_fir8_tb)
    {
        sc_clock                clk;
        sc_signal<sc_uint<8> >  Xin;
        sc_signal<sc_uint<8> >  Xout;
        sc_signal<sc_uint<16> > Yin;
        sc_signal<sc_uint<16> > Yout;

        sc_fir8*                u_sc_fir8;

        // Test utilities
        void Test_Gen();
        void Test_Mon();

        SC_CTOR(sc_fir8_tb):
            clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false),......
        { .... }

    };

구성자에서 테스트 벤치 크래스를 구성하면서 모듈 내에서 사용될 포트와 채널들의 초기화는 객체에 이름 붙이기다. 이는 디버깅용으로 필수 사항은 아니다. 클럭 객체 sc_clock의 경우 특별히 클럭 발생기로서 작동하도록 초기화한다. 아래 예에서 sc_clock 객체로 선언된 clk는 주기 100 나노 초, 듀티 비 0.5로 반복적인 클럭 신호를 생성한다. 

        SC_CTOR(sc_fir8_tb):
            clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false),
            Xin("Xin"), ...... , Yout("Yout")
        {
            SC_THREAD(Test_Gen);
            sensitive << clk;

            SC_THREAD(Test_Mon);
            sensitive << clk;

            // Instaltiate FIR8
            u_sc_fir8 = new sc_fir8("u_sc_fir8");
            u_sc_fir8->clk(clk);
            u_sc_fir8->Xin(Xin);
            u_sc_fir8->Xout(Xout);
            u_sc_fir8->Yin(Yin);
            u_sc_fir8->Yout(Yout);

        }

테스트벤치 모듈 내의 두 소속함수는 쓰레드로 작동하기 위해 SC_THREAD()로 지정하였고 clk로 감응 되었다. 두 스레드 소속함수는 별도의 파일로 작성되었다.

    sc_fir8_tb.cpp

DUT에 주입될 시험 신호 생성용 쓰레드 함수는 Test_Gen() 아다. 모듈 크래스의 소속함수로 신호의 사건에 감응되어 호출될 메쏘드 또는 쓰레드 함수는 입력과 되돌림이 없어야 한다.

    void sc_fir8_tb::Test_Gen()
    {
        double      X_in[F_SAMPLE]; // Noise
        uint16_t    yn;
        int         t = 0;

        // Generate tests & reference from C-Model 
        srand(time(NULL));
        cnoise_generate_colored_noise_uniform( X_in, F_SAMPLE, 0, NOISE_RANGE );

        for (t=0; t<F_SAMPLE; t++)
        {
            x[t] = sc_uint<8>(AMPLITUDE/16.0
                            *
(cos((2*M_PI/F_SAMPLE)*51.0*t
                                    +(float)(rand() %  10)/ 10.0)+1))
                  + ......
                  + sc_uint<8>(X_in[t]+NOISE_RANGE);

            fir(&yn, x[t]); // Un-Timed C-Model FIR Filter

            y[t] = yn;
        }

        Yin.write(0);

        t = 0;

        while(true)
        {
            wait(clk.posedge_event());
            Xin.write(x[t]);
            t = ((++t) % F_SAMPLE);
        }
    }

몇개의 각기 다른 주파수의 유효신호와 백색잡음을 섞어 시험신호를 생성한다. 이 값들을 언-타임드 알고리즘에 주고 그 결과를 DUT 출력과 비교하기 위해 담아 두었다. 쓰레드 함수는 한번 호출되면 재호출 되지 않는다. 따라서 함수내에 무한 반복문 while(true) {......} 을 포함한다. 시그널 clk에 감응된 이 쓰레딩 함수는 상승 엣지 사건을 대기 후 재개한다.

테스트벤치 크래스의 다른 쓰레드 함수 Test_Mon()은 DUT의 출력과 표준 참조값과 비교하여 오류를 검사한다.

    void sc_fir8_tb::Test_Mon()
    {
        int         n = 0;
        uint16_t    yout;

        FILE *fp = fopen ( "sc_fir8_tb_out.txt", "w" );

        while(true)
        {
            wait(clk.posedge_event());
            yout = (uint16_t)Yout.read();

            if (yout==0)    continue;

            if (y[n]!=yout)
                printf("Error:");

            printf("[%4d] y=%d / Yout=%d\n", n, (uint16_t)y[n], yout);
            fprintf(fp, "%5d %5d\n", (uint16_t)x[n], (uint16_t)yout);   //y[i]);

            n++;
            if (n==F_SAMPLE)
            {
                fflush(fp);
                fclose(fp);
                sc_stop();
            }
        }
    }

매 클럭마다 DUT의 출력을 취하도록 clk의 상승 엣지 사건에 대기 후 비교를 재개한다. 시험을 마친 후 파일에 저장해 두었던 결과는 파이썬 프로그램으로 시각적 분석한다. 다양한 수리 라이브러리를 활용할 수 있는 파이썬은 과학기술 용으로 매우 유용하게 사용된다.

    sc_plotDFT.py

SystemC로 작성한 타임드 모형의 시뮬레이션 Makefile은 아래와 같다.

    Makefile

SystemC로 작성된 코드에서 읽어들일 인클루드 폴더의 지정과 링크용 라이브러리 그리고 컴파일 후 실행시 필요한 동적 라이브러리(so, shared-object)의 위치등을 변수로 설정해 놨다.

    export SYSTEMC          = /usr/local/systemc-3.0.0
    export SYSTEMC_HOME     = $(SYSTEMC)
    export SYSTEMC_INCLUDE  = $(SYSTEMC_HOME)/include
    export SYSTEMC_LIBDIR   = $(SYSTEMC_HOME)/lib-linux64
    export LD_LIBRARY_PATH :=$(LD_LIBRARY_PATH):$(SYSTEMC_LIBDIR)
    export CXX              = clang++
    export CXXFLAGS         = -std=c++17

시뮬레이션을 수행하려면 명령줄에서 작업 폴더로 이동,

    ~$ cd
    ~$ cd cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8
    ~$ cd 0_algorithm/sc_timed

메이크 유틸리티로 빌드,

    ~$ make

실행,

    ~$ make run

SystemC는 VCD(Value-Changed Dump) 파형 기록을 지원한다. 타임드 시뮬레이션을 수행하며 시간상 발생한 시그널 채널과 포트의 사건을 VCD형식 파형으로 기록할 수 있다.


신호처리 알고리즘들은 수없이 많은 자료를 다룬다. 입출력 신호를 파형으로 살펴보기는 지루하기 짝이 없는 노릇이지만 개발중 확인 용도로 유용하다.

2-2-5. 패드 제한(pad-limit) 검토

클럭 및 비트 단위 상세히 기술된 경우 언어에 상관 없이 수월하게 합성 할 수 있다. SystemC로 작성된 PE의 타임드 모형은 합성이 가능할 정도의 RTL로서 언타임드 알고리즘과 비교 검증 역시 완료되었다. 하지만 '내칩(MyChip)' MPW의 핀수 조건을 만족하지 못한다. PE의 코어가 차지할 면적이 작지만 외부로 연결된 핀의 갯수가 무려 60여개에 이른다. 데이터 패쓰는 디지털 설계의 큰 골칫꺼리다. 이의 해결을 위해 클럭 소모를 감수하고 비트 단위 또는 디지트 단위 입출력과 연산을 고려해야 한다.

3. 예제 수행

깃-허브에서 예제 다운로드

    $ cd
    $ git clone https://github.com/GoodKook/ETRI-0.5u-CMOS-MPW-DK-Example--FIR8.git

FIR8의 언타임드 시뮬레이션

    $ cd
    $ cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8/0_algorithm/
    $ cd c_untimed
    $ make
    $ make run
    $ make plot_fy

배열형 병렬 계산기 구조 처리단위(PE, processing element)의 타임드 시뮬레이션

    $ cd
    $ cd ETRI-0.5u-CMOS-MPW-DK-Example--FIR8/0_algorithm/
    $ cd sc_timed
    $ make
    $ make run


4. 참고

Git-Hub:

1. 디자인 킷, https://github.com/GoodKook/ETRI-0.5um-CMOS-MPW-Std-Cell-DK.git

2. 예제 ALU8, https://github.com/GoodKook/ETRI-0.5u-CMOS-MPW-DK-Example--ALU8.git

3. 예제 FIR8, https://github.com/GoodKook/ETRI-0.5u-CMOS-MPW-DK-Example--FIR8.git 

유용한 바로가기:

1. KION MPW 안내문 공지: http://mpw.kion.or.kr/info/notice_list.asp

2. Design of FIR Filters, https://www.robots.ox.ac.uk/~gari/teaching/cdt/A3/readings/Filtering_and_FFT/3F3_5_Design_of_FIR_Filters.pdf

3. Finite Impulse Response, https://en.wikipedia.org/wiki/Finite_impulse_response

4. TFilter, http://t-filter.engineerjs.com/

5. Make 유틸리티 강좌, http://ebook.pldworld.com/_eBook/make/make_utility_lecture_(cWyANG).pdf

6. Python Programming And Numerical Methods: A Guide For Engineers And Scientists, https://pythonnumericalmethods.berkeley.edu/

7. 고위합성 튜토리얼, https://hls-goodkook.blogspot.com/2021/08/ug871-xilinx-high-level-synthesis.html

8. Towards Automatic High-Level Code Deployment on Reconfigurable Platforms: A Survey of High-Level Synthesis Tools and Toolchains, https://ieeexplore.ieee.org/abstract/document/9195872

9. oneAPI DPC++(Data Parallel C++), https://www.intel.com/content/www/us/en/developer/tools/oneapi/dpc-compiler.html

10. High-Level Synthesis, https://en.wikipedia.org/wiki/High-level_synthesis

11. IEEE1666 SystemC LRM, https://ieeexplore.ieee.org/document/10246125

12. SystemC, https://en.wikipedia.org/wiki/SystemC

13. SystemC는 새로운 설계방법론일까?, https://fun-teaching-goodkook.blogspot.com/2024/03/systemc.html

14. 클래스 템플릿, https://learn.microsoft.com/ko-kr/cpp/cpp/class-templates

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

[다음] [2] 아듀이노 보드 에뮬레이션







댓글 없음:

댓글 쓰기