# Chipset phase sampling

The former `c3 <= clk` sampled the DLL's 7 MHz output on a coincident
28 MHz rising edge. It needed the old 7 MHz value to remain at the flip-flop's
data input after that edge. The R2 route's mixed-corner SDF path estimate
left 0.565 ns after the flip-flop hold requirement, before DLL phase/jitter
allowances; the original route left 0.894 ns. These estimates did not prove
a hardware failure, and the ordinary PERIOD reports did not cover this
clock-as-data input path.

`clk7_sample` now samples the 7 MHz signal on the falling 28 MHz edge.
The existing rising-edge `c3` register samples that held value, and `c1`
continues sampling `~c3`. Both sampling steps have a nominal half period
(17.621 ns). The settled Q0/Q1/Q2/Q3 sequence stays the same; this adds no
chipset bus cycle. Startup/reset holds the rest of the core inactive until
the clocks have locked and the readiness pipeline has completed.

## Functional checks

Run `bash tests/clock/run.sh`.

- The UNISIM test retains startup dependency, lock-loss, clock ratios,
  speed switching and readiness checks. It also compares the resulting
  phase sequence against the former sampler with a representative 1.3 ns
  clock-to-data routing lag. Raw zero-route UNISIM can order coincident DLL
  outputs differently, so it is not a suitable old-value phase reference.
- The skew test exercises the phase registers in production `Clock.v`,
  forcing only its generated clock nets. It checks 196 route/skew cases
  and 50,176 phase values, including ±12 ns injected skew. That injected
  range is a robustness test, not a claimed DCM specification. It checks
  the input sampling edge's setup/hold separation and demonstrates where
  the former direct sampler would select the wrong Q phase.

## Audit a completed implementation

After PAR and the build's timing checks finish:

```sh
bash scripts/audit_phase_timing.sh build/r3-60mhz-03 build/r3-phase-audit-03
python3 tests/clock/test_phase_audit.py build/r3-phase-audit-03
```

Use a new audit directory. The script checks the snapshotted phase RTL,
copies the completed route, adds two diagnostic FROM/TO inventories, and
runs TRACE and NETGEN. It requires one path to `clk7_sample` from CLKDV
and one from `clk7_sample` to `c3`. The source build is unchanged.

The optional second command checks private mutations: restoring direct
sampling, changing the sampling edge, excessive route delay and missing
TRACE coverage must fail. It also checks that unexpected sampler RTL is
rejected before running ISE.

The 1000 ns diagnostic constraints establish path coverage. Their pass
status does **not** establish phase timing. The summary follows the routed
buffer chains in NETGEN/SDF, verifies their polarity and sampling edges,
and computes these four margins:

| Check | Margin before the clock allowance |
| --- | --- |
| CLKDV to falling-edge sampler setup | H + Cs(min) − D(max) − sampler setup |
| CLKDV to falling-edge sampler hold | H + D(min) − Cs(max) − sampler hold |
| Sampler to c3 setup | H + Ct(min) − Cs(max) − P(max) − c3 setup |
| Sampler to c3 hold | H + Cs(min) + P(min) − Ct(max) − c3 hold |

Here H is half the constrained 28 MHz period; D is CLKDV-to-sampler data
delay; Cs and Ct are CLK0-to-sampler/c3 clock delays; P includes sampler
clock-to-output and routing to c3. Combining minimum and maximum bounds
is conservative and does not assume both paths share the same corner.

The input path subtracts an additive allowance for the constrained
`SYSTEM_JITTER`, 0.140 ns DLL output phase alignment, 0.150 ns CLKDV added
period jitter, 0.100 ns CLK0 added period jitter, and 0.250 ns duty variation
for each output. The interstage path subtracts `SYSTEM_JITTER`, 0.100 ns
CLK0 added period jitter and 0.250 ns duty variation. These deliberately
additive guard bands are not a statistical jitter calculation; correlated
terms can overlap. Device values come from the XC3S400 entries in
[DS099, Table 59](https://docs.amd.com/v/u/en-US/ds099).

The script writes `phase-summary.json` with the path bounds, allowances,
four margins, coverage and input hashes. It fails on a negative margin,
missing coverage, unexpected topology, or TRACE errors. This model assumes
a locked DLL within its specified operating conditions. A passing audit
does not prove that the reported turbo-mode graphics problem is fixed;
hardware testing remains necessary.
