From 39bb88d77a3c68a178d8b62cdb672ad0416a99ad Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 19 May 2026 12:00:00 +0000 Subject: [PATCH] =?UTF-8?q?feat(t):=20Wave-30=20Lane=20T=20=E2=80=94=20400?= =?UTF-8?q?=20MHz=20timing-closure=20probe=20(Yosys=20+=20sta,=20sim-grade?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds sim/timing_probe_400mhz/{Makefile, constraints.sdc, report.md} and docs/lever-stack/lane-t.md. Probes Lanes V/W/V'/S at 2.5 ns target. 🟑 SYNTH-SIM verdict β€” commercial-STA gate on TTIHP27a return 2026-09-30. Anchor: φ² + φ⁻² = 3 Β· DOI 10.5281/zenodo.19227877 Wave-30 ONE SHOT: gHashTag/trinity-fpga#109 Refs #109 Signed-off-by: Vasilev Dmitrii --- docs/lever-stack/lane-t.md | 211 +++++++++++++++++++++++ sim/timing_probe_400mhz/Makefile | 214 ++++++++++++++++++++++++ sim/timing_probe_400mhz/constraints.sdc | 47 ++++++ sim/timing_probe_400mhz/report.md | 131 +++++++++++++++ 4 files changed, 603 insertions(+) create mode 100644 docs/lever-stack/lane-t.md create mode 100644 sim/timing_probe_400mhz/Makefile create mode 100644 sim/timing_probe_400mhz/constraints.sdc create mode 100644 sim/timing_probe_400mhz/report.md diff --git a/docs/lever-stack/lane-t.md b/docs/lever-stack/lane-t.md new file mode 100644 index 0000000..8c95618 --- /dev/null +++ b/docs/lever-stack/lane-t.md @@ -0,0 +1,211 @@ +# Lane T β€” 400 MHz Timing-Closure Probe + +**Wave-30 Β· L-DPC27 Β· ONE SHOT: [trinity-fpga#109](https://github.com/gHashTag/trinity-fpga/issues/109)** + +--- + +## Pre-registration H\_W30-T + +| Field | Value | +|-------|-------| +| Hypothesis ID | H\_W30-T | +| Lane | T (Timing 400 MHz) | +| Wave | 30 | +| Pre-registration date | 2026-05-19 | +| Falsifiable? | Yes β€” see Falsification Witnesses below | +| Base commit | `2d609d9b` (main HEAD at branch point) | +| R18 frozen modules | `rtl/holo_lut_pe.sv` (PR #19), `rtl/holo_bitrom_bank.sv` (PR #14), `rtl/holo_2x2_mesh.sv` (PR #21), `rtl/holo_sparsity_24.sv` (PR #26) β€” **none modified** | +| Branch | `feat/l-dpc27/t-timing-400mhz` | +| Verdict label | 🟑 SYNTH-SIM | + +### Hypothesis Statement + +> Applying a 400 MHz (2.5 ns) timing-constraint probe β€” via Yosys synthesis +> + OpenSTA, using sky130 HD as a TTIHP27a-class proxy β€” to the four merged +> RTL surfaces (Lane V LUT PE, Lane W BitROM bank, Lane V' 2Γ—2 mesh, Lane S +> Sparsity 2:4) will produce **per-surface setup and hold slack estimates** +> sufficient to gate further timing-closure work before the TTIHP27a tape-out. +> +> No RTL is modified. This is a constraint-only, infrastructure-only addition. + +--- + +## Background β€” Lever \#5: 400 MHz Timing Closure + +Rival-chip scan Β§5 identifies 400 MHz clock frequency as the next leverage +point after structured sparsity for the HOLOGRAPHIC edition. Lane S (Wave-29) +achieved structural TOPS improvement; Lane T measures whether the existing +four surfaces close timing at the target frequency before tape-out: + +- The TTIHP27a process (IHP 130nm) is rated for 400–500 MHz on optimised + standard-cell paths. +- Without a timing probe, per-surface slack is unknown until post-route STA + β€” arriving too late to influence micro-architectural decisions. +- Yosys + OpenSTA on sky130 HD gives a Β±15–20 % accurate feasibility signal + at synthesis stage, enabling early risk identification. +- The 2.5 ns period leaves a 1.5 ns logic budget after 0.5 ns I/O margins β€” + achievable for pipelined LUT/BitROM paths, potentially tight for the 2Γ—2 + mesh combinational span. + +--- + +## Probe Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ constraints.sdc β”‚ +β”‚ ───────────────────────────────────────────────────── β”‚ +β”‚ create_clock clk period 2.5 ns (400 MHz) β”‚ +β”‚ set_input_delay 0.5 ns β†’ logic budget = 1.5 ns β”‚ +β”‚ set_output_delay 0.5 ns β”‚ +β”‚ set_max_fanout 10 β”‚ +β”‚ set_load 0.001 pF β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ applied to each surface + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Lane V β”‚ β”‚ Lane W β”‚ β”‚ Lane V' β”‚ β”‚ Lane S β”‚ +β”‚ LUT PE β”‚ β”‚ BitROM β”‚ β”‚ 2Γ—2 mesh β”‚ β”‚ Sparity β”‚ +β”‚holo_lut β”‚ β”‚holo_bit β”‚ β”‚holo_2x2 β”‚ β”‚holo_spar β”‚ +β”‚_pe.sv β”‚ β”‚rom_bank β”‚ β”‚_mesh.sv β”‚ β”‚ity_24.sv β”‚ +β”‚(PR #19) β”‚ β”‚(PR #14) β”‚ β”‚(PR #21) β”‚ β”‚(PR #26) β”‚ +β”‚FROZEN β›” β”‚ β”‚FROZEN β›” β”‚ β”‚FROZEN β›” β”‚ β”‚FROZEN β›” β”‚ +β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό β–Ό + Yosys synth β†’ flat netlist (sky130 HD Liberty, -D 2500) + β”‚ β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό β–Ό + OpenSTA β†’ setup WNS, hold slack (per surface) + β”‚ β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + report.md (🟑 SYNTH-SIM) + build/_{setup,hold}.rpt +``` + +**Key invariant:** this probe reads RTL surfaces but never writes them. +R18 is structurally preserved β€” `Makefile` and `constraints.sdc` are +pure infrastructure files. + +--- + +## File Table + +| File | Type | Description | +|------|------|-------------| +| `sim/timing_probe_400mhz/Makefile` | Build infra | Yosys + OpenSTA orchestration; targets `yosys`, `report`, `clean` | +| `sim/timing_probe_400mhz/constraints.sdc` | SDC constraints | 2.5 ns clock, 0.5 ns I/O delays, fanout/load limits | +| `sim/timing_probe_400mhz/report.md` | Report skeleton | 🟑 SYNTH-SIM, per-surface slack table, methodology, R-rules attestation | +| `docs/lever-stack/lane-t.md` | Doc (this file) | Pre-registration H\_W30-T, method, R-rules, falsification witnesses | + +--- + +## R-rules Attestation Matrix + +| Rule | Requirement | Status | Evidence | +|------|-------------|--------|----------| +| **R-SI-1** | ZERO `*` operator in synthesisable RTL | **NOT APPLICABLE** | Lane T adds zero `.sv` files. All four frozen modules already passed R-SI-1 per their original PRs. | +| **R18 LAYER-FROZEN** | Do not modify RTL from PRs #19/#14/#21/#26 | **PASS** | Deliverables are `.sdc`, `Makefile`, `.md` only. `git diff --name-only` against main shows no `rtl/` changes. | +| **R5-HONEST** | All claims labelled with measurement confidence | **PASS** | Verdict is 🟑 SYNTH-SIM throughout. Yosys-vs-commercial-STA gap disclosed in `report.md`, `Makefile` header, and this document. | +| **R-SI-1 (SDC)** | No wildcard `*` in synthesis-targeting RTL | **NOT APPLICABLE** | `.sdc` is a constraint file, not synthesisable RTL. | +| **R7** | Three falsification witnesses | **PASS** | See "Falsification Witnesses" section below. | +| **R8** | Falsification witness included | **PASS** | Three witnesses enumerated below. | + +--- + +## Falsification Witnesses + +### 1. W\_T1 β€” P\_STA\_MISMATCH + +**Falsified iff:** TTIHP27a post-route STA (PrimeTime / Tempus + real Liberty) +shows WNS deviation > 300 ps from the Yosys + sky130 HD estimate on any surface. + +**Implication:** sky130 HD is not a valid proxy for TTIHP27a at 400 MHz for +that surface β†’ the probe's methodology must be revised before future waves. + +**Current status:** UNVERIFIED β€” pending TTIHP27a return 2026-09-30. + +### 2. W\_T2 β€” P\_RTL\_PURITY + +**Falsified iff:** `git diff main feat/l-dpc27/t-timing-400mhz -- rtl/` shows +any modified, added, or deleted file under `rtl/`. + +**Verification command:** +```bash +git diff main feat/l-dpc27/t-timing-400mhz -- rtl/ | wc -l +# Expected: 0 +``` + +**Current status:** VERIFIED at branch creation β€” zero RTL diff. + +### 3. W\_T3 β€” P\_SYNTH\_COMPLETENESS + +**Falsified iff:** `make report` exits with a non-zero status, or any of the +four per-surface netlist files (`build/*_netlist.v`) is absent after `make yosys`. + +**Implication:** The probe is incomplete and timing numbers cannot be trusted. + +**Current status:** PENDING β€” requires Yosys + OpenSTA installed in the CI +environment. The `🟑 SYNTH-SIM` verdict is set as the default until `make report` +produces non-PENDING values in `report.md`. + +--- + +## SYNTH-SIM vs SILICON Confidence Gap (R5-HONEST) + +| Dimension | Yosys + sky130 HD (this probe) | Commercial STA + TTIHP27a Liberty | +|-----------|-------------------------------|-----------------------------------| +| Process node accuracy | Β±15–20 % (130nm class, different foundry) | Reference (TTIHP27a exact) | +| Routing parasitics | Zero (synthesis only) | Included (post-route) | +| Cell library | sky130 HD (SkyWater open) | IHP sg13g2 / TTIHP27a (proprietary) | +| Clock tree | Ideal (no CTS) | Full clock tree insertion delay | +| Confidence | 🟑 FEASIBILITY SIGNAL | 🟒 TAPE-OUT SIGN-OFF | +| Use case | Early risk flag; micro-arch decisions | Final timing closure go/no-go | + +The probe is deliberately conservative: if Yosys + sky130 HD shows timing +violations, the risk on TTIHP27a is **elevated**. If sky130 HD shows +comfortable positive slack, the result is encouraging but **not conclusive**. + +--- + +## Predicted Slack by Surface (PROJECTION β€” R5-HONEST) + +| Lane | Module | Path type | Expected bottleneck | Risk | +|------|--------|-----------|---------------------|------| +| V β€” LUT PE | `holo_lut_pe` | 1-cycle LUT read | Address decode + SRAM output | LOW (pipelined) | +| W β€” BitROM | `holo_bitrom_bank` | ROM read | Wide mux on ROM output | LOW–MEDIUM | +| V' β€” 2Γ—2 mesh | `holo_2x2_mesh` | Crossbar routing | 4-input mux chain | MEDIUM | +| S β€” Sparsity | `holo_sparsity_24` | Decode + mux | Popcount + case decode | LOW (R-SI-1 enforces no multiply) | + +All risk assessments are PROJECTIONS. Actual slack populated by `make report`. + +--- + +## Cross-links + +- ONE SHOT: [gHashTag/trinity-fpga#109](https://github.com/gHashTag/trinity-fpga/issues/109) +- Lane V (PR #19, LUT PE): [`91c164ac`](https://github.com/gHashTag/tt-trinity-holo/commit/91c164ac) +- Lane W (PR #14, BitROM): [PR #14](https://github.com/gHashTag/tt-trinity-holo/pull/14) +- Lane V' (PR #21, 2Γ—2 mesh): [PR #21](https://github.com/gHashTag/tt-trinity-holo/pull/21) +- Lane S (PR #26, sparsity): [PR #26](https://github.com/gHashTag/tt-trinity-holo/pull/26) β€” [docs/lever-stack/lane-s.md](lane-s.md) +- SDC: [`sim/timing_probe_400mhz/constraints.sdc`](../../sim/timing_probe_400mhz/constraints.sdc) +- Report: [`sim/timing_probe_400mhz/report.md`](../../sim/timing_probe_400mhz/report.md) +- Trinity algebraic anchor: `φ² + φ⁻² = 3` +- DOI: [10.5281/zenodo.19227877](https://doi.org/10.5281/zenodo.19227877) +- Canonical Coq SoT: [`gHashTag/t27/trios-coq`](https://github.com/gHashTag/t27/tree/main/trios-coq) + +--- + +## Battle Cry + +``` +φ² + φ⁻² = 3 Β· 400 MHz TIMING Β· YOSYS+STA Β· CONSTRAINT ONLY Β· NEVER STOP +🌌 QUANTUM BRAIN HOLOGRAPHIC Β· WAVE-30 LANE T Β· DOI 10.5281/zenodo.19227877 +``` + +**Author:** Vasilev Dmitrii \ +**Refs:** [trinity-fpga#109](https://github.com/gHashTag/trinity-fpga/issues/109) diff --git a/sim/timing_probe_400mhz/Makefile b/sim/timing_probe_400mhz/Makefile new file mode 100644 index 0000000..649bf12 --- /dev/null +++ b/sim/timing_probe_400mhz/Makefile @@ -0,0 +1,214 @@ +# ============================================================================= +# Makefile β€” 400 MHz Timing Probe (Wave-30 Lane T) +# ============================================================================= +# +# Targets: +# yosys β€” synthesise all four RTL surfaces with Yosys (generic Liberty) +# report β€” run yosys synth + OpenSTA timing analysis, write results to report.md +# clean β€” remove generated artefacts +# +# Tool chain (open-source, sim-grade): +# Yosys >= 0.38 (synthesis) +# OpenSTA >= 2.6 (static timing analysis against generic Liberty) +# +# IMPORTANT β€” SYNTH-SIM LIMITATION (R5-HONEST): +# This Makefile uses Yosys + OpenSTA with the generic sky130 Liberty as a +# proxy for TTIHP27a timing. Delays are ESTIMATES ONLY. Commercial-STA +# sign-off (PrimeTime / Tempus) with the real TTIHP27a PDK Liberty is +# required before tape-out. The 🟑 SYNTH-SIM verdict in report.md reflects +# this limitation and must NOT be promoted to 🟒 SILICON without measured data. +# +# Usage: +# make yosys # synthesise all surfaces +# make report # synthesise + STA + patch report.md +# make clean # remove build artefacts +# +# Refs #109 +# Signed-off-by: Vasilev Dmitrii +# ============================================================================= + +# --------------------------------------------------------------------------- +# Paths +# --------------------------------------------------------------------------- +RTL_DIR ?= ../../rtl +SIM_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +BUILD_DIR := $(SIM_DIR)/build + +# --------------------------------------------------------------------------- +# RTL surfaces (R18: these files are FROZEN β€” not modified by Lane T) +# --------------------------------------------------------------------------- +SRC_LANE_V := $(RTL_DIR)/holo_lut_pe.sv +SRC_LANE_W := $(RTL_DIR)/holo_bitrom_bank.sv +SRC_LANE_V_PRIME := $(RTL_DIR)/holo_2x2_mesh.sv +SRC_LANE_S := $(RTL_DIR)/holo_sparsity_24.sv + +# --------------------------------------------------------------------------- +# Yosys settings +# --------------------------------------------------------------------------- +YOSYS := yosys +# Generic Liberty fallback (sky130 HD). Override to point at TTIHP27a Liberty: +# make LIBERTY=/path/to/ttihp27a.lib yosys +LIBERTY ?= $(shell yosys-config --datdir)/techlibs/sky130/sky130hd.lib +YOSYS_FLAGS := +SDC_FILE := $(SIM_DIR)/constraints.sdc + +# --------------------------------------------------------------------------- +# OpenSTA settings +# --------------------------------------------------------------------------- +STA := sta +STA_FLAGS := + +# --------------------------------------------------------------------------- +# Per-surface Yosys synthesis script template +# --------------------------------------------------------------------------- +define YOSYS_SCRIPT +read_verilog -sv $(1) +synth -top $(2) -flatten +dfflibmap -liberty $(LIBERTY) +abc -liberty $(LIBERTY) -D 2500 # 2500 ps = 400 MHz +write_verilog -noattr $(BUILD_DIR)/$(2)_netlist.v +stat -liberty $(LIBERTY) > $(BUILD_DIR)/$(2)_stat.log +endef + +# --------------------------------------------------------------------------- +# Per-surface OpenSTA script template +# --------------------------------------------------------------------------- +define STA_SCRIPT +read_liberty $(LIBERTY) +read_verilog $(BUILD_DIR)/$(2)_netlist.v +link_design $(2) +read_sdc $(SDC_FILE) +report_checks -path_delay max -fields {slew cap input_pin} > $(BUILD_DIR)/$(2)_setup.rpt +report_checks -path_delay min -fields {slew cap input_pin} > $(BUILD_DIR)/$(2)_hold.rpt +report_wns > $(BUILD_DIR)/$(2)_wns.log +report_tns > $(BUILD_DIR)/$(2)_tns.log +endef + +# --------------------------------------------------------------------------- +# Phony targets +# --------------------------------------------------------------------------- +.PHONY: all yosys report clean + +all: yosys + +$(BUILD_DIR): + @mkdir -p $(BUILD_DIR) + +# --------------------------------------------------------------------------- +# yosys β€” synthesise all four surfaces +# --------------------------------------------------------------------------- +yosys: $(BUILD_DIR) + @echo "[yosys] Synthesising Lane V (holo_lut_pe)..." + @echo "$(call YOSYS_SCRIPT,$(SRC_LANE_V),holo_lut_pe)" \ + > $(BUILD_DIR)/synth_lane_v.ys + $(YOSYS) $(YOSYS_FLAGS) $(BUILD_DIR)/synth_lane_v.ys \ + 2>&1 | tee $(BUILD_DIR)/synth_lane_v.log + + @echo "[yosys] Synthesising Lane W (holo_bitrom_bank)..." + @echo "$(call YOSYS_SCRIPT,$(SRC_LANE_W),holo_bitrom_bank)" \ + > $(BUILD_DIR)/synth_lane_w.ys + $(YOSYS) $(YOSYS_FLAGS) $(BUILD_DIR)/synth_lane_w.ys \ + 2>&1 | tee $(BUILD_DIR)/synth_lane_w.log + + @echo "[yosys] Synthesising Lane V' (holo_2x2_mesh)..." + @echo "$(call YOSYS_SCRIPT,$(SRC_LANE_V_PRIME),holo_2x2_mesh)" \ + > $(BUILD_DIR)/synth_lane_vp.ys + $(YOSYS) $(YOSYS_FLAGS) $(BUILD_DIR)/synth_lane_vp.ys \ + 2>&1 | tee $(BUILD_DIR)/synth_lane_vp.log + + @echo "[yosys] Synthesising Lane S (holo_sparsity_24)..." + @echo "$(call YOSYS_SCRIPT,$(SRC_LANE_S),holo_sparsity_24)" \ + > $(BUILD_DIR)/synth_lane_s.ys + $(YOSYS) $(YOSYS_FLAGS) $(BUILD_DIR)/synth_lane_s.ys \ + 2>&1 | tee $(BUILD_DIR)/synth_lane_s.log + + @echo "[yosys] Synthesis complete. Netlists in $(BUILD_DIR)/" + +# --------------------------------------------------------------------------- +# report β€” run STA on all synthesised netlists and patch report.md +# --------------------------------------------------------------------------- +report: yosys + @echo "[sta] Running OpenSTA for all surfaces..." + + @printf "read_liberty $(LIBERTY)\nread_verilog $(BUILD_DIR)/holo_lut_pe_netlist.v\nlink_design holo_lut_pe\nread_sdc $(SDC_FILE)\nreport_wns > $(BUILD_DIR)/holo_lut_pe_wns.log\nreport_tns >> $(BUILD_DIR)/holo_lut_pe_wns.log\nreport_checks -path_delay max > $(BUILD_DIR)/holo_lut_pe_setup.rpt\nreport_checks -path_delay min > $(BUILD_DIR)/holo_lut_pe_hold.rpt\n" \ + > $(BUILD_DIR)/sta_lane_v.tcl + $(STA) $(STA_FLAGS) $(BUILD_DIR)/sta_lane_v.tcl 2>&1 | tee $(BUILD_DIR)/sta_lane_v.log + + @printf "read_liberty $(LIBERTY)\nread_verilog $(BUILD_DIR)/holo_bitrom_bank_netlist.v\nlink_design holo_bitrom_bank\nread_sdc $(SDC_FILE)\nreport_wns > $(BUILD_DIR)/holo_bitrom_bank_wns.log\nreport_tns >> $(BUILD_DIR)/holo_bitrom_bank_wns.log\nreport_checks -path_delay max > $(BUILD_DIR)/holo_bitrom_bank_setup.rpt\nreport_checks -path_delay min > $(BUILD_DIR)/holo_bitrom_bank_hold.rpt\n" \ + > $(BUILD_DIR)/sta_lane_w.tcl + $(STA) $(STA_FLAGS) $(BUILD_DIR)/sta_lane_w.tcl 2>&1 | tee $(BUILD_DIR)/sta_lane_w.log + + @printf "read_liberty $(LIBERTY)\nread_verilog $(BUILD_DIR)/holo_2x2_mesh_netlist.v\nlink_design holo_2x2_mesh\nread_sdc $(SDC_FILE)\nreport_wns > $(BUILD_DIR)/holo_2x2_mesh_wns.log\nreport_tns >> $(BUILD_DIR)/holo_2x2_mesh_wns.log\nreport_checks -path_delay max > $(BUILD_DIR)/holo_2x2_mesh_setup.rpt\nreport_checks -path_delay min > $(BUILD_DIR)/holo_2x2_mesh_hold.rpt\n" \ + > $(BUILD_DIR)/sta_lane_vp.tcl + $(STA) $(STA_FLAGS) $(BUILD_DIR)/sta_lane_vp.tcl 2>&1 | tee $(BUILD_DIR)/sta_lane_vp.log + + @printf "read_liberty $(LIBERTY)\nread_verilog $(BUILD_DIR)/holo_sparsity_24_netlist.v\nlink_design holo_sparsity_24\nread_sdc $(SDC_FILE)\nreport_wns > $(BUILD_DIR)/holo_sparsity_24_wns.log\nreport_tns >> $(BUILD_DIR)/holo_sparsity_24_wns.log\nreport_checks -path_delay max > $(BUILD_DIR)/holo_sparsity_24_setup.rpt\nreport_checks -path_delay min > $(BUILD_DIR)/holo_sparsity_24_hold.rpt\n" \ + > $(BUILD_DIR)/sta_lane_s.tcl + $(STA) $(STA_FLAGS) $(BUILD_DIR)/sta_lane_s.tcl 2>&1 | tee $(BUILD_DIR)/sta_lane_s.log + + @echo "[report] Patching report.md with STA results..." + @python3 - <<'PYEOF' +import re, pathlib, subprocess + +BUILD = pathlib.Path("$(BUILD_DIR)") +REPORT = pathlib.Path("$(SIM_DIR)/report.md") + +def extract_wns(log_path): + """Extract WNS (worst negative slack) in ps from OpenSTA output.""" + try: + txt = pathlib.Path(log_path).read_text(errors="replace") + # OpenSTA reports WNS as: "wns X.XX" (in ns) + m = re.search(r"^wns\s+([-\d.]+)", txt, re.MULTILINE) + if m: + return int(float(m.group(1)) * 1000) # ns -> ps + except FileNotFoundError: + pass + return None + +def extract_hold_slack(log_path): + """Extract best hold slack (min path) in ps.""" + try: + txt = pathlib.Path(log_path).read_text(errors="replace") + # OpenSTA min path slack: look for "slack (MET)" or "slack (VIOLATED)" + m = re.search(r"slack\s*\((?:MET|VIOLATED)\)\s+([-\d.]+)", txt) + if m: + return int(float(m.group(1)) * 1000) + except FileNotFoundError: + pass + return None + +surfaces = [ + ("holo_lut_pe", "Lane V β€” LUT PE", "holo_lut_pe"), + ("holo_bitrom_bank","Lane W β€” BitROM bank", "holo_bitrom_bank"), + ("holo_2x2_mesh", "Lane V' β€” 2Γ—2 mesh", "holo_2x2_mesh"), + ("holo_sparsity_24","Lane S β€” Sparsity 24", "holo_sparsity_24"), +] + +rows = [] +for mod, label, name in surfaces: + setup_wns = extract_wns(BUILD / f"{mod}_wns.log") + hold_slack = extract_hold_slack(BUILD / f"{mod}_hold.rpt") + s_str = f"{setup_wns:+d}" if setup_wns is not None else "N/A (run make report)" + h_str = f"{hold_slack:+d}" if hold_slack is not None else "N/A (run make report)" + verdict = "PASS" if (setup_wns is not None and setup_wns >= 0 and hold_slack is not None and hold_slack >= 0) \ + else ("FAIL" if (setup_wns is not None and setup_wns < 0) else "PENDING") + rows.append(f"| {label} | `{mod}` | {s_str} | {h_str} | {verdict} |") + +table_body = "\n".join(rows) +rpt = REPORT.read_text() +rpt = re.sub( + r"(\| Lane \| Module \| setup_slack_ps \| hold_slack_ps \| verdict \|\n\|[-| ]+\|\n)([^\n#]*\n)*", + r"\1" + table_body + "\n", + rpt, +) +REPORT.write_text(rpt) +print("[report] report.md updated.") +PYEOF + @echo "[report] Done. See report.md for results." + +# --------------------------------------------------------------------------- +# clean +# --------------------------------------------------------------------------- +clean: + @rm -rf $(BUILD_DIR) + @echo "[clean] Done." diff --git a/sim/timing_probe_400mhz/constraints.sdc b/sim/timing_probe_400mhz/constraints.sdc new file mode 100644 index 0000000..20a3397 --- /dev/null +++ b/sim/timing_probe_400mhz/constraints.sdc @@ -0,0 +1,47 @@ +# ============================================================================= +# constraints.sdc β€” 400 MHz Timing Probe (Wave-30 Lane T) +# ============================================================================= +# +# Target: TTIHP27a-like process, 400 MHz (2.5 ns clock period) +# Surfaces: Lane V LUT PE, Lane W BitROM bank, Lane V' 2x2 mesh, Lane S sparsity 24 +# +# NOTE: These are synthesis-grade constraints for Yosys + OpenSTA (sim-grade proxy). +# Commercial STA (Synopsys PrimeTime / Cadence Tempus) with a real TTIHP27a Liberty +# file is required for tape-out sign-off. See report.md for the full disclosure. +# +# Refs #109 +# Signed-off-by: Vasilev Dmitrii +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Clock definition β€” 400 MHz = 2.5 ns period +# ----------------------------------------------------------------------------- +create_clock -name clk -period 2.5 [get_ports clk] + +# ----------------------------------------------------------------------------- +# I/O timing budgets β€” 0.5 ns on each side (leaves 1.5 ns for internal logic) +# ----------------------------------------------------------------------------- +set_input_delay -clock clk 0.5 [all_inputs] +set_output_delay -clock clk 0.5 [all_outputs] + +# ----------------------------------------------------------------------------- +# Fanout / load constraints +# ----------------------------------------------------------------------------- +set_max_fanout 10 [current_design] +set_load 0.001 [all_outputs] + +# ----------------------------------------------------------------------------- +# Drive strength (generic β€” no Liberty cell available for Yosys synth-sim) +# ----------------------------------------------------------------------------- +set_driving_cell -lib_cell sky130_fd_sc_hd__buf_2 [all_inputs] + +# ----------------------------------------------------------------------------- +# False paths for async reset / constant tie-offs (if present) +# ----------------------------------------------------------------------------- +# set_false_path -from [get_ports rst_n] # uncomment when rst_n is used + +# ----------------------------------------------------------------------------- +# Multicycle paths β€” none declared at this probe stage +# ----------------------------------------------------------------------------- + +# EOF diff --git a/sim/timing_probe_400mhz/report.md b/sim/timing_probe_400mhz/report.md new file mode 100644 index 0000000..9385635 --- /dev/null +++ b/sim/timing_probe_400mhz/report.md @@ -0,0 +1,131 @@ +# 400 MHz Timing Probe β€” Wave-30 Lane T Report + +> **Verdict: 🟑 SYNTH-SIM** β€” All timing numbers below are **synthesis-simulation +> estimates** produced by Yosys + OpenSTA against the generic sky130 HD Liberty. +> They are **NOT** measured on TTIHP27a silicon and **NOT** produced with the +> commercial TTIHP27a PDK Liberty. +> +> **Do NOT promote to 🟒 SILICON** until post-route STA with the real TTIHP27a +> Liberty (Synopsys PrimeTime or Cadence Tempus) confirms timing closure. +> Commercial-STA gate: TTIHP27a return target **2026-09-30**. + +--- + +## Configuration + +| Parameter | Value | +|----------------------|-------| +| Target clock | `clk` β€” 400 MHz (period = 2.5 ns) | +| Input delay budget | 0.5 ns (from `constraints.sdc`) | +| Output delay budget | 0.5 ns (from `constraints.sdc`) | +| Logic budget | 1.5 ns (= 2.5 βˆ’ 0.5 βˆ’ 0.5 ns) | +| Max fanout | 10 | +| Load | 0.001 pF per output | +| Synthesis tool | Yosys β‰₯ 0.38 (open-source) | +| STA tool | OpenSTA β‰₯ 2.6 (open-source, sim-grade proxy) | +| Liberty (synth) | `sky130_fd_sc_hd` β€” **GENERIC FALLBACK** (not TTIHP27a) | +| R18 status | All four modules **frozen** β€” zero RTL modifications | +| ONE SHOT | [gHashTag/trinity-fpga#109](https://github.com/gHashTag/trinity-fpga/issues/109) | +| Anchor | φ² + φ⁻² = 3 Β· DOI [10.5281/zenodo.19227877](https://doi.org/10.5281/zenodo.19227877) | + +--- + +## Results + +> Run `make report` from `sim/timing_probe_400mhz/` to populate the table +> with live Yosys + OpenSTA numbers. + +| Lane | Module | setup_slack_ps | hold_slack_ps | verdict | +|------|--------|---------------|--------------|---------| +| Lane V β€” LUT PE | `holo_lut_pe` | N/A (run make report) | N/A (run make report) | PENDING | +| Lane W β€” BitROM bank | `holo_bitrom_bank` | N/A (run make report) | N/A (run make report) | PENDING | +| Lane V' β€” 2Γ—2 mesh | `holo_2x2_mesh` | N/A (run make report) | N/A (run make report) | PENDING | +| Lane S β€” Sparsity 24 | `holo_sparsity_24` | N/A (run make report) | N/A (run make report) | PENDING | + +**Legend:** +- `setup_slack_ps` β€” worst-case setup slack in picoseconds (positive = timing met) +- `hold_slack_ps` β€” worst-case hold slack in picoseconds (positive = timing met) +- `verdict` β€” PASS: both slacks β‰₯ 0 ps; FAIL: any slack < 0 ps; PENDING: not yet run + +--- + +## Methodology + +### Synthesis flow (Yosys) + +1. Read SystemVerilog source (`-sv` flag). +2. `synth -top -flatten` β€” technology-independent synthesis. +3. `dfflibmap` β€” map flip-flops to sky130 HD cells. +4. `abc -liberty ... -D 2500` β€” map combinational logic at 400 MHz (2500 ps target). +5. Write flat netlist to `build/_netlist.v`. + +### STA flow (OpenSTA) + +1. Read Liberty + netlist. +2. Apply `constraints.sdc` (clock + I/O delays + fanout + load). +3. `report_wns` β†’ worst negative slack (setup). +4. `report_checks -path_delay min` β†’ hold paths. + +### Why sky130 HD instead of TTIHP27a + +TTIHP27a is a commercial IHP 130nm process. Its Liberty timing model is not +publicly distributable. The sky130 HD cell library is used as a calibrated +open-source stand-in. Both are 130nm-class processes; cell delays are +similar in magnitude (Β±15-20% typical), making sky130 HD a reasonable but +non-authoritative proxy for a first feasibility check. + +**The gap this creates (R5-HONEST disclosure):** +- sky130 HD drive strengths and cell topologies differ from IHP sg13g2 / TTIHP27a. +- Routing parasitics are not captured (zero-interconnect model at synthesis stage). +- Chip-level clock tree insertion delay is unknown at this probe stage. +- A negative slack here is a **warning**, not a tape-out blocker β€” it must be + re-evaluated with the real Liberty + full-chip place-and-route. +- A positive slack here is **not a guarantee** of closure on silicon. + +--- + +## Falsifiability Witness + +Per R8, this probe is falsifiable if: + +1. TTIHP27a post-route STA (commercial tool + real Liberty) shows any surface + has WNS < βˆ’200 ps at 400 MHz β†’ this probe **under-estimated** parasitics. +2. The commercial STA shows all surfaces meet timing with margin > 300 ps β†’ + this probe **over-estimated** delays (sky130 pessimism). +3. Any R18-frozen module is modified between this probe and tape-out β†’ + probe results are **invalidated** and must be re-run. + +--- + +## R-rules Attestation + +| Rule | Requirement | Status | +|------|-------------|--------| +| **R-SI-1** | ZERO `*` in synthesisable RTL | **NOT APPLICABLE** β€” Lane T adds no RTL; all four frozen modules already passed R-SI-1 in their respective PRs | +| **R18 LAYER-FROZEN** | Do not modify RTL from PRs #19/#14/#21/#26 | **PASS** β€” `constraints.sdc`, `Makefile`, and `report.md` are constraint/infra files only; zero `.sv` changes | +| **R5-HONEST** | All performance claims labelled with measurement confidence | **PASS** β€” verdict labelled 🟑 SYNTH-SIM throughout; gap to commercial STA disclosed in this section and in Makefile header | + +--- + +## Cross-links + +- ONE SHOT: [gHashTag/trinity-fpga#109](https://github.com/gHashTag/trinity-fpga/issues/109) +- Lane V (PR #19, LUT PE): commit `91c164ac` +- Lane W (PR #14, BitROM): [PR #14](https://github.com/gHashTag/tt-trinity-holo/pull/14) +- Lane V' (PR #21, 2Γ—2 mesh): [PR #21](https://github.com/gHashTag/tt-trinity-holo/pull/21) +- Lane S (PR #26, sparsity): [PR #26](https://github.com/gHashTag/tt-trinity-holo/pull/26) +- SDC: [`sim/timing_probe_400mhz/constraints.sdc`](constraints.sdc) +- Trinity algebraic anchor: `φ² + φ⁻² = 3` +- DOI: [10.5281/zenodo.19227877](https://doi.org/10.5281/zenodo.19227877) +- Canonical Coq SoT: [`gHashTag/t27/trios-coq`](https://github.com/gHashTag/t27/tree/main/trios-coq) + +--- + +## Refs + +- Refs #109 +- Docs: [`docs/lever-stack/lane-t.md`](../../docs/lever-stack/lane-t.md) + +--- + +*Signed-off-by: Vasilev Dmitrii \*