# Vdesign

> Generate a design proposal, documentation, and RTL backbone from a requirement file

- **Type:** Skill
- **Install:** `agentstack add skill-phamcuong21478-rtl-skills-vdesign`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [phamcuong21478](https://agentstack.voostack.com/s/phamcuong21478)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [phamcuong21478](https://github.com/phamcuong21478)
- **Source:** https://github.com/phamcuong21478/rtl-skills/tree/main/skills/vdesign

## Install

```sh
agentstack add skill-phamcuong21478-rtl-skills-vdesign
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Verilog Designer

## Overview

This guide defines the workflow for generating a design proposal, documentation, and a skeleton RTL module from a Markdown requirement file.

The input is a `.md` requirement file that describes what the module should do, typically `./ddoc/_req.md` produced by `varch`. The output is:

1. A proposal file with function description, architecture and algorithm if applicable
2. A design documentation file
3. A backbone Verilog file with `//@` direction comments, ready for implementation by `vfill`

`vdesign` runs once per **new submodule**. Reused `lib` modules have no `_req.md` (they are already designed and documented), so there is nothing here to drive — `vdesign` simply skips them; `varch` still instantiates them in the skeleton.

### Module Name Derivation

All output file names are derived from the **module name**, not the raw requirement file name. The module name is the requirement file base name with any trailing `_req` removed.

Example:

- requirement `./ddoc/foo_ctrl_req.md` → module name `foo_ctrl`

Use this module name consistently for the proposal, documentation, and RTL backbone file names below.

### Preconditions

Two stop conditions, checked before anything is written:

- **Requirement file missing.** `./ddoc/_req.md` does not exist → stop and
  report: run `varch` first (or place a hand-written requirement file). Never
  design from a module name alone.
- **Target is the IP top.** The module name resolves to `_top` → refuse. The
  top-level integration skeleton is owned by `varch` (it has no `_req.md`, and its
  `//@` are integration notes, not fill directions); `vdesign` generates submodule
  backbones only.

### Before You Start — Re-run Safety

`vdesign` overwrites three artifacts. Two of them carry hand-owned downstream content once the flow has progressed past `vfill`:

- `rtl/.v` — after `vfill`, this holds the real implementation and **every `//@` marker has been converted away**. A blind re-generate destroys the implementation.
- `ddoc/_proposal.md` — `vfill` records design updates and debug notes in its `## Implementation Notes (vfill)` section (seeded empty in Step 2). A blind re-generate clobbers them.

So before writing anything, classify the current state of the backbone:

| State | How to detect | Action |
|-------|---------------|--------|
| **Fresh** | `rtl/.v` does not exist | Generate all three outputs normally. |
| **Backbone only** | `rtl/.v` exists and still contains `//@` markers, no real logic | Safe to regenerate — the requirement changed and nothing downstream depends on it yet. |
| **Filled** | `rtl/.v` has no `//@` markers (the same marker `vflow` uses to detect completion, CodingStyle §18) / contains implemented logic, or the proposal's `## Implementation Notes (vfill)` section has content | **Stop and confirm with the user before overwriting.** Re-running discards `vfill`'s implementation and notes. The safe path is to re-run `vdesign` *before* `vfill`; after that, requirement changes must be reconciled into the filled RTL by hand. |

This mirrors how `varch` guards `_top.v` against clobbering integration edits.

## Step 1 - Read Requirements and Generate Proposal

Read the target requirement `.md` file and extract the design intent.

A `varch`-generated `_req.md` has **two parts** separated by the marker line
``:

- **Structural section (above the marker)** — overview, parameters, and the port/interface table. This is the **authoritative interface contract**: `varch` already fixed these port and parameter names, widths, defaults, and directions and wired `_top.v` to them by name. Carry them through verbatim — **do not rename, re-width, re-default, or re-derive a port or parameter.** Renaming a port or parameter here breaks the skeleton wiring three phases later.
- **Hand-owned functional section (below the marker)** — `## Functional Description`. This is the real design intent the proposal and documentation must stay faithful to.

(If the requirement has no marker line — e.g. it was hand-written — treat the whole file as intent and take ports from whatever port table it provides.)

**If the design genuinely needs a port or parameter the requirement does not
list, that is an architecture change, not a local fix.** Do not invent it here —
adding a port that `_top.v` does not wire breaks integration. Stop and flag
the gap to the user so it can be resolved in `varch` (which updates the
architecture document, the `_req.md`, and the skeleton together), then re-run
`vdesign` against the corrected requirement.

Based on the requirements, generate a design proposal. The proposal must include:

- Functional description of the module, consistent with the requirement's functional section
- Port list with signal names, directions, and widths — **taken verbatim from the requirement's structural port table**
- Parameter list with names, defaults, and **legal ranges** — names and defaults **taken verbatim from the requirement's structural parameter table** (including `RS_LV` for a clocked module); the legal range is a design decision made here (it feeds the doc's Parameters table, `ModuleDocContract §2`, and ultimately the release datasheet)
- Algorithm description, if applicable
- **Micro-architecture design** — the heart of the proposal; which artifacts are mandatory depends on what the module contains (see "Micro-architecture design" below)
- **Intended timing — mandatory for every clocked module**: latency from input to output, pipeline depth, and throughput. If there is no fixed latency, state that explicitly (e.g. "handshake-bound, no fixed latency") rather than omitting the section — `vassert`'s Latency/Throughput properties and the doc's mandatory Timing Characteristics section (`ModuleDocContract §6`) are both derived from this. A purely combinational module states "combinational".

### Pattern scan (do this before finalizing the architecture)

Run an explicit two-part scan against `.claude/skills/shared/DesignPatterns.md` —
recognition is the weak link, so make it a deliberate pass, not incidental
noticing:

1. **Feature scan.** For each pattern, read its **Recognize when** line against the
   requirement's functional section. These are phrased in requirement/symptom
   language (back-pressure, arbitration, occupancy, configuration registers, …) so
   the match is keyword-level. A requirement may hit several.
2. **Reflex scan.** Walk the **Reflex triggers** table against the architecture you
   are *about to choose*. These patterns (P4, P8, P9, P10, P6, P7, P12) fire from a
   structural commitment you make — a RAM, a pipeline, a bus, an array port — not
   from anything the requirement says, so they are the ones silently missed. The
   moment you decide to put state in a RAM, the preclear (P4) and read-during-write
   (P8) checks become mandatory.

For every hit, shape the architecture after the matching pattern and **name the
pattern in the proposal's architecture section** (e.g. "the per-id count RAM needs
P4 preclear + P8 forwarding"; "buffer the output with `vb_stream_fifo`, P1"). This
keeps related modules consistent and tells `vfill` which idiom to implement. Be
precise — match a pattern only when its discriminator actually holds (don't add a
buffer where always-ready upstream is fine). Do not paste the pattern's code into the
proposal — reference it by name; the actual widths and reset scope are derived per
module.

### Using library modules inside the design

A pattern hit (or the architecture itself) often calls for a standard building
block — a stream FIFO, a synchronizer, a dual-port RAM. Before designing one from
scratch, check `./lib` for a module that already provides it (the same
reuse-first rule `varch` applies at the IP level):

- Take its ports and parameters **verbatim from its `.md` documentation**
  (the doc follows `ModuleDocContract` and is usable without reading the RTL; fall
  back to the source only if the doc lacks them). Never invent, rename, or
  re-width a library port; bind only the parameters it actually declares.
- **Record the reuse in the proposal's architecture section** (library path +
  instance role), so `vfill` and the debuggers know the block is library code and
  do not re-derive or re-implement it.
- The instantiation goes **into the backbone as structural code** (Step 3), not
  into a `//@` marker — wiring a known, fixed interface is a design decision made
  here; leaving it to `vfill` forces a re-derivation of the same interface.

### Micro-architecture design (the heart of the proposal)

The proposal is a *design*, not a restatement of the requirement: every decision
`vfill` would otherwise have to make while implementing is made **here**, where it
can be reviewed. Which artifacts are mandatory depends on what the module
contains — detect, then design:

| The module has… | Then the proposal must carry |
|---|---|
| more than one internal block or stage | **Datapath & control diagram** (mermaid): the internal blocks, the signals between them named per `CodingStyle §3` (`s0_`/`s1_` stage prefixes, `_ff` registers), and which part is control vs datapath |
| control sequencing (modes, multi-step transactions, protocol handling) | **FSM design**: the state list with a one-line meaning each; the encoding choice (`localparam` binary / one-hot — and why); the reset state; a transition table or mermaid `stateDiagram-v2` covering every documented stimulus, including the error/abort paths; Moore vs Mealy per output; recovery from an illegal state (the mandatory `default:`) |
| latency > 1 cycle | **Pipeline table** — one row per stage: stage name (`s0`/`s1`/…), the registers it owns (named), the computation it performs, its valid qualifier, and its behavior on stall/bubble. The rows must sum to the `## Timing` latency. State the back-pressure strategy (full-pipe stall vs skid/elastic buffer) and the pattern it follows |
| internal state | **Storage inventory**: every register, counter, and RAM with its width, reset value (or "no reset, qualified by valid" per `CodingStyle §5`/`§14`), and the reflex-pattern rulings that apply (P4 preclear, P8 read-during-write, …) |
| a non-obvious choice (algorithm variant, encoding, RAM vs FF array, single- vs multi-cycle) | **Decision note**: one or two sentences — the choice, the alternative rejected, and why |

All diagrams (architecture, FSM state, algorithm flow) are written in mermaid format.

A module with none of the above — pure combinational glue, a trivial register
slice — may compress the architecture section to a paragraph. **Omission is
allowed only when there is genuinely nothing to decide, never because the design
is merely unwritten.**

**The backbone mirrors the micro-architecture (Step 3).** Each diagram block /
pipeline stage becomes a section banner; the `//@` markers name the proposal's
states and stages (e.g. `//@ implement the IDLE→LOAD→RUN→DRAIN FSM from the
proposal, one-hot, default: recover to IDLE`), so `vfill` implements the
*designed* FSM and pipeline rather than inventing its own.

## Step 2 - Generate Proposal and Documentation Files

Generate the following files:

### Proposal File

Create a new Markdown file in the `./ddoc` folder, alongside the requirement file.

Output file rules:

- Use the module name as the base name
- Append `_proposal` before the extension
- Use the `.md` extension

Example:

- requirement `foo_req.md` → `./ddoc/foo_proposal.md`

#### Proposal sections

The proposal carries these sections in order (omitting only the ones Step 1 marks
optional): `## Function Description`, `## Ports`, `## Parameters` (with legal
ranges), `## Architecture` (the micro-architecture artifacts from Step 1 —
datapath/control diagram, FSM design, pipeline table, storage inventory, decision
notes — naming any matched patterns and reused lib modules), `## Algorithm`,
`## Timing`, and — always last — an empty seed:

```markdown
## Implementation Notes (vfill)

```

The seed is the contract that keeps re-runs safe: `vfill` writes its notes
**inside this section only**, updating in place rather than appending duplicates,
so "has vfill touched this proposal?" reduces to one check — whether the section
has content (the Re-run Safety table above relies on it).

### Design Documentation File

Create a new Markdown file in the `./doc` folder.

Output file rules:

- Use the module name as the base name
- Use the `.md` extension

Example:

- requirement `foo_req.md` → `./doc/foo.md`

#### Required Content for the Design Documentation

The design documentation must follow the module documentation contract defined in
`.claude/skills/shared/ModuleDocContract.md`. Populate every required section of
that contract from the proposal and the requirement file.

The functional description must be consistent with the proposal and with the
requirement's hand-owned functional section. Because the RTL is not yet
implemented at this stage, derive the port table, reset values, and timing
characteristics from the proposal's port list and architecture; if a value is
not yet decided, state the intended value from the proposal rather than leaving
it blank. The reset section must reflect the project convention: synchronous
reset, `rst_n` compared against `RS_LV` (default active-low).

For a register-bearing module, the Register Map (`ModuleDocContract §9`) is
**designed here**: addresses, access types (`RO`/`RW`/`W1C`/`RC`), and reset
values come from the requirement's register list plus the architecture's decode
design — they are design decisions, not implementation details, so they must not
be deferred to `vfill`. The Instantiation Template (`§11`) binds every parameter
to the default from the structural parameter table.

## Step 3 - Create Backbone RTL Module

Create a skeleton Verilog file in the `./rtl` folder.

Output file rules:

- Use the module name as the base name
- Use the `.v` extension

Example:

- requirement `foo_req.md` → `./rtl/foo.v`

This skill generates backbones for submodules only. The top-level integration skeleton `./rtl/_top.v` is owned by `varch`; do not create or overwrite it here.

### Backbone Structure

The backbone must be **style-compliant from the start** — `vfill` fills it in
place, so the scaffold must already match `.claude/skills/shared/CodingStyle.md`,
not just the empty-logic shape. When the proposal names a design pattern (Step 1),
lay the section dividers and `//@` markers out after that pattern's canonical
shape in `.claude/skills/shared/DesignPatterns.md`, keeping the markers
plain-English (no code, `CodingStyle §18`). It must include:

- Plain **Verilog-2005 only** (`CodingStyle §0`) — the backbone *is* the future
  synthesizable RTL; no SystemVerilog constructs.
- `` `default_nettype none `` at the top and `` `default_nettype wire `` at the end (`CodingStyle §14`).
- Module declaration with all ports from the proposal, ANSI style, with `//!` Doxygen doc-comments on every port and parameter (`CodingStyle §1`, `§10`).
- `RS_LV` as the **last parameter** of the (clocked) module, default `0` (`CodingStyle §1`, `§12`).
- `//@` direction comments that guide `vfill` on what to implement in each section.
- Section dividers using the standard banner format, indented to body level (4 spaces) (`CodingStyle §4`).
- Empty logic bodies — no implementation. The one exception is **structural code
  for a reused library module** (Step 1): instantiate it here with named port
  connections (`CodingStyle §9`), its interface taken verbatim from the lib doc;
  any glue logic *around* it stays a `//@` direction for `vfill`.

Port and signal naming follows `CodingStyle §3` (do not re-derive a partial copy
of those rules here): `s_`/`m_` interface prefixes, `_ff` for flip-flops,
`s0_`/`s1_` pipeline-stage prefixes, etc. Port names themselves come straight from
the requirement's structural port table (see Step 1).

Example backbone structure:

```verilog
`default_nettype none

module foo #(
    parameter DATA_W = 8,   //! data bus

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [phamcuong21478](https://github.com/phamcuong21478)
- **Source:** [phamcuong21478/rtl-skills](https://github.com/phamcuong21478/rtl-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-phamcuong21478-rtl-skills-vdesign
- Seller: https://agentstack.voostack.com/s/phamcuong21478
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
