CommunityPesquisa e Análise de Dadosgithub.com

pleguina/tikz-hardware-figures

Desenhe diagramas de bloco de hardware/FPGA/dataflow de qualidade para publicação em TikZ (kernels HLS, matrizes AIE, matrizes sistólicas, SoCs, pipelines) em escala de cinza ou paletas seguras para daltônicos.

O que é tikz-hardware-figures?

Esta habilidade permite que agentes de IA gerem diagramas de bloco de hardware prontos para publicação usando TikZ/LaTeX, com foco em designs orientados a dataflow para aceleradores FPGA, arquiteturas de sistemas SoC e matrizes de processamento. A habilidade produz código TikZ editável e visualizações PDF/PNG compiladas, seguindo uma gramática visual rigorosa: linhas de dados fluem da esquerda para a direita, constantes de compilação são colocadas acima/abaixo dos blocos que configuram, e operações de requantização seguem cada bloco de computação que altera precisão. Suporta múltiplas paletas de cores: cinza (padrão), Okabe–Ito (seguro para daltônicos), Tol (suave), Nord (slides) e Slate (apresentações científicas), todas definidas através de um mecanismo de papéis (roles) que mantém a consistência entre figuras contidas no mesmo documento. O pacote inclui estilos de nós para dezenas de componentes: kernels HLS, quantizadores, operadores, tipos de memória (BRAM, URAM, DDR), processadores (ARM, RISC-V), elementos de processamento, redes-em-chip (NoCs), barramentos AXI e domínios de clock. Recursos paramétricos via `\pic` simplificam a criação de matrizes AIE, matrizes sistólicas, árvores de adição, pipelines, grades NoC e layouts de colunas FPGA. O fluxo de trabalho exige um planejamento em grade com coordenadas explícitas (não `positioning`), compilação com `pdflatex` e verificação visual do PNG para evitar sobreposições. A habilidade impõe regras rigorosas de roteamento: canais vazios entre regiões, níveis de fiação dedicados e posicionamento cuidadoso de rótulos para evitar conflitos. O pacote `hwfig.sty` (v1.1, licença LPPL) é copiado byte a byte do diretório base da habilidade — nunca redefinido inline. Esta ferramenta é ideal para engenheiros de hardware, arquitetos de FPGA e pesquisadores que buscam figuras de dataflow precisas e esteticamente consistentes para artigos acadêmicos, teses ou apresentações técnicas.

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

Installed? Explore more Pesquisa e Análise de Dados skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Figuras de hardware TikZ (hwfig v1.1)

Use esta habilidade sempre que o usuário quiser uma figura de hardware em LaTeX/TikZ: dataflow de um kernel HLS/FPGA, uma camada de NN quantizada, um diagrama de bloco SoC Versal/Zynq, matrizes AI Engine, matrizes sistólicas, árvores de adição, pipelines, NoCs, hierarquias de memória, domínios de clock, floorplans. A saída é sempre código TikZ editável mais uma visualização PDF/PNG compilada.

Fluxo de trabalho

  1. Obter o pacote. Copie hwfig.sty do diretório base desta habilidade para o diretório de trabalho (a menos que o usuário já tenha uma cópia — se a cópia dele não tiver v1.1 na linha \ProvidesPackage, ofereça para atualizá-la). Leia o arquivo e copie-o byte por byte; nunca redigite ou redefina os estilos inline — as paletas só funcionam através das cores de papéis.
  2. Escolher uma paleta (padrão grey), ou como opção de pacote \usepackage[okabe]{hwfig} ou com \hwpalette{...} em qualquer lugar (local ao grupo, portanto por figura):
    • grey — padrão para impressão/periódicos, espelha o modelo de referência (caixas de computação brancas, quantizadores cinza, constantes cinza tracejadas).
    • okabe — Okabe–Ito, seguro para daltônicos, contraste mais forte. Boa opção padrão para artigos coloridos.
    • tol — Paul Tol muted, seguro para daltônicos, mais suave.
    • nord — tons frios, para slides.
    • slate — azul-cinza + malva + coral, combina com decks de slides científicos. Se o usuário não especificar, produza grey e ofereça uma paleta colorida; para comparar, compile a mesma figura em várias paletas (loop \foreach \pal in {grey,okabe,...}{\hwpalette{\pal}...} dentro de um documento standalone dá uma página para cada). Um nome de paleta desconhecido é um erro grave.
  3. Esboçar o layout em uma grade primeiro (coordenadas explícitas at (x,y), espaçamento de colunas ~2.4 cm, linhas ±1.4 cm), depois conectar. Coordenadas explícitas vencem positioning para figuras densas de dataflow.
  4. Compilar como \documentclass[tikz,border=4pt]{standalone} + \usepackage{hwfig} com pdflatex -interaction=batchmode -halt-on-error (com time-out; nonstopmode pode travar), rasterizar com pdftoppm -r 110 -png, olhar o PNG, e corrigir sobreposições (rótulos em fios, fios cruzando caixas, títulos colidindo, rótulos de quadro tocando nós) antes de entregar. Iterar até ficar limpo.
  5. Entregar o .tex (corpo da figura pronto para colar em um artigo), o .sty, e o PDF. Lembre o usuário de que no artigo dele precisa de \usepackage{hwfig} (ou \usepackage[<palette>]{hwfig}).

