2026-06-15 14:42:34 +02:00
|
|
|
<!-- DESCRIPTION: Verilator: Repository-wide guidelines for AI coding agents
|
|
|
|
|
SPDX-FileCopyrightText: 2026-2026 Wilson Snyder
|
|
|
|
|
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -->
|
|
|
|
|
|
|
|
|
|
# Verilator Guidelines for AI Coding Agents
|
|
|
|
|
|
|
|
|
|
These files are the general layer an agent loads first -- nearest file wins, so
|
|
|
|
|
you read this repository-root file plus the one for the directory you are
|
|
|
|
|
editing. They stay deliberately high-level: where to start, how the tree is laid
|
|
|
|
|
out, and the conventions reviewers otherwise enforce by hand. They are an index,
|
|
|
|
|
not the architecture reference -- for depth (how a pass works internally, the
|
|
|
|
|
algorithms, node lifetime) they point you to `docs/internals.rst`. When the
|
|
|
|
|
guidance here is not enough, that is where to look next.
|
|
|
|
|
|
|
|
|
|
This file has two parts. **Orientation** gets you productive in the codebase from
|
|
|
|
|
a cold start. **Before you open a PR** is the checklist of conventions reviewers
|
|
|
|
|
otherwise have to enforce by hand -- read it before submitting any change.
|
|
|
|
|
|
|
|
|
|
Then read the directory guide for the area you are editing:
|
|
|
|
|
|
|
|
|
|
- [src/AGENTS.md](src/AGENTS.md) -- compiler C++ sources: AST, visitors, passes, parser, style
|
|
|
|
|
- [include/AGENTS.md](include/AGENTS.md) -- runtime library (`verilated*`): C++14, MT-safety, fixed-width types
|
|
|
|
|
- [test_regress/AGENTS.md](test_regress/AGENTS.md) -- regression tests: harness, drivers, golden files
|
|
|
|
|
- [docs/AGENTS.md](docs/AGENTS.md) -- documentation (`*.rst`)
|
|
|
|
|
|
2026-06-15 23:44:50 +02:00
|
|
|
______________________________________________________________________
|
2026-06-15 14:42:34 +02:00
|
|
|
|
|
|
|
|
# Orientation
|
|
|
|
|
|
|
|
|
|
## What Verilator is
|
|
|
|
|
|
|
|
|
|
Verilator is a *compiler*, not an interpreter. It translates synthesizable (and
|
|
|
|
|
much behavioral) SystemVerilog into a cycle-accurate C++ model that you then
|
|
|
|
|
compile and run. Almost every decision is made at compile ("verilation") time;
|
|
|
|
|
the generated C++ just advances state each evaluation. Optimize for verilation-
|
|
|
|
|
time work over runtime work.
|
|
|
|
|
|
|
|
|
|
## The pipeline is the spine
|
|
|
|
|
|
|
|
|
|
A run is an ordered sequence of passes over one shared AST (abstract syntax
|
|
|
|
|
tree). In source order:
|
|
|
|
|
|
|
|
|
|
| Stage | What it does | Key files |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| Preprocess + parse | Lex and parse text into a raw AST -- builds nodes only, no semantic checks | `verilog.l`, `verilog.y` |
|
|
|
|
|
| Link / elaborate | Resolve names, scopes, parameters; instantiate the hierarchy | `V3LinkParse`, `V3LinkDot`, `V3Param` |
|
|
|
|
|
| Width / type | Assign and check data types and bit widths | `V3Width` |
|
|
|
|
|
| Transform / optimize / schedule | Constant fold, lower language features, schedule events | `V3Const`, `V3Randomize`, `V3Assert*`, `V3Sched`, `V3Timing`, `V3Dfg` |
|
|
|
|
|
| Emit | Lower the final AST to generated C++ | `V3EmitC*` |
|
|
|
|
|
| Runtime | Library the generated model links against | `include/verilated*` |
|
|
|
|
|
|
|
|
|
|
This table is the map; `docs/internals.rst` has the detail behind each stage.
|
|
|
|
|
|
|
|
|
|
## Where to make a change
|
|
|
|
|
|
|
|
|
|
Map the symptom to the pass that owns it, then start by reading that pass's
|
|
|
|
|
top-of-file comment.
|
|
|
|
|
|
|
|
|
|
| Symptom or feature area | Start in |
|
|
|
|
|
|---|---|
|
|
|
|
|
| Type/width error, "what type is this", implicit conversion | `V3Width` |
|
|
|
|
|
| Name/scope/parameter resolution ("Can't find...", hierarchy) | `V3LinkDot`, `V3Param` |
|
|
|
|
|
| `randomize` / `constraint` / `rand` / `randc` | `V3Randomize` |
|
|
|
|
|
| `assert` / `property` / `sequence` / `cover` | `V3Assert`, `V3AssertPre`, `V3AssertNfa` |
|
|
|
|
|
| `fork` / timing / `#delay` / NBA / event scheduling | `V3Sched`, `V3Timing`, `V3Fork` |
|
|
|
|
|
| Syntax wrongly accepted or rejected | `verilog.y`, `verilog.l` |
|
|
|
|
|
| Wrong generated C++ | `V3EmitC*` |
|
|
|
|
|
| Runtime model behavior | `include/verilated*` |
|
|
|
|
|
|
|
|
|
|
## Build and run a test
|
|
|
|
|
|
|
|
|
|
- Build in the source tree: `autoconf && ./configure && make -j8`. Configure with
|
|
|
|
|
`--enable-ccwarn` so a new compiler warning stops the build.
|
|
|
|
|
- Run one test from the repository root: `test_regress/t/t_<name>.py`.
|
|
|
|
|
- Run the full regression with `make test`. The complete suite requires
|
|
|
|
|
configuring with `--enable-longtests` (works on every OS, including macOS).
|
|
|
|
|
|
2026-06-15 23:44:50 +02:00
|
|
|
______________________________________________________________________
|
2026-06-15 14:42:34 +02:00
|
|
|
|
|
|
|
|
# Before you open a PR
|
|
|
|
|
|
|
|
|
|
## Scope and process
|
|
|
|
|
|
|
|
|
|
- [ ] Searched open PRs and issues -- duplicating in-flight work wastes review time.
|
|
|
|
|
- [ ] Fixed the general root cause, not just the reported case -- if it also
|
2026-06-15 23:44:50 +02:00
|
|
|
affects other modules/classes/interfaces, cover them or expect rejection.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] PR is single-purpose. Refactors, drive-by fixes found along the way, and new
|
2026-06-15 23:44:50 +02:00
|
|
|
features each go in separate PRs; land standalone cleanups first.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Every bug fix has a test that fails *without* the fix; include the issue's
|
2026-06-15 23:44:50 +02:00
|
|
|
own reproducer when possible.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] New code aims for 100% line coverage; branch coverage far below line coverage
|
2026-06-15 23:44:50 +02:00
|
|
|
signals guards callers never violate -- justify or remove them.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Ran `make format` (clang-format), `make cppcheck`, and `make lint-py`;
|
2026-06-15 23:44:50 +02:00
|
|
|
self-reviewed the diff for leftover debug code, stale comments, and
|
|
|
|
|
copy-paste errors.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Ran the full regression on at least one OS before submitting. Partial runs
|
2026-06-15 23:44:50 +02:00
|
|
|
are fine during development, but the submitted PR is expected to pass every
|
|
|
|
|
test.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Did not edit `docs/CONTRIBUTORS` (humans only) or `Changes` (maintainer
|
2026-06-15 23:44:50 +02:00
|
|
|
updates it near release).
|
2026-06-15 14:42:34 +02:00
|
|
|
|
|
|
|
|
## Pick the right diagnostic (and its required test)
|
|
|
|
|
|
|
|
|
|
The API you choose determines which test must accompany the change.
|
|
|
|
|
|
|
|
|
|
| API | Output | Meaning | Required test |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| `v3error("...")` | `%Error:` | User wrote invalid SystemVerilog | `t_*_bad*.v` + `.out` golden |
|
|
|
|
|
| `v3error("Unsupported: ...")` | `%Error-UNSUPPORTED:` | Legal SV that Verilator does not yet support | `t_*_unsup*.v` + `.out` golden |
|
|
|
|
|
| `v3warn(CODE, "...")` | `%Warning-CODE:` | Legal but suspicious code | warning test + `.out` golden |
|
|
|
|
|
| `v3fatalSrc("...")` | `%Error: Internal Error` | Should-never-happen internal assertion | none -- not user-triggerable |
|
|
|
|
|
|
|
|
|
|
- Every `v3error`/`v3warn` needs a test in `test_regress/t/` -- enforced by the
|
|
|
|
|
warn-coverage distribution test. `v3fatalSrc` is exempt.
|
|
|
|
|
- Reserve "Unsupported:" for not-yet-implemented features, never for user mistakes.
|
|
|
|
|
- When an error enforces a spec-defined restriction, cite the clause
|
|
|
|
|
(`IEEE 1800-2023 11.4.7`) so it is verifiable. Update `docs/guide/warnings.rst`
|
|
|
|
|
when adding or changing a warning.
|
|
|
|
|
- On error paths, clean up or replace invalid AST (e.g. `AstConst::BitFalse`) so
|
|
|
|
|
later passes do not crash after the error.
|
|
|
|
|
|
|
|
|
|
## Cross-cutting code rules
|
|
|
|
|
|
|
|
|
|
- [ ] No non-ASCII characters in C++ sources or headers: write `--` (two ASCII
|
2026-06-15 23:44:50 +02:00
|
|
|
hyphens) rather than a Unicode em-dash, and a plain `'` rather than a smart
|
|
|
|
|
quote. At write time, not when CI complains.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Lists stay sorted: lexer/parser tokens, option declarations, enum values,
|
2026-06-15 23:44:50 +02:00
|
|
|
configure feature lists, documented option lists.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] `bin/` scripts are Python (distributed cross-platform); `nodist/` may use
|
2026-06-15 23:44:50 +02:00
|
|
|
bash and platform-specific code (developer-only, not packaged).
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] Runtime code in `include/` targets C++14 (`--no-timing` builds must work);
|
2026-06-15 23:44:50 +02:00
|
|
|
C++20 only in timing code paths.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] In `include/` public headers, prefix public classes with `Verilated`/`Vl`
|
2026-06-15 23:44:50 +02:00
|
|
|
and document the API with `///` comments.
|
2026-06-15 14:42:34 +02:00
|
|
|
- [ ] A new code pattern is applied globally or not at all -- no one-off
|
2026-06-15 23:44:50 +02:00
|
|
|
convention in a single file.
|
2026-06-15 14:42:34 +02:00
|
|
|
|
|
|
|
|
## Commits
|
|
|
|
|
|
|
|
|
|
- Subject line is short and imperative and conventionally ends with the PR number:
|
|
|
|
|
`Support property case (#7721)`. A body is optional and common for non-trivial
|
|
|
|
|
changes.
|