2025년 1월 27일 월요일

ETRI 0.5um CMOS DK 예제: FIR8 / [3] 칩 테스트 장치

ETRI 0.5um CMOS DK 예제: FIR8 / [3] 칩 테스트 장치

"내 칩 서비스" MPW 2024-2차 칩이 28핀 SSOP 패키지로 배포 되었다. 디지털 회로의 경우 비록 28핀 밖에 않되는 칩이지만 테스트 하려면 테스트 벡터 제네레이터, 로직 아날라이져 같은 장비를 필요로 한다. 여러 클럭에 걸쳐 일련의 테스트 벡터를 주어 기능을 확인해야 하므로 입출력 신호 검사 장비는 프로그래머블 해야함은 물론이다. 비록 이런 장비를 갖췄더라도 장비 사용법은 쉽지 않다. 고가의 테스트 장비에 복잡한 사용법으로 인해 테스트 할 엄두가 나지 않는다면 직접 만들어 보자.

칩 테스트 장치는 기본적으로 SCE-MI 에 준하여 구성되었다.


SCE-MI(Standard Co-Emulation Modeling Interface), https://www.accellera.org/downloads/standards/sce-mi

SystemC 로 작성한 테스트 벤치를 통해 테스트 벡터 생성하고 출력을 검출한다. 동작 모드는 클럭 상세(Cycle Accurate)다. 아듀이노 메가보드를 활용하여 DUT(하드웨어)와 SystemC 테스트 벤치(소프트웨어) 사이의 모델 인터페이스 한다.

테스트 대상 칩은 아래와 같다.

설계명: FIR_PE/DB-19

설계자: 지하은/경희대학교

설계내용: 어레이 FIR 필터 용 프로세싱 엘리먼트(PE)

입출력 핀 수: 입력 17개, 출력: 8개

패키지 핀맵:

 

테스트 장치 제작

준비물

















Arduino MEGA/Modeling Interface

회로도: https://content.arduino.cc/assets/MEGA2560_Rev3e_sch.pdf

디지털 핀: https://docs.arduino.cc/resources/pinouts/A000067-full-pinout.pdf


