2026년 2월 27일 금요일

[베릴로그 RTL 예제] 탁구게임기 -1편-

[베릴로그 RTL 예제] 탁구게임기

0. 개요

베릴로그 HDL로 그리 화려하지는 않은 비디오 게임기를 만들어본다. 1인 탁구 게임기다. 마이크로 컨트롤러보드에서 C++언어로 이정도 게임기를 만들기는 그리 어려운 일은 아닐지도 모른다. 이런 동작을 하는 디지털 회로를 설계하기는 좀더 난해할 수 있다.

디지털 회로 설계에도 컴퓨팅 언어가 사용된다. 베릴로그 HDL(Hardware Description)을 사용할 것이다. 제대로 설계 되었는지 확인도 하지 않고 무턱대고 회로를 꾸밀 수는 없다. 하드웨어는 매우 단단해서 한번 잘못 만들어 놓으면 고치기는 매우 어렵다. 디지털 회로를 실제 하드웨어로 꾸며보기 전에 먼저 시뮬레이션을 해볼 텐데 프로그래밍 언어 C++와 하드웨어 묘사용 크래스 라이브러리 SystemC 를 사용한다. 동작이 확인 되면 디지털 논리 소자들은 FPGA 에 넣어 작동 시켜볼 것이다. 이에 만족하면 한걸음 더 나가 "내 칩"으로 만들어 보기로 하자. 세상에서 유일한 내가 만든 게임기 IC를 내놓을 꿈을 꾸면서 말이다. 나만의 반도체 IC 부품을 제작하려면 큰 비용이 들지만 우리나라 정부에서 학생들에게 무료로 제공하는 "내 칩 제작 서비스"를 통해 "내 칩"을 만들어 볼 수 있다. 왼쪽에 노란 딱지가 붙여진 칩이 탁구 게임기 "내 칩"이다. SOP 28 무료다.

1. 탁구대

비디오 게임기 설계를 목표하는 만큼 그래픽 시현에 대해 알아보자. 2파원 평면에 그림을 그리는 방식은 다양하지만 그중 가장 단순하면서 직관적인 것이 래스터 스캔(Raster Scan)이다. 가로와 세로로 훓어가며 그림이 될 좌표에 점을 찍는다. 그래픽 평면은 가로 128, 세로 64개의 점으로  정했다. 한 화면은 총 8192개의 점으로 구성된다. 공과 패들이 움직이는 모습을 보여 주려면 초당 10개 화면이 만들어져야 한다. 간단해 보이지만 무려 8만 1천여개의 점을 쏟아내는 하드웨어를 설계하는 것이 목표다.

움직이는 화면을 보여주려면 끊임 없이 가로 축 좌표와 세로축 좌표를 생성하고 그림의 위치에 점을 찍어 주어야 한다. 2차원 그래픽의 좌표점을 생성하고 탁구대의 벽을 그리는 하드웨어의 베릴로그 묘사는 다음과 같다. 디지털 회로의 카운터는 클럭을 받아 숫자를 센다. 가로축 좌표 x_pos 를 생성하기 위해 0부터 127까지 센다. 세로축 카운터의 숫자 범위는 0부터 63까지다. 각각 7비트와 6비트로 선언되었다. 가로 축 좌표 9에서 15 사이의 좌표점에 점을 찍어 탁구대 벽을 그리는 베릴로그 묘사는 다음과 같다.

//
// Filename: pong_SbS.v
// Purpose: Draw Table
//
module pong_SbS(clk, reset, x_pos, y_pos, pixel);
input           clk;
input           reset;
output [6:0]    x_pos;
output [5:0]    y_pos;
output          pixel;

    reg [6:0]   x_pos;
    reg [5:0]   y_pos;
    reg         pixel;
    always @(posedge clk or posedge reset)
    begin
        if (reset)
        begin
            x_pos <= 0;
            y_pos <= 0;
        end
        else
        begin
            x_pos += 1;
            if (x_pos==0)   y_pos += 1;
        end
    end

    assign pixel = (x_pos>9 && x_pos<15)? 1'b1:1'b0;

endmodule

가로 축 x_pos 는 7비트로 선언되었으므로 127(=1111111b)까지 센 후 다음은 0이다. 세로 축 y_pos는 가로 선을 모두 찍고난 x_pos가 0일 때 1씩 증가한다. 6비트 이므로 63(=111111b)다음은 0이다. 세로 축 카운트가 63까지 모두 세면 한 화면의 모두 그려진 셈이다.

탁구대 평면 그림을 그리는 베릴로그를 시뮬레이션 해보자. 테스트 벤치는 SystemC 로 작성 하였다.

