2025년 12월 8일 월요일

[실습] HLS/basic_loops

[실습] HLS/basic_loops

목차:

1. 실습 개요

2. 환경 설정

3. C 시뮬레이션(언-타임드)

4. 고위합성(HLS)
     4-1. Vitis-HLS 고위합성(HLS)
     4-2. 고위 합성으로 얻은 RTL
     4-3. HLS 결과 보기

5. RTL 기능 시뮬레이션(Functional Simulation)
     5-1. HDL(Verilog RTL)와 SystemC TB
     5-2. 공동 시뮬레이션(Co-Simulation)
     5-3. 디지털 시뮬레이션 결과 파형

6. ETRI050 노드
    6-1. 합성 환경
    6-2. RTL 합성
    6-3. 합성 후 네트 시뮬레이션
    6-4. 표준 셀 자동 배치와 배선


CC-BY-NC
by GoodKook, goodkook@gmail.com

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

1. 실습 개요

HLS(High Level Synthesis)와 ETRI050 노드 설계 플로우  학습

    - C++ 로 기술된 누산(accumulation) 알고리즘을 RTL 하드웨어 언어로 합성

    - 소프트웨어 함수(언-타임드, Un-Timed)와 하드웨어 모듈(타임드, Timed)의 외형 차이

    - HLS의 디지털 하드웨어 인터페이스: 모듈의 핸드 쉐이크 및 동기 메모리 인터페이스

    - RTL하드웨어 언어(Verilog)와 C++ 타임드 테스트벤치(SystemC)의 공동 시뮬레이션

    - "내 칩 제작 서비스"/ETRI050 노드: RTL 합성, 자동 배치 배선 그리고 사인오프 검사

    - 베릴로그 VPI: RTL 합성 후 네트리스트 타이밍 시뮬레이션


C++: basic_loops.cpp

// Filename: basic_loop.cpp
#include "basic_loops.h"

dout_t basic_loops(din_t A[N_MEM])
{
    dout_t out_accum = 0;
    dsel_t x;   // Address of Ext. Mamory

    LOOP_1:
    for (x = 0; x < N_MEM; x++)
        out_accum += A[x];

    return out_accum;
}

헤더: basic_loops.h

// Filename: basic_loop.h

#ifndef _BASIC_LOOPS_H_
#define _BASIC_LOOPS_H_

// Vitis HLS no longer support SystemC after 2020.1
// Fortunately, bit-wised ap_(u)int<> type is compatible with sc_(u)int<>

#if VM_SC==1    // SystemC ---------------------------------

#include "systemc.h"

typedef sc_int<8>   din_t;
typedef sc_int<13>  dout_t;
typedef sc_uint<5>  dsel_t; // Address of Ext. Memory

#else           // Vitis-HLS -------------------------------

#include "ap_int.h"

typedef ap_int<8>   din_t;
typedef ap_int<13>  dout_t;
typedef ap_uint<5>  dsel_t; // Address of Ext. Memory

#endif

#define N_MEM   10

dout_t basic_loops(din_t A[N_MEM]);

#endif

실습 소스: [깃 허브]

2. 환경 설정

$ cd ~/ETRI050_DesignKit/Projects/HLS/basic_loops

$ tree

  .
  ├── c_untimed
  │   ├── basic_loops.cpp
  │   ├── basic_loops.h
  │   ├── basic_loops_TB.cpp
  │   └── Makefile
  ├── simulation
  │   ├── Makefile
  │   ├── sc_basic_loops_TB.cpp
  │   ├── sc_basic_loops_TB.h
  │   └── sc_main.cpp
  ├── emulation
  │   ├── PSCE-MI
  │   │   ├── Ebasic_loops_CA
  │   │   │   ├── Ebasic_loops_CA.ino
  │   │   │   ├── PinMap_A7_100T.h
  │   │   │   ├── PinMap_TANG_25K.h
  │   │   │   ├── PSCE_APIs.cpp
  │   │   │   ├── PSCE_APIs.h
  │   │   │   ├── PSCE_Config.h
  │   │   │   └── PSCE_Splash.h
  │   │   └── Makefile
  │   ── PSCE-TRANS
  │      └── Altera_Cmd
  │          ├── basic_loops_wrapper_II.tcl
  │          ── basic_loops_wrapper_I.tcl
  │          └── Makefile
  │   ├── basic_loops_wrapper.v
  │   ├── Ebasic_loops.h
  │   ── Makefile
  ├── ETRI050
  │   ├── chip_top
  │   │   ├── ETRI050_CMOS.lyp
  │   │   └── Makefile
  │   ├── layout
  │   │   ├── basic_loops.cel2
  │   │   ├── basic_loops.par
  │   │   ├── ETRI050_CMOS.lyp
  │   │   └── Makefile
  │   ── simulation
  │      ├── basic_loops_TB.v
  │      ├── Makefile
  │      ├── sc_basic_loops_TB.h
  │      ├── vpi_basic_loops_tb.cpp
  │      ├── vpi_basic_loops_tb_exports.h
  │      ├── vpi_basic_loops_tb_ports.h
  │      └── vpi_stub.cpp
  │   ├── Makefile
  │   ├── project_vars.sh
  │   ├── qflow_exec.sh
  │   ── qflow_vars.sh
  ├── Makefile
  ├── env_settings
  └── Vitis-HLS.tcl

$ source env_settings

  #****************************************************************
  #* Environment setting for HLS, Co-Simulmatio/Emulation & ETRI050
  #****************************************************************
  Setting Environment variables as follows;
    PROJECT_DIR=~/ETRI050_DesignKit/Projects/HLS/basic_loops
    TOP_MODULE=basic_loops
    HW_STYLE=HW_STYLE
    MODE=CA
    MI=DUE_NORMAL

3. C 시뮬레이션(언-타임드)

pwd

  ~/ETRI050_DesignKit/Projects/HLS/basic_loops

make

  Vitis-HLS Project: basic_loops
    TOP_MODULE=basic_loops HW_STYLE=HW_STYLE make csim
    TOP_MODULE=basic_loops HW_STYLE=HW_STYLE make csynth
    TOP_MODULE=basic_loops make view_rpt
    TOP_MODULE=basic_loops make co-sim
    TOP_MODULE=basic_loops make wave

    make emulation
    make ETRI050

$ make csim

  TOP_MODULE=basic_loops HW_STYLE=HW_STYLE make -C ./c_untimed build
  make[1]: Entering directory './c_untimed'
  clang++ -I/opt/systemc/include -L/opt/systemc/lib \
        -o basic_loops_TB \
        -DHW_STYLE_SC \
        -DVM_SC=1 \
        ./basic_loops.cpp ./basic_loops_TB.cpp \
        -lsystemc
  make[1]: Leaving directory './c_untimed'

  TOP_MODULE=basic_loops make -C ./c_untimed run
  make[1]: Entering directory './c_untimed'
  ./basic_loops_TB

        SystemC 3.0.2-Accellera --- Dec  8 2025 10:15:05
        Copyright (c) 1996-2025 by all Contributors,
        ALL RIGHTS RESERVED

    Sum=45
  make[1]: Leaving directory './c_untimed'

4. 고위합성(HLS)

