BeenLi/claude-skills

Desenhe Verilog / SystemVerilog (além de artigos, patentes e descrições orais) como diagramas draw.io editáveis, em quatro perspectivas: diagrama de arquitetura no estilo de artigos, diagrama estrutural no nível de portas, diagrama de máquina de estados e diagrama de estrutura de controle.

O que é claude-skills?

Este skill do Claude transforma descrições de hardware (código Verilog/SystemVerilog, artigos, patentes ou descrições textuais) em diagramas draw.io editáveis, oferecendo quatro perspectivas complementares. A primeira e padrão é o diagrama de arquitetura no estilo de artigos de conferência, que lê o código-fonte, extrai os pontos centrais do design e produz um diagrama limpo com estágios de pipeline (linhas tracejadas), registradores entre estágios, realces visuais para estruturas-chave e tabelas SRAM com campos detalhados. A segunda perspectiva é o diagrama estrutural no nível de portas, gerado a partir da netlist do Yosys, mostrando registradores, multiplexadores, operadores aritméticos, comparadores, portas lógicas, arrays de memória, FIFOs e submódulos organizados por estágio de pipeline. A terceira é o diagrama de máquina de estados (FSM), que analisa diretamente o código-fonte para extrair estados e transições. A quarta é o diagrama de estrutura de controle, que foca apenas nos sinais de controle e mostra como as várias FSMs se interconectam. O skill suporta exportação para PNG e SVG, e inclui scripts auxiliares como `arch2drawio.py`, `rtl2drawio.py` e `fsm2drawio.py` para cada tipo de diagrama. É ideal para engenheiros de hardware que desejam visualizar rapidamente a arquitetura de seus designs para documentação, revisão ou publicação.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/BeenLi/claude-skills/tree/HEAD/skills/verilog-diagram

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Verilog → draw.io: Diagrama de Arquitetura / Diagrama Estrutural / Máquina de Estados / Estrutura de Controle

Quatro perspectivas, escolha conforme a pergunta: Qual é a ideia de projeto (para explicar a alguém, colocar em artigo/relatório) → arch2drawio.py (seção zero, padrão); Como é a aparência no nível de portas (caminho de dados unidade por unidade) → rtl2drawio.py; Como os estados fluem (FSM individual) → fsm2drawio.py fsm; Quem controla quem (estrutura geral de controle) → fsm2drawio.py ctrl. Módulos focados em controle (FSM, decodificação, árbitros) ficam confusos com diagramas estruturais; use as duas últimas opções.

Dependências: PyYAML; para exportar PNG/SVG é necessário drawio (ordem de busca $DRAWIO_BIN → PATH → aplicativo macOS → ~/.local/opt/drawio; Linux sem $DISPLAY usa automaticamente xvfb-run; servidores sem root podem instalar com tools/install-drawio-linux.sh do repositório). Sem exportador, todos os comandos geram .drawio normalmente, apenas sem PNG, com uma linha de aviso no stderr. Diagramas estruturais/controle também precisam de yosys, sv2v (SystemVerilog), dot (Graphviz), e o drawio-skill instalado (padrão ~/.claude/skills/drawio-skill, substituível pela variável de ambiente DRAWIO_SKILL_DIR; ele só chama autolayout.py, não o modifica). Os três scripts de geração aceitam --png / --svg / --scale N (escala PNG padrão 3, aproximadamente 1 unidade de modelo = 3 px; $DRAWIO_SCALE pode alterar o padrão), ou exporte separadamente: python3 $S/scripts/drawio_export.py X.drawio --png --svg. Para inserir em Markdown/Obsidian, prefira SVG (não desfoca). $S é o diretório deste skill. examples/ contém dois exemplos de referência: wrr_arbiter.v (único estágio + registrador de estado), load_pipe.v (pipeline multinível com replay).

Zero: Diagrama de Arquitetura Estilo Artigo (arch2drawio.py) – Padrão

A entrada é código (ou artigo, patente, descrição do usuário). Netlists do Yosys são muito detalhadas para diagramas de arquitetura, portanto aqui não há síntese: o script fornece o esboço do código-fonte, você (agente) lê o código, captura o essencial e escreve a descrição do diagrama, e o script então gera o diagrama deterministicamente. O usuário não precisa escrever nenhum arquivo de descrição; apenas veja o diagrama, a menos que o usuário queira modificar a descrição.

