Community연구 & 데이터 분석github.com

TikZ 하드웨어 그림 (hwfig v1.1)

HLS 커널, AIE 어레이, 시스톨릭 어레이, SoC, 파이프라인 등 하드웨어/FPGA/데이터플로우 블록 다이어그램을 TikZ로 출판 품질(흑백 또는 색맹 안전 팔레트)로 그리는 스킬입니다.

TikZ 하드웨어 그림 (hwfig v1.1)란 무엇인가요?

이 스킬은 LaTeX/TikZ 환경에서 하드웨어 블록 다이어그램을 그리는 전용 패키지 hwfig v1.1을 사용합니다. 사용자는 HLS/FPGA 커널의 데이터플로우, 양자화된 신경망 계층, Versal/Zynq SoC 구조, AI Engine 어레이, 시스톨릭 어레이, 가산기 트리, 파이프라인, NoC, 메모리 계층, 클록 도메인, 플로어플랜 등 다양한 하드웨어 주제의 그림을 요청할 수 있습니다. 스킬은 먼저 hwfig.sty 패키지 파일을 작업 디렉토리에 복사하고, 사용자가 별도 팔레트를 지정하지 않으면 기본적으로 grey 팔레트(흑백)를 사용하며, Okabe-Ito, Tol, Nord, Slate 등 색맹 안전 또는 슬라이드용 팔레트를 제공합니다. 그림은 격자 기반 좌표계를 사용하여 설계되고, 데이터 흐름은 왼쪽에서 오른쪽으로 진행되며, 컴파일 타임 상수, 양자화 블록, 연산 노드, 버스, 핫 패스 등 시각적 문법이 일관되게 적용됩니다. 출력은 편집 가능한 TikZ 소스(.tex)와 함께 컴파일된 PDF/PNG 미리보기이며, 논문에 바로 삽입할 수 있도록 설계되었습니다. 이 스킬은 Cursor, Claude Code, Codex 등 에이전트 환경에서 동작하며, 하드웨어 설계 자동화 및 문서화에 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pleguina/hwfig/tree/HEAD/skill

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

TikZ 하드웨어 그림 (hwfig v1.1)은(는) 무엇을 하나요?

사용자가 LaTeX/TikZ로 하드웨어 그림(예: HLS/FPGA 커널의 데이터플로우, 양자화된 NN 계층, Versal/Zynq SoC 블록 다이어그램, AI Engine 어레이, 시스톨릭 어레이, 가산기 트리, 파이프라인, NoC, 메모리 계층, 클록 도메인, 플로어플랜)을 원할 때 이 스킬을 사용하십시오. 출력은 항상 편집 가능한 TikZ 소스와 함께 컴파일된 PDF/PNG 미리보기입니다.

작업 흐름

  1. 패키지 가져오기. hwfig.sty를 이 스킬의 기본 디렉토리에서 작업 디렉토리로 복사합니다(사용자가 이미 복사본을 가지고 있지 않은 한 — 사용자 복사본의 \ProvidesPackage 줄에 v1.1이 없으면 업데이트를 제안하세요). 파일을 읽고 바이트 단위로 복사하십시오. 절대 다시 입력하거나 인라인으로 스타일을 재정의하지 마십시오. 팔레트는 역할 색상을 통해서만 작동합니다.
  2. 팔레트 선택 (기본값 grey), 패키지 옵션 \usepackage[okabe]{hwfig} 또는 \hwpalette{...} (그룹-로컬, 그림마다 적용):
    • grey — 인쇄/저널 기본값, 참조 템플릿을 따름(흰색 계산 상자, 회색 양자화기, 점선 회색 상수).
    • okabe — Okabe–Ito, 색맹 안전, 가장 강한 대비. 컬러 논문에 좋은 기본값.
    • tol — Paul Tol muted, 색맹 안전, 부드러움.
    • nord — 차가운 톤, 슬라이드용.
    • slate — 청회색 + 자주색 + 산호색, 과학 슬라이드 데크에 적합. 사용자가 지정하지 않으면 grey로 생성하고 하나의 컬러 팔레트를 제안하십시오. 비교를 위해 여러 팔레트로 같은 그림을 컴파일하려면 (standalone 문서 내부에서 \foreach \pal in {grey,okabe,...}{\hwpalette{\pal}...} 루프를 사용하면 각 페이지가 한 팔레트가 됩니다). 알 수 없는 팔레트 이름은 하드 오류입니다.
  3. 먼저 격자에 레이아웃을 스케치 (명시적 at (x,y) 좌표, 약 2.4 cm 열 간격, ±1.4 cm 행), 그런 다음 배선. 밀집된 데이터플로우 그림에서는 명시적 좌표가 positioning 라이브러리보다 좋습니다.
  4. 컴파일은 \documentclass[tikz,border=4pt]{standalone} + \usepackage{hwfig}로 pdflatex -interaction=batchmode -halt-on-error (타임아웃 설정; nonstopmode는 중단될 수 있음) 사용, pdftoppm -r 110 -png로 래스터화하고, PNG를 보고 겹침(와이어 위의 레이블, 상자를 가로지르는 와이어, 충돌하는 제목, 노드에 닿는 프레임 레이블 등)을 수정한 후 전달하십시오. 깔끔해질 때까지 반복하십시오.
  5. 전달은 .tex (논문에 바로 붙여넣을 수 있는 그림 본문), .sty, PDF를 함께 제공합니다. 사용자에게 논문에서 \usepackage{hwfig} (또는 \usepackage[<palette>]{hwfig})가 필요함을 상기시키십시오.