Gramática visual (mantenha consistente)

  • Dados fluem esquerda → direita; o caminho principal fica em um eixo horizontal, ramos paralelos acima/abaixo (±1.4 cm).
  • Constantes de compilação (ctime, caixa tracejada) ficam diretamente acima/abaixo do bloco que configuram e conectam com darr (seta tracejada).
  • Todo bloco de computação que muda de precisão é seguido por um qbox (requant/deslocamento/saturação).
  • Ramos convergem em um nó op com fios que se aproximam verticalmente: \draw[arr] (qr.east) -| ($(sum.north)+(0,0.32)$) -- (sum.north);
  • Ramos alternativos de uma fonte: uma coordenada de bifurcação com um ponto, \fill[hwwire] (fork) circle (1.3pt);, depois cotovelos |- para cada ramo.
  • Use hot para o caminho crítico/destacado, bus para datapaths largos com pic[pos=.5]{buswidth=512}, node[lbl,midway,above]{AXI4-S} para nomes de protocolo (lblbox quando o rótulo precisa ficar sobre fios que cruzam).
  • Molduras de agrupamento vão na camada de fundo com fit: \begin{scope}[on background layer]\node[group,fit=(a)(b),label={[grouplabel]above:PL}] {};\end{scope}
  • Domínios de clock: clkdomain (cor de destaque, tracejado) ou clkdomain=<color>; marque cruzamentos com um nó cdc.
  • Comece toda figura com \begin{tikzpicture}[hw] (define fonte \footnotesize, largura de linha, pontas de seta).

Roteamento e rótulos (verifique em cada PNG)

  • Lacunas entre regiões. Deixe ≥ 0.6 cm entre quadros adjacentes (Runtime | Passagem de mensagens, PL | AIE). Nós, operações op de junção e fios nunca devem ficar sobre a borda de um quadro — se um nó não pertence a nenhum dos quadros, dê espaço fora de ambos.
  • Canais de roteamento. Fios entre regiões correm em um canal vazio entre os quadros (defina: \def\chan{6.7}), depois em seu próprio nível horizontal abaixo/acima do quadro de destino (\def\lvla{-1.7}). Dois fios nunca compartilham um nível; mantenha ≥ 0.3 cm entre um fio e qualquer borda de quadro ou lado de bloco paralelo, e ≥ 0.4 cm entre fios paralelos.
  • Rótulos ficam apenas em segmentos livres. Coloque lbl/buswidth em um segmento que esteja inteiramente em espaço vazio — nunca onde o fio cruza uma borda de quadro, e nunca a menos de ~0.2 cm de um bloco. Se a única extensão livre é vertical, gire o rótulo para ler de baixo para cima: node[lbl,rotate=90,below]{AXI4-S}. Em links curtos use pic[pos=.35..0.4] para que o número fique longe do bloco de destino.
  • Segmentos explícitos para cotovelos com rótulos. -|/|- não podem receber um rótulo em uma perna escolhida; escreva os cantos explicitamente: (a.east) -- (\chan,ya) -- node[lbl,...]{X} (\chan,\lvla) -- (b.south|-{(0,\lvla)}) -- (b.south);
  • Matemática em rótulos: $W_{\mathrm{root}}$; rótulos de duas linhas com \\ (todos os estilos definem align=center).

Estilos de nó (todos sensíveis à paleta)

estilouso
runtimeentradas/saídas de tempo de execução, portas, tensores
ctimeconstantes de compilação: pesos, escalas, config
hlsboxkernel de computação / função HLS / kernel AIE
qboxquantizador, requant, deslocamento+sat
op+, ×, max (círculo)
mux, demuxmultiplexador (entradas oeste, saída leste) / demultiplexador (espelhado)
mem, bram, urambuffers on-chip
fifostream/FIFO
reg / ffregistrador com cunha de clock
lut, dspprimitivas FPGA (dsp coloca uma pequena etiqueta "DSP" fora do canto superior direito — deixe espaço)
extmemDDR / HBM (cilindro)
cpuPS / ARM / RISC-V (moldura dupla)
hostCPU host (lado PCIe)
xbarinterconexão AXI / barra NoC (\rotatebox{90}{AXI IC})
routerroteador/switch NoC (losango)
peelemento de processamento
aietile AI Engine (núcleo + memória local; rótulo centralizado no núcleo)
chipencapsulamento/die com pinos
portmarcador de pino pequeno
cdcsincronizador de cruzamento de domínio de clock
group, plregion, psregion, clkdomainmolduras de fundo
grouplabel, lbl, lblboxtítulos de quadro, rótulos de fio (lblbox = fundo branco)