//
// Filename: sc_pong_SbS_TB.h
//
#ifndef _SC_PONG_SBS_TB_H_
#define _SC_PONG_SBS_TB_H_

#include <systemc.h>

#ifdef VCD_TRACE_DUT_VERILOG
#include <verilated_vcd_sc.h>
#endif

#include "Vpong_SbS.h"

SC_MODULE(sc_pong_SbS_TB)
{
    sc_clock        clk;
    sc_signal<bool> reset;
    sc_signal<bool> pixel;
    sc_signal<sc_uint<7> > x_pos;
    sc_signal<sc_uint<6> > y_pos;

    Vpong_SbS*  u_pong_SbS;

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

#ifdef VCD_TRACE_DUT_VERILOG
    VerilatedVcdSc*     tfp;    // Verilator VCD
#endif

    void Test_Gen(void);

    SC_CTOR(sc_pong_SbS_TB):
            clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false)
    {
        SC_THREAD(Test_Gen);
        sensitive << clk;
        // Instantiate DUT ----------
        u_pong_SbS = new Vpong_SbS("u_pong_SbS");
        u_pong_SbS->clk(clk);
        u_pong_SbS->reset(reset);
        u_pong_SbS->x_pos(x_pos);
        u_pong_SbS->y_pos(y_pos);
        u_pong_SbS->pixel(pixel);

#ifdef VCD_TRACE_TEST_TB
        // VCD Trace
        fp = sc_create_vcd_trace_file("sc_pong_SbS_TB");
        fp->set_time_unit(100, SC_PS);
        sc_trace(fp, clk,   "clk");
        sc_trace(fp, reset, "reset");
        sc_trace(fp, x_pos, "x_pos");
        sc_trace(fp, y_pos, "y_pos");
        sc_trace(fp, pixel, "pixel");
#endif

#ifdef VCD_TRACE_DUT_VERILOG
        // Trace Verilated Verilog internals
        Verilated::traceEverOn(true);
        tfp = new VerilatedVcdSc;
        sc_start(SC_ZERO_TIME);
        u_pong_SbS->trace(tfp, 99);  // Trace levels of hierarchy
        tfp->open("Vpong_SbS.vcd");
#endif
    }
};
#endif

SystemC는 C++ 로 하드웨어를 묘사하기 위해 만들어진 크래스 라이브러리다. 만일 SystemC가 생소하다면 유튜브 동영상 "Learn SystemC"[링크]를 보도록 한다. 10여분짜리 6편으로 구성된 이 동영상은 SystemC를 간략하게 핵심만 짚어 설명한다. 처음 세편 정도만 들어보는 것 만으로 시작하기에 충분하다.

탁구대 그리기를 기술한 베릴로그 pong_SbS.v의 테스트벤치를 살펴보자. C++의 크래스를 사용하기 위해 먼저 SystemC를 인클루드 한다.

#include <systemc.h>

베릴로그 HDL로 묘사된 하드웨어를 SystemC의 테스트벤치로 불러오려면 언어변환 되어야 한다. 베릴레이터(Verilator)는 오픈-소스 언어변환기로서 베릴로그를 SystemC의 C++ 크래스로 변환해준다. C++의 SystemC 크래스로 변환된 베릴로그의 파일들은 현재 작업 디렉토리의 obj_drv에 저장된다. 언어 변환한 C++ 헤더 파일 명은 베릴로그 파일 앞에 대문자 V 가 붙는다. SystemC 테스트벤치에서 C++로 변환된 베릴로그의 헤더 파일을 인클루드 한다.

#include "Vpong_SbS.h"

테스트벤치 모듈은 SystemC의 크래스 sc_pong_SbS_TB 다. 크래스와 동일한 이름의 구성자(constructor)가 존재한다.

SC_MODULE(sc_pong_SbS_TB)
{
    SC_CTOR(sc_pong_SbS_TB):
            clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false)
    {

        ......

    }
};

구성자가 수행할 주요 임무 중 하나는 사건(event)과 이에 반응할 콜백(call-back) 함수의 지정이다. 클럭 신호 clk에 발생하는 사건에 감응되어 반응할 콜백 함수 Test_Gen() 를 아래와 같이 지정하였다.

        SC_THREAD(Test_Gen);
        sensitive << clk;

시험의 대상 DUT(Design Under Test)는 포인터 크래스로 선언되었다.

    Vpong_SbS*  u_pong_SbS;