python3 $S/scripts/arch2drawio.py outline src/*.sv --top gpu [--module core]   # Esboço do código-fonte (sem síntese)
python3 $S/scripts/arch2drawio.py render  fig.yaml -o diagrams/arch_core.drawio --png

outline lista: árvore de hierarquia (generate replicado ×N), portas, arrays de memória (profundidade × largura, campos de packed struct, arrays de mesma profundidade sugerem "possivelmente mesma tabela"), registradores sequenciais nomeados por estágio (s1_ / stage2_ / if_id_ …), máquinas de estado, sinais suspeitos de realimentação (replay/kill/flush/stall/forward/refill…), fluxo de dados entre instâncias (via sinais compartilhados, já excluindo clk/reset/variáveis de loop). Para entrada de artigo/patente/descrição, esta etapa é pulada.

Regras de desenho (ao escrever a descrição, siga)

  1. Desenhe apenas o essencial: Primeiro, explique a ideia central do design em uma ou duas frases; mantenha apenas os componentes que a materializam; lógica de cola, clk/reset, portas de depuração e controles dispersos são omitidos. Geralmente 8–20 caixas; se exceder, divida em duas (uma visão geral + uma de unidade chave).
  2. Destaque os pontos principais: 1–3 pontos de design chave com hl: true (cor contrastante: fundo escuro, texto branco) ou bold: true (negrito); linhas de caminho crítico também podem ter | hl. Para enfatizar uma área, use groups + hl: true (caixa de fundo claro).
  3. Não numere cada componente: Numere apenas os componentes centrais com num: N quando necessário para referência textual, e explique em callouts.
  4. Texto conciso nas caixas: Dentro da caixa, apenas o nome (≤ 2 linhas); o significado é expresso pela forma: operações usam adder / mult / cmp / op (símbolo circular) ou alu, seleção usa mux (pino de seleção x.sel entra por baixo), armazenamento usa table, fila usa fifo, registrador usa reg, porta usa and/or/xor/not.
  5. Tabelas SRAM mostram campos de uma única entrada: Os fields de table escrevem o significado de cada campo (ex.: [V, Tag (20b), Data (32b)]), para conjunto associativo múltiplo, use stack: 4 (empilhado + ×4); arrays paralelos de mesma profundidade e endereço são combinados em uma tabela, cada array como um campo.
  6. Pipeline: stages define os estágios (id + função sub, ex.: {id: S1, sub: Verificação de hit}), o script desenha divisórias tracejadas e nomes dos estágios; registradores/FIFOs entre estágios usam between: [S0, S1], o script os coloca na linha divisória; realimentação (destino em estágio anterior) é automaticamente roteada pelo corredor inferior, ou pode ser | fb, | fb via=top (rota por cima). Múltiplos pipelines usam lanes, cada lane compartilha as colunas dos estágios, e estágios temporalmente correspondentes são automaticamente alinhados.
  7. Diagramas de nível de bloco sem estágios (topo, SoC) não escrevem stages; unidades replicadas usam stack: N; recursos por thread/por núcleo são agrupados com groups.

Formato da descrição (YAML)

title: dcache_pipe: Pipeline de busca dcache de mapeamento direto
stages: [{id: S0, sub: Seleção / Leitura de array}, {id: S1, sub: Verificação de hit}, {id: S2, sub: Miss / Repetição}]
lanes:  [{id: ld, name: Pipeline Load}, {id: st, name: Pipeline Store}]     # Opcional, para múltiplos pipelines
nodes:
  - {id: arr, type: table, label: "Cache Array · 64 entradas", fields: [V, "Tag (20b)", "Data (32b)"], stage: S0}
  - {id: r1, type: reg, label: addr, between: [S0, S1]}              # Na divisória S0|S1
  - {id: tcmp, type: cmp, label: Comparação de Tag, stage: S1, hl: true}      # Círculo "=", texto explicativo abaixo
  - {id: rmux, type: mux, stage: S0, ports: 2}
edges:
  - "rmux => arr : idx | w=6"            # -> dados  => barramento (grosso)  ~> controle (tracejado); w=N largura
  - "rpl -> rmux.sel : replay | fb hl"   # .sel/.en entra por baixo, .top por cima; fb realimentação, hl destaque, via=top, pos=src|dst
groups: [{label: "Por thread ×4", members: [rf, alu, lsu], hl: true}]
legend: {reg: Registrador de pipeline, fb: Realimentação, ctrl: Controle, hl: Design chave}      # Chaves disponíveis: data bus ctrl fb hl hl_edge hl_region reg
callouts: {1: "Numere apenas para referência"}

Tipos de nó: block reg fifo table(fields, rows, stack) array(dims, cell) mux(ports) adder mult cmp/op(sym) alu and or xor nand nor xnor not cloud mem xbar in out text dot. Atributos gerais: stage / lane / between, hl bold num stack, ajuste fino com row / col (linha/coluna dentro do estágio, pode ser negativo), dx / dy, w / h. Outros: array suporta cell_labels (rótulos por célula, ex.: T0..T3) e cell_h (retângulos altos, para canais de thread); groups suporta stack: N (empilha área inteira, ex.: "Core ×2" e mostra interior) e label_align: right; name de lanes vazio = apenas divisão sem rótulo; arestas com | both desenham seta dupla (requisição/resposta); realimentação entre duas unidades na mesma coluna vira uma linha vertical curta e rente (ex.: Dispatcher ⇅ Core).

Fluxo

  1. outline + leitura do código-fonte chave (ou leitura do artigo/patente), anote a ideia central → decida qual camada desenhar e quais são os pontos principais.
  2. Escreva a descrição em um diretório temporário (scratchpad), cada nó recebe stage (quando houver estágios). Os loops são quebrados automaticamente: nós com nomes de controlador (sched / ctrl / fsm / arbiter / dispatch / 调度 / 控制 …, seguido por grande fan-out de linhas de controle) são colocados primeiro, suas saídas vão para a direita e arestas que voltam para eles são marcadas como realimentação; se a classificação estiver errada, escreva explicitamente | fb na aresta. Opcional: Referência de composição (gpt-image-bridge, requer aprovação do usuário para cada imagem) – O posicionador de grade garante conexões corretas, mas não "compõe". Quando o módulo tem ≥ 10 ou há partições óbvias (plano de controle/plano de dados/hierarquia de memória), pode-se gerar uma linha de base no draw.io e, em seguida, escrever a lista de módulos e conexões obtida do código no prompt (estilo de ilustração de artigo, fundo branco, uma única cor de destaque, layout de três regiões, texto mínimo, rótulos curtos em inglês), gerar 1 esboço com gpt-image-bridge e lê-lo. Apenas a composição e hierarquia visual são usadas (partições, quem está acima de quem, formação, espaços em branco, posição dos itens importantes); converta para lane / row / col / groups; Módulos, conexões e nomes sempre se baseiam no código – Erros comuns em esboços: conectar fonte errada, módulos a mais/menos, fundo escuro. Antes de gerar, liste as imagens (uso, caminho, dimensão, resumo do prompt) conforme as regras deste skill e aguarde consentimento explícito do usuário; esboços salvos em diagrams/sketch_*.png, cabeçalho do arquivo de descrição referencia.
  3. render --png → validate.py (erro deve ser 0; avisos de overlap/through-vertex nas divisórias tracejadas que cruzam cabeçalhos de estágio/registradores são intencionais) → Leia o PNG para inspeção visual, ajuste fino com row / col no máximo duas rodadas (comum: fazer o caminho de dados principal ocupar a linha 0 em linha reta, caminhos alternativos/controle na linha seguinte).
  4. Entregue .drawio + .png; o arquivo de descrição permanece no scratchpad; entregue ao usuário apenas se ele quiser modificar.

Exemplos: topo do tiny-gpu ~/hardware-project/tiny-gpu/diagrams/arch_gpu.* (composição guiada pelo esboço sketch_gpu_top.png, compare com arch_gpu_baseline.png sem esboço); examples/dcache_pipe.v → dcache_pipe.arch.yaml (descrição escrita a partir do código) → .png; arch_dual_issue.yaml (alinhamento de pipeline duplo + encaminhamento + notas numeradas); arch_mac.yaml (nível de circuito: símbolos de multiplicador/somador, realimentação de acumulação, pino de seleção MUX). Diagrama de bloco do core tiny-gpu em ~/hardware-project/tiny-gpu/diagrams/arch_core.*.

Um: Diagrama Estrutural (rtl2drawio.py, Detalhes de Portas)

python3 $S/scripts/rtl2drawio.py src/*.sv --top gpu --list                     # Módulos e composição de unidades
python3 $S/scripts/rtl2drawio.py src/*.sv --top gpu --module alu -o diagrams/alu.drawio --png

Fluxo: sv2v (automático para .sv) → Yosys proc; opt; opt_dff; wreduce; memory -nomap → netlist JSON → análise de pipeline por unidade → simplificação → layout com restrição de coluna. Após a geração, execute python3 ~/.claude/skills/drawio-skill/scripts/validate.py X.drawio (erro deve ser 0; avisos de through-vertex/overlap devido a linhas de divisória de estágio/registradores sobre a linha divisória são intencionais), então leia o PNG para inspeção visual.

Regras de layout (--layout pipeline; padrão auto: módulos hierárquicos com predominância de instâncias de submódulos usam layout livre, os demais usam layout por estágio de pipeline)

  • Entrada à esquerda, saída à direita, lógica organizada da esquerda para a direita por profundidade combinacional; pipelines multinível vão de S0 → Sn da esquerda para a direita, divisórias tracejadas, cabeçalho de coluna com número do estágio.
  • Registradores divididos em duas classes:
    • Registradores de pipeline (faixa vertical estreita) colocados nas linhas divisórias de estágio; a fileira final que só se conecta a portas de saída são registradores de saída (não contam como um estágio, não desenham divisória).
    • Registradores de estado (FSM/contadores/pontos: saída volta à própria entrada apenas por lógica combinacional) desenhados dentro do estágio, suas saídas como realimentação.
    • Quando o nome do registrador inclui número de estágio (s2_x, x_s2, stage2_x, if_id_/id_ex_/ex_mem_/mem_wb_, e pelo menos dois tipos) o nome prevalece – bits de valid com kill, mesmo com loop combinacional, ainda são registradores de pipeline. Designs sem nomes baseados em estágio só podem ser inferidos por estrutura; o tempo de chegada das portas de entrada é desconhecido, o número do estágio pode ser precoce.
  • Cálculo do estágio: A partir de registradores com número de estágio, o estágio de uma unidade = o registrando operando mais tardio (máximo); lógica acionada apenas por portas de entrada é classificada pelo estágio do registrador que a "amostra" (ALAP), as portas de entrada correspondentes também são colocadas no início desse estágio (ex.: resposta TLB colocada em S1).
  • Realimentação: Sinais que entram no cone de entrada de um registrador com número de estágio, mas só podem vir de estágios posteriores (replay→S0, kill→S1), e loops de registradores de estado, são desenhados como linhas vermelhas contornando por baixo, com maior alcance por fora; se houver mais de 3 realimentações entre o mesmo par de estágios, desenhe apenas uma linha grossa representando um feixe (rótulo Realimentação ×N: …).
  • Agrupamento: Se houver mais de 4 registradores de pipeline na mesma divisória, combine em um grupo de registradores (faixa vertical com rótulo Registradores S1→S2 ×N e largura total).
  • Simplificação: Registradores com mesmo nome e fatias são mesclados; cadeias de MUX de if/case aninhados são fundidas em um único MUX N:1; pequena lógica de decodificação que aciona apenas um pino de seleção MUX / enable de registrador é incorporada como linha de seleção / linha de enable; até 3 portas são desenhadas como símbolos de porta AND/OR/NOT/XOR, portas maiores são dobradas em nuvem "lógica combinacional" (cortadas em torno de unidades de operação para evitar loops falsos); unidades de mesma origem (mesma localização no código-fonte) expandidas por generate e instâncias threads[i].x são dobradas em "×N" (com sombra). Todas as mesclagens são feitas apenas dentro do mesmo estágio. clk/reset ocultos por padrão.
  • Conexões: linha sólida = dados (grossa = barramento múltiplo, /N = largura); linha roxa tracejada = seleção MUX; linha azul pontilhada = enable; linha vermelha = realimentação.

Parâmetros

ParâmetroFunção
--listLista módulos e composição de unidades e sai
--module MDesenha qual módulo (variante parametrizada desenha a primeira, com aviso)
--layout auto|pipeline|freePadrão auto: módulos com instâncias de submódulos e poucos nós de lógica combinacional (módulos de cola de topo) usam free (comunicação bidirecional entre blocos não é realimentação de pipeline), caso contrário pipeline
--show-clockDesenha clk/reset
--no-foldNão dobra instâncias generate/unidades de mesma origem
--no-collapseNão dobra lógica de controle/combinacional
--sv2v auto|always|neverFrontend SV (sintaxe como portas de array não compactado requer sv2v)
--keep-json PATHMantém netlist JSON do Yosys

Dois: Diagrama de Máquina de Estados (fsm2drawio.py fsm)

python3 $S/scripts/fsm2drawio.py list src/*.sv
python3 $S/scripts/fsm2drawio.py fsm  src/*.sv [--module M] -d diagrams --png [--no-actions]
  • Analisa diretamente o código-fonte, as condições de transição mantêm a expressão original. Reconhece atribuições a S (ou variável de próximo estado S <= N) em ramos case (S); os nomes de estado são obtidos de localparam; constantes de variáveis de estado de outras FSMs são traduzidas para o nome do estado da outra FSM (core_state == 3'b001 → core_state == FETCH).
  • Condição de transição = if/case/for que envolve diretamente a atribuição de estado; else if escreve apenas sua própria condição; condições em for são escritas como ∃j: …; for i externo envolvendo todo o case indica replicação por i; guardas fora do case (enable, ramo de leitura/escrita) entram em caixa de comentário; variáveis booleanas locais setadas em loop têm definição na caixa de comentário.
  • Desenho: Cada estado é um círculo de tamanho igual (nome quebra em _, abaixo em letras pequenas a codificação e ⟳), estado final círculo duplo, ponto preto = entrada de reset. Quando o fluxo principal cobre a maioria dos estados, organize em loop em forma de U (linha superior esquerda→direita, desce, linha inferior direita→esquerda); ramificações organizadas por distância do estado inicialem colunas uniformes. Estados adjacentes conectados diretamente; transições que pulam outros estadosarqueiam por cima/baixo, rótulo no ápice; A↔B bidirecional cada um curvado para um lado; self-loop explícito desenhado acima do círculo. Espaçamento de coluna adapta-se ao rótulo mais longo. Após /, atribuições na transição (no máximo 2 exibidas).
  • Não reconhece: Estruturas sem case(state) (contadores, decodificação puramente combinacional) – não aparecem em list, conforme esperado.

Três: Estrutura Geral de Controle (fsm2drawio.py ctrl)

python3 $S/scripts/fsm2drawio.py ctrl src/*.sv --top gpu --module core -o diagrams/ctrl_core.drawio --png
  • Desenha instâncias de submódulos do módulo L (instâncias generate dobradas ×N), mantêm apenas sinais de controle: linha laranja grossa = broadcast de estado FSM; linha azul = handshake valid/ready; linha roxa tracejada = start/done/enable/seleção/reset etc.; barramentos de dados omitidos. Caixas de instância com FSM listam sequência de estados, submódulos com FSM são marcados "Contém FSM".
  • Sinais de controle penetram no máximo 3 níveis de unidades básicas (comparador, porta, registrador) para rastrear a origem. Classificação baseada em nome de sinal; nomes não padronizados podem resultar em omissão/excesso.
  • Sugestão de cima para baixo: primeiro topo (quem inicia quem, quem aperta a mão com a memória) → próxima camada (como a FSM mestre escala) → diagrama de estado da FSM chave.

Limitações

  • O layout é feito automaticamente pelo Graphviz com restrições de coluna; cruzamentos não podem ser completamente eliminados; ajuste fino no draw.io arrastando (todos os objetos são nativamente editáveis).
  • Módulos de controle grandes (centenas de unidades) ainda produzirão diagramas estruturais confusos; conforme acima, mude para diagrama de máquina de estados / estrutura de controle, ou desenhe submódulo por submódulo.
  • Círculos/arcos de diagrama de estado são desenhados diretamente por coordenadas; ao arrastar um estado, os pontos de inflexão dos arcos não acompanham, precisam ser ajustados manualmente.

Habilidades Relacionadas