Community研究與資料分析github.com

pleguina/tikz-hardware-figures

在 TikZ 中繪製出版級硬體/FPGA/資料流程方塊圖(HLS 核心、AIE 陣列、脈動陣列、SoC、管線),支援灰階或色盲安全色板。

tikz-hardware-figures 是什麼?

此技能提供一個強大的 TikZ 套件 `hwfig`,讓使用者在 LaTeX 文件中建立高品質、可編輯的硬體方塊圖。它專門針對現代異構計算架構設計,例如 HLS 核心、AI Engine 陣列、脈動陣列、NoC、SoC 區塊和記憶體層次結構。使用者只需描述所需的圖形,AI 就會產生完整的 TikZ 原始碼和編譯後的 PDF/PNG 預覽。該套件包含多種色盲安全色板(Okabe-Ito、Paul Tol 等),可確保在出版物、投影片和文件中具有良好的可讀性。關鍵功能包括用於路由和標籤的一致視覺語法、用於並行結構(如 AIE 陣列和加法器樹)的參數化 `pic` 元素,以及用於時脈域跨越和分組框架的專用節點樣式。AI 遵循結構化工作流程:獲取套件、選擇色板、在網格上規劃佈局、編譯並透過光柵化 PNG 進行視覺檢查,最後交付 .tex 原始碼、.sty 套件檔案和已編譯的 PDF,確保圖形易於整合到任何論文中。

相容平台~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 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

TikZ 硬體圖形 (hwfig v1.1)

當使用者需要在 LaTeX/TikZ 中建立硬體圖形時使用此技能:HLS/FPGA 核心的資料流程、量化神經網路層、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 公分,行間距 ±1.4 公分),然後進行連線。對於密集的資料流程圖,明確座標優於 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[<色板>]{hwfig})。

視覺語法(保持一致)

  • 資料流向左 → 右;主路徑位於水平軸上,平行分支位於上方/下方(±1.4 公分)。
  • 編譯時常數(ctime,虛線框)直接位於其配置的區塊上方/下方,並使用 darr(虛線箭頭)連接。
  • 每個改變精度的運算區塊後面都跟著一個 qbox(重新量化/移位/飽和)。
  • 分支透過肘型導線合併到 op 節點,導線垂直接近: \draw[arr] (qr.east) -| ($(sum.north)+(0,0.32)$) -- (sum.north);
  • 來自同一來源的替代分支:一個帶有點的分叉座標,\fill[hwwire] (fork) circle (1.3pt);,然後用 |- 肘型連接到每個分支。
  • 使用 hot 表示關鍵/高亮路徑,bus 表示具有 pic[pos=.5]{buswidth=512} 的寬資料路徑,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 公分的空間。節點、合併 op 和導線絕不能位於框架邊緣上 — 如果一個節點不屬於任何框架,則在框架外部為其留出空間。
  • 路由通道。 區域間的導線在框架之間的空通道中執行(定義:\def\chan{6.7}),然後在目標框架下方/上方的自己的水平層級上執行(\def\lvla{-1.7})。兩條導線絕不共享同一層級;在導線與任何平行框架邊緣或區塊側面之間保持 ≥ 0.3 公分,在平行導線之間保持 ≥ 0.4 公分。
  • 標籤僅位於空閒段上。 將 lbl/buswidth 放在完全位於空白空間的段上 — 絕不能放在導線穿過框架邊框的位置,也絕不能放在距離區塊約 0.2 公分以內。如果唯一的空閒段是垂直的,請將標籤旋轉為從下往上讀取: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(左側)。

參數化 pics

每個 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,...}(角色:io comp quant const op mem ctrl group);自動間距—

導線應繞過 pics 佈線(例如,從下方進入襯墊磁貼:(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 檔案,而不是使用 shell heredocs、sed 或 Python 字串文字:這些通常會將 \\ 轉換為 \(或將 \c... 轉換為控制字元)並破壞節點文字中的換行。
  • label= 文字中的冒號或逗號會破壞鍵解析 — 請用大括號將其括起來:label={[grouplabel]above:{INT8: shifts}}。
  • fit= 清單不能包含 ($(a)+(1,2)$)(逗號會分割清單);請先定義一個具名 \coordinate。
  • 若要在節點內新增額外一行,請使用純文字節點,搭配 align=center 和 \\[-2pt]{\tiny ...} — 不要在方塊上疊加第二個標籤。
  • shapes.geometric trapezium 搭配空文字會除以零 — 這就是為什麼 mux/demux 是自訂路徑圖片;不要將它們換回來。
  • 在 \foreach 內部,在節點名稱中使用數值之前,請使用 \pgfmathtruncatemacro 進行整數運算;在 \foreach \a/\b in {...} 中,標籤文字中的 / 會將其分割(請寫 Port,不要寫 I/O)。
  • clkdomain 具有淺色填色;當將其繪製在 fabric 或其他密集內容上時,請傳遞 fill=none。
  • MiKTeX 忽略 POSIX 風格的 TEXINPUTS;請將 hwfig.sty 放在 .tex 旁邊(或傳遞 --include-directory=<windows 路徑>)。
  • 對於雙欄論文,請將圖形寬度保持在約 16 公分以內,字體為 \footnotesize;僅在最後手段時使用 \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};

  % routing levels
  \def\chan{6.7}    % vertical channel between PL and AIE regions
  \def\lvla{-1.7}   % mm2s -> AIE, under the AIE frame
  \def\lvlb{-2.3}   % AIE -> s2mm, one level lower (= s2mm row)

  \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 -> shim 1: right into the channel, down, along level a, up into the shim
  \draw[arr] (k1.east) -- (\chan,1.6)
       -- node[lbl,rotate=90,below]{AXI4-S} (\chan,\lvla)
       -- (arr-s1.south|-{(0,\lvla)}) -- (arr-s1.south);
  % shim 4 -> s2mm: down to level b, left to 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 打包。

相關技能