HLS 도구는 자일링스(Xilinx)의 비티스HLS(Vitis-HLS)다. C++ 코드를 합성 가능한 RTL 하드웨어 언어(베릴로그 또는 VHDL)로 합성해 준다. 기능 합성은 물론 인터페이스 합성을 수행한다. 비티스HLS 는 분석기(RTL analyzer)등 일부를 제외하고 전 기능 무료다. 합성으로 생성된 RTL 모델은 자일링스 사의 FPGA 구조에 최적화 되어 있다고 하지만 매우 보편적인 코딩 스타일을 따른다. ASIC은 물론 타사 FPGA에서도 큰 손해 없이 표준 하드웨어 언어 설계 플로우(시뮬레이션 및 합성기)를 따라 포팅 가능하다. 자사 FPGA로 타게팅 했을 경우 타이밍 분석과 최적화가 있을 뿐 합성된 RTL은 표준의 하드웨어 언어로 기술되어 있다. 자일링스 사의 디지털 회로 개념과 알테라의 디지털 회로 또는 ETRI050의 디지털 회로가 다를리가 없다. 높은 추상화 수준의 컴퓨팅 언어를 사용하는 이유는 이전가능(portability)이다. 

4-1. Vitis-HLS 고위합성

$ make csynth

  vitis-run --mode hls --tcl Vitis-HLS.tcl

  ****** vitis-run v2025.1 (64-bit)
  **** SW Build 6137779 on 2025-05-21-18:10:03
  **** Start of session at: Mon Dec  8 16:17:55 2025
    ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
    ** Copyright 2022-2025 Advanced Micro Devices, Inc.
       All Rights Reserved.

  **** HLS Build v2025.1 6135595

  Sourcing Tcl script './Vitis-HLS.tcl'
   ..........

VitisHLS 스크립트: Vitis-HLS.tcl

append PROJECT_NAME $env(TOP_MODULE)
puts $PROJECT_NAME
append HW_STYLE "-D" $env(HW_STYLE)
puts $HW_STYLE
append CPP_FILES $env(CPP_FILES)
puts $CPP_FILES

open_project "$PROJECT_NAME"
set_top "$PROJECT_NAME"

add_files "$CPP_FILES" -cflags "$HW_STYLE"

open_solution "hls_component" -flow_target vivado

set_part {xa7a100tcsg324-2I}

create_clock -period 1000 -name default

csynth_design

write_ini ./$PROJECT_NAME.cfg

exit

$ ll

  total 60
  drwxr-xr-x 8 mychip mychip  4096 Dec  8 16:18 .
  drwxr-xr-x 6 mychip mychip  4096 Oct 27 22:22 ..
  drwxr-xr-x 3 mychip mychip  4096 Dec  8 16:18 basic_loops
  drwxr-xr-x 2 mychip mychip  4096 Dec  8 16:17 c_untimed
  drwxr-xr-x 4 mychip mychip  4096 Dec  8 15:40 emulation
  drwxr-xr-x 7 mychip mychip  4096 Dec  8 15:42 ETRI050
  drwxr-xr-x 2 mychip mychip  4096 Dec  8 16:17 logs
  drwxr-xr-x 2 mychip mychip  4096 Dec  8 15:41 simulation
  -rw-r--r-- 1 mychip mychip   173 Dec  8 16:18 basic_loops.cfg
  -rw-r--r-- 1 mychip mychip   540 Oct 27 22:22 env_settings
  -rw-r--r-- 1 mychip mychip 13940 Oct 27 22:22 Makefile
  -rw-r--r-- 1 mychip mychip   425 Oct 27 22:22 Vitis-HLS.tcl

$ cd basic_loops

$ tree

  .
  └── hls_component
      ├── ......
      ├── impl
      │   ── ......
      └── syn
        ├── report
        │   ├── basic_loops_csynth.rpt
        │   ├── ......
        │   ├── csynth.rpt
        │   └── csynth.xml
        ├── verilog
        │   ├── basic_loops_flow_control_loop_pipe.v
        │   └── basic_loops.v
        └── vhdl
            ├── basic_loops_flow_control_loop_pipe.vhd
            └── basic_loops.vhd

4-2. 고위 합성으로 얻은 RTL

module basic_loops (
    input   ap_clk,
    input   ap_rst,
    input   ap_start,
    output   ap_done,
    output   ap_idle,
    output   ap_ready,
    output  [3:0] A_address0,
    output   A_ce0,
    input  [7:0] A_q0,
    output  [12:0] ap_return
);

언-타임드 모델(C++ 의 함수)에서 없던 신호들이 있다는 점에 주목한다. 하드웨어 언어로 RTL(Register Transfer Level)에서 기술된 하드웨어는 클럭과 입출력의 신호들의 비트 단위로 상세히 기술되었다.

4-3. HLS 결과 보기

계산을 시작하여 마칠 때 까지 소요되는 클럭의 수(Latency Clcles)와 하드웨어 인터페이스에 주목한다. 하드웨어 인터페이스는 모듈의 핸드웨이크와 동기식 메모리가 있다.

$ make view_report

  ......

  + Latency:
    * Summary:

    +----------------+-------------+-----------+--------------------+
    |Latency (cycles)| (absolute)  |  Interval | Pipeline           |
    |  min   |  max  | min  | max  | min | max |   Type             |
    +--------+-------+------+------+-----+-----+--------------------+
    |      12|     12|12.0us|12.0us|   10|   10|loop auto-rewind stp|
    |        |       |      |      |     |     |  (delay=0 clock(s))|
    +--------+-------+------+------+-----+-----+--------------------+

  ......

  ================================================================
  == Interface
  ================================================================
  * Summary:
  +------------+-----+-----+------------+--------------+------------+
  |  RTL Ports | Dir | Bits|  Protocol  | Source Object|  C Type    |
  +------------+-----+-----+------------+--------------+------------+
  |ap_clk      |   in|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_rst      |   in|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_start    |   in|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_done     |  out|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_idle     |  out|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_ready    |  out|    1|  ap_ctrl_hs|   basic_loops|return value|
  |ap_return   |  out|   13|  ap_ctrl_hs|   basic_loops|return value|
  |A_address0  |  out|    4|   ap_memory|             A|       array|
  |A_ce0       |  out|    1|   ap_memory|             A|       array|
  |A_q0        |   in|    8|   ap_memory|             A|       array|
  +------------+-----+-----+------------+--------------+------------+

5. RTL 기능 시뮬레이션(Functional Simulation)

5-1. HDL(Verilog RTL)와 SystemC TB

HLS 로 얻은 RTL 베릴로그는 오픈-소스 도구 베릴레이터(Verilator)로 SystemC 타임드 모델로 변환 후 테스트 벤치에 물려 시뮬레이션한다. 컴퓨팅 언어로 디지털 회로의 행위를 모사한 기능적 시뮬레이션이다. 실제 디지털 회로가 아니므로 지연은 없다(Zero-Delay simulation). SystemC로 작성된 타임드 테스트벤치는 다음과 같다.

sc_basic_loops_TB.h