Estilos de aresta: arr, darr, bus, hot. Marca de barramento: pic[pos=.5]{buswidth=32} (número à direita da marca) ou buswidth'=32 (à esquerda).

Pics paramétricos

Passe opções por pic — elas permanecem locais àquele pic, então tamanhos diferentes podem compartilhar uma figura: \pic (A) at (0,0) {aiearray={rows=2,cols=4}};. \hwset{key=value,...} define padrões para o resto do escopo atual. Nós internos são endereçáveis como (name-...).

picchavespartes endereçáveis
aiearrayrows, cols, dx, dy, tilelabeltiles (n-t<r>-<c>) (r=1 inferior), shims (n-s<c>), moldura (n-box)
systolicrows, cols(n-pe<r>-<c>) (r=1 superior)
addertreedepth (entradas 2^depth)entradas (n-in<k>), somadores (n-a<level>-<k>), saída (n-out)
pipelinelabels={Load,MAC,Requant,...}estágios (n-st<k>), regs (n-r<k>)
nocrows, cols, nocpe (verdadeiro/falso)roteadores (n-n<r>-<c>), PEs (n-pe<r>-<c>)
fabriccolumns={I,C,C,D,C,B,...}, fabricrows (qualquer valor)topos de coluna (n-c<k>). C=CLB D=DSP B=BRAM U=URAM I=IO
legendlegend={comp/Compute,mem/BRAM,...} (papéis: io comp quant const op mem ctrl group); espaçamento automático—

Roteie fios ao redor de pics (por exemplo, para tiles shim por baixo: (k1.east) -- ++(0.9,0) |- ($(arr-s1.south)+(0,-0.35)$) -- (arr-s1.south)), nunca através de tiles.

Paletas personalizadas

Não são necessários internos @ — defina todos os 8 papéis (traçado, preenchimento) e as três cores de fio:

\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}}   % fio, fio de constante, destaque/quente
\hwpalette{mine}

Mantenha preenchimentos ≤ 25% de matiz para que o texto preto permaneça legível, e verifique se a conversão para escala de cinza ainda separa os papéis.

Armadilhas

  • Escreva arquivos .tex com a ferramenta de escrita de arquivos, não com heredocs de shell, sed ou literais de string Python: estes rotineiramente transformam \\ em \ (ou \c... em caracteres de controle) e quebram quebras de linha em texto de nó.
  • Dois-pontos ou vírgulas dentro do texto label= quebram a análise de chaves — coloque entre chaves: label={[grouplabel]above:{INT8: shifts}}.
  • Uma lista fit= não pode conter ($(a)+(1,2)$) (a vírgula divide a lista); defina uma \coordinate nomeada primeiro.
  • Para uma linha extra dentro de um nó, use um nó simples com align=center e \\[-2pt]{\tiny ...} — não sobreponha um segundo rótulo na caixa.
  • shapes.geometric trapezium com texto vazio divide por zero — é por isso que mux/demux são path pictures personalizadas; não as troque de volta.
  • Dentro de \foreach, use \pgfmathtruncatemacro para aritmética de inteiros antes de usar valores em nomes de nós; em \foreach \a/\b in {...} uma / dentro do texto do rótulo o divide (escreva Port, não I/O).
  • clkdomain tem um preenchimento claro; passe fill=none ao desenhá-lo sobre um fabric ou outro conteúdo denso.
  • MiKTeX ignora TEXINPUTS no estilo POSIX; mantenha hwfig.sty próximo ao .tex (ou passe --include-directory=<caminho windows>).
  • Mantenha figuras com ≤ ~16 cm de largura para um artigo de duas colunas em \footnotesize; escale com \resizebox{\linewidth}{!}{...} apenas como último recurso.

Exemplo de referência (camada GNN, o modelo 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}

Exemplo de referência (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};

  % níveis de roteamento
  \def\chan{6.7}    % canal vertical entre regiões PL e AIE
  \def\lvla{-1.7}   % mm2s -> AIE, abaixo da moldura AIE
  \def\lvlb{-2.3}   % AIE -> s2mm, um nível abaixo (= linha 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: à direita no canal, desce, ao longo do nível, sobe para o 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: desce até o nível b, esquerda para 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-fonte do pacote

hwfig.sty (v1.1, por Pelayo Leguina, [email protected], LPPL 1.3c) acompanha este arquivo. O changelog, galeria e exemplos vivem no repositório público hwfig; esta habilidade é mantida lá em skill/ e empacotada com skill/package.sh.

Habilidades Relacionadas