Analyze and debug a failing HighTide2 design. Diagnose synthesis problems, memory inference issues, congestion, timing violations, and placement/routing failures. Can generate layout images for visual diagnosis.
You are debugging the design at designs/$0. The user may have specified a stage ($1) and/or an issue description ($2). If the stage or issue is not provided, determine them by examining build artifacts and logs.
Important: HighTide is a benchmark suite — the RTL is a fixed input. Never suggest modifying the upstream Verilog/RTL. All fixes must be scoped to flow parameters (config.mk), timing constraints (constraint.sdc), physical design files (io.tcl, pdn.tcl), and FakeRAM configuration.
Check for artifacts in three locations, in order of preference:
ls bazel-bin/designs/$0/results/*/base/*.odb 2>/dev/null
ls bazel-bin/designs/$0/logs/*/base/*.log 2>/dev/null
ls bazel-bin/designs/$0/logs/*/base/6_report.json 2>/dev/null
Artifacts downloaded from the Nautilus PVC are stored at artifacts/<platform>/<design>/:
ls artifacts/$0/results/*/base/*.odb 2>/dev/null
ls artifacts/$0/logs/*/base/*.log 2>/dev/null
ls artifacts/$0/logs/*/base/6_report.json 2>/dev/null
If no local artifacts exist, the design may have been built on the Nautilus NRP cluster (via ./k8s/run.sh --upload-artifacts). Fetch the artifacts:
./tools/fetch_artifacts.sh --keep <platform> <design>
This downloads results, reports, and logs from the hightide-artifacts PVC to artifacts/<platform>/<design>/. Use --keep to preserve the remote copy for other users. Without --keep, remote artifacts are deleted after fetch.
Other fetch options:
./tools/fetch_artifacts.sh --keep <platform> # all designs for a platform
./tools/fetch_artifacts.sh --keep # all designs, all platforms
./tools/fetch_artifacts.sh --keep --design <design> # one design, all platforms
Identify the last completed stage (1_synth, 2_floorplan, 3_place, 4_cts, 5_route, 6_final) and the first failed stage by checking which .odb files exist. Check whichever artifact location has the files (bazel-bin or artifacts directory).
Artifact path convention: Throughout this skill, paths like logs/<platform>/<design>/base/ refer to whichever artifact location has the files. Check in order: bazel-bin/designs/$0/, then artifacts/$0/. Use the one that exists.
Read these files to understand the design setup:
designs/<platform>/<design>/config.mk — flow parametersdesigns/<platform>/<design>/constraint.sdc — timing constraintsdesigns/<platform>/<design>/BUILD.bazel — Bazel flow config (if it exists)designs/<platform>/<design>/pdn.tcl — power delivery (if it exists)designs/<platform>/<design>/io.tcl — pin placement (if it exists)designs/src/<design>/verilog.mk — which Verilog files are usedBased on the failed stage and symptoms, follow the appropriate diagnosis path below.
Read the synthesis log (check bazel-bin or artifacts directory, whichever has the files):
tail -200 bazel-bin/designs/$0/logs/*/base/1_1_yosys.log 2>/dev/null
tail -200 artifacts/$0/logs/*/base/1_1_yosys.log 2>/dev/null
Common synthesis issues:
Missing modules / unresolved references: Check that all Verilog files are listed in verilog.mk or BUILD.bazel. Search the RTL for the missing module name.
Incorrectly synthesized memories: Yosys may infer memories as flip-flops instead of using FakeRAM macros.
Creating memory... or $mem cellsgrep -i "mem\|ram\|reg.*\[" <synth-log>designs/<platform>/<design>/sram/ADDITIONAL_LEFS and ADDITIONAL_LIBS must be set in config.mkSYNTH_MEMORY_MAX_BITS may need adjustment to prevent Yosys from synthesizing large memoriesSystemVerilog not supported: Yosys has limited SV support. The design may need sv2v conversion. Check designs/src/<design>/dev/setup.sh.
Synthesis timeout / excessive runtime: Consider SYNTH_HIERARCHICAL = 1 and ABC_AREA = 1 in config.mk.
Read the floorplan log:
tail -200 logs/<platform>/<design>/base/2_*.log
Common floorplan issues:
Macro placement failures (MPL-0040 or similar): The macro placer cannot find valid placements.
MACRO_PLACE_HALO (e.g., 6 6 or 8 8)CORE_UTILIZATION or increase die area — macros + std cells may not fitDIE_AREA and CORE_AREA instead of utilization-based sizingPDN failures: Power grid cannot be constructed.
pdn.tcl exists and metal layer names match the platform (M1-M7 for asap7, met1-met5 for sky130hd)IO placement failures: Too many pins for the die perimeter — increase die area or create a manual io.tcl.
Generate a floorplan image to visualize macro placement and die area (see Step 4).
Read the placement log:
tail -200 logs/<platform>/<design>/base/3_*.log
Common placement issues:
Placement overflow / cannot place: Die too small or utilization too high.
PLACE_DENSITY (try 0.5-0.65)Congestion hotspots: Router estimates show high congestion during placement.
.claude/skills/shared/congestion-analysis.mdRead the CTS log:
tail -200 logs/<platform>/<design>/base/4_*.log
Common CTS issues:
constraint.sdcclk_port_name in the SDC matches the actual design port nameRead the routing log:
tail -200 logs/<platform>/<design>/base/5_*.log
Common routing issues:
DRC violations:
head -100 reports/<platform>/<design>/base/5_route_drc.rpt 2>/dev/null
Congestion-driven routing failures: Too many routing resources consumed.
.claude/skills/shared/congestion-analysis.md):
grep -A 15 "Final congestion report" logs/*/base/5_1_grt.log 2>/dev/null
.claude/skills/shared/congestion-analysis.mdAntenna violations: Check antenna report if available
Timing analysis should cover setup slack, hold slack, clock skew, and IO constraint realism. Since the RTL is fixed, the goal is to find the best achievable Fmax by tuning constraints and flow parameters.
Read timing reports:
# Setup timing (critical for Fmax)
head -100 reports/<platform>/<design>/base/6_finish_setup.rpt 2>/dev/null
# Hold timing
head -100 reports/<platform>/<design>/base/6_finish_hold.rpt 2>/dev/null
# JSON metrics summary
cat logs/<platform>/<design>/base/6_report.json 2>/dev/null
Key metrics to extract and present:
report_clock_min_period — look for this in the finish report; it gives the true minimum achievable clock period directly, which is more reliable than computing it from WNSImportant: utilization and clock period are coupled. Tighter clock constraints cause synthesis to produce more cells (more buffering, complex gate decompositions), which increases the effective utilization. A design that fits at 80% util with a relaxed clock may overflow at 80% with an aggressive clock. When diagnosing timing, also check if the cell count and instance area increased compared to a relaxed-clock build.
Clock skew analysis:
Clock tree insertion delay can cause timing violations when IO constraints assume ideal clocks. Check for this:
Read the clock tree report to find insertion delay:
grep -i "insertion\|skew\|latency" reports/<platform>/<design>/base/4_cts*.rpt 2>/dev/null
grep -i "insertion\|skew\|latency" logs/<platform>/<design>/base/4_*.log 2>/dev/null
Compare insertion delay to IO constraints: In the SDC, IO delays are typically set as a fraction of the clock period (clk_io_pct). If the clock tree insertion delay is significant compared to clk_period * clk_io_pct, the IO paths will have unrealistic timing targets.
For example, if clk_period = 1.0ns and clk_io_pct = 0.2, the IO delay budget is 0.2ns. If clock insertion delay is 0.15ns, that leaves almost no margin for actual IO path logic.
Check if failing paths are IO paths: Look at the worst timing paths in the setup report. If they are input-to-register or register-to-output paths (not register-to-register), the IO constraints are likely the problem, not the core logic.
Fixes for clock-skew-related IO timing:
clk_io_pct to account for clock tree insertion delay (e.g., 0.3 or 0.4)set_clock_uncertainty in the SDC to model expected skew# Instead of using clk_io_pct for both:
set_input_delay [expr $clk_period * 0.3] -clock $clk_name $non_clock_inputs
set_output_delay [expr $clk_period * 0.4] -clock $clk_name [all_outputs]
set_false_path on IO ports to focus on core register-to-register FmaxCommon timing fixes:
constraint.sdc to find the achievable Fmax for this design/platform combinationTNS_END_PERCENT = 100 in config.mk to prioritize timing closureRead the finish log and DRC report:
tail -100 logs/<platform>/<design>/base/6_*.log
head -50 reports/<platform>/<design>/base/6_finish_drc.rpt 2>/dev/null
Check the summary metrics:
./tools/summary.sh # Bazel flow
# Or manually parse 6_report.json
For visual diagnosis of floorplan, placement, congestion, and power routing problems, generate images using OpenROAD's save_image command.
See .claude/skills/shared/image-generation.md for the full Docker/Xvfb setup, Tcl scripts, and heatmap variants (routing congestion, placement density, RUDY, IR drop).
Based on the diagnosis, recommend specific changes. Always explain what to change, why, and provide the exact file edits. Remember: never suggest RTL modifications — the Verilog is a fixed benchmark input.
Congestion fix priority — see .claude/skills/shared/congestion-analysis.md
Timing fix priority:
clk_io_pct or IO delays to account for clock tree insertion delayset_clock_uncertainty to model expected skewTNS_END_PERCENT = 100 in config.mkMemory fix priority:
ADDITIONAL_LEFS / ADDITIONAL_LIBSAfter applying changes, re-run the flow:
Make flow:
./runorfs_ni.sh make DESIGN_CONFIG=./designs/<platform>/<design>/config.mk clean_all
./runorfs_ni.sh make DESIGN_CONFIG=./designs/<platform>/<design>/config.mk
Bazel flow:
bazel build //designs/<platform>/<design>:<design>_final
Compare metrics before and after (WNS, TNS, Fmax, DRC count, cell count) to verify the fix improved the situation.
Once the design is passing cleanly, suggest that the user run /optimize-ppa to maximize utilization and clock frequency.