DUT를 사례화(instantiate)한 후 지역 하드웨어 객체에 연결(mapping)도 구성자 내에서 이뤄진다.

        // Instantiate DUT ----------
        u_pong_SbS = new Vpong_SbS("u_pong_SbS");
        u_pong_SbS->clk(clk);
        u_pong_SbS->reset(reset);
        u_pong_SbS->x_pos(x_pos);
        u_pong_SbS->y_pos(y_pos);
        u_pong_SbS->pixel(pixel);

모듈 내의 지역 하드웨어 객체(베릴로그의 wire 또는 reg에 해당)들은 미리 선언 되었다.

    sc_clock        clk;
    sc_signal<bool> reset;
    sc_signal<bool> pixel;
    sc_signal<sc_uint<7> > x_pos;
    sc_signal<sc_uint<6> > y_pos;

주기적인 클럭을 선언하기 위한 객체는 sc_clock 이다. 주기(period)와 비율(duty ratio)등 클럭의 규격은 구성자와 함께 선언되었다. 다음은 테스트벤치의 구성자에서 주기 100 나노 초, 듀티 비 50% 인 클럭 발생기의 초기화 선언이다.

            clk("clk", 100, SC_NS, 0.5, 0.0, SC_NS, false)

하드웨어 신호 clk에 발생하는 사건에 감응된 콜백 함수 Test_Gen()는 별도의 sc_pong_SbS_TB.cpp에 기술하였다.

//
// Filename: sc_pong_SbS_TB.cpp
//
#include "sc_pong_SbS_TB.h"

void sc_pong_SbS_TB::Test_Gen()
{
    reset.write(true);
    wait(clk.posedge_event());
    wait(clk.posedge_event());
    wait(clk.posedge_event());
    reset.write(false);

    while(true)
    {
        wait(clk.posedge_event());
        if (x_pos.read()==127 && y_pos.read()==63)
        {
            wait(5000, SC_NS);
            sc_stop();
        }
    }
}

콜백 함수의 형식은 사건에 대기 시킬 수 있는 SC_THREAD 다. 사건 또는 시간 지연의 방식으로 테스트 절차를 기술 할 수 있다. 시뮬레이션이 개시되면 DUT에 reset 을 준 후 3회에 걸쳐 clk의 상승 엣지 사건을 기다린 후 리셋을 풀어준다. 이어 while(true)의 무한 반복문으로 이어진다. 실행 선점권을 이 무한 반복문이 점유하지 않도록 wait(clk.posedge_event()) 를 두고 있는 점에 유의한다.




2026년 2월 25일 수요일

유럽의 오픈-소스 칩(Open Source Chips for Europe)

유럽의 오픈-소스 칩(Open Source Chips for Europe)

Open Letter on the Urgency of Access to Open Source Chip Manufacturing
To Whom It May Concern
March 31, 2025

반도체 설계 인력의 부족이 심각하여 EU 위원회에서 "유럽 칩 법(European Chip Acts)"을 제정하고 투자를 아끼지 않고 있다고 합니다. 이에 공공 파운드리가 참여하고 PDK를 개방 하고 있으며 유수의 교육기관(대학)들이 참여 하고 있습니다. 2025년 3월에 게시된 유럽의 오픈-소스 칩의 현황과 향후 발전을 도모하기 위한 공개서한은 아래의 링크에서 확인 할 수 있습니다.

https://open-source-chips.eu/

위 서한에  등장하는 독일의 공공 팹 IHP에서 발표한 내용을 보면 설계인력의 부족 이 심각하여 이에 대응하기 위해 PDK를 공개하고 교육 과정을 마련 했다고 합니다. 이 교육과정의 시작이  2024년 인데 1년사이에 벌써 수십껀의 MPW를 수행 했다고 합니다.

독일의 오픈-소스 도구를 활용한 반도체 설계 인증 교육과정(2024년 발표)
https://fun-teaching-goodkook.blogspot.com/2024/09/blog-post_30.html

반도체 설계 인력 부족은 우리나라 뿐만 아니라 세계적인 현상 입니다. "내 칩 제작 서비스"가 반도체 설계 인력 양성에 기여할 수 있길 바랍니다.


2026년 2월 21일 토요일

인공지능 시대를 맞이하는 FPGA의 역활

인공지능 시대를 맞이하는 FPGA의 역활
FPGA In the new AI era

"인공지능 반도체(또는 AI 칩)"은 인공지능 알고리즘을 "효율적"으로 처리하는 칩(GPU, NPU, ASIC 등)이다. 범용 CPU에서도 인공지능 알고리즘의 수행이 물론 가능하다. 다만 AI 칩이라고 따로 분류하는 이유는 인공지능 알고리즘의 엄청난 량의 곱셈과 덧셈을 "효율적"으로 수행하는 것에 주안점을 두었기 때문이다.