SC_MODULE(sc_basic_loops_TB)
{
    sc_clock                ap_clk;
    sc_signal<bool>         ap_rst;
    sc_signal<bool>         ap_start;
    sc_signal<bool>         ap_done;
    sc_signal<bool>         ap_idle;
    sc_signal<bool>         ap_ready;
    sc_signal<sc_uint<4> >  A_address0;
    sc_signal<bool>         A_ce0;
    sc_signal<sc_uint<8> >  A_q0;
    sc_signal<sc_uint<13> > ap_return;

    Vbasic_loops*    u_basic_loops; // Instantiate Verilated DUT

    sc_uint<8>      MEM_Dut[10];
    sc_int<8>       MEM_Ref[10];
    dout_t          DutOut;
    dout_t          RefOut;

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

    SC_CTOR(sc_basic_loops_TB):
        ap_clk("ap_clk", 100, SC_NS, 0.5, 0.0, SC_NS, false)
    {
        SC_THREAD(Test_Gen);
        sensitive << ap_clk;

        SC_THREAD(Test_Mon);
        sensitive << ap_clk;

        SC_THREAD(Memory);
        sensitive << ap_clk;

        u_basic_loops = new Ebasic_loops("u_Ebasic_loops");
        u_basic_loops->ap_clk(ap_clk);
        u_basic_loops->ap_rst(ap_rst);
        u_basic_loops->ap_start(ap_start);
        u_basic_loops->ap_done(ap_done);
        u_basic_loops->ap_idle(ap_idle);
        u_basic_loops->ap_ready(ap_ready);
        u_basic_loops->A_address0(A_address0);
        u_basic_loops->A_ce0(A_ce0);
        u_basic_loops->A_q0(A_q0);
        u_basic_loops->ap_return(ap_return);
    }
};

sc_basic_loops_TB.cpp

#include "sc_basic_loops_TB.h"
#include "basic_loops.h"

// Cycle-Accurate Test Generator
void sc_basic_loops_TB::Test_Gen()
{
    ap_start.write(0);
    ap_rst.write(1);

    wait(ap_clk.posedge_event());
    wait(ap_clk.posedge_event());

    ap_rst.write(0);

    while(true)
    {
        wait(ap_clk.posedge_event());

        if (ap_ready.read())
            ap_start.write(false);  // Hold hardware, New test vector

        if (ap_idle.read())
        {                           // At hardware's IDLE state,
            for(int i=0; i<10; i++) // Generate new test vector
                MEM_Ref[i] = MEM_Dut[i] = (int8_t)rand();

            ap_start.write(true);   // Then, START hardware
        }
    }
}

// Cycle-Accurate Output Monitor

void sc_basic_loops_TB::Test_Mon()
{
    int test_count = 0;
    while(true)
    {
        wait(ap_clk.posedge_event());

        if (ap_done.read())
        {
            RefOut = basic_loops(MEM_Ref); // Un-Timed Result
            DutOut = ap_return.read();  // Hardware Result

            if ((dout_t)RefOut!=(dout_t)DutOut)
                cout << "Error[";
            else
                cout << "Pass [";
            cout << std::setw(3) << test_count++ << "]:";
            cout << "RefOut=" << std::setw(5) << (dout_t)RefOut;
            cout << " | ";
            cout << "DutOut=" << std::setw(5) << (dout_t)DutOut;
            cout << std::endl;

            if (test_count>100)  break;
        }
    }
    sc_stop();
}

// Synchronous Memory

void sc_basic_loops_TB::Memory()
{
    while(true)
    {
        wait(ap_clk.posedge_event());

        if (A_ce0.read())
            A_q0.write(MEM_Dut[(sc_uint<8>)A_address0.read()]);
    }
}

5-2. 공동 시뮬레이션(Co-Simulation)

추상화 수준(abstraction level) 격차가 있는 이종 언어 사이의 공동 시뮬레이션(Co-Simulation)

pwd

  ~/ETRI050_DesignKit/Projects/HLS/basic_loops