/*
  Filenale: fir8_test.ino
  FIR8 with SystemC Co-Emulation
  Chip Test at Cycle Accurate Level
  MyChip MPW 2024-2
*/
//----------------------// SOIC-28 Package
#define PIN_Xin_3   22  // 1
#define PIN_Xin_2   23  // 2
#define PIN_Xin_1   24  // 3
#define PIN_Xin_0   25  // 4
//            VDD       // 5
#define PIN_Yin_3   26  // 6
#define PIN_Yin_2   27  // 7
#define PIN_Yin_1   28  // 8
#define PIN_Yin_0   29  // 9
#define PIN_RDY_i   30  // 10
#define PIN_CLK_i   31  // 11
#define PIN_Cin_0   32  // 12
#define PIN_Cin_1   33  // 13
#define PIN_Cin_2   34  // 14
#define PIN_Cin_3   35  // 15
#define PIN_Cin_4   36  // 16
#define PIN_Cin_5   37  // 17
#define PIN_Cin_6   38  // 18
#define PIN_VLD_o   39  // 19
#define PIN_Yout_0  40  // 20
#define PIN_Yout_1  41  // 21
#define PIN_Yout_2  42  // 22
#define PIN_Yout_3  43  // 23
//            VSS       // 24
#define PIN_Xout_0  44  // 25
#define PIN_Xout_1  45  // 26
#define PIN_Xout_2  46  // 27
#define PIN_Xout_3  47  // 28
//-------------------------------------------------------------------
class Port_Xin {
  uint8_t _val;
public:
  Port_Xin(uint8_t val)  // Constructor
  {
    // Set digital pins to output connecting DUT's INPUT
    pinMode(PIN_Xin_3, OUTPUT);
    pinMode(PIN_Xin_2, OUTPUT);
    pinMode(PIN_Xin_1, OUTPUT);
    pinMode(PIN_Xin_0, OUTPUT);
    write(val);
  }
  uint8_t read()
  {
    return _val;
  }
  void write(uint8_t val)
  {
    digitalWrite(PIN_Xin_3, val & 0x08);
    digitalWrite(PIN_Xin_2, val & 0x04);
    digitalWrite(PIN_Xin_1, val & 0x02);
    digitalWrite(PIN_Xin_0, val & 0x01);
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_Yin {
  uint8_t _val;
public:
  Port_Yin(uint8_t val)
  {
    // Set digital pins to output connecting DUT's INPUT
    pinMode(PIN_Yin_3, OUTPUT);
    pinMode(PIN_Yin_2, OUTPUT);
    pinMode(PIN_Yin_1, OUTPUT);
    pinMode(PIN_Yin_0, OUTPUT);
    write(val);
  }
  uint8_t read()
  {
    return _val;
  }
  void write(uint8_t val)
  {
    digitalWrite(PIN_Yin_3, val & 0x08);
    digitalWrite(PIN_Yin_2, val & 0x04);
    digitalWrite(PIN_Yin_1, val & 0x02);
    digitalWrite(PIN_Yin_0, val & 0x01);
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_Cin {
  uint8_t _val;
public:
  Port_Cin(uint8_t val)
  {
    // Set digital pins to output connecting DUT's INPUT
    pinMode(PIN_Cin_6, OUTPUT);
    pinMode(PIN_Cin_5, OUTPUT);
    pinMode(PIN_Cin_4, OUTPUT);
    pinMode(PIN_Cin_3, OUTPUT);
    pinMode(PIN_Cin_2, OUTPUT);
    pinMode(PIN_Cin_1, OUTPUT);
    pinMode(PIN_Cin_0, OUTPUT);
    write(val);
  }
  uint8_t read()
  {
    return _val;
  }
  void write(uint8_t val)
  {
    digitalWrite(PIN_Cin_6, val & 0x40);
    digitalWrite(PIN_Cin_5, val & 0x20);
    digitalWrite(PIN_Cin_4, val & 0x10);
    digitalWrite(PIN_Cin_3, val & 0x08);
    digitalWrite(PIN_Cin_2, val & 0x04);
    digitalWrite(PIN_Cin_1, val & 0x02);
    digitalWrite(PIN_Cin_0, val & 0x01);
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_RDY_i {
  bool _val;
public:
  Port_RDY_i(bool val)
  {
    // Set digital pins to output connecting DUT's INPUT
    pinMode(PIN_RDY_i, OUTPUT);
    write(val);
  }
  bool read()
  {
    return _val;
  }
  void write(bool val)
  {
    digitalWrite(PIN_RDY_i, val);
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_Xout {
  uint8_t _val;
public:
  Port_Xout(uint8_t val)  // Constructor
  {
    // Set digital pins to input connecting DUT's OUTPUT
    pinMode(PIN_Xout_3, INPUT);
    pinMode(PIN_Xout_2, INPUT);
    pinMode(PIN_Xout_1, INPUT);
    pinMode(PIN_Xout_0, INPUT);
    write(val);
  }
  uint8_t read()
  {
    _val = ((digitalRead(PIN_Xout_3)? 0x08:0x00) |
            (digitalRead(PIN_Xout_2)? 0x04:0x00) |
            (digitalRead(PIN_Xout_1)? 0x02:0x00) |
            (digitalRead(PIN_Xout_0)? 0x01:0x00));
    return _val;
  }
  void write(uint8_t val)
  {
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_Yout {
  uint8_t _val;
public:
  Port_Yout(uint8_t val)  // Constructor
  {
    // Set digital pins to input connecting DUT's OUTPUT
    pinMode(PIN_Yout_3, INPUT);
    pinMode(PIN_Yout_2, INPUT);
    pinMode(PIN_Yout_1, INPUT);
    pinMode(PIN_Yout_0, INPUT);
    write(val);
  }
  uint8_t read()
  {
    _val = ((digitalRead(PIN_Yout_3)? 0x08:0x00) |
            (digitalRead(PIN_Yout_2)? 0x04:0x00) |
            (digitalRead(PIN_Yout_1)? 0x02:0x00) |
            (digitalRead(PIN_Yout_0)? 0x01:0x00));
    return _val;
  }
  void write(uint8_t val)
  {
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_VLD_o {
  bool _val;
public:
  Port_VLD_o(bool val)  // Constructor
  {
    // Set digital pins to input connecting DUT's OUTPUT
    pinMode(PIN_VLD_o, INPUT);
    write(val);
  }
  bool read()
  {
    _val = digitalRead(PIN_VLD_o);
    return _val;
  }
  void write(uint8_t val)
  {
    _val = val;
  }
};
//-------------------------------------------------------------------
class Port_CLK {
  bool _val;
public:
  Port_CLK(bool val)
  {
    pinMode(PIN_CLK_i, OUTPUT);
    write(val);
  }
  void write(bool val)
  {
    digitalWrite(PIN_CLK_i, val);
    _val = val;
  }
  bool read()
  {
    return _val;
  }
  void posedge()
  {
    digitalWrite(PIN_CLK_i, false);
    digitalWrite(PIN_CLK_i, true);
    _val = true;
  }
  void negedge()
  {
    digitalWrite(PIN_CLK_i, true);
    digitalWrite(PIN_CLK_i, false);
    _val = false;
  }
  bool cycle()
  {
    if (_val)
    {
      negedge();
      posedge();
    }
    else
    {
      posedge();
      negedge();
    }
    return _val;
  }
};
//-------------------------------------------------------------------
void establishContact()
{
  while (Serial.available() <= 0)
  {
    Serial.print('A');  // send a capital A
    delay(300);
    if (Serial.read()==(int)'A')
      break;
  }
}
//-------------------------------------------------------------------
void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial)
  {
    ;  // wait for serial port to connect.
  }
  establishContact();  // send a byte to establish contact until receiver responds
  // Monitoring LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
}
#define N_RX  3 // [0]={Xin[7:4]|Yin[3:0]}
                // [1]={-|Cin[6:0]};
                // [2]={-[7:2]|Clk|RDY};
#define N_TX  2 // [0]={Xout[7:4]|Yout[3:0]}
                // [1]={-[7:1]|VLD[0]}
uint8_t rxBuf[N_RX], txBuf[N_TX];
// Instantiate DUT Ports
Port_Xin    Xin(0x00);
Port_Yin    Yin(0x00);
Port_Cin    Cin(0x00);
Port_Xout   Xout(0);
Port_Yout   Yout(0);
Port_RDY_i  RDY_i(false);
Port_VLD_o  VLD_o(false);
Port_CLK    CLK(false);
void RxPacket()
{
  int rxByte;
  while(true)
  {
    if (Serial.available() >= N_RX)
    {
      for(int i=0; i<N_RX; i++)
      {
        rxByte = Serial.read();
        rxBuf[i] = (uint8_t)rxByte;
      }
      //rxBuf[0]={Xin[7:4]|Yin[3:0]}
      Xin.write((rxBuf[0] & 0xF0) >> 4);
      Yin.write((rxBuf[0] & 0x0F));
      //rxBuf[1]={-|Cin[6:0]};
      Cin.write((rxBuf[1] & 0x7F));
      //rxBuf[2]={-[7:2]|Clk|RDY};
      RDY_i.write((rxBuf[2] & 0x01));
      CLK.write((rxBuf[2] & 0x02));
      return;
    }
  }
}
void TxPacket()
{
  int txByte;
  while(1)
  {
    if (Serial.availableForWrite() >= N_TX)
    {
      // [0]={Xout[7:4]|Yout[3:0]}
      txBuf[0] = (((uint8_t)Xout.read() << 4) | ((uint8_t)Yout.read() & 0x0F));
      // [1]={-[7:1]|VLD[0]}
      txBuf[1] = ((uint8_t)VLD_o.read() & 0x01);
      for(int i=0; i<N_TX; i++)
      {
        txByte = (int)txBuf[i];
        Serial.write(txByte);
      }
      return;
    }
  }
}
uint8_t counter;
void loop()
{
  counter += 1;
  digitalWrite(LED_BUILTIN, (counter & 0x10)? HIGH:LOW);
  RxPacket();
  TxPacket();
}

SystemC Testbench

1. DUT Wrapper


/********************************************************************
Filename: sc_fir_pe.h
Purpose : Test wrapper
          Chip Test of FIR PE (MyChip 2024-2)
Author  : goodkook@gmail.com
History : Jan. 2025, First release
********************************************************************/
#ifndef _SC_FIR_PE_H_
#define _SC_FIR_PE_H_
#include <systemc.h>
// Includes for accessing Arduino via serial port
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

SC_MODULE(sc_fir_pe)
{
    sc_in<bool>             clk;
    sc_in<bool>             Rdy;
    sc_out<bool>            Vld;
    sc_in<sc_uint<8> >      Cin;
    sc_in<sc_uint<4> >      Xin;
    sc_out<sc_uint<4> >     Xout;
    sc_in<sc_uint<4> >      Yin;
    sc_out<sc_uint<4> >     Yout;
#define N_TX    3
#define N_RX    2
    void transact(void)
    {
        uint8_t     x, y, txPacket[N_TX], rxPacket[N_RX];
        txPacket[0] = ((uint8_t)Xin.read()<<4) \
                    | ((uint8_t)Yin.read() & 0x0F);
        txPacket[1] = ((uint8_t)(Cin.read()) & 0x7F);
        txPacket[2] = (((uint8_t)Rdy.read())? 0x01:0x00) \
                    | (((uint8_t)clk.read())? 0x02:0x00);
        // Send to Emulator
        for (int i=0; i<N_TX; i++)
        {
            x = txPacket[i];
            while(write(fd, &x, 1)<=0)  usleep(1);
        }
        // Receive from Emulator
        for (int i=0; i<N_RX; i++)
        {
            while(read(fd, &y, 1)<=0)   usleep(1);
            rxPacket[i] = y;
        }
        Xout.write((sc_uint<4>)(rxPacket[0]>>4));
        Yout.write((sc_uint<4>)(rxPacket[0] & 0x0F));
        Vld.write(rxPacket[1]? true:false);
    }
    
    void pe_thread(void)
    {
        while(true)
        {
            wait(clk.posedge_event());
            transact();
            wait(clk.negedge_event());
            transact();
        }
    }
    // Arduino Serial IF
    int fd;                 // Serial port file descriptor
    struct termios options; // Serial port setting
    SC_CTOR(sc_fir_pe):
        clk("clk"),
        Cin("Cin"), Xin("Xin"), Xout("Xout"),
        Yin("Yin"), Yout("Yout")
    {
        SC_THREAD(pe_thread);
        sensitive << clk;
        // Arduino DUT
        //fd = open("/dev/ttyACM0", O_RDWR | O_NDELAY | O_NOCTTY);
        fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
        if (fd < 0)
        {
            perror("Error opening serial port");
            return;
        }
        // Set up serial port
        options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
        options.c_iflag = IGNPAR;
        options.c_oflag = 0;
        options.c_lflag = 0;
        // Apply the settings
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &options);
        // Establish Contact
        int len = 0;
        char rx;
        while(!len)
            len = read(fd, &rx, 1);
        if (rx=='A')
            write(fd, &rx, 1);
        printf("Connection established...\n");
    }
    
    ~sc_fir_pe(void)
    {
    }
};
#endif

2. Testbench


/**********************************************************************
Filename: sc_fir_pe_tb.h
Purpose : Testbench
          Chip Test of FIR PE (MyChip 2024-2)
Author  : goodkook@gmail.com
History : Jan. 2025, First release
***********************************************************************/

#ifndef _SC_FIR_PE_TB_H_
#define  _SC_FIR_PE_TB_H_

#include <systemc.h>
#include "sc_fir_pe.h"

SC_MODULE(sc_fir_pe_tb)
{
    sc_clock                clk;
    sc_signal<sc_uint<8> >  Cin;
    sc_signal<sc_uint<4> >  Xin;
    sc_signal<sc_uint<4> >  Xout;
    sc_signal<sc_uint<4> >  Yin;
    sc_signal<sc_uint<4> >  Yout;
    sc_signal<bool>         Vld;
    sc_signal<bool>         Rdy;

    sc_fir_pe*                u_sc_fir_pe;

    uint16_t    Test_Cin[5] = {0, 0, 0, 0, 0};
    uint16_t    Test_Xin[5] = {0, 0, 0, 0, 0};
    uint16_t    Test_Yin[5] = {0, 0, 0, 0, 0};
    uint8_t     Test_Xout = 0;
    uint16_t    Test_Yout = 0;

    // Test utilities
    void Test_Gen()
    {
        Cin.write(0x00);
        Xin.write(0x00);
        Yin.write(0x00);
        Rdy.write(false);

        // INIT
        for (int i=0; i<10; i++)
            wait(clk.posedge_event());
        wait(clk.posedge_event());
        Rdy.write(true);
        wait(clk.posedge_event());
        Rdy.write(false);
        for (int i=0; i<10; i++)
            wait(clk.posedge_event());

        Cin.write(Test_Cin[0]);
        Xin.write(0x00);
        Yin.write(0x00);
        Rdy.write(false);

        while(true)
        {
            Cin.write(Test_Cin[0] & 0x007F);    // Cin: 7-Bits
            wait(clk.posedge_event());
            Rdy.write(true);
            wait(clk.posedge_event());
            Rdy.write(false);
            Xin.write(Test_Xin[0] & 0x000F);    // Xin: 4-Bits
            Yin.write(Test_Yin[0] & 0x000F);    // Yin: 4-Bits
            wait(clk.posedge_event());
            Xin.write(Test_Xin[0] >> 4);
            Yin.write((Test_Yin[0] >> 4) & 0x000F);     // Yin: 4-Bits
            wait(clk.posedge_event());
            Yin.write((Test_Yin[0] >> 8) & 0x000F);     // Yin: 4-Bits
            wait(clk.posedge_event());
            Yin.write((Test_Yin[0] >> 12) & 0x000F);    // Yin: 4-Bits
            wait(clk.posedge_event());
            //printf("Cin = %04d Xin = %04d Yin = %06d ---> ", Test_Cin[0], Test_Xin[0], Test_Yin[0]);

            Test_Xin[4] = Test_Xin[3];  Test_Xin[3] = Test_Xin[2];  Test_Xin[2] = Test_Xin[1];  Test_Xin[1] = Test_Xin[0];
            Test_Yin[4] = Test_Yin[3];  Test_Yin[3] = Test_Yin[2];  Test_Yin[2] = Test_Yin[1];  Test_Yin[1] = Test_Yin[0];
            Test_Cin[4] = Test_Cin[3];  Test_Cin[3] = Test_Cin[2];  Test_Cin[2] = Test_Cin[1];  Test_Cin[1] = Test_Cin[0];

#if defined(TEST_MULTIPLIER_C)
            Test_Cin[0]++;
            if (Test_Cin[0]>127)
            {
                Test_Cin[0] = 0;
                Test_Xin[0]++;
                if (Test_Xin[0]>255)
                    sc_stop();
            }
#elif defined(TEST_MULTIPLIER_X)
            Test_Xin[0]++;
            if (Test_Xin[0]>255)
            {
                Test_Xin[0] = 0;
                Test_Cin[0]++;
                if (Test_Cin[0]>127)
                    sc_stop();
            }
#elif defined(TEST_ADDER_X)
            Test_Cin[0] = 1;
            Test_Xin[0]++;
            if (Test_Xin[0]>255)
            {
                Test_Xin[0] = 0;
                Test_Yin[0]++;
                if (Test_Yin[0]>1000)
                    sc_stop();
            }
#elif defined(TEST_ADDER_Y)
            Test_Cin[0] = 1;
            Test_Yin[0]++;
            if (Test_Yin[0]>255)
            {
                Test_Yin[0] = 0;
                Test_Xin[0]++;
                if (Test_Xin[0]>255)
                    sc_stop();
            }
#elif defined(TEST_ADDER_R)
            Test_Cin[0] = 1;
            Test_Xin[0] = (uint16_t)rand() & 0x00FF;    // Xin: unsigned 8-bit
            Test_Yin[0] = (uint16_t)rand() & 0xFFFF;    // Yin: unsigned 16-bit
#else   // RAND (default)
            Test_Cin[0] = (uint16_t)rand() & 0x007F;    // Cin: unsigned 7-bit
            Test_Xin[0] = (uint16_t)rand() & 0x00FF;    // Xin: unsigned 8-bit
            Test_Yin[0] = (uint16_t)rand() & 0xFFFF;    // Yin: unsigned 16-bit
#endif            
        }
    }

    void Test_Mon()
    {
        uint16_t    Yout_Expected = 0;

        while(true)
        {
            wait(clk.posedge_event());
            if (Vld.read())
            {
                wait(clk.posedge_event());
                wait(clk.posedge_event());
                Test_Xout = (uint8_t)Xout.read();
                Test_Yout = (uint16_t)Yout.read();
                wait(clk.posedge_event());
                Test_Xout |= (uint8_t)Xout.read() << 4;
                Test_Yout |= (uint16_t)Yout.read() << 4;
                wait(clk.posedge_event());
                Test_Yout |= (uint16_t)Yout.read() << 8;
                wait(clk.posedge_event());
                Test_Yout |= (uint16_t)Yout.read() << 12;
                printf("[Cin=%03d] * [Xin=%03d] + [Yin=%05d] ---> ",
#if defined(TEST_ADDER_X) || defined(TEST_ADDER_Y) || defined(TEST_ADDER_R) || defined(RAND)
                        Test_Cin[3], Test_Xin[3], Test_Yin[3]);
                Yout_Expected = (Test_Cin[3]*Test_Xin[3]+Test_Yin[3]);
#else
                        Test_Cin[2], Test_Xin[2], Test_Yin[2]);
                Yout_Expected = (Test_Cin[2]*Test_Xin[2]+Test_Yin[2]);
#endif
                printf("Xout = %03d Yout = %05d", Test_Xout, Test_Yout);
                if (Test_Yout!=Yout_Expected)
                    printf(":ERROR, Expected Yout = %05d\n", Yout_Expected);
                else
                    printf("\n");
            }
        }
    }

#ifdef VCD_TRACE_YES
    sc_trace_file* fp;  // VCD file
#endif

    SC_CTOR(sc_fir_pe_tb):
        clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false),
        Vld("Vld"),
        Rdy("Rdy"),
        Xin("Xin"),
        Xout("Xout"),
        Yin("Yin"),
        Yout("Yout")
    {
        SC_THREAD(Test_Gen);
        sensitive << clk;

        SC_THREAD(Test_Mon);
        sensitive << clk;
        
        // Instaltiate FIR8
        u_sc_fir_pe = new sc_fir_pe("u_sc_fir_pe");
        u_sc_fir_pe->clk(clk);
        u_sc_fir_pe->Cin(Cin);
        u_sc_fir_pe->Xin(Xin);
        u_sc_fir_pe->Xout(Xout);
        u_sc_fir_pe->Yin(Yin);
        u_sc_fir_pe->Yout(Yout);
        u_sc_fir_pe->Rdy(Rdy);
        u_sc_fir_pe->Vld(Vld);

#if VCD_TRACE_YES
        // WAVE
        fp = sc_create_vcd_trace_file("sc_fir_pe_tb");
        sc_trace(fp, clk, "clk");
        sc_trace(fp, Cin,  "Cin");
        sc_trace(fp, Xin,  "Xin");
        sc_trace(fp, Xout, "Xout");
        sc_trace(fp, Yin,  "Yin");
        sc_trace(fp, Yout, "Yout");
        sc_trace(fp, Rdy,  "Rdy");
        sc_trace(fp, Vld,  "Vld");
#endif
    }
    
    ~sc_fir_pe_tb(void)
    {
    }
};

#endif


3. Main

/********************************************************************
Filename: sc_main.cpp
Purpose : Chip Test of FIR PE (MyChip 2024-2)
Author  : goodkook@gmail.com
History : Jan. 2025, First release
********************************************************************/
#include "sc_fir_pe_tb.h"
int sc_main(int argc, char** argv)
{
    sc_fir_pe_tb u_sc_fir_pe_tb("u_sc_fir_pe_tb");
    //sc_start(990, SC_US);
    sc_start();
    return 0;
}

4. Makefile


# SystemC Environments -----------------------------------------
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

# SystemC testbench Reuse --------------------------------------
SC_SRCS      =  ./sc_main.cpp
SC_HDRS      =  ./sc_fir_pe.h \
./sc_fir_pe_tb.h
SC_TARGET    = sc_fir_pe_tb

# Conditional building option
ifeq ($(VCD_TRACE),YES)
  VCD_TRACE = VCD_TRACE_YES
else
  VCD_TRACE = VCD_TRACE_NO
endif
ifeq ($(TEST_MODE), MULTIPLIER_C)
  TEST_MODE = TEST_MULTIPLIER_C
else ifeq ($(TEST_MODE), MULTIPLIER_X)
  TEST_MODE = TEST_MULTIPLIER_X
else ifeq ($(TEST_MODE), ADDER_X)
  TEST_MODE = TEST_ADDER_X
else ifeq ($(TEST_MODE), ADDER_Y)
  TEST_MODE = TEST_ADDER_Y
else ifeq ($(TEST_MODE), ADDER_R)
  TEST_MODE = TEST_ADDER_R
endif

# Build Rules --------------------------------------------------
all :
@echo 'Makefile for Chip Test of "FIR_PE/MyChip MPW 2024-2"'
@echo 'Usage:'
@echo '        TEST_MODE=<...> VCD_TRACE=<...> make build'
@echo '           TEST_MODE: MULTIPLIER_C, MULTIPLIER_X, ADDER_R, ADDER_X, ADDER_Y, RAND'
@echo '           VCD_TRACE: YES or NO'
@echo '        make run'
@echo '        make clean'

build: $(SC_TARGET)

$(SC_TARGET): $(SC_SRCS) $(SC_HDRS)
$(CXX) $(CXXFLAGS) -I$(SYSTEMC_INCLUDE) -L$(SYSTEMC_LIBDIR) \
-D$(TEST_MODE) -D$(VCD_TRACE) \
-lsystemc -o$(SC_TARGET) $(SC_SRCS)

run: $(SC_TARGET)
./$(SC_TARGET)

clean :
rm -f $(SC_TARGET)
rm -f *.vcd



테스트 실행





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

[이전] [2] 아듀이노 보드 에뮬레이터

[참고]
1. "내 칩 제작 서비스" 2025년 1차 MPW 대비 오픈-소스 도구 설치 [바로가기]
2. ETRI 0.5um CMOS DK 예제: counter8/16, 디지털 회로 칩 테스트 방법 [바로가기]



댓글 없음:

댓글 쓰기