시각적 문법 (일관성 유지)

  • 데이터는 왼쪽 → 오른쪽으로 흐릅니다. 기본 경로는 수평 축에 있고, 평행 분기는 위/아래 (±1.4 cm)에 있습니다.
  • 컴파일 타임 상수 (ctime, 점선 상자)는 설정하는 블록 바로 위/아래에 있으며 darr (점선 화살표)로 연결됩니다.
  • 정밀도를 변경하는 모든 계산 블록 뒤에는 qbox (재양자화/시프트/포화)가 옵니다.
  • 분기는 수직으로 접근하는 엘보우 와이어로 op 노드에 합류합니다: \draw[arr] (qr.east) -| ($(sum.north)+(0,0.32)$) -- (sum.north);
  • 하나의 소스에서 대체 분기: 점이 있는 포크 좌표, \fill[hwwire] (fork) circle (1.3pt);, 그 다음 각 분기로 |- 엘보우.
  • 임계/강조 경로에는 hot을, 넓은 데이터 경로에는 pic[pos=.5]{buswidth=512}와 함께 bus를, 프로토콜 이름에는 node[lbl,midway,above]{AXI4-S} (lblbox는 레이블이 교차하는 와이어 위에 있어야 할 때)를 사용하십시오.
  • 그룹화 프레임은 배경 레이어에 fit으로 추가합니다: \begin{scope}[on background layer]\node[group,fit=(a)(b),label={[grouplabel]above:PL}] {};\end{scope}
  • 클록 도메인: clkdomain (강조 색상, 점선) 또는 clkdomain=<color>; 교차점을 cdc 노드로 표시.
  • 모든 그림은 \begin{tikzpicture}[hw]로 시작 (글꼴 \footnotesize, 선 두께, 화살표 끝 모양 설정).

라우팅 및 레이블 (모든 PNG에서 확인)

  • 영역 간 여백. 인접한 프레임(Runtime | Message passing, PL | AIE) 사이에 최소 0.6 cm 이상의 간격을 두십시오. 노드, 합류 op, 와이어는 절대 프레임 가장자리 위에 놓이면 안 됩니다. 노드가 어느 프레임에도 속하지 않으면, 두 프레임 외부에 공간을 주십시오.
  • 라우팅 채널. 영역 사이의 와이어는 프레임 사이의 빈 채널(정의: \def\chan{6.7})을 통해 달리고, 그런 다음 대상 프레임 아래/위의 자체 수평 레벨 (\def\lvla{-1.7})로 이동합니다. 두 와이어가 레벨을 공유하지 않도록 하고, 와이어와 평행한 프레임 가장자리 또는 블록 측면 사이에 최소 0.3 cm, 평행 와이어 사이에 최소 0.4 cm의 간격을 유지하십시오.
  • 레이블은 빈 세그먼트에만 배치. lbl/buswidth는 완전히 빈 공간에 있는 세그먼트에만 배치하십시오(와이어가 프레임 경계를 교차하는 곳이나 블록에서 약 0.2 cm 이내에는 절대 배치 금지). 유일한 빈 구간이 수직이면 레이블을 아래에서 위로 읽을 수 있도록 회전: node[lbl,rotate=90,below]{AXI4-S}. 짧은 링크에서는 pic[pos=.35..0.4]를 사용하여 숫자가 대상 블록에서 벗어나도록 하십시오.
  • 레이블이 있는 엘보우의 명시적 세그먼트. -|/|-는 선택한 구간에 레이블을 취할 수 없습니다. 모서리를 직접 작성: (a.east) -- (\chan,ya) -- node[lbl,...]{X} (\chan,\lvla) -- (b.south|-{(0,\lvla)}) -- (b.south);
  • 레이블의 수학: $W_{\mathrm{root}}$; 두 줄 레이블은 \\ 사용 (모든 스타일은 align=center 설정).

노드 스타일 (모든 팔레트 인식)

스타일용도
runtime실행 시간 입력/출력, 포트, 텐서
ctime컴파일 타임 상수: 가중치, 스케일, 설정
hlsbox계산 커널 / HLS 함수 / AIE 커널
qbox양자화기, 재양자화, 시프트+포화
op+, ×, max (원)
mux, demux멀티플렉서(입력 서쪽, 출력 동쪽) / 디멀티플렉서(미러)
mem, bram, uram온칩 버퍼
fifo스트림/FIFO
reg / ff클록 웨지가 있는 레지스터
lut, dspFPGA 기본 요소 (dsp는 오른쪽 상단 모서리 바깥에 작은 "DSP" 태그를 넣습니다 — 공간 확보)
extmemDDR / HBM (원통형)
cpuPS / ARM / RISC-V (이중 프레임)
host호스트 CPU (PCIe 측)
xbarAXI 상호 연결 / NoC 막대 (\rotatebox{90}{AXI IC})
routerNoC 라우터/스위치 (다이아몬드)
pe처리 요소
aieAI Engine 타일 (코어 + 로컬 메모리; 코어 중앙에 레이블)
chip패키지/다이 (핀 포함)
port작은 핀 마커
cdc클록 도메인 교차 동기화기
group, plregion, psregion, clkdomain배경 프레임
grouplabel, lbl, lblbox프레임 제목, 와이어 레이블 (lblbox = 흰색 배경)

엣지 스타일: arr, darr, bus, hot. 버스 틱: pic[pos=.5]{buswidth=32} (숫자는 틱 오른쪽) 또는 buswidth'=32 (왼쪽).

매개변수형 픽스

pic당 옵션 전달 — 해당 pic에만 로컬로 적용되므로, 다양한 크기가 하나의 그림을 공유할 수 있습니다: \pic (A) at (0,0) {aiearray={rows=2,cols=4}};. \hwset{key=value,...}는 현재 범위의 나머지에 대한 기본값을 설정합니다. 내부 노드는 (name-...)로 주소 지정 가능합니다.

pic키주소 지정 가능한 부분
aiearrayrows, cols, dx, dy, tilelabel타일 (n-t<r>-<c>) (r=1 하단), 쉼 (n-s<c>), 프레임 (n-box)
systolicrows, cols(n-pe<r>-<c>) (r=1 상단)
addertreedepth (2^depth 입력)입력 (n-in<k>), 가산기 (n-a<level>-<k>), 출력 (n-out)
pipelinelabels={Load,MAC,Requant,...}단계 (n-st<k>), 레지스터 (n-r<k>)
nocrows, cols, nocpe (true/false)라우터 (n-n<r>-<c>), PE (n-pe<r>-<c>)
fabriccolumns={I,C,C,D,C,B,...}, fabricrows (모든 값)열 상단 (n-c<k>). C=CLB D=DSP B=BRAM U=URAM I=IO
legendlegend={comp/Compute,mem/BRAM,...} (roles: io comp quant const op mem ctrl group); 자동 간격—

와이어는 pic 주위로 라우팅 (예: 아래에서 쉼 타일로: (k1.east) -- ++(0.9,0) |- ($(arr-s1.south)+(0,-0.35)$) -- (arr-s1.south)), 절대 타일을 통과하지 않도록.

사용자 정의 팔레트

@ 내부 메커니즘 불필요 — 8가지 역할(그리기, 채우기)과 세 가지 와이어 색상을 모두 설정:

\hwdefinepalette{mine}{%
  \hwrole{io}{black}{white} \hwrole{comp}{teal}{teal!12} \hwrole{quant}{orange}{orange!15}
  \hwrole{const}{black!55}{black!4} \hwrole{op}{red!70!black}{red!10} \hwrole{mem}{blue!60!black}{blue!10}
  \hwrole{ctrl}{violet}{violet!10} \hwrole{group}{teal!40}{teal!3}
  \hwwires{black}{black!50}{red!70!black}}   % 와이어, 상수 와이어, 강조/핫
\hwpalette{mine}

채우기는 25% 이하의 농도로 유지하여 검은 텍스트를 읽을 수 있게 하고, 회색조 변환에서도 역할이 분리되는지 확인하십시오.

주의 사항

  • .tex 파일은 파일 쓰기 도구로 작성하고, 셸 히어독, sed 또는 Python 문자열 리터럴로 작성하지 마십시오: 이런 도구들은 \\를 \로 (또는 \c...를 제어 문자로) 바꾸거나 노드 텍스트의 줄 바꿈을 깨뜨리는 경우가 많습니다.
  • label= 텍스트 내부의 콜론이나 쉼표는 키-값 구문 분석을 깨뜨립니다 — 중괄호로 감싸십시오: label={[grouplabel]above:{INT8: shifts}}.
  • fit= 목록은 ($(a)+(1,2)$)를 포함할 수 없습니다 (쉼표가 목록을 분할함); 먼저 명명된 \coordinate를 정의하십시오.
  • 노드 내부에 추가 줄을 넣으려면 align=center와 \\[-2pt]{\tiny ...}가 있는 일반 노드를 사용하십시오 — 상자에 두 번째 레이블을 겹쳐 놓지 마십시오.
  • shapes.geometric trapezium을 빈 텍스트와 함께 사용하면 0으로 나누기 오류가 발생합니다 — 이것이 mux/demux가 사용자 정의 경로 그림인 이유입니다; 다시 바꾸지 마십시오.
  • \foreach 내부에서 노드 이름에 값을 사용하기 전에 정수 산술을 위해 \pgfmathtruncatemacro를 사용하십시오; \foreach \a/\b in {...}에서 레이블 텍스트 내부의 /는 분할을 일으킵니다 (I/O 대신 Port로 작성).
  • clkdomain은 밝은 채우기가 있습니다; fabric이나 다른 밀집된 내용 위에 그릴 때는 fill=none을 전달하십시오.
  • MiKTeX는 POSIX 스타일 TEXINPUTS를 무시합니다; hwfig.sty를 .tex 옆에 두십시오 (또는 --include-directory=<windows path> 전달).
  • 그림은 두 칼럼 논문에서 \footnotesize일 때 폭이 약 16 cm를 넘지 않도록 유지하십시오; 최후의 수단으로만 \resizebox{\linewidth}{!}{...}로 크기 조정하십시오.

참조 예제 (GNN 계층, 하우스 템플릿)

\begin{tikzpicture}[hw]
  \node[runtime] (xin) at (-0.9,1.4) {$X_i$};
  \node[runtime] (xein) at (-0.9,-1.4) {$(X,E)$};
  \node[hlsbox] (root) at (2.5,1.4) {Root\\$W_{\mathrm{root}}x_i$};
  \node[qbox] (qr) at (4.9,1.4) {$Q_r$\\shift + sat8};
  \node[mem] (agg) at (2.5,-1.4) {Mean aggregation\\$m_i$};
  \node[hlsbox] (neigh) at (5.5,-1.4) {Neighbor\\$W_{\mathrm{neigh}}m_i+b$};
  \node[qbox] (qn) at (8.1,-1.4) {$Q_n$\\shift + sat8};
  \node[op] (sum) at (9.8,0) {$+$};
  \node[qbox,minimum width=1.45cm] (qc) at (11.6,0) {sat8};
  \node[hlsbox,minimum width=1.55cm] (relu) at (13.6,0) {$\rho_l$\\ReLU / id.};
  \node[runtime] (yout) at (15.5,0) {$y_i^{(l)}$};
  \node[ctime] (wroot) at (2.5,2.45) {$W_{\mathrm{root}}$};
  \node[ctime] (wneigh) at (5.5,-2.55) {$W_{\mathrm{neigh}},b$};
  \node[ctime] (sr) at (4.9,2.45) {$S_r$};
  \node[ctime] (sn) at (8.1,-2.55) {$S_n$};
  \node[ctrl] (fsm) at (13.6,-1.6) {Layer FSM};
  \draw[arr] (xin)--(root);
  \draw[bus] (xein)--(agg) pic[pos=.5]{buswidth=16};
  \draw[arr] (agg)--(neigh);
  \draw[arr] (root)--(qr);
  \draw[arr] (neigh)--(qn);
  \draw[arr] (qr.east) -| ($(sum.north)+(0,0.32)$) -- (sum.north);
  \draw[arr] (qn.east) -| ($(sum.south)+(0,-0.32)$) -- (sum.south);
  \draw[hot] (sum)--(qc);
  \draw[hot] (qc)--(relu);
  \draw[hot] (relu)--(yout);
  \draw[darr] (wroot)--(root);
  \draw[darr] (wneigh)--(neigh);
  \draw[darr] (sr)--(qr);
  \draw[darr] (sn)--(qn);
  \draw[darr] (fsm)--(relu);
  \begin{scope}[on background layer]
    \node[group,fit=(xin)(xein),label={[grouplabel]above:Runtime}] {};
    \node[group,fit=(root)(qr)(agg)(neigh)(qn)(wroot)(wneigh),label={[grouplabel]above:Message passing}] {};
  \end{scope}