$ make co-sim

  TOP_MODULE=basic_loops HW_STYLE=HW_STYLE make -C simulation build

  make[1]: Entering directory '.../simulation'
  verilator --sc -Wno-WIDTHTRUNC -Wno-WIDTHEXPAND \
            --trace --timing --pins-sc-uint \
            --top-module basic_loops  --exe --build \
            -CFLAGS -g \
            -CFLAGS -I../../c_untimed \
            -CFLAGS -I/opt/systemc/include \
            -CFLAGS -DVCD_TRACE_TEST_TB \
            -CFLAGS -DVCD_TRACE_DUT_VERILOG \
            -CFLAGS -DHW_STYLE_SC \
            -LDFLAGS -lm -LDFLAGS -lgsl \
            ./basic_loops/hls_component/syn/verilog/*.v  \
            ../c_untimed/basic_loops.cpp \
            ./sc_main.cpp ./sc_basic_loops_TB.cpp

  ......

  - V e r i l a t i o n   R e p o r t: Verilator 5.043 ......
  - Verilator: Built from 0.063 MB sources in 3 modules, ......
  - Verilator: Walltime 3.316 s (elab=0.031,......

  make[1]: Leaving directory '.../simulation'

  TOP_MODULE=basic_loops make -C simulation run

  make[1]: Entering directory '.../simulation'

  ./obj_dir/Vbasic_loops

        SystemC 3.0.2-Accellera --- Dec  8 2025 10:15:05
        Copyright (c) 1996-2025 by all Contributors,
        ALL RIGHTS RESERVED

  Info: (I703) tracing timescale unit set: 100 ps
                               (sc_basic_loops_TB.vcd)

  Warning: (W509) module construction not properly completed:...

  Pass [  0]:RefOut=  389 | DutOut=  389
  Pass [  1]:RefOut=    5 | DutOut=    5
  Pass [  2]:RefOut=  170 | DutOut=  170
   ......
  Pass [ 98]:RefOut=   51 | DutOut=   51
  Pass [ 99]:RefOut=  -74 | DutOut=  -74
  Pass [100]:RefOut= -115 | DutOut= -115

5-3. 디지털 시뮬레이션 결과 파형

$ make wave

  TOP_MODULE=basic_loops make -C ./simulation wave

  make[1]: Entering directory '.../simulation'

  gtkwave Vbasic_loops.vcd --save=Vbasic_loops.gtkw &
  gtkwave sc_basic_loops_TB.vcd --save=sc_basic_loops_TB.gtkw &

핸드-쉐이크와 동기식 메모리 인터페이스 타이밍에 유의할 것

계산) 103-58+105+115+81-1+74-20+41-51=389

6. ETRI050 노드

"내 칩 제작 서비스" 0.5um Si-CMOS(2P3M) 공정

6-1. 합성 환경

$ pwd

    ~/ETRI050_DesignKit/Projects/HLS/basic_loops

$ make ETRI050

    Create ETRI050/log directory......
    Link ETRI050/source directory......
    Create ETRI050/synthesis directory......

    Vitis-HLS Project: basic_loops
      Targetting ETRI050 node,

      (1) Synthesize
        TOP_MODULE=basic_loops make synth_ETRI050
      (2) Netlist Simulation
        TOP_MODULE=basic_loops make sim_ETRI050
        TOP_MODULE=basic_loops make wave_ETRI050
      (3) P&R, Generate layout
        TOP_MODULE=basic_loops make pnr_ETRI050
      (4) View GDS
        TOP_MODULE=basic_loops make layout_ETRI050

$ cd ETRI050

$ ll

    total 48
    drwxr-xr-x 7 mychip mychip 4096 Dec  9 14:24 .
    drwxr-xr-x 8 mychip mychip 4096 Dec  9 11:08 ..
    drwxr-xr-x 2 mychip mychip 4096 Nov  5 17:45 chip_top
    drwxr-xr-x 2 mychip mychip 4096 Dec  9 14:25 layout
    drwxr-xr-x 2 mychip mychip 4096 Dec  9 14:27 log
    drwxr-xr-x 2 mychip mychip 4096 Dec  9 14:24 simulation
    lrwxrwxrwx 1 mychip mychip   42 Dec  9 14:24 source -> ../basic_loops/hls_component/syn/verilog
    drwxr-xr-x 2 mychip mychip 4096 Dec  9 14:27 synthesis
    -rw-r--r-- 1 mychip mychip 5118 Dec  9 14:24 Makefile
    -rw-r--r-- 1 mychip mychip 1771 Dec  9 14:27 project_vars.sh
    -rwxr--r-- 1 mychip mychip 1904 Dec  9 14:27 qflow_exec.sh
    -rw-r--r-- 1 mychip mychip  857 Dec  9 14:27 qflow_vars.sh

합성에서 레이아웃 GDS 를 만드는 칩 작업은 급격한 추상화 수준의 변화가 일어난다. 이 변화는 대부분 자동화 도구에 의한다. 그 과정에서 생성되는 각종 중간 파일들이 저장될 디렉토리들이 존재한다. HLS로 얻은 베릴로그 RTL이 저장된 디렉토리가 소스 ./source 로 심볼링크 되어있다.

6-2. RTL 합성

RTL 베릴로그로 기술된 basic_loops 모듈을 ETRI050 표준 셀의 네트리스트로 합성한다. 합성은 행위 묘사에서 논리회로로 변환하는 절차다.

$ make synthesize

    qflow synthesize -T etri050 basic_loops

합성기가 실시하는 주요 절차를 따라가 본다. 자세한 합성 기록은 ./log/synth.log 다.

    --------------------------------
    Qflow project setup
    --------------------------------

    Technology set to etri050
    Regenerating files for existing project basic_loops
    Technology .magicrc file has been updated.
    Technology .par file has been updated.

    Running yosys for verilog parsing and synthesis

목표 공정기술을 etri050으로 지정하고 라이브러리 정의 파일(리버티 형식, Liberty)을 읽어들인다.

    yosys  -s basic_loops.ys

    /--------------------------------------------------------------\
    |  yosys -- Yosys Open SYnthesis Suite                         |
    |  Copyright (C) 2012 - 2025  Claire Xenia Wolf                |
    |  Distributed under an ISC-like license, type "license"....   |
    \--------------------------------------------------------------/

    Yosys 0.60+8 (git sha1 0e31e389f, clang++ 18.1.3 -fPIC -O3)
    
-- Executing script file `basic_loops.ys' --

    1. Executing Liberty frontend:
         /usr/local/share/qflow/tech/etri050/etri05_stdcells.lib

    Imported 39 cell types from liberty file.

    2. Executing Verilog-2005 frontend: ./source/basic_loops.v
       Parsing Verilog input from `../basic_loops.v'
                             to AST representation.
        Generating RTLIL representation for module `\basic_loops'.

        Successfully finished Verilog frontend.

        ......

기본적인 문법 검사를 마치면 합성을 시작한다. 먼저 설계 계층 구조 구축,

    4. Executing SYNTH pass.

    4.1.2. Analyzing design hierarchy..
    Top module:  \basic_loops
    Used module:     \basic_loops_flow_control_loop_pipe
    Removed 0 unused modules.

절차구문(프로시져, 베릴로그의 always @(...)) 분석한다. 메모리, 레지스터 등 순차구문 요소들을 확인한다.

    4.2. Executing PROC pass (convert processes to netlists).

사용되지 않는 순차구문 제거, 초기화 속성(동기 또는 비동기 리셋과 프리셋) 확인,

    4.2.3. Executing PROC_PRUNE pass
            (remove redundant assignments in processes).
        ......
    4.2.4. Executing PROC_INIT pass (extract init attributes).
        Found init rule in
           `\basic_loops_flow_control_loop_pipe.
                $proc$basic_loops_flow_control_loop_pipe.v:51$93'.
        Set init value: \ap_loop_init = 1'1
        Found init rule in
           `\basic_loops.$proc$/source/basic_loops.v:73$88'.
          Set init value: \ap_CS_fsm = 1'1
          Set init value: \ap_enable_reg_pp0_iter1 = 1'0
          Set init value: \x1_fu_42 = 4'0000
          Set init value: \out_accum2_fu_46 = 12'000000000000
          Set init value: \ap_done_reg = 1'0

    4.2.5. Executing PROC_ARST pass
             (detect async resets in processes).

절차구문 내에 조합 구문(멀티 플렉서)여부 검사: 롬 구조 또는 멀티 플렉서(온전한 case ... 또는 if~else~문),

    4.2.6. Executing PROC_ROM pass (convert switches to ROMs).

    4.2.7. Executing PROC_MUX pass
                    (convert decision trees to multiplexers).

온전하지 않은 경우 래치,

    4.2.8. Executing PROC_DLATCH pass
            (convert process syncs to latches).

행위 묘사에서 합성한 디지털 논리식의 최적화 과정은 매우 길게 이어진다. 최적화된 논리식을 얻는 도구는 ABC(A System for Sequential Synthesis and Verification) 다.

    4.22.1.1. Executed ABC.
    Extracted 93 gates and 125 wires to a netlist network
             with 31 inputs and 26 outputs.
    Running ABC script: <abc-temp-dir>/abc.script
    ABC: UC Berkeley, ABC 1.01 (compiled Dec  9 2025 10:44:30)
    ......

    4.22.1.2. Re-integrating ABC results.
    ABC RESULTS:               AND cells:        6
    ABC RESULTS:            ANDNOT cells:       22
    ABC RESULTS:              NAND cells:        8
    ABC RESULTS:               NOR cells:        9
    ABC RESULTS:               NOT cells:        1
    ABC RESULTS:                OR cells:       13
    ABC RESULTS:             ORNOT cells:        3
    ABC RESULTS:              XNOR cells:       13
    ABC RESULTS:               XOR cells:       13
    ABC RESULTS:        internal signals:       68
    ABC RESULTS:           input signals:       31
    ABC RESULTS:          output signals:       26

        ......

합성과 최적화된 디지털 논리(식)에 사용된 표준 셀들의 통계를 보자.

    4.25. Printing statistics.

    === basic_loops ===
        +----------Local Count, excluding submodules.
        | 
      102 wires
      229 wire bits
       37 public wires
      164 public wire bits
       10 ports
       32 port bits
      107 cells
       22   $_ANDNOT_
        6   $_AND_
        4   $_DFFE_PP_
        1   $_DFF_P_
        8   $_NAND_
        9   $_NOR_
        1   $_NOT_
        3   $_ORNOT_
       13   $_OR_
       12   $_SDFFCE_PP0P_
        2   $_SDFF_PP0_
       13   $_XNOR_
       13   $_XOR_
        1 submodules
        1   basic_loops_flow_control_loop_pipe

=== basic_loops_flow_control_loop_pipe ===
        +----------Local Count, excluding submodules.
        | 
       14 wires
       14 wire bits
       13 public wires
       13 public wire bits
       13 ports
       13 port bits
        2 cells
        1   $_OR_
        1   $_SDFFE_PP1P_

논리 요소들 앞에 $는 내부의 가상 셀들로 표현되었다는 뜻이다. ETRI050 디자인 킷에서 제공하는 표준 셀로 변환 해야 한다. 만일 동일한 기능의 셀이 제공되지 않는다면 등가 논리식으로 변환한다. 이때에도 ABC 가 동원된다.

    7. Executing ABC pass (technology mapping using ABC).

    7.1. Extracting gate netlist of module `\basic_loops'
                     to `<abc-temp-dir>/input.blif'..

    7.1.1. Executed ABC.
    Extracted 118 gates and 150 wires to a netlist network
                                 with 31 inputs and 37 outputs.

    Running ABC script: <abc-temp-dir>/abc.script

    ABC: UC Berkeley, ABC 1.01 (compiled Dec  9 2025 10:44:30)
        ......

    ABC: Scl_LibertyReadGenlib() skipped sequential cell "DFFNEGX1".
    ABC: Scl_LibertyReadGenlib() skipped sequential cell "DFFPOSX1".
    ABC: Scl_LibertyReadGenlib() skipped sequential cell "DFFSR".
    ABC: Scl_LibertyReadGenlib() skipped cell "FAX1" due to dont_use attribute.
    ABC: Scl_LibertyReadGenlib() skipped cell "PADVDD" without logic function.
    ABC: Scl_LibertyReadGenlib() skipped cell "PADGND" without logic function.

    ABC: Library "etri05_stdcells" from
         "/usr/local/share/qflow/tech/etri050/etri05_stdcells.lib"
         has 24 cells (15 skipped: 4 seq; 1 tri-state; 4 no func;
                 6 dont_use; 0 with 2 outputs; 0 with 3+ outputs).

        ......

    7.1. Extracting gate netlist of module `\basic_loops'....

    7.1.2. Re-integrating ABC results.
    ABC RESULTS:            AND2X2 cells:       11
    ABC RESULTS:           AOI21X1 cells:        4
    ABC RESULTS:           AOI22X1 cells:        1
    ABC RESULTS:             INVX1 cells:       41
    ABC RESULTS:           NAND2X1 cells:       44
    ABC RESULTS:           NAND3X1 cells:       10
    ABC RESULTS:            NOR2X1 cells:       33
    ABC RESULTS:           OAI21X1 cells:       33
    ABC RESULTS:           OAI22X1 cells:        1
    ABC RESULTS:             OR2X2 cells:        7
    ABC RESULTS:        internal signals:       82
    ABC RESULTS:           input signals:       31
    ABC RESULTS:          output signals:       37

        ......

    7.2. Extracting gate netlist of module
                     `\basic_loops_flow_control_loop_pipe'......

    7.2.2. Re-integrating ABC results.
    ABC RESULTS:             INVX1 cells:        1
    ABC RESULTS:            NOR2X1 cells:        1
    ABC RESULTS:           OAI21X1 cells:        1
    ABC RESULTS:        internal signals:        4
    ABC RESULTS:           input signals:        4
    ABC RESULTS:          output signals:        1

        ......

    13. Printing statistics.

    === basic_loops ===
        +----------Local Count, excluding submodules.
        |
      190 wires
      241 wire bits
      190 public wires
      241 public wire bits
       10 ports
       32 port bits
      230 cells
        1   $scopeinfo
       11   AND2X2
        4   AOI21X1
        1   AOI22X1
       21   BUFX2
       20   DFFPOSX1
       42   INVX1
       44   NAND2X1
       10   NAND3X1
       34   NOR2X1
       34   OAI21X1
        1   OAI22X1
        7   OR2X2

    End of script. Logfile hash: ...
    Number of gates changed: 0

합성이 완료되어 네트리스트가 만들어 졌다. 이후 작업(자동 배치 배선과 LVS)를 위한 파일 형식 변환이 이뤄진다. 배치 후 배선을 하려면 표준 셀의 내부 풋 프린트(셀 크기와 포트위치, 배선 금지구역등)를 들여다 봐야 한다. 표준 셀과 배선 규칙들을 기록하는 형식은 LEF(Library Exchange Format)다.

    Running vlog2Verilog for antenna cell mapping.

    vlog2Verilog -c -p -v vdd -g gnd \
      -l /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef \
      -o basic_loops.v basic_loops_sized.v

    Generating RTL verilog and SPICE netlist file in directory
    Files:
       Verilog: ./synthesis/basic_loops.rtl.v
       Verilog: ./synthesis/basic_loops.rtlnopwr.v
       Verilog: ./synthesis/basic_loops.rtlbb.v
       Spice:   ./synthesis/basic_loops.spc

향후 표준셀 배치배선을 마친 후 얻게될 레이아웃과 LVS(Layout-vs-Schematic)를 수행하기 위한 네트리스트를 만든다. 합성으로 얻은 네트리스트가 LVS 검사의 기준이 된다. 오픈-소스 LVS 도구는 netgen 이다. netgen은 SPICE 네트리스트 형식을 읽어 두 회로의 등가성을 검사한다.

    Running spi2xspice.py

    spi2xspice.py \
        "/usr/local/share/qflow/tech/etri050/etri05_stdcells.lib" \
        basic_loops.spc basic_loops.xspice

    Reading liberty netlist
        usr/local/share/qflow/tech/etri050/etri05_stdcells.lib

    Reading spice netlist basic_loops.spc

    Writing xspice netlist basic_loops.xspice

    Writing xspice file

    Done.

6-3. 합성 후 네트 시뮬레이션

....

$ cd simulation

$ make

    Netlist timing simulation using iVerilog-VPI:basic_loops

        TOP_MODULE=basic_loops HW_STYLE=HW_STYLE make build
        TOP_MODULE=basic_loops make run
        TOP_MODULE=basic_loops make wave

        TOP_MODULE=basic_loops make clean

$ ll

  total 1520
  drwxr-xr-x 2 ... .
  drwxr-xr-x 7 ... ..
  -rw-r--r-- 1 ... Makefile
  -rw-r--r-- 1 ... basic_loops_TB.v
  lrwxrwxrwx 1 ... sc_basic_loops_TB.cpp -> ../../simulation/sc_basic_loops_TB.cpp
  -rw-r--r-- 1 ... sc_basic_loops_TB.h
  -rw-r--r-- 1 ... vpi_basic_loops_tb.cpp
  -rw-r--r-- 1 ... vpi_basic_loops_tb_exports.h
  -rw-r--r-- 1 ... vpi_basic_loops_tb_ports.h
  -rw-r--r-- 1 ... vpi_stub.cpp

$ $ make build

    g++ -DVM_SC=1 \
        -I/usr/local/share/verilator/include \
        -I/usr/local/share/verilator/include/vltstd \
        -I/usr/local/include/iverilog -I/opt/systemc/include \
        -I../../c_untimed -I.. -L/opt/systemc/lib \
        -DHW_STYLE_SC -g -fPIC \
        ../../c_untimed/basic_loops.cpp \
        ./sc_basic_loops_TB.cpp \
        ./vpi_stub.cpp ./vpi_basic_loops_tb.cpp  \
        -o vpi_stub.vpi \
        -shared -latomic -lsystemc

    iverilog -g2005-sv -Tmin -gspecify -o basic_loops_TB  \
            basic_loops_TB.v  \
            ~/ETRI050_DesignKit/digital_ETRI/khu_etri05_stdcells.v  \
            ../synthesis/basic_loops_mapped.v

$ make run

    vvp -M. -mvpi_stub basic_loops_TB -v

    Icarus Verilog started
    VCD info: dumpfile basic_loops_TB.vcd opened for output.

    Info: (I703) tracing timescale unit set: 100 ps

    #0 s SystemC started
    Pass [  0]:RefOut=  389 | DutOut=  389
    Pass [  1]:RefOut=    5 | DutOut=    5
    Pass [  2]:RefOut=  170 | DutOut=  170
        ......
    Pass [ 98]:RefOut=   51 | DutOut=   51
    Pass [ 99]:RefOut=  -74 | DutOut=  -74
    Pass [100]:RefOut= -115 | DutOut= -115

    Info: /OSCI/SystemC: Simulation stopped by user

$ make wave

<그림 3,4>



6-4. 표준 셀 자동 배치와 배선

합성으로 얻은 네트리스트를 가지고 표준 셀 배치,

$ make place

    qflow place -T etri050 basic_loops

    --------------------------------
    Qflow project setup
    --------------------------------

    Technology set to etri050
    Regenerating files for existing project basic_loops
    Qrouter detail maze router version 1.4.88.T

    Reading LEF data from file
          /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef.

    LEF file:  Defines site corner (ignored)
    LEF file:  Defines site IO (ignored)
    LEF file:  Defines site core (ignored)
    LEF read: Processed 3266 lines.

    LEF Read: encountered 0 errors and 8 warnings total.

베릴로그 네트리스트를 자동 배치 오픈-소스 도구 graywolf의 입력 파일 형식 .cel 로 변환,

    Running vlog2Cel to generate input files for graywolf

    vlog2Cel  -l \
         /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef \
        -o ./layout/basic_loops.cel \
        ./synthesis/basic_loops.rtlnopwr.v

    Preparing pin placement hints from basic_loops.cel2

표준 셀 리버티와 입출력 핀 배치 파일 .cel2 참조하여 배치를 수행한다. 배치된 표준 셀의 빈 곳을 채우기 위해 필러 셀은 FILL 이다. 배치 후 배선도구가 사용할 네트리스트 형식은 DEF(Design Exchange Format)다.

    Running GrayWolf placement
    graywolf  basic_loops

    Running getantennacell to determine cell to use for antenna anchors.
    getantennacell.tcl basic_loops

    Running getfillcell to determine cell to use for fill.

    Running place2def to translate graywolf output to DEF format.
    place2def.tcl basic_loops FILL

    Running arrangepins to adjust pin positions for optimal routing.

    ......

<그림 5>

자동 배치로 얻은 DEF는 표준 셀 네트리스트에 표준 셀의 좌표와 놓인 방향 정보를 담고 있다.

$ ll layout

    total 348
    drwxr-xr-x 2 mychip mychip   4096 Dec  9 16:18 .
    drwxr-xr-x 7 mychip mychip   4096 Dec  9 14:24 ..
    -rw-r--r-- 1 mychip mychip    779 Dec  9 14:25 .magicrc
    -rw-r--r-- 1 mychip mychip  14563 Nov  5 17:45 ETRI050_CMOS.lyp
    -rw-r--r-- 1 mychip mychip   2862 Nov  5 17:45 Makefile
    -rw-r--r-- 1 mychip mychip 135246 Dec  9 16:18 basic_loops.cel
    -rw-r--r-- 1 mychip mychip     70 Dec  9 16:18 basic_loops.cel2
    -rw-r--r-- 1 mychip mychip    578 Dec  9 16:18 basic_loops.cfg
    -rw-r--r-- 1 mychip mychip  29126 Dec  9 16:18 basic_loops.def
    -rw-r--r-- 1 mychip mychip    116 Dec  9 16:18 basic_loops.info
    -rw-r--r-- 1 mychip mychip    320 Dec  9 16:18 basic_loops.obs
    -rw-r--r-- 1 mychip mychip   1671 Dec  9 14:25 basic_loops.par
    -rw-r--r-- 1 mychip mychip  69190 Dec  9 16:18 basic_loops.pin
    -rw-r--r-- 1 mychip mychip  11381 Dec  9 16:18 basic_loops.pl1
    -rw-r--r-- 1 mychip mychip   1807 Dec  9 16:18 basic_loops.pl2

$ less ./layout/basic_loops.def

    VERSION 5.6 ;
    DIVIDERCHAR "/" ;
    BUSBITCHARS "[]" ;
    DESIGN basic_loops ;
    UNITS DISTANCE MICRONS 100 ;

    DIEAREA ( -600 -600 ) ( 35700 36900 ) ;

    TRACKS Y -600 DO 126 STEP 300 LAYER metal1 ;
    TRACKS X -600 DO 122 STEP 300 LAYER metal2 ;
    TRACKS Y -600 DO 126 STEP 300 LAYER metal3 ;

    COMPONENTS 249 ;
    - _386_ BUFX2 + PLACED ( 150 150 ) S ;
    - _384_ BUFX2 + PLACED ( 1350 150 ) S ;
    - _316_ OR2X2 + PLACED ( 2550 150 ) S ;
    - _318_ NAND3X1 + PLACED ( 4050 150 ) FS ;
    - _319_ OAI21X1 + PLACED ( 5550 150 ) S ;
        ......
    - _208_ OR2X2 + PLACED ( 22650 10950 ) N ;
    - CLKBUF1_insert0 CLKBUF1 + PLACED ( 24150 10950 ) N ;
    - _363_ DFFPOSX1 + PLACED ( 27150 10950 ) N ;

        ......
    - FILL34650x18150 FILL + PLACED ( 34650 18150 ) N ;
    - FILL34650x25350 FILL + PLACED ( 34650 25350 ) N ;
    - FILL34650x28950 FILL + PLACED ( 34650 28950 ) S ;
    END COMPONENTS

    PINS 34 ;
    - gnd + NET gnd
      + LAYER metal1 ( -450 0 ) ( 450 0 )
      + PLACED ( 35580 30 ) N ;
    - vdd + NET vdd
      + LAYER metal1 ( -450 0 ) ( 450 0 )
      + PLACED ( -480 30 ) N ;
    - ap_clk + NET ap_clk
      + LAYER metal2 ( -52 -52 ) ( 52 52 )
      + PLACED ( 21300 36900 ) N ;
        ......
    END PINS

    NETS 245 ;
    - ap_clk
      ( PIN ap_clk ) 
      ( CLKBUF1_insert0 A ) 
      ( CLKBUF1_insert1 A ) 
      ( CLKBUF1_insert2 A ) 
      ( CLKBUF1_insert3 A ) ;
    - ap_clk_bF$buf0
      ( _365_ CLK ) 
      ( _359_ CLK ) 
      ( _370_ CLK ) 
      ( _376_ CLK ) 
      ( _361_ CLK ) 
      ( CLKBUF1_insert3 Y ) ;

배치하는 중에 구동력이 부족한 경우 버퍼가 삽입되기도 한다. 표준 셀 배선 도구는 qrouter 다. 자동 배치로 얻은 DEF를 읽어 배선 규칙에 따라 자동 배선 한다. 자동 배선 규칙이 포함된 배선 명령 스크립트 파일은 basic_loops.cfg 다.

$ cat ./layout/basic_loops.cfg

    # qrouter runtime script for project basic_loops
    verbose 1
    read_lef 
        /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef

    catch {layers 3}

    via stack none

    vdd vdd
    gnd gnd

    obstruction -9.0 364.5 360.0 372.0 metal1
    obstruction -9.0 -9.0 360.0 1.5 metal1
        ......
    obstruction 1.5 364.5 352.5 372.0 metal3
    obstruction 1.5 -9.0 352.5 1.5 metal3
    obstruction -9.0 1.5 1.5 364.5 metal2
    obstruction 352.5 1.5 360.0 364.5 metal2

    read_def basic_loops.def

    qrouter::standard_route basic_loops_route.def false

    quit

적층 비아를 금지하고 이미 표준셀이 점유 중인 배선할 수 없는 영역(obstruction)을 지정하고 있다.

$ make route

    qflow route -T etri050 basic_loops

    Running qrouter 1.4.88.T
    qrouter -noc  -s basic_loops.cfg

    *** Running stage1 routing with defaults
    Nets remaining: 200
    Nets remaining: 100
        ......

    Progress: Stage 1 total routes completed: 463
    Failed net routes: 9

    *** Running stage2 routing with options mask 10, effort 10
    Nets remaining: 9
    Nets remaining: 9
        ......

    Nets remaining: 1

    Progress: Stage 2 total routes completed: 508
    No failed routes!

    *** Running stage3 routing with defaults, 1st round
    Nets remaining: 200
    Nets remaining: 100
    Nets remaining: 80
        ......

    Nets remaining: 4
    Nets remaining: 1

    Progress: Stage 3 total routes completed: 929
    No failed routes!

    *** Running stage3 routing with defaults, 2nd round
    Nets remaining: 200
        ......
    Nets remaining: 1

    Progress: Stage 3 total routes completed: 1344
    No failed routes!

    *** Writing DEF file basic_loops_route.def

    Final: No failed routes!

최적의 배선을 위해 몇회 반복한다. 배선까지 마친 DEF에서 RC 정보를 추출하고 배선 전과 후를 비교하기 위해 네트리스트를 추출한다. 표준 셀을 배치하는 과정에서 구동력이 부족한 경우 버퍼 셀이 삽입되기도 하므로 배선까지 마친 네트리스트를 다시 추출한다.

    *** Writing RC file basic_loops_route.rc

    DEF2Verilog -v ./synthesis/basic_loops.rtlnopwr.v \
            -o ./synthesis/basic_loops_postroute.v \
            /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef
            basic_loops_route.def

    Generating RTL verilog and SPICE netlist file in directory
    Running vlog2Verilog.
    vlog2Verilog -c -v vdd -g gnd \
            -o basic_loops.rtl.anno.v basic_loops_postroute.v

    Running vlog2Spice.
    vlog2Spice -i \
    -l  /usr/local/share/qflow/tech/etri050/etri050_stdcells.sp \
    -o basic_loops.anno.spc basic_loops.rtl.anno.v

배선을 마친 DEF(./layer/basic_loops.def)에는 네트에 배선의 좌표와 필러셀 들이 포함된다.

    COMPONENTS 249 ;
    - _386_ BUFX2 + PLACED ( 150 150 ) S ;
    - _384_ BUFX2 + PLACED ( 1350 150 ) S ;
    - _316_ OR2X2 + PLACED ( 2550 150 ) S ;

        ......

    - FILL34650x18150 FILL + PLACED ( 34650 18150 ) N ;
    - FILL34650x25350 FILL + PLACED ( 34650 25350 ) N ;
    - FILL34650x28950 FILL + PLACED ( 34650 28950 ) S ;

    END COMPONENTS

    PINS 34 ;
    - gnd + NET gnd
      + LAYER metal1 ( -450 0 ) ( 450 0 )
      + PLACED ( 35580 30 ) N ;
    - vdd + NET vdd
      + LAYER metal1 ( -450 0 ) ( 450 0 )
      + PLACED ( -480 30 ) N ;
    - ap_clk + NET ap_clk
      + LAYER metal2 ( -52 -52 ) ( 52 52 )
      + PLACED ( 21300 36900 ) N ;
        ......
    - ap_return[0] + NET ap_return[0]
      + LAYER metal3 ( -60 -60 ) ( 60 60 )
      + PLACED ( 35700 19500 ) N ;
    END PINS

    NETS 245 ;
    - ap_clk
      ( PIN ap_clk ) 
      ( CLKBUF1_insert0 A ) 
      ( CLKBUF1_insert1 A ) 
      ( CLKBUF1_insert2 A ) 
      ( CLKBUF1_insert3 A ) 
    + ROUTED metal2 ( 9300 16500 ) ( * 16200 ) M3_M2 
      NEW metal3 ( 9300 16200 ) ( 17700 * ) M3_M2 
      NEW metal2 ( 17700 16200 ) ( * 16500 ) 
      NEW metal2 ( 24600 12600 ) ( * 13500 ) M3_M2 
      NEW metal3 ( 24600 13500 ) ( 17700 * ) M3_M2 
        ......
    + ROUTED metal2 (27900 36900) (28200 *) (* 33900) (27900 *) ;
    - ap_return[9]
      ( PIN ap_return[9] ) 
      ( _402_ Y ) 
    + ROUTED metal2 (18300 36900) (18000 *) (* 33900) (18300 *) ;
    END NETS

6-5. 표준 셀 병합과 LVS 검사

배치와 배선을 완료한 DEF에 표준 셀의 내부 트랜지스터 회로(레이아웃)을 병합한다.

$ make migrate

    qflow migrate -T etri050 basic_loops

    --------------------------------
    Qflow project setup
    --------------------------------

    Technology set to etri050
    Regenerating files for existing project basic_loops
    Running magic 8.3.538
    magic -dnull -noconsole  migrate_basic_loops.tcl

    Magic 8.3 revision 538

    Starting magic under Tcl interpreter
    Using the terminal as the console.

        ......

    Loading "migrate_basic_loops.tcl" from command line.

    Root cell box:
           width x height  (   llx,  lly  ), (   urx,  ury  )
    microns:   0.000 x 0.000   ( 0.000,  0.000), ( 0.000,  0.000)
    lambda:     0.00 x 0.00    (  0.00,  0.00 ), (  0.00,  0.00 )
    internal:      0 x 0       (     0,  0    ), (     0,  0    )

    Reading LEF data from file
        /usr/local/share/qflow/tech/etri050/etri050_stdcells.lef.

    This action cannot be undone.
    LEF read: Processed 3266 lines.
    Reading DEF data from file basic_loops.def.

    This action cannot be undone.
    DEF read, Line 13 (Error): END statement out of context.
      Processed 249 subcell instances total.
      Processed 34 pins total.
      Processed 245 nets total.
      Processed 2 special nets total.

    Generating LEF output basic_loops.lef for cell basic_loops:
    Diagnostic:  Write LEF header for cell basic_loops
    Diagnostic:  Writing LEF output for cell basic_loops

    Diagnostic:  Scale value is 0.150000
    Extracting BUFX2 into BUFX2.ext:
    Extracting OR2X2 into OR2X2.ext:
    Extracting NOR2X1 into NOR2X1.ext:
    Extracting OAI21X1 into OAI21X1.ext:
    Extracting NAND3X1 into NAND3X1.ext:
        ......
    Extracting CLKBUF1 into CLKBUF1.ext:
    Extracting OAI22X1 into OAI22X1.ext:
    Extracting AOI21X1 into AOI21X1.ext:
    Extracting basic_loops into basic_loops.ext:

    exttospice finished.

표준 셀이 병합된 레이아웃에서 LVS 에서 사용될  추출된 SPICE 네트리스트가 추출 된다. 병합된 레이아웃에서 트랜지스터의 네트리스트를 역추출한 후 LVS 검사를 수행할 수 있다. 오픈-소스 LVS 도구는 netgen 이다. 합성으로 얻은 네트리스트와 배치배선이 완료된 레이아웃에서 추출된 네트리스트를 비교하여 등가성을 검사한다.

$ make lvs

    ~/ETRI050_DesignKit/scripts/fix_net_name.sh \
                        ./synthesis/basic_loops.spc

    ***************************************************
    * Replace back-slash with underscore on netname
    ***************************************************

    qflow lvs -T etri050 basic_loops

    --------------------------------
    Qflow project setup
    --------------------------------

    Technology set to etri050
    Regenerating files for existing project basic_loops

    Running netgen

    netgen -batch lvs "basic_loops.spice basic_loops"  \
            "./synthesis/basic_loops.spc basic_loops"  \
            /usr/local/share/qflow/tech/etri050/etri050_setup.tcl  \
            comp.out -json -blackbox

    Netgen 1.5.295 compiled on Sat Aug  9 00:37:50 KST 2025

      ......

    Contents of circuit 1:  Circuit: 'basic_loops'
    Circuit basic_loops contains 233 device instances.
        ......
      Class: NOR2X1                instances:  34
      Class: NAND3X1               instances:  10
      Class: OAI22X1               instances:   1
      Class: DFFPOSX1              instances:  20
        ......
      Class: INVX1                 instances:  39
      Class: INVX2                 instances:   3
    Circuit contains 246 nets.

    Contents of circuit 2:  Circuit: 'basic_loops'
    Circuit basic_loops contains 233 device instances.

        ......
      Class: NOR2X1                instances:  34
      Class: NAND3X1               instances:  10
      Class: OAI22X1               instances:   1
      Class: DFFPOSX1              instances:  20
        ......
      Class: INVX1                 instances:  39
      Class: INVX2                 instances:   3
    Circuit contains 246 nets.

    Circuit 1 contains 233 devices, Circuit 2 contains 233 devices.
    Circuit 1 contains 246 nets,    Circuit 2 contains 246 nets.

    Final result:
        Circuits match uniquely.

    Logging to file "comp.out" disabled

    LVS Done.

    Running count_lvs.py

    /usr/local/share/qflow/scripts/count_lvs.py
    LVS reports no net, device, pin, or property mismatches.

    Total errors = 0

LVS 검사항목은 배선(net)을 포함하여 입출력 핀(pin) 그리고 트랜지스터의 갯수(device)와 특성(폭과 길이, property)들을 포함된다.

6-6. 레이아웃의 크기 측정

"내칩 제작 서비스" MPW의 표준 칩의 크기는 1900x1900um 다. 표준 입출력 패드를 고려하면 사용 가능한 설계영역(코어 크기)는 1000x1000 이내로 제한 된다.

$ make size

    ~/ETRI050_DesignKit/scripts/size_core.sh basic_loops

    **************************************************************
    * Measure the size of the Core
    **************************************************************

    Magic 8.3 revision 538
    Starting magic under Tcl interpreter
    Using the terminal as the console.

    Processing system .magicrc file
    Using technology "scmos", version 2001a

        ......

    Root cell box:
           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
    microns:  369.600 x 373.050  (-9.300, -3.600), ( 360.300,  369.450)  137879.297
    lambda:   1232.00 x 1243.50  (-31.00, -12.00), ( 1201.00,  1231.50)  1531992.00
    internal:   2464 x 2487    (   -62, -24   ), (  2402,  2463 )  6127968

7. 레이아웃 검사

자동화 도구에 의하여 생성된 레이아웃을 "내칩 제작 서비스"의 공정에서 요구하는 규정에 부합하는지 최종 검사한다. 자동배치와 배선을 마친 Magic 레이아웃이 저장되는 디렉토리는 ./layout 이다.

$ cd layout

$ pwd

    ~/ETRI050_DesignKit/Projects/HLS/basic_loops/ETRI050/layout

표준 셀들이 병합된 레이아웃은 오픈-소스 레이아웃 도구 Magic 의 형식으로 파일 확장명은 .mag 다.

$ ll

    total 988
    drwxr-xr-x 2 mychip mychip   4096 Dec 10 12:00 .
    drwxr-xr-x 7 mychip mychip   4096 Dec  9 14:24 ..
    -rw-r--r-- 1 mychip mychip    779 Dec  9 14:25 .magicrc
    -rw-r--r-- 1 mychip mychip    779 Dec  9 14:25 .magicrc.orig
    -rw-r--r-- 1 mychip mychip  14563 Nov  5 17:45 ETRI050_CMOS.lyp
    -rw-r--r-- 1 mychip mychip   2862 Nov  5 17:45 Makefile
    -rw-r--r-- 1 mychip mychip 135246 Dec  9 16:33 basic_loops.cel
    -rw-r--r-- 1 mychip mychip     70 Dec  9 16:18 basic_loops.cel2
    -rw-r--r-- 1 mychip mychip    578 Dec  9 16:33 basic_loops.cfg
    -rw-r--r-- 1 mychip mychip  84185 Dec  9 16:44 basic_loops.def
    -rw-r--r-- 1 mychip mychip 453348 Dec 10 11:53 basic_loops.lef
    -rw-r--r-- 1 mychip mychip  73697 Dec 10 11:53 basic_loops.mag
    
-rw-r--r-- 1 mychip mychip   1671 Dec  9 14:25 basic_loops.par
        ......
    -rw-r--r-- 1 mychip mychip  22924 Dec  9 16:44 basic_loops.rc
    -rw-r--r-- 1 mychip mychip  13126 Dec 10 11:53 basic_loops.spice
        ......

7-1. 적층 비아 검사(Stacked VIA)


7-2. 디자인 룰 검사 (Design Rule Check)


7-3. 네트리스트 등가 검사(Layout-Vs-Schematic)


8. 칩 탑(Chip Top)

입출력 패드 부착 후 공정에 제출할 최종 레이아웃 생성

MPW의 표준 패드 프레임 복사

코어 복사

표준 패드 프레임에 코어 레이아웃 넣기

입출력 패드 배치

코어와 입출력 패드 배선