범용 CPU가 미리 정해둔 규칙을 기반(Rule-Based)으로 IF~THEN~ELSE 방식의 알고리즘 처리에 적합하다면 AI 프로세서는 스스로 규칙을 만들기 위해 엄청난 계산을 한다. 범용 CPU로  인공지능 알고리즘을 수행하면 메모리에서 명령을 읽어 그 뜻을 해독하고 계산에 필요한 값을 불러와 계산하고 다시 그 값을 메모리에 저장하는 일을 수없이 반복한다. 명령중 정작 인공지능을 위한 계산 비중은 매우 낮다. 이에 비해 AI 칩은 범용 CPU의 ALU(Arithmetic-Logical Unit) 대신 단번에 곱셈과 덧셈(Multiplication-Accumulation)을 반복 계산하는 전용의 산술 장치를 가지고 있다. 당연히 명령을 해석하고 이에 맞춰 값을 불러오고 저장하는데 클럭을 소모하지 않는다. 따라서 AI 칩은 적은 클럭을 들이고도 방대한 계산을 할 수 있는 "효율적"인 반도체다. 게다가 자료의 교차 의존이 거의 없는 인공지능 알고리즘의 특성 상 대규모 연산기를 동원한 병렬처리 구조를 취하기 매우 적합하다. 반도체 칩의 집적도가 폭발해 버린 지금 연산장치의 갯수는 얼마든지 늘릴 수 있다. 일상의 인식체계(패러다임)가 경직된 규칙 기반의 알고리즘에서 유연한 인공지능으로 전환되어 버린 지금 반도체의 화두는 "AI"의 지배가 더욱 공고해질 것은 자명하다.

인공지능의 유연성에 하드웨어의 경직성이 대응하는 방안은 명령처리 방식의 프로세서다. 인공지능 프로세서는 매우 특회된 몇가지 산술명령을 가지고 고용량 메모리를 곁에 두고 있다. 대부분 인공지능 개발자들이 전용 프로세서의 소프트웨어에 집중되어 있는 것을 본다. GPU, NPU 등 프로세서가 지배적인 "AI 칩"에 FPGA의 미래가 있을까?

구조 재편이 가능한 FPGA는 하드웨어의  유연화 방안으로 주목받고 있다. 아예 명령어 자체를 두지 않는 알고리즘 전용의 계산기(하드웨어)를 구성 할 수 있다. 따라서 알고리즘에 소요될 클럭의 수를 극단적으로 줄일 수 있다. 클럭은 곧 에너지 소모를 의미한다. 특히 일방적인 계산을 반복하는 "추론(inference)"에 재구성 가능한 FPGA의 미래가 있다.

아래 동영상은 인공지능 알고리즘에 맞춰 FPGA의 구조가  어떻게 변화되고 있는지 설명한다. 순차적인 알고리즘을 병렬처리 하드웨어를 목표로 기술하기는 소프트웨어에 비하면 매우 어렵다. 하드웨어 설계 생산성을 높이기 위해 기존의 프로그래밍 언어로 기술된 알고리즘을 직접 하드웨어로 합성하는 설계방법론이 이미 성숙되었음을 보여 준다.

The Hidden Weapon for AI Inference EVERY Engineer Missed
거의 모든 기술자들이 놓치고 있는 인공지능 추론용 하드웨어 장치
https://youtu.be/ysd545AjEOU?si=hNBOzb8lbcLSGXxT

How to Build a Neural Network on an FPGA
FPGA에 신경망을 구성하는 방법
https://youtu.be/3qtMs5jD-OY?si=joOEUEez7sbfYFk3

Resources Mentioned:
    hls4ml Repository: https://github.com/fastmachinelearning/hls4ml
    Iris Model on FPGAs GitLab: https://gitlab.com/ai-examples/iris-model-on-fpgas/
    Make your own Neural Network by TARIQ RASHID [pdf]


이미 핏빛으로 물들어 있는 인공지능 소프트웨어에서 그나마 시원한 하드웨어 설계에 눈길을 줘보자. 끝으로,

Challengers Are Coming for Nvidia’s Crown
엔비디아의 아성에 도전자들이 몰려온다 [링크]

    [검색 참고]
    "규칙 기반 알고리즘" [검색]
    "AI Semiconductor" [검색]




2026년 1월 20일 화요일

"내 칩" 에뮬레이션 검증 키트: 조립과 시험(칩 테스터 편)

"내 칩" 에뮬레이션 검증 키트: 조립과 시험(칩 테스터 편)

"내 책상 위에서 내 칩 설계(MyChip-on-MyDesk)"