\end{tikzpicture}

참조 예제 (Versal SoC)

\begin{tikzpicture}[hw]
  \node[host] (host) at (-3.4,0.3) {Host\\(x86)};
  \node[cpu] (ps) at (0,2.2) {PS\\Cortex-A72};
  \node[extmem] (ddr) at (0,-2.0) {DDR4};
  \node[xbar,minimum height=5.6cm] (noc) at (2,0.1) {\rotatebox{90}{NoC}};
  \node[hlsbox] (k1) at (4.7,1.6) {mm2s\\(HLS)};
  \node[hlsbox] (k2) at (4.7,-2.3) {s2mm\\(HLS)};
  \node[bram] (buf) at (4.7,-0.35) {BRAM buf};
  \pic (arr) at (8.3,0.1) {aiearray};

  % 라우팅 레벨
  \def\chan{6.7}    % PL과 AIE 영역 사이의 수직 채널
  \def\lvla{-1.7}   % mm2s -> AIE, AIE 프레임 아래
  \def\lvlb{-2.3}   % AIE -> s2mm, 한 레벨 아래 (= s2mm 행)

  \draw[bus] (host) -- (host-|noc.west) node[lbl,midway,above=2pt]{PCIe Gen4};
  \draw[arr] (ps.east) -- (ps-|noc.west);
  \draw[arr,<->] (ddr.east) -- (ddr-|noc.west);
  \draw[bus] (k1-|noc.east) -- (k1) pic[pos=.4]{buswidth=128};
  \draw[bus] (k2) -- (k2-|noc.east);
  % mm2s -> 쉼 1: 오른쪽으로 채널 진입, 아래로, 레벨 a 따라, 위로 쉼으로
  \draw[arr] (k1.east) -- (\chan,1.6)
       -- node[lbl,rotate=90,below]{AXI4-S} (\chan,\lvla)
       -- (arr-s1.south|-{(0,\lvla)}) -- (arr-s1.south);
  % 쉼 4 -> s2mm: 아래로 레벨 b까지, 왼쪽으로 s2mm까지
  \draw[arr] (arr-s4.south) -- (arr-s4.south|-{(0,\lvlb)})
       -- node[lbl,above,pos=0.2]{AXI4-S} (k2.east);
  \draw[darr] (buf) -- (k1);
  \draw[darr] (buf) -- (k2);

  \begin{scope}[on background layer]
    \node[psregion,fit=(ps),label={[grouplabel]above:PS}] {};
    \node[plregion,fit=(k1)(k2)(buf),inner sep=8pt,label={[grouplabel]above:PL @ 300 MHz}] {};
    \node[clkdomain,fit=(arr-box),inner sep=3pt,label={[grouplabel,text=hwaccent]above:AIE array $3\times4$ @ 1.25 GHz}] {};
  \end{scope}
\end{tikzpicture}

패키지 소스

hwfig.sty (v1.1, Pelayo Leguina, [email protected], LPPL 1.3c)는 이 파일 옆에 제공됩니다. 변경 로그, 갤러리 및 예제는 공개 hwfig 저장소에 있으며, 이 스킬은 skill/ 아래에서 유지 관리되고 skill/package.sh로 패키징됩니다.

관련 스킬