Figuras TikZ de hardware (hwfig v1.1)

Dibuja diagramas de bloques de hardware/FPGA/dataflow de calidad de publicación en TikZ (kernels HLS, arreglos AIE, arreglos sistólicos, SoCs, pipelines) en escala de grises o paletas seguras para daltonismo.

¿Qué es Figuras TikZ de hardware (hwfig v1.1)?

Esta habilidad está diseñada para ayudar a desarrolladores e ingenieros de hardware a generar diagramas de bloques de hardware, FPGA y flujo de datos de alta calidad, listos para publicación, usando TikZ en LaTeX. Soporta una amplia gama de componentes como kernels HLS, arreglos de motores de IA (AIE), arreglos sistólicos, SoCs Versal/Zynq, pipelines, memorias, dominios de reloj y más. La salida es código TikZ editable y una vista previa compilada en PDF/PNG. La habilidad incluye paletas de colores seguras para daltonismo (Okabe-Ito, Paul Tol, Nord, Slate) y una paleta de grises predeterminada para revistas. Proporciona guías detalladas sobre gramática visual, enrutamiento, etiquetado y uso de estilos de nodo como `hlsbox`, `qbox`, `mem`, `aie`, `group`, etc. También ofrece componentes paramétricos (`pic`) para arreglos AIE, matrices sistólicas, árboles de sumadores, pipelines y NoCs. Está diseñado para herramientas de agente de IA como Claude Code, Cursor y Codex, y se utiliza cuando el usuario solicita una figura de hardware en LaTeX/TikZ.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pleguina/hwfig/tree/HEAD/skill

Installed? Explore more Investigación y análisis de datos skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Figuras TikZ de hardware (hwfig v1.1)?

Usa esta habilidad siempre que el usuario quiera una figura de hardware en LaTeX/TikZ: flujo de datos de un kernel HLS/FPGA, una capa de red neuronal cuantizada, un diagrama de bloques de un SoC Versal/Zynq, arreglos de motores de IA (AIE), arreglos sistólicos, árboles de sumadores, pipelines, NoCs, jerarquías de memoria, dominios de reloj, planos de planta. La salida es siempre código TikZ editable más una vista previa compilada en PDF/PNG.

Flujo de trabajo

  1. Obtén el paquete. Copia hwfig.sty del directorio base de esta habilidad al directorio de trabajo (a menos que el usuario ya tenga una copia — si la suya no tiene v1.1 en su línea \ProvidesPackage, ofrécete a actualizarla). Lee el archivo y cópialo byte por byte; nunca lo reescribas ni redefinas los estilos en línea — las paletas solo funcionan a través de los colores de rol.
  2. Elige una paleta (por defecto grey), ya sea como opción del paquete \usepackage[okabe]{hwfig} o con \hwpalette{...} en cualquier lugar (local al grupo, por lo tanto por figura):
    • grey — predeterminado para impresión/revistas, refleja la plantilla de referencia (cajas de cómputo blancas, cuantizadores grises, constantes grises discontinuas).
    • okabe — Okabe–Ito, segura para daltonismo, máximo contraste. Buena opción predeterminada para artículos a color.
    • tol — Paul Tol muted, segura para daltonismo, más suave.
    • nord — tonos fríos, para diapositivas.
    • slate — azul grisáceo + malva + coral, combina con presentaciones científicas. Si el usuario no lo especifica, produce grey y ofrece una paleta de color; para comparar, compila la misma figura en varias paletas (un bucle \foreach \pal in {grey,okabe,...}{\hwpalette{\pal}...} dentro de un documento standalone da una página por cada una). Un nombre de paleta desconocido es un error grave.
  3. Dibuja el diseño en una cuadrícula primero (coordenadas at (x,y) explícitas, paso de columna ~2.4 cm, filas ±1.4 cm), luego cablea. Las coordenadas explícitas son mejores que positioning para figuras de flujo de datos densas.
  4. Compila como \documentclass[tikz,border=4pt]{standalone} + \usepackage{hwfig} con pdflatex -interaction=batchmode -halt-on-error (con tiempo de espera; nonstopmode puede colgarse), rasteriza con pdftoppm -r 110 -png, mira el PNG y corrige superposiciones (etiquetas sobre cables, cables que cruzan cajas, títulos que chocan, etiquetas de marco que tocan nodos) antes de entregar. Itera hasta que quede limpio.
  5. Entrega el .tex (cuerpo de la figura listo para pegar en un artículo), el .sty y el PDF. Recuerda al usuario que en su artículo necesita \usepackage{hwfig} (o \usepackage[<paleta>]{hwfig}).

Gramática visual (mantenla consistente)

  • Los datos fluyen de izquierda a derecha; la ruta principal se sitúa sobre un eje horizontal, las ramas paralelas arriba/abajo (±1.4 cm).
  • Las constantes en tiempo de compilación (ctime, caja discontinua) se sitúan directamente encima/debajo del bloque que configuran y se conectan con darr (flecha discontinua).
  • Cada bloque de cómputo que cambia de precisión va seguido de un qbox (requantización/desplazamiento/saturación).
  • Las ramas se fusionan en un nodo op con cables de codo que se aproximan verticalmente: \draw[arr] (qr.east) -| ($(sum.north)+(0,0.32)$) -- (sum.north);
  • Ramas alternativas desde una fuente: una coordenada de bifurcación con un punto, \fill[hwwire] (fork) circle (1.3pt);, luego codos |- hacia cada rama.
  • Usa hot para la ruta crítica/destacada, bus para caminos de datos anchos con pic[pos=.5]{buswidth=512}, node[lbl,midway,above]{AXI4-S} para nombres de protocolo (lblbox cuando la etiqueta debe colocarse sobre cables que se cruzan).
  • Los marcos de agrupación van en la capa de fondo con fit: \begin{scope}[on background layer]\node[group,fit=(a)(b),label={[grouplabel]above:PL}] {};\end{scope}
  • Dominios de reloj: clkdomain (color de acento, discontinuo) o clkdomain=<color>; marca los cruces con un nodo cdc.
  • Comienza cada imagen con \begin{tikzpicture}[hw] (establece la fuente \footnotesize, el ancho de línea, las puntas de flecha).

Enrutamiento y etiquetas (verifica estos en cada PNG)

  • Espacios entre regiones. Deja ≥ 0.6 cm entre marcos adyacentes (Runtime | Message passing, PL | AIE). Los nodos, los op de fusión y los cables nunca deben apoyarse en el borde de un marco — si un nodo no pertenece a ningún marco, dale espacio fuera de ambos.
  • Canales de enrutamiento. Los cables entre regiones corren en un canal vacío entre los marcos (defínelo: \def\chan{6.7}), luego en su propio nivel horizontal debajo/encima del marco de destino (\def\lvla{-1.7}). Dos cables nunca comparten un nivel; mantén ≥ 0.3 cm entre un cable y cualquier borde de marco o lado de bloque paralelo, y ≥ 0.4 cm entre cables paralelos.
  • Las etiquetas solo van en segmentos libres. Pon lbl/buswidth en un segmento que esté completamente en espacio vacío — nunca donde el cable cruce un borde de marco, y nunca a menos de ~0.2 cm de un bloque. Si el único tramo libre es vertical, rota la etiqueta para que se lea de abajo arriba: node[lbl,rotate=90,below]{AXI4-S}. En enlaces cortos usa pic[pos=.35..0.4] para que el número se aleje del bloque de destino.
  • Segmentos explícitos para codos etiquetados. -|/|- no pueden tomar una etiqueta en una pata elegida; escribe las esquinas explícitamente: (a.east) -- (\chan,ya) -- node[lbl,...]{X} (\chan,\lvla) -- (b.south|-{(0,\lvla)}) -- (b.south);
  • Matemáticas en etiquetas: $W_{\mathrm{root}}$; etiquetas de dos líneas con \\ (todos los estilos tienen align=center).

Estilos de nodo (todos conscientes de la paleta)

estilouso
runtimeEntradas/salidas, puertos, tensores en tiempo de ejecución
ctimeConstantes en tiempo de compilación: pesos, escalas, configuración
hlsboxKernel de cómputo / función HLS / kernel AIE
qboxCuantizador, requantización, desplazamiento+sat
op+, ×, max (círculo)
mux, demuxMultiplexor (entradas al oeste, salida al este) / demultiplexor (espejo)
mem, bram, uramBúferes en chip
fifoStream/FIFO
reg / ffRegistro con cuña de reloj
lut, dspPrimitivas FPGA (dsp coloca una pequeña etiqueta "DSP" fuera de su esquina superior derecha — deja espacio)
extmemDDR / HBM (cilindro)
cpuPS / ARM / RISC-V (doble marco)
hostCPU host (lado PCIe)
xbarInterconexión AXI / barra NoC (\rotatebox{90}{AXI IC})
routerEnrutador/conmutador NoC (diamante)
peElemento de procesamiento
aieTile de motor de IA (núcleo + memoria local; etiqueta centrada en el núcleo)
chipPaquete/dado con pines
portMarcador de pin pequeño
cdcSincronizador de cruce de dominio de reloj
group, plregion, psregion, clkdomainMarcos de fondo
grouplabel, lbl, lblboxTítulos de marco, etiquetas de cable (lblbox = fondo blanco)

Estilos de borde: arr, darr, bus, hot. Marca de bus: pic[pos=.5]{buswidth=32} (número a la derecha de la marca) o buswidth'=32 (a la izquierda).

Pics paramétricos

Pasa opciones por pic — permanecen locales a ese pic, por lo que diferentes tamaños pueden compartir una imagen: \pic (A) at (0,0) {aiearray={rows=2,cols=4}};. \hwset{key=value,...} establece valores predeterminados para el resto del ámbito actual. Los nodos internos son direccionables como (name-...).

picclavespartes direccionables
aiearrayrows, cols, dx, dy, tilelabeltiles (n-t<r>-<c>) (r=1 abajo), shims (n-s<c>), marco (n-box)
systolicrows, cols(n-pe<r>-<c>) (r=1 arriba)
addertreedepth (2^depth entradas)entradas (n-in<k>), sumadores (n-a<level>-<k>), salida (n-out)
pipelinelabels={Load,MAC,Requant,...}etapas (n-st<k>), registros (n-r<k>)
nocrows, cols, nocpe (verdadero/falso)enrutadores (n-n<r>-<c>), PEs (n-pe<r>-<c>)
fabriccolumns={I,C,C,D,C,B,...}, fabricrows (cualquier valor)partes superiores de columna (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); espaciado automático—

Enruta los cables alrededor de los pics (por ejemplo, hacia los tiles shim desde abajo: (k1.east) -- ++(0.9,0) |- ($(arr-s1.south)+(0,-0.35)$) -- (arr-s1.south)), nunca a través de los tiles.

Paletas personalizadas

No se necesitan internas @ — establece los 8 roles (dibujo, relleno) y los tres colores de cable:

\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}}   % cable, cable constante, acento/caliente
\hwpalette{mine}

Mantén los rellenos ≤ 25% de tinte para que el texto negro siga siendo legible y verifica que la conversión a escala de grises aún separe los roles.

Errores comunes

  • Escribe los archivos .tex con la herramienta de escritura de archivos, no con heredocs de shell, sed o literales de cadena de Python: esos convierten \\ en \ (o \c... en caracteres de control) y rompen los saltos de línea en el texto del nodo.
  • Un signo de dos puntos o coma dentro del texto de label= rompe el análisis de claves — ponlo entre llaves: label={[grouplabel]above:{INT8: shifts}}.
  • Una lista de fit= no puede contener ($(a)+(1,2)$) (la coma divide la lista); define primero una \coordinate nombrada.
  • Para una línea extra dentro de un nodo, usa un nodo simple con align=center y \\[-2pt]{\tiny ...} — no superpongas una segunda etiqueta en la caja.
  • shapes.geometric trapezium con texto vacío divide por cero — por eso mux/demux son imágenes de trazado personalizadas; no los intercambies.
  • Dentro de \foreach, usa \pgfmathtruncatemacro para aritmética de enteros antes de usar valores en nombres de nodos; en \foreach \a/\b in {...} una / dentro del texto de la etiqueta la divide (escribe Port, no I/O).
  • clkdomain tiene un relleno claro; pasa fill=none cuando lo dibujes sobre un fabric u otro contenido denso.
  • MiKTeX ignora TEXINPUTS al estilo POSIX; mantén hwfig.sty junto al .tex (o pasa --include-directory=<ruta de windows>).
  • Mantén las figuras con un ancho ≤ ~16 cm para un artículo de dos columnas a \footnotesize; escala con \resizebox{\linewidth}{!}{...} solo como último recurso.

Ejemplo de referencia (capa GNN, la plantilla base)

\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}

Ejemplo de referencia (SoC Versal)

\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};

  % niveles de enrutamiento
  \def\chan{6.7}    % canal vertical entre regiones PL y AIE
  \def\lvla{-1.7}   % mm2s -> AIE, debajo del marco AIE
  \def\lvlb{-2.3}   % AIE -> s2mm, un nivel más abajo (= fila 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 -> shim 1: directamente al canal, hacia abajo, a lo largo del nivel a, hacia arriba al 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: hacia abajo al nivel b, izquierda a 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}

Código fuente del paquete

hwfig.sty (v1.1, de Pelayo Leguina, [email protected], LPPL 1.3c) se distribuye junto a este archivo. El registro de cambios, la galería y los ejemplos viven en el repositorio público hwfig; esta habilidad se mantiene allí bajo skill/ y se empaqueta con skill/package.sh.

Skills relacionados