This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
HighTide is a VLSI design benchmark suite built on OpenROAD-flow-scripts (ORFS). It ports open-source hardware designs to asap7/sky130hd/nangate45 technologies using the OpenROAD RTL-to-GDSII flow, serving as a benchmark suite for ML projects.
Requires an Ubuntu machine with Bazelisk (or Bazel 7.6.1+). No additional setup needed — Bazel fetches everything via MODULE.bazel and the pinned bazel-orfs submodule.
# Build the full RTL-to-GDS flow for one design (through the gallery
# render — caches the layout PNG too, so update-results is a pure fetch)
bazel build //designs/asap7/lfsr:lfsr_gallery
# Build a design across all available platforms
bazel build //designs/asap7/minimax:minimax_final \
//designs/nangate45/minimax:minimax_final \
//designs/sky130hd/minimax:minimax_final
# Build all designs for a platform
bazel build //designs/asap7/...
# Build all designs across all platforms
bazel build //designs/...
# Build individual stages (target suffixes: _synth, _floorplan, _place, _cts, _grt, _route, _final)
bazel build //designs/asap7/lfsr:lfsr_synth
bazel build //designs/asap7/lfsr:lfsr_placeNote: hightide_design() exposes the per-stage orfs_flow targets (_synth … _final), _generate_abstract / _generate_metadata, and _<design>_gallery (renders the layout PNG; src = :<design>_final). There is no aggregate :<design> target. Build :<design>_gallery for sweeps — it runs the whole flow and renders+caches the gallery image, so update-results (and k8s/run.sh, which now targets _gallery) becomes a pure cache fetch with no per-design local re-render. Use :<design>_final only when you explicitly don't want the image.
Three tools export a design's resolved inputs out of bazel so it can run under plain ORFS or a non-OpenROAD PD tool (README's "Two tools bridge the gap" has full usage):
tools/bazel_to_config_mk.sh [--abs] <design> <out.config.mk>— extracts just an ORFS-compatibleconfig.mk(cheap bazel analysis only, no synth/PnR).tools/bazel_to_orfs.sh <design>— materializes the RTL + copies every input into a self-contained, relocatable ORFS bundle (.orfs_bundles/<platform>/<design>/with arun.sh);--runruns it against your own ORFS install.tools/bazel_to_orfs.sh --benchmark-dir <dir> all— a tool-neutral export:platforms/+designs/<platform>/<design>/, each carrying a versionedmanifest.json(RTL top, inputs, LEF/Liberty/GDS, placement/routing config) alongside the ORFSconfig.mk. Inputs only — no synth/PnR results. Implemented bytools/benchmark_manifest.py+stage_platform.py/stage_prepared_inputs.py.
Publishing: the publish-benchmark-bundle.yml Actions workflow (manual workflow_dispatch only) runs the --benchmark-dir all export and attaches the zipped bundle to a GitHub Release benchmark-inputs-<sha>. Free (public repo; Release assets aren't metered) and it does not run synthesis/PnR. Each run creates a new release — prune old ones occasionally; the per-asset cap is 2 GB.
Caveat: this is a portable input contract, not a complete tool-independent flow — synth args/Tcl are still Yosys/Slang/OpenROAD syntax, and extracted workaround vars (SKIP_CTS_REPAIR_TIMING, etc.) may be stale against a different ORFS, so re-validate QoR on your own toolchain.
MODULE.bazel— Mirrorsbazel-orfs's root-only overrides (it pins ORFS/OpenROAD viaarchive_overridetarballs, builds OpenROAD from source, yosys0.64, sv-lang/scip/sed/boost.unorderedsingle_version_overrides) and adds HighTide's yosys-slang plugin. Keep in sync withbazel-orfs/MODULE.bazelat the pinned submodule commit when bumping (see theupgrade-toolsskill)..bazelrccarries--@openroad//:platform=gui(needed by the_galleryrender)defs.bzl—hightide_design()macro wrappingorfs_flow()with common defaults (GDS_ALLOW_EMPTY, platform-to-PDK mapping)BUILD.bazel(root) — Defines themerge_yosys_sharetarget that bundles the yosys-slang plugin- Each design has a
BUILD.bazelcallinghightide_design()with its parameters (utilization, density, SRAMs, etc.) - RTL sources are fetched hermetically:
designs/src/<design>/BUILD.bazelaliases:rtlto the pinned@<design>_srcarchive (or to a local converter target)
Each design lives at designs/<platform>/<design>/ and contains:
BUILD.bazel— Callshightide_design()with verilog_files, sources (SDC, LEFs, LIBs), arguments (utilization, density, etc.)constraint.sdc— Clock definitions and timing constraintspdn.tcl(optional) — Power delivery network configuration (layer stripes, pitches)io.tcl(optional) — Pin placement constraints
Design RTL sources are pinned as hermetic http_archives in the root MODULE.bazel (@<design>_src) — no git submodules, no vendored RTL.
Each designs/src/<design>/ has:
external.BUILD.bazel— injected BUILD for the fetched archive; exposes an:rtlfilegroup (or the source files a converter consumes)BUILD.bazel— a stable:rtlalias pointing at@<design>_src//:rtl, or at a local converter target (sv2v genrule, Chiselscala_binaryunderrules_scala, or a Pythonpy_binarygenerator that emits:gen_<design>)
Source fixes are declarative patches = [...] on the http_archive. To move a design to a newer upstream, bump its archive urls/sha256/strip_prefix in MODULE.bazel.
| Platform | Node | Designs |
|---|---|---|
| asap7 | 7nm academic | coralnpu, gemmini, lfsr, litedram, minimax, sha3, vortex, liteeth, NVDLA (partitions a/c/m/o/p), bp_processor (bp_uno, bp_quad), cnn, floonoc, NyuziProcessor, snitch_cluster |
| nangate45 | 45nm | coralnpu, gemmini, lfsr, litedram, minimax, NyuziProcessor, sha3, liteeth, bp_processor (bp_uno, bp_quad), cnn |
| sky130hd | 130nm open | gemmini, lfsr, litedram, minimax, sha3, liteeth, cnn, bp_processor (bp_uno) |
Per-design close history, knobs, QoR, and known issues live in designs/src/<design>/DECISIONS.md, with one ## <platform> section per technology. Update there, not here — this index just tracks which (design, platform) pairs are reaching _final.
The authoritative "which pairs finish" list is the webpage worktree's results.html (one QoR row per finishing pair), not this index — the lists below had drifted stale (they understated coverage; e.g. eyeriss/floonoc/litepci/snitch_cluster/ternip/partition_p all finish). As of the 2026-06 toolchain upgrade the suite has 59 finishing (platform, design) pairs.
Reaching _final on the 2026-06 upgraded tools (bazel-orfs 553c1c3), validated clean (QoR within ~5 % of the pre-upgrade results.html baseline):
- lfsr, minimax, sha3, ternip (all 3 platforms); coralnpu, liteeth, gemmini, litedram (all 3); NyuziProcessor (asap7/nangate45); floonoc (all 3 platforms); eyeriss (all 3); litepci (asap7/nangate45); all NVDLA partitions a/m/o/p (asap7/sky130hd), a/c/m/o/p (nangate45), partition_c (asap7); vortex-asap7.
Reaching _final but with a flagged QoR regression the upgrade introduced (not flow-knob recoverable without RTL/SDC — see each DECISIONS.md): vortex-nangate45/sky130hd (yosys-0.64 FF-fallback cell growth +25–28 %), cnn-nangate45 (new-RTLMP macro placement, Fmax −49 %), coralnpu-sky130hd / vortex-sky130hd (marginal setup), litepci-nangate45 (pre-existing unconstrained forwarded clock).
In progress / not yet re-validated on the upgraded tools at last checkpoint: cnn-asap7/sky130hd, bp_uno (all 3), snitch_cluster (asap7/nangate45), litepci-sky130hd (GRT-congestion retune). sky130hd NVDLA partition_c still does not finish (GP plateau).
2026-07 re-validation on the newer pin (bazel-orfs 6c1bbca / OpenROAD b65c274c / OpenSTA 8572175a): the above "in progress" designs were re-validated and closed on the newer OpenROAD (this pin also resolves the snitch_cluster-nangate45 global-placement hang that 553c1c3 had):
- PASS (QoR within tolerance): snitch_cluster (asap7 +253 ps / nangate45 +5801 ps), bp_uno (asap7 −510 ps, nangate45 +576 ps, sky130hd +3489 ps), litepci-asap7 (+927 ps) and litepci-nangate45 (+4266 ps at a relaxed 10 ns probe clock — tighten via
period_minfollow-up). - Finishes but flagged: cnn-asap7 (macro-placement Fmax −49 %, now finishes via
SKIP_INCREMENTAL_REPAIRinstead of spinning in the non-converging new-resizer repair). - Fixes required (see workaround table):
SKIP_INCREMENTAL_REPAIRfor cnn-asap7 + litepci-asap7/nangate45 (new-resizer repair non-convergence); litepci-nangate45 SDC clock-period sed-poisoning; and aMODULE.bazelyosys-slang tarball-checksum bump to unblock fresh/k8s fetches. - Still non-finishing on this pin: litepci-sky130hd (GRT congestion), NVDLA partition_c-sky130hd (GP plateau). partition_o-sky130hd does finish on b65c274c (verified 2026-07-15 on k8s): its detail route is extremely slow (~10 h) but converges cleanly to
_final— the earlier "detail-route congestion" non-finishing claim was wrong (it was slow, not blocked; antenna repair converged 5391→23). The new resizer'splace_gpruns two timing-drivenrepair_designpasses, making 1.3M+ cell designs ~2–3× slower (snitch-nangate45 ~14 h end-to-end).
Use tools/fetch_cache.sh to pull cached _final results from the remote cache; designs in the local-only / not-finishing lists above aren't on it.
Build artifacts go to bazel-bin/designs/<platform>/<design>/. Key outputs:
results/<platform>/<design>/base/6_final.{odb,v,sdc,spef}— Final ODB and netlist (and6_final.gdswhenGDS_ALLOW_EMPTYis not suppressing GDS write)results/<platform>/<design>/base/<N>_<stage>.{odb,sdc,...}— Per-stage outputs (1_synth, 2_floorplan, 3_place, 4_cts, 5_1_grt, 5_2_route, 6_final)reports/<platform>/<design>/base/— QoR and OpenROAD-generated.webp.pngheatmaps/placement images written by ORFS's own report stagelogs/<platform>/<design>/base/— Per-stage logs
Designs with embedded memories use FakeRAM (LEF-only, no GDS). Controlled by GDS_ALLOW_EMPTY = fakeram.* set as a default in defs.bzl.
Every design's LEF/LIB is generated by tools/bsg_fakeram (VLSIDA fork — https://github.com/VLSIDA/bsg_fakeram, branch asap7-area-calib-v2). The fork carries local patches on top of upstream BSG: per-bit write_granularity end-to-end, calibrated asap7 area (2.5× periphery overhead + dynamic column mux for ~1.5:1 aspect, bitcell from Clark et al. 2016), the same analytical path for sky130hd (1.07×1.74 µm bitcell from OpenRAM), and the wd_in LEF pin-direction fix (c83ecb4). nangate45 still uses CACTI directly. The fork README acknowledges both BSG and ABKGroup's FakeRAM2.0 as upstream sources.
wd_inLEF bug (fixedc83ecb4, submodule bumped in HighTide044c02b9): beforec83ecb4,generate_lef.pyset the pinDIRECTIONby physical die side, not pin function, so the upper half of every write-data bus (*_wd_in[ceil(W/2)..W-1]) was emitted asDIRECTION OUTPUTwhile Liberty correctly saidinput. yosys (uses Liberty) synthesized correctly, but OpenROAD PnR (uses LEF) shorted half of every write-data bus into one giant net → unroutable GRT-0116 congestion (first caught on cnn-sky130hd, net with 1964 iterms / 512 bogus drivers). Pre-existing since fork commit0e1b3c00(Oct 2025). Any LEF generated beforec83ecb4is electrically invalid — regenerate viatools/regenerate_sram.shand verifygrep 'DIRECTION OUTPUT' -B1shows no*_wd_inpins.
Generation flow:
- One JSON cfg per (design, platform) lives at
designs/src/<design>/dev/generated/fakeram_<platform>.cfg. Lists the macrosramsarray with width / depth / banks /no_wmask/ port spec. tools/regenerate_sram.sh <design> <platform>runsbsg_fakeram/scripts/run.pyon that cfg, then copies the resulting.lef/.libintodesigns/<platform>/<design>/sram/{lef,lib}/. The intermediatedev/generated/sram/<platform>/tree is gitignored.tools/diff_sram_size.sh <design> <platform>emits a markdown diff of new vsgit HEADsizes (area %, aspect ratios, flag on >25% area or >2× aspect change) for pre-commit review.tools/reconstruct_cfg_from_lef.py <design> <platform>— for designs whose cfg was lost or drifted (Section B:coralnpu,vortex,NyuziProcessorhad no usable cfg / stale names). Derives a standard-path cfg from the committed LEF macro set (the ground truth for what the RTL instantiates): width fromwd_inpin count, depth from the macro-name dims disambiguated by width (handles bothWIDTHxDEPTHandDEPTHxWIDTHnaming and non-power-of-2 depths like16x52), ports from the name suffix,write_granularityfrom wmask/width.
Committed LEF/LIB lives at designs/<platform>/<design>/sram/{lef,lib}/ for every design.
Sub-CACTI-sized memories: a few designs need sizes below CACTI's reach (very narrow words, depth ≤ 16, or under ~1 Kb). Those don't get LEF/LIB; instead a small behavioural Verilog stub is added to the RTL filegroup and yosys synthesises the array as flip-flops. Two scripts emit these stubs:
designs/src/NVDLA/dev/gen_ff_rams.py→dev/generated/sram_ff/fakeram_*_1r1w.vfor(6,128),(9,80),(66,8),(64,16),(256,16),(272,16). Included in the NVDLA:rtlfilegroup.designs/src/bp_processor/dev/gen_macros_v.py→designs/{asap7,nangate45}/bp_processor/macros.v. Wrapsbsg_mem_1rw_sync_synth/bsg_mem_1rw_sync_mask_write_bit_synth; sizes not inLARGE_CONFIGS(currently 32x66 and 8x174) fall through to a register-array branch.designs/src/vortex/dev/VX_dp_ram_REPLACE.sv— the 6 vortex macros bsg_fakeram cannot size on all target platforms (192x16/193x16/85x16/87x16depth 16 below nangate45 CACTI range;560x4/654x4depth 4 exceed asap7 analytical pin-routing) have theirg_fakerambranches removed so those(DATAW,SIZE)configs fall through to the stub's existing behavioral reg-array path (FF on all 3 platforms — the stub is shared RTL). Hard macros kept:128x64/21x256/21x64(dp),32x1024/512x64/128x256(sp).
When reporting or comparing cell counts across designs or platforms, exclude fill cells, tap cells, and antenna cells. They are physical-only / manufacturing-rule cells, not part of the design's logic. Their counts vary wildly across platforms (sky130hd uses ~17× more tap cells than nangate45 due to a stricter max-tap-distance rule, and lower CORE_UTILIZATION inflates filler counts proportionally), so including them obscures real differences.
Use the per-class fields in 6_report.json (e.g. class:sequential_cell, class:multi_input_combinational_cell, class:inverter, class:clock_buffer, class:timing_repair_buffer) — not the top-level instance__count — when comparing designs.
When tightening a design's clock period to raise Fmax, do not use finish__timing__setup__ws (reported WNS) as the limiter. For LiteX/protocol/NVDLA designs (litedram, liteeth, litepci, floonoc, NVDLA, bp_uno) the worst setup path is often a pure input→output combinational feedthrough constrained only by set_input_delay + set_output_delay = clk_io_pct*period, so its slack is ~0.6*period and shows a permanent huge "margin" no matter how tight the clock — it tracks the constraint, not silicon, and masks the real register-to-register path (some designs were reg2reg-violated at baseline while reported WNS stayed positive). 6_finish.rpt's setup section only prints the worst path per group (= this io path), so it can't reveal reg2reg slack either.
Use report_clock_min_period instead — the period_min field in 6_finish.rpt is the achievable minimum period from the routed netlist and is reg2reg-dominated. ORFS synthesis optimizes to the target clock, so period_min keeps dropping as you tighten (litedram-asap7 floor fell 2373→1217→902 ps as the target tightened); iterate clk_period = period_min * 1.10, rebuild, re-read, until set/period_min ≈ 1.10 (converged). Some designs hit a routability floor first (P&R fails before timing runs out — back off to the tightest that routes). Retrieve period_min for large designs via k8s/run.sh --upload-artifacts (PVC); their stage ODBs bust the Cloudflare cache cap.
Designs in this repo carry workarounds for upstream tool bugs. Update this table whenever a new workaround lands, and remove rows once the upstream bug is fixed and the workaround can be reverted.
2026-06 toolchain upgrade (bazel-orfs
553c1c3/ OpenROAD299f3015/ OpenSTA8575070/ yosys0.64). The following bugs are fixed upstream and their workarounds were removed where QoR allowed (see per-design DECISIONS.md): CTS-0122 (in the pin — local patch dropped), CTS-0105 ([#10177], removed on NyuziProcessor), ODB-1200 / RSZ-0074 (resizer rewrite — removed on liteeth n45/sky, gemmini, litedram-asap7, NyuziProcessor, eyeriss, litepci a7/n45), ODB-0445 (removed on NyuziProcessor). A few designs keep an ODB-1200-family skip not for the (fixed) crash but because the new resizer'srepair_timingdoes not converge on them (litepci-sky: ~23 h GRT spin →SKIP_INCREMENTAL_REPAIR; asap7 liteeth/eyeriss kept for QoR). New issues introduced by the upgrade: the OpenSTAwrite_sdcUTF-8 corruption row below (NVDLA partition_m/c), and MPL-0040 recurs under the new RTLMP (eyeriss-asap7, fixed via util 40→30). Genuine, non-workaround QoR regressions from the new synth/place: vortex-n45/sky cell growth (+25–28 %), cnn macro-placement (Fmax −49 %) — flagged in their DECISIONS.md.
| Bug | Affected designs | Workaround | First commit | Issue |
|---|---|---|---|---|
GRT-0183 heap underflow in repair_antennas — updateRouteGridsLayer in FastRoute.cpp modified the routing grids vector in-place; when two jumpers were inserted on the same net at adjacent positions, their promoted endpoints merged into a single same-layer chain. releaseNetResources then decremented a uint16_t usage counter for an edge that was never incremented, wrapping to 65535. Triggered by sky130hd's high post-DRT antenna violation count (→ many diodes + jumpers, high probability of adjacent jumpers on the same net). |
sky130hd NVDLA partition_c (baseline floorplan) |
Local patch patches/openroad-grt-0183-fix.patch (upstream PR #10743, merged 2026-06-24). Remove once OR pin advances past 2026-06-24. |
(this PR) | OpenROAD#10156, #10273 |
OpenSTA write_sdc instance-name corruption (new in OpenROAD 299f3015) — expanding a wildcard set_false_path -to [get_pin */SETN] / */RESETN writes corrupted (invalid-UTF-8) instance names into 1_synth.sdc; Tcl 9's strict UTF-8 then hard-fails floorplan reading it (error reading "fileN": invalid or incomplete multibyte) |
NVDLA partition_m (asap7/sky130hd), partition_c (asap7/nangate45) |
Remove the two redundant -to [get_pin */SETN|/RESETN] async-reset false-paths from constraint.sdc (reset sources are already -from false-pathed and the reset nets are set_ideal_network, so no real timed path is lost) |
(this PR) | None filed yet |
bsg_fakeram wd_in LEF direction — generate_lef.py set pin DIRECTION by physical die side, not function, so the upper half of every write-data bus was OUTPUT in LEF while Liberty said input; OpenROAD PnR shorted half of each wd_in bus → unroutable GRT-0116 (cnn-sky130hd net: 1964 iterms / 512 bogus drivers) |
every fakeram design's pre-c83ecb4 LEF (Section A + B); all prior _final passes invalid |
Fork fix c83ecb4 (submodule bumped 044c02b9); regenerate all macros via tools/regenerate_sram.sh / tools/reconstruct_cfg_from_lef.py; vortex's 6 unsizable macros → FF-fallback |
c83ecb4 / 044c02b9 |
Pre-existing in fork since 0e1b3c00 (Oct 2025); fixed in VLSIDA/bsg_fakeram |
bsg_fakeram snap-grid key mismatch — cfg files set snap_width_nm/snap_height_nm (snake_case), but class_process.py only reads snapWidth_nm/snapHeight_nm (camelCase) and silently falls back to a 1 nm grid on a miss, so the intended platform site-grid snap never applies. Confirmed on committed asap7 LEF (fakeram_64x256_1r1w: SIZE 107.137 BY 66.961 — divides evenly by 0.001 µm, not by the intended 0.190/1.400 µm grid) |
Every asap7 fakeram cfg in the repo (NVDLA, cnn, coralnpu, NyuziProcessor, vortex, ternip, bp_processor, liteeth, litepci, eyeriss, snitch_cluster) — all use the wrong snake_case keys. nangate45/sky130hd cfgs are unaffected (correctly use camelCase). Suspected contributor to asap7 macro designs with unresolved timing/congestion (not yet confirmed) | Fixed so far only for gt2n NVDLA cfgs (this PR) — renamed keys, regenerated via tools/regenerate_sram.sh, confirmed macros now land on-grid. asap7 cfgs across the suite not yet fixed or regenerated — flagged for follow-up, no designs rebuilt against this yet |
(this PR, gt2n only) | None filed yet |
CTS-0105 false skip — yosys hierarchical synthesis output port buffers arrive in ODB with dbSourceType::TIMING instead of NETLIST; CTS skips them as pre-existing clock buffers and leaves the clock net unbuffered |
asap7 NyuziProcessor; asap7/nangate45/sky130hd bp_quad, bp_uno |
PRE_CTS_TCL script resets affected buffers' dbSourceType from TIMING → NETLIST before CTS runs |
81b0ed4b |
OpenROAD#10177 |
MPL-0040 — rtl_macro_placer annealing failure on certain macro clusters |
asap7 bp_quad (pipe_fma cluster), asap7 cnn |
Hand-place fakeram macros in left-edge columns at FIRM status via macros.tcl so RTLMP only sees pre-placed macros; for cnn also drop CORE_UTILIZATION 65→60 |
09542e19 |
OpenROAD#9985 |
ODB-1200 in repair_timing — InsertBufferBeforeLoads iterates a stale load list and aborts the flow with Load pin '...' is not connected to net '...'. Triggered by the resizer's SplitLoadMove step in CTS-time repair_timing |
asap7 liteeth; sky130hd NyuziProcessor; asap7 NyuziProcessor (surfaced post-wd_in-fix); asap7 bp_quad; asap7 gemmini |
Most designs: SKIP_CTS_REPAIR_TIMING = 1 (skips the whole repair pass; route still does its own hold-repair). Gemmini: drop split_load from SETUP_MOVE_SEQUENCE ("unbuffer,sizeup,swap,buffer,clone") — keeps the rest of repair_timing working (try this first). asap7 NyuziProcessor: split_load-drop did not clear it (ODB-1200 recurred via another move) → escalated to the full SKIP_CTS_REPAIR_TIMING = 1 |
87829fdb |
HighTide#75 |
DPL-0036 in CTS-internal detailed_placement — cts.tcl builds its own dpl_args ignoring DETAIL_PLACEMENT_ARGS, so CTS-inserted leaf clock buffers can land too far from a legal stdcell row |
asap7 snitch_cluster |
PRE_CTS_TCL wraps detailed_placement to inject -max_displacement {2000 400} for the CTS call |
0af20020 |
None (ORFS layering issue; no upstream issue filed yet) |
yosys-slang phantom 1'x drivers on interface-array modport ports — extra driver wins at opt_clean, real driver silently dropped |
asap7 vortex |
Bumped yosys-slang 4e53d77 → eabdfd1 (vendored via MODULE.bazel) |
cb488bea |
yosys-slang#304 |
repair_timing non-convergence — repair loop spends iterations on the same RTL-bounded endpoint without making progress. Not a bug per se, but a flow pathology when the clock target is too tight for the design |
asap7 snitch_cluster, asap7 litedram |
SKIP_INCREMENTAL_REPAIR = 1 to skip post-GRT repair_timing |
39ca8670 |
None |
ODB-0445 in post-GRT repair_timing — [CRITICAL ODB-0445] No undo_updateField support for type dbTechNonDefaultRule. The resizer's Journal::undo can't unroll changes to dbTechNonDefaultRule made during repair; crash trips during the slack-spiral retry on a single endpoint. Surfaces in dense placements that need NDR-using moves |
asap7 NyuziProcessor (post util 55→65 PPA push) |
SKIP_INCREMENTAL_REPAIR = 1 — same workaround family as repair_timing non-convergence; detailed-route hold-repair still runs |
(this PR) | None (no upstream issue filed yet) |
LiteX GENSDRPHY input sdram_dq — litedram/gen.py declares the bidirectional SDR DQ bus as a plain input port (Lattice-platform convention; the tristate buffer lives at the IOB), but the same module instantiates 16 TRELLIS_IO cells that internally drive the port via OE-gated logic. yosys' check -assert -mapped sees the conflict and aborts synth on all 3 platforms |
asap7/nangate45/sky130hd litedram |
Patch litedram_core.v to make sdram_dq an inout port (patch/litedram_core.patch). Combined with SYNTH_HIERARCHICAL = 1 so abc keeps each TRELLIS_IO as a hierarchy boundary |
(this PR) | None (LiteX gen.py:870 carries a # FIXME: Allow other Vendors. note) |
PSM-0069 power/ground net not reaching boundary row — Grid::makeVias silently drops via candidates connecting a power/ground stripe to the boundary cell row when signal IO pins on an intermediate layer have their spacing-expanded obstruction overlapping that row's via area; the stripe terminates short of the boundary row, leaving all its cells with disconnected power/ground. No PDN-0110 fires for obstruction removal (PDN-0110 is for via geometry failures only); manifests as a PSM-0039 flood on boundary-row instances and PSM-0069 at _final. |
sky130hd floonoc |
Reduce edge_margin in io.tcl until the IO-pin obstruction clears the boundary-row via area; threshold: edge_margin < core_yMin − row_height/2 − met_spacing. See DECISIONS.md for platform-specific values. |
bbc7fd0 |
None filed upstream |
dbNet::getFirstOutput() skipped the driver of clock nets sourced by a clock: true macro output. Fixed upstream ([#10549], cd4f5041); the OpenROAD 299f3015 pin is past it, so the local patches/openroad-cts-0122-fix.patch was dropped. litepci-asap7 went from WNS −883 ps (broken clock tree) to +944 ps. |
sky130hd/nangate45/asap7 litepci |
(removed — fix in pin) | (this PR) | OpenROAD#10549 (merged cd4f5041) |
New-resizer post-GRT repair_timing non-convergence on structurally-unfixable reg2reg (OpenROAD b65c274c) — when the worst reg2reg path is structural and unrepairable (a macro-placement-bound path, or a LiteX forwarded-clock io-feedthrough), the post-GRT repair_timing never terminates: it keeps buffering while TNS decays asymptotically, and per-iteration incremental STA time grows past an hour, so the stage runs for many hours with no closure. Distinct from the older RTL-bounded repair_timing non-convergence row above — this one is the new resizer chewing on a path it cannot fix. |
asap7 cnn (macro-bound, Fmax−49 %); asap7/nangate45 litepci (forwarded-clock WNS≈−898 ps) |
SKIP_INCREMENTAL_REPAIR = 1 — GRT then finishes in minutes and the design reaches _final. (litepci-asap7's BUILD.bazel had described this skip in a comment but never actually set the arg — now set.) The unfixable path remains (documented per-design), but the design finishes instead of spinning. |
(this PR) | None filed yet |
SDC clock-period sed poisoning — ORFS derives the ABC target clock period from the SDC with a naive sed (variables.mk: s/^set\s+clk_period\s+(\S+)|.*-period\s+(\S+)/…/) that takes the first -period <n> or set clk_period <n> token in the file. A quoted example in a comment above the real clock line can be captured verbatim; a trailing backtick then makes echo <val> > clock_period.txt an unterminated shell command-substitution → make Error 2, killing synth before floorplan. |
nangate45 / sky130hd litepci |
Put the real set clk_period assignment before historical syntax, and keep the parser's conflicting token out of preceding comments. The nangate45 note was already reworded; sky130hd now puts the assignment first and rewords its note. |
nangate45: existing; sky130hd: this PR | HighTide#238 |
Stale yosys-slang slang-elab tarball checksum — GitHub regenerated the archive tarball for the OpenROAD-vendored yosys-slang submodule (commit 82effc8d), changing its gzip and thus its sha256 (d319a1f… → ea31b4a…; same source content, verified byte-identical after extraction). The stale pin in the openroad archive_override patch_cmds breaks every fresh bazel fetch (k8s pods, fresh output_bases) at repo-mapping time; only output_bases that cached the old tarball keep building. |
any fresh build (all designs, on k8s / new output_base) | Update the sha256 in MODULE.bazel (the mirrored patch_cmds for openroad) to the current value. If GitHub flips it again, re-fetch and re-pin. |
(this PR) | GitHub archive-tarball checksum instability |
PRE_CTS_TCL/PRE_GRT_TCL/ etc — point at a Tcl script that runs before the named stage. Used for the CTS-0105 reset and DPL-0036 displacement injection.SETUP_MOVE_SEQUENCE— comma-separated list of moves passed torepair_timing -sequence. Default sequence isunbuffer,sizeup,swap,buffer,clone,split_load. Dropsplit_loadto dodge ODB-1200 while keeping the rest of repair_timing active.SKIP_CTS_REPAIR_TIMING = 1— skip the entirerepair_timing_helpercall insidects.tcl. Heavier hammer than dropping a single move; route's own hold-repair still runs.SKIP_INCREMENTAL_REPAIR = 1— skip post-GRTrepair_timing. Use when the loop never converges (RTL-bounded critical paths).SKIP_LAST_GASP = 1— skip the final repair_timing pass.
These go into arguments = { ... } of hightide_design().
- This is a shared multi-user machine. When checking process status (e.g.,
ps aux | grep openroad), always filter to the current user's processes or check for bazel sandbox paths (external/bazel-orfs) to avoid confusing other users' builds with ours.
- NEVER run
bazel clean --expungeor delete the entire disk cache (~/.cache/bazel-disk-cache). Synthesis takes hours and clearing the cache forces a full rebuild of all designs. - To invalidate a single design's cached results, use targeted approaches:
- Change an argument in the design's BUILD.bazel (forces re-run of affected stages)
- Use
bazel build --strategy=<target>=localto bypass cache for one target
- The remote cache (
--remote_cachein.bazelrc) is shared and read-only by default. Never delete or corrupt it. - If you suspect a stale cache, verify by checking the process count in bazel output:
N processwrapper-sandboxmeans N actions actually ran;N internalmeans cached.
The remote cache is self-hosted bazel-remote fronted by a Cloudflare Tunnel whose free tier caps request bodies at 100 MB. ORFS emits multi-100-MB stage ODBs (2_floorplan.odb, 3_place.odb) for the largest designs; even with --remote_cache_compression (zstd) the very biggest still exceed the ceiling, so their _final results fail to upload and never get cached remotely — every k8s run rebuilds them from scratch and re-fails the upload. Build these locally instead so they at least populate the local ~/.cache/bazel-disk-cache:
bp_quad(asap7, nangate45) — biggest design (560 macros, 64–160 Gi RAM, 14 h+); k8s-hostile.bp_uno(sky130hd) — 140 macros + 7.6 M cells;6_final.odb2.9 GB. asap7/nangate45bp_unoupload OK; sky130hd's coarser pitches inflate the routed netlist past the ceiling.NVDLA/partition_c(asap7, nangate45, sky130hd) — the named offender in.bazelrc. The other NVDLA partitions (a/m/o/p) stay under the ceiling with zstd and run fine on k8s.cnn(nangate45, sky130hd) — 65 macros each.
Everything else — including NVDLA partitions a/m/o/p and the smaller recovery designs (ternip, bp_uno, liteeth, litepci, coralnpu, vortex, NyuziProcessor, cnn-asap7) — stays on k8s via ./k8s/run.sh --branch fakeram <platform> <design>.
Keep this list current: remove a design once all its cache objects are confirmed < 100 MB (it can go back to k8s); add a design the moment it fails to upload on k8s (the bazel log shows a cache-upload error / 413 / size-limit on a stage ODB). The list is a live record of which designs currently bust the Cloudflare ceiling, not a fixed set.