rtl-area-timing — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited rtl-area-timing (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Making RTL smaller or faster is a sequence of structural decisions, each justified by a measurement. The wins are rarely where intuition points: the giant is often a structure you didn't think of (a "ROM" that is really 94k flops), and the critical path is usually one specific primitive, not "logic depth" in general.
Core principle: Diagnose with data, change one structure, re-measure. Optimize the actual critical path or the actual giant, and stop the moment it stops being the bottleneck. Guessing wastes builds and can place worse.
This is the RTL-technique companion to fpga-synthesis-fit (the tool methodology for measuring). Measure there, transform here.
A single-cycle NxN multiply (64x64) maps to DSP tiles plus a long partial-product carry chain, and that chain is usually the critical path.
Registering only the multiply's OUTPUT does not break the internal carry chain; the operands-to-output path is still essentially the whole multiply. You must pipeline INTERNALLY: decompose into smaller products (four 32x32), register the partial products, then sum the shifted partials in a second registered stage. Make the op multi-cycle with a small stall counter. On ECP5 this took a 64x64 from about 33 MHz to about 47 MHz.
Registering the multiply INPUTS too gave diminishing returns and placed worse. Stop once the multiply leaves the critical path; re-read the report to confirm.
A microcoded exec or decoder that computes all handler datapaths in parallel and muxes the winner by opcode builds every handler's logic. Real area wins:
addr >> (base + k*stride) is a 64-bit barrel shifter plus a multiply. If it extracts a FIXED field per k (a page-table VPN[level] slice), replace it with a mux of fixed slices.
But on ECP5 this can be post-pack neutral: barrel shifters and mux trees pack to similar slice counts. It reduces pre-pack LUT4 but may not move TRELLIS_COMB. Measure post-pack before believing the win (see the metric trap in fpga-synthesis-fit).
Sign-extension from W to 2W bits is monotonic for BOTH signed and unsigned W-bit ordering (it maps the two halves of the W-bit range to two ordered ranges in the wider unsigned space). So one comparator on sign-extended operands computes signed min/max AND unsigned minu/maxu, useful for AMOs and ALUs.
Verify the stored RESULT width: compute at XLEN but store the low size.bits, and match the surrounding code's sign-vs-zero extension of the stored value. A test once caught a sign/zero-extend mismatch on the store side here.
differential-verification.Before making hardware stricter to "fix" it, check whether the old behavior is permitted by the spec. Pre-Svade RISC-V PERMITS hardware page-table A/D-bit update; "always update A/D" is a legal implementation, not a violation. Making it Svade-strict (fault on A=0) is an ISA-policy choice tied to what the core advertises (Svadu/Svade), and it needs the tests' page tables updated to set A/D. It is not a free correctness fix. One such change hung 12 tests for no clear gain and was reverted.
$mux vs $add vs $sdffe). Don't guess the bottleneck.fpga-synthesis-fit; verify with differential-verification.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.