diff --git a/AGENTS.md b/AGENTS.md index 1f0c6a6be..2f5f06eda 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,7 +23,7 @@ Then read the directory guide for the area you are editing: - [test_regress/AGENTS.md](test_regress/AGENTS.md) -- regression tests: harness, drivers, golden files - [docs/AGENTS.md](docs/AGENTS.md) -- documentation (`*.rst`) ---- +______________________________________________________________________ # Orientation @@ -75,7 +75,7 @@ top-of-file comment. - Run the full regression with `make test`. The complete suite requires configuring with `--enable-longtests` (works on every OS, including macOS). ---- +______________________________________________________________________ # Before you open a PR @@ -83,21 +83,21 @@ top-of-file comment. - [ ] 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 - affects other modules/classes/interfaces, cover them or expect rejection. + affects other modules/classes/interfaces, cover them or expect rejection. - [ ] PR is single-purpose. Refactors, drive-by fixes found along the way, and new - features each go in separate PRs; land standalone cleanups first. + features each go in separate PRs; land standalone cleanups first. - [ ] Every bug fix has a test that fails *without* the fix; include the issue's - own reproducer when possible. + own reproducer when possible. - [ ] New code aims for 100% line coverage; branch coverage far below line coverage - signals guards callers never violate -- justify or remove them. + signals guards callers never violate -- justify or remove them. - [ ] Ran `make format` (clang-format), `make cppcheck`, and `make lint-py`; - self-reviewed the diff for leftover debug code, stale comments, and - copy-paste errors. + self-reviewed the diff for leftover debug code, stale comments, and + copy-paste errors. - [ ] Ran the full regression on at least one OS before submitting. Partial runs - are fine during development, but the submitted PR is expected to pass every - test. + are fine during development, but the submitted PR is expected to pass every + test. - [ ] Did not edit `docs/CONTRIBUTORS` (humans only) or `Changes` (maintainer - updates it near release). + updates it near release). ## Pick the right diagnostic (and its required test) @@ -122,18 +122,18 @@ The API you choose determines which test must accompany the change. ## Cross-cutting code rules - [ ] No non-ASCII characters in C++ sources or headers: write `--` (two ASCII - hyphens) rather than a Unicode em-dash, and a plain `'` rather than a smart - quote. At write time, not when CI complains. + hyphens) rather than a Unicode em-dash, and a plain `'` rather than a smart + quote. At write time, not when CI complains. - [ ] Lists stay sorted: lexer/parser tokens, option declarations, enum values, - configure feature lists, documented option lists. + configure feature lists, documented option lists. - [ ] `bin/` scripts are Python (distributed cross-platform); `nodist/` may use - bash and platform-specific code (developer-only, not packaged). + bash and platform-specific code (developer-only, not packaged). - [ ] Runtime code in `include/` targets C++14 (`--no-timing` builds must work); - C++20 only in timing code paths. + C++20 only in timing code paths. - [ ] In `include/` public headers, prefix public classes with `Verilated`/`Vl` - and document the API with `///` comments. + and document the API with `///` comments. - [ ] A new code pattern is applied globally or not at all -- no one-off - convention in a single file. + convention in a single file. ## Commits diff --git a/Makefile.in b/Makefile.in index c2b60d004..6bcbdbaa5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -495,6 +495,11 @@ MAKE_FILES = \ src/Makefile*.in \ test_regress/Makefile* \ +# Markdown +MD_FILES = \ + *.md \ + */*.md \ + # Perl programs PERL_PROGRAMS = \ bin/redirect \ @@ -553,7 +558,7 @@ YAML_FILES = \ # Format format: - $(MAKE) -j 5 format-c format-cmake format-exec format-py format-yaml + $(MAKE) -j 5 format-c format-cmake format-exec format-md format-py format-yaml BEAUTYSH = beautysh BEAUTYSH_FLAGS = --indent-size 2 @@ -590,6 +595,13 @@ format-make mbake: $(MBAKE) --version $(MBAKE) $(MBAKE_FLAGS) $(MAKE_FILES) +MDFORMAT = mdformat +MDFORMAT_FLAGS = + +format-md: + $(MDFORMAT) --version + $(MDFORMAT) $(MDFORMAT_FLAGS) $(MD_FILES) + YAPF = yapf YAPF_FLAGS = -i --parallel diff --git a/docs/AGENTS.md b/docs/AGENTS.md index ee4ae5249..1c0524c78 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -2,7 +2,7 @@ SPDX-FileCopyrightText: 2026-2026 Wilson Snyder SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 --> -# docs/ Guidelines -- Verilator documentation (*.rst) +# docs/ Guidelines -- Verilator documentation (\*.rst) When to check: before editing anything under `docs/`. Read the repository-root [AGENTS.md](../AGENTS.md) first for process and cross-cutting rules. diff --git a/include/AGENTS.md b/include/AGENTS.md index 5b409dfaf..0ac1fcbfe 100644 --- a/include/AGENTS.md +++ b/include/AGENTS.md @@ -9,7 +9,7 @@ that every generated model links against. Read the repository-root [AGENTS.md](../AGENTS.md) first. The rules here differ from `src/`: this code ships to users, runs every simulation cycle, and must stay portable and fast. ---- +______________________________________________________________________ # Orientation @@ -22,7 +22,7 @@ ships to users, runs every simulation cycle, and must stay portable and fast. (`--timing` runtime), `verilated_vcd_c.*`/`verilated_fst_c.*` (tracing). - A runtime-only fix lives entirely here and does not rebuild `verilator_bin`. ---- +______________________________________________________________________ # Before you open a PR diff --git a/python-dev-requirements.txt b/python-dev-requirements.txt index 11f9fad84..d6bcba7b1 100644 --- a/python-dev-requirements.txt +++ b/python-dev-requirements.txt @@ -21,6 +21,7 @@ compiledb==0.10.7 distro==1.9.0 gersemi==0.23.1 mbake==1.4.3 +mdformat==1.0.0 mypy==1.19.0 pylint==3.0.2 ruff==0.14.8 diff --git a/src/AGENTS.md b/src/AGENTS.md index 1904eb5c9..cb53dc31c 100644 --- a/src/AGENTS.md +++ b/src/AGENTS.md @@ -9,7 +9,7 @@ Covers all C++ under `src/`, including astgen inputs and the parser/lexer first. This file has two parts: **Orientation** explains the AST and pass model; **Before you open a PR** is the style and correctness checklist. ---- +______________________________________________________________________ # Orientation: the AST and the visitor model @@ -38,7 +38,7 @@ first. This file has two parts: **Orientation** explains the AST and pass model; - `docs/internals.rst` is the authoritative reference for the AST, the pass list, and node lifetime. ---- +______________________________________________________________________ # Before you open a PR @@ -77,6 +77,7 @@ first. This file has two parts: **Orientation** explains the AST and pass model; - Build logic as AST nodes, never as raw C text in `AstCStmt` -- later passes (V3Name, `--protect`) rename AST identifiers but cannot see into raw strings. + - Know the cast forms (above) and never pair `VN_IS` with `VN_AS` on the same node -- use a single `VN_CAST`: @@ -89,34 +90,47 @@ first. This file has two parts: **Orientation** explains the AST and pass model; - Use `UASSERT_OBJ(cond, nodep, "...")` over `UASSERT` when a node is in scope; use `v3fatalSrc("...")` for unreachable paths, never a silent `if (!ptr) return;`. + - Use `VL_DO_DANGLING(pushDeletep(nodep), nodep)` instead of `deleteTree()` in visitors -- deferred deletion is safe against re-entry and unlinking order. `deleteTree()` is only for fresh nodes that never entered the tree. + - Every new AST member needs both `dump()` and `dumpJson()` support -- never wrap these in `LCOV_EXCL`; cover them by adding a construct to `t_debug_emitv.v`. Override `isSame()` to include any new semantically meaningful field. + - Pointers to nodes outside op1p-op4p require a `broken()` override and `cloneRelink()` support -- avoid storing out-of-tree node pointers when possible. + - Never allocate AstNode objects on the stack or by value -- always pointers. + - Prefer a new `visit()` in an existing visitor over `nodep->foreach(...)` -- better for runtime, and handles diverse node types better. Prefer named accessors over `op1p()`..`op4p()`, and verify traversal order is preserved when converting manual iteration. + - Prefer `AstForeach` over generating unrolled loop bodies -- constant-size code instead of O(N); wrap the body in `AstBegin` for scope isolation. + - Always `skipRefp()` when comparing or resolving dtypes -- missing it breaks typedef support; prove the paths with typedef tests. + - Use `num().isOpaque()` rather than `isDouble() || isString()` when guarding V3Number comparisons against non-integer types. + - Use `FileLine::operatorCompare` for source-position ordering -- never hand-roll filename/lineno comparisons. + - Identify compiler-generated constructs by an attribute flag on the node (with dump support), never by name-pattern matching -- magic names break with escaped identifiers. + - Use `V3Number` arithmetic for `AstConst` values wider than 32 bits -- `1 << i` silently overflows at `i >= 32`. + - Use `VMemberMap`/`findMember()` for name lookups in structs, classes, modules, and packages -- O(1) versus quadratic linear scans. + - Never emit raw source filenames or identifiers in generated code -- pass them through `protect()`/`putsQuoted` so `--protect` does not leak source. diff --git a/test_regress/AGENTS.md b/test_regress/AGENTS.md index 05833d460..7d6b1b708 100644 --- a/test_regress/AGENTS.md +++ b/test_regress/AGENTS.md @@ -9,7 +9,7 @@ Covers `.v`/`.sv` sources, `.py` drivers, and `.out` golden files under file has two parts: **Orientation** explains how the harness runs a test; **Before you open a PR** is the test-authoring checklist. ---- +______________________________________________________________________ # Orientation: how the harness works @@ -30,7 +30,7 @@ file has two parts: **Orientation** explains how the harness runs a test; lists, warning documentation, ASCII-only) -- run the relevant ones before submitting. ---- +______________________________________________________________________ # Before you open a PR @@ -78,6 +78,7 @@ file has two parts: **Orientation** explains how the harness runs a test; ## Verilog style - 2-space indentation, no tabs. + - Declarations are flush-left with a single space between type and name; never column-align: @@ -92,12 +93,17 @@ file has two parts: **Orientation** explains how the harness runs a test; - Run `nodist/verilog_format` on new `.v` files; wrap macro definitions in `// verilog_format: off`/`on` so the formatter does not split them. + - Use `$display("%0d", ...)` not `%d` -- avoids leading-space padding. + - Wrap Verilator-specific test code (e.g. `$c`) in `` `ifdef VERILATOR ``. + - Use inline `// verilator lint_off WARNCODE` only when that warning is itself under test -- fix root causes otherwise. + - Use only IEEE 1800-compliant constructs other simulators also accept -- tests validate standard behavior, not Verilator's parser leniency. + - Omit optional end labels on `endmodule`/`endclass`/`endtask`/`endfunction`. ## Self-checking