# 60 MHz optimization results — 15 September 2026

This records the first test image (`5016887`). For the follow-up after the
7 MHz pass / 60 MHz red-screen report, see [R2 results](r2-results.txt).

## Candidate

The test image is built from branch `optimize/60mhz-timing`, targeting the
existing XC3S400-4-PQ208 six-SRAM board. The displayed version is
`PI FMG260915__60Mhz`; the actual turbo clock is 60.2972184 MHz.

Test image: [Minimig-FMG260915-60MHz-test.bin](../releases/2026-09-15-60mhz-test/Minimig-FMG260915-60MHz-test.bin)
(raw binary, 212,392 bytes). The matching `.bit`, checksums and raw reports
are in the same local release directory. Generated release files are outside
Git; the source, scripts, tests and compact result summaries are versioned.

Binary SHA-256:
`6652458602a943797718d73218760f2d4dccbc0ddb3b4c4778fcbd2c7fc21e8a`.

## Measured implementation

Both comparison builds use ISE 14.7, XST speed optimization level 1,
MAP area mode with pack factor 95, and PAR high effort with seed 1.
The baseline is commit `a8c27a167cec5598fd439cbbef11ea1591d09c90` with the
explicit timing model applied. The candidate additionally checks its new
DCM reset pipeline and CPU-to-SRAM write-capture registers.

| Resource/result | Original with comparison constraints | Candidate |
| --- | ---: | ---: |
| Synthesis warnings reported by ISE | 250 | **54** |
| Occupied slices | 3,558 | **3,510** |
| LUTs excluding route-throughs | 5,359 | **5,313** |
| Slice registers, including latches | 3,757 | **3,736** |
| Inferred latch bits | 20 | **16** |
| Block RAMs | 14 | **14** |
| Hardware multipliers | 8 | **6** |
| Global clock buffers | 4 | **5** |
| Main routed timing errors | 10 | **0** |

The candidate saves 48 occupied slices (1.35%) at the same packing setting.
It remains dense at 3,510/3,584 slices. The extra global buffer gives the
cascaded DCM a proper clock route. See the [baseline summary](../reports/implementation/baseline-summary.json)
and [candidate summary](../reports/implementation/candidate-summary.json).

The synthesis warning total comes from ISE's own summary: the baseline
reports 250, although its report contains 248 explicit warning lines.
No warning filter was used. Remaining warnings and their significance
are listed in [remaining-warnings.txt](remaining-warnings.txt).

The original repository did not constrain all internal clocks. An old
report with zero errors is therefore not evidence of 60 MHz closure.
The comparison applies internal clock periods and the existing external
path budgets to both sources. Adding cache invalidation and holding
registers spends some of the area saved elsewhere to improve reliability.

## Timing and its scope

The final `build/release-60mhz-03` implementation passes the main, slow-mode
and DCM component reports, with **zero setup/hold/component timing errors**
in each report under its documented constraints.

| Main constraint | Original setup/max-delay slack | Candidate setup/max-delay slack |
| --- | ---: | ---: |
| 60.297 MHz internal CPU | +3.635 ns | **+1.690 ns** |
| 28.375 MHz chipset | +1.622 ns | **+2.247 ns** |
| 7.094 MHz chipset | +1.595 ns | **+3.336 ns** |
| Registers → SRAM data, 33 ns budget | −1.223 ns | **+20.538 ns** |
| CPU data → new SRAM holding register, 33 ns budget | Not present | **+19.779 ns** |

Cache protection uses some CPU timing headroom; this is not a claim of a
higher maximum CPU frequency. The nominal 60 MHz setting passes, while the
SRAM write-data path and chipset margins improve. The output path's large
improvement comes from moving combinational work before a holding register,
so the paths into that register are checked separately.

The SRAM output margin improves because disk/Blitter data uses a dedicated
bus and is captured in Q2. The word stays fixed across write-strobe release;
FPGA drive persists another half 28 MHz cycle. Internal timing also checks
the path into those holding registers. See the
[SRAM timing review](sram-write-timing.txt) for measured pin-path bounds.

The slow-mode report uses an explicit half-cycle phase displacement and
only documented inactive-path exceptions. Turbo acknowledgment is inactive
in slow mode; cache configuration cannot affect cache writes while slow
mode holds invalidation asserted. The second synchronizer stage and active
paths remain timed. The [timing model](timing-model.txt) explains coverage.

These reports do not establish every external CPU/SPI setup/hold limit,
analog jitter, metastability risk, or stability on the actual board. The
0.5 ns system-jitter allowance is an engineering assumption. Confirm the
candidate with the [morning hardware test](hardware-test.txt).

## Functional verification

The complete `scripts/run_regressions.sh` suite passed against the released
RTL, including full-core elaboration with ISE UNISIM primitives. The
[regression log](../reports/implementation/regressions.log) is retained.

- Exhaustive Blitter minterms, pointer arithmetic and 256 complete Blitter
  jobs compared cycle-by-cycle against the original source.
- 65,536 DMA selection combinations, including 41,008 real DMA writes,
  checked against the original complete custom-register readback bus.
- 1,563 SRAM transactions, 6,252 phase/pin checks and 780 write endings:
  every bank and byte mask, late write data, and read/write turnaround.
  Removing the holding register, capturing too early, or removing the
  drive extension each makes this regression fail.
- Audio arithmetic, stereo/PWM behavior, autoconfig reset/enumeration,
  UART frames, floppy selection/stepping and 9,102 FIFO cycles.
- Continuous host SPI writes at the actual 7.09 MHz core clock and an
  additional 60 MHz stress run, version replies, large transfers and wrap.
- Cache initialization, byte-valid replacement, pending fills, tiny
  invalidation pulses, slow writes, and fresh cache contents after turbo
  restart. Read hits and slow accesses do not cause cache refills.
- Clock lock sequencing, startup dependency, reset readiness, frequency
  ratios, E clock, and turbo switching. The vendor model emits two expected
  startup period warnings while the pre-GWE test holds downstream resets.
  A negative test enables downstream lock waits and correctly fails.

This is targeted RTL verification, not a full Amiga software simulation.
The test image has not been programmed onto the board during this work.

## Main source changes

- Removed the bitplane address latch and shortened Blitter pointer/minterm
  logic; narrowed unused DMA address and audio pointer bits to the physical
  chip-memory address space.
- Preserved exact audio arithmetic while using two fewer multipliers in
  the complete core; simplified floppy mux/track logic and fixed FIFO
  registered-read scheduling.
- Reduced host counters/address logic, made ROM bounds deterministic, and
  corrected incomplete combinational sensitivity and autoconfig reset
  priority.
- Added reset/host/slow-mode cache invalidation using the existing BRAM
  write ports. Returning to turbo runs uncached for about 34 microseconds
  while clearing 2,048 entries and refreshing the read outputs.
- Buffered cascaded DCM inputs and sequenced reset release with a
  compatible configuration startup order. System/CPU reset remains held
  until all clocks lock.
- Added reproducible build snapshots, source and bitstream checksums,
  timing coverage gates, timing audits, and regression scripts.