- "내 칩" 에뮬레이션 검증 키트: 자재 목록 [링크]
- "내 칩" 에뮬레이션 검증 키트: 조립과 시험 (측정기 편) [링크]
- "내 칩" 에뮬레이션 검증 키트: 조립과 시험 (에뮬레이터 편) [링크]

목차:

1. 테스트: "내 칩" 설계의 완성 
2. PSCE-TESTER 회로도와 부품
3. PSCE-TESTER 보드 조립
4. PSCE-MI/TRANS/TESTER 동작 시험

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

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

1. 테스트: "내 칩" 설계의 완성

"내 칩 제작 서비스[링크]"는 ETRI 반도체 실험실의 0.5um Si-CMOS 공정을 활용한 MPW 파운드리 서비스다. 칩 공정은 물론 패키지까지 무료로 제공한다. MPW는 연 4회에 걸쳐 진행된다. 각고의 노력 끝에 설계한 "내 칩"을 몇개월에 걸친 기다림 끝에 마침내 내 손에 받아들었다. 그냥 들여다 보자고 공을 들인 것이 아니다. 내가 설계한 IC 부품을 내 책상 위에서 내 손으로 테스트 해보자. 설계한 의도대로 작동 하는지 봐야 비로서 "내 칩"이라고 드러내 말할 수 있다.

2. PSCE-TESTER 회로도와 부품


3. PSCE-TESTER 보드 조립

3-1. 2열 28핀 직각 헤더 소켓, 1열 14핀 헤더 소켓(2개)

- 우측의 2열 28핀 직각 헤더 소켓은 PSCE-TRANS에 연결
- 중앙의 1열 14핀 암 헤더 소켓(2개)은 28핀 SOP 테스트 소켓을 꼽을 자리


3-2. 28핀 SOP 테스트 칩 장착

- MPW로 제작된 SOP28 패키지의 "내 칩" 테스트 소켓에 장착

"내 칩"을 테스트 소켓에 주의하여 장착한다.

3-3. PSCE-MI/TRANS/TESTER 를 모두 결합

아래 사진은 PSCE-MI/TRANS/TESTER를 모두 결합한 모습이다. PSCE-MI의 측정기 부분에 피코 W(와이파이 모듈)가 장착되었다. 안드로이드 휴대전화를 로직스코프의 시현 장치로 사용중이다.

4. "내 칩"동작 시험

디자인 킷에 준비된 예제를 실행 하여 "내 칩"을 테스트 한다. 테스트 대상 칩은 "내 칩 제작 서비스"의 MPW를 통해 제작된 "내 칩" 샘플이다. 아래에 설명하는 절차는 윈도우즈 WSL에 우분투 리눅스 24.04를 기준으로 한다. 아울러 오픈-소스 설계 도구와 알테라 FPGA용 쿼터스가 설치된 경우다.

4-1. 모델링 인터페이스 펌웨어 빌드

모델링 인터페이스 펌웨어를 빌드하는 방법은 "에뮬레이터 편[링크]"과 동일하다.

    $ make build-mi

4-2. "내 칩" 트랜잭터 빌드

DUT가 "내 칩"으로 제작 되었으므로 FPGA에는 트랜잭터 만 들어간다.

    $ make build-tester

4-3. 모델링 인터페이스 펌웨어 업로드

피코에 모델링 인터페이스 펌웨어를 업로드 하는 절차는 "내 칩" 에뮬레이션 검증 키트: 에뮬레이터 편[링크]의 4-2절과 같다. 에뮬레이션의 테스트 벤치를 칩 테스트에서도 동일하게 사용할 것이다.

    $ make upload-mi

4-4. "내 칩" 테스트 트랜잭터 구성

JTAG 다운로드 케이블이 인식 되었는지 확인 후 칩 테스트 용 트랜잭터를 FPGA에 구성,

    $ make config-tester

4-5. "내 칩" 테스트 에뮬레이션 실행

에뮬레이션 테스트벤치 실행,

    $ make co-emu

"내 칩"은 FPGA의 트랜잭터를 통해 테스트벤치와 입출력을 주고 받는다. 따라서 테스트벤치의 입장에서 타깃이 되는 하드웨어가 FPGA에 구현된 DUT인지 MPW를 거쳐 제작된 "내 칩"인지 구분하지 않아도 된다. 베릴로그 기능 검증에서 사용했던 테스트벤치를 에뮬레이션과 칩 테스트에 이르기까지 재사용 하였다. SystemC로 작성된 테스트 벤치가 검증의 대상이 되는 DUT의 추상화 수준의 정도를 따지지 않는 "시스템 수준"의 검증 방법이다.