DMG-CPU Research

Clock Generator & System Control

In general, we can consider that everything is good here. There may be some minor refinements, but in general "the engine has started"

ClkGen generates the clock signals for the whole chip, synchronizes the resets, and controls the external chip select and write synchronization.

locator_clkgen

clkgen

clkgen_netlist

Module Overview

Signals

clkgen_ports

The names of signals of the CLK group have many synonyms used by different authors at different times.

Signal Dir From/Where To Description
clk_ena Input From Core Clock enable signal
osc_ena Input From Core Oscillator enable signal
cpu_wr_sync Output To MMIO,Arb Synchronized SM83 Core write signal
cpu_wr Input From Core SM83 Core write signal
ext_cs_en Output To Arb External chip select enable signal
test_1 Input From MMIO Test1 mode enable (disable all internal CPU A/D bus drivers). (Aka T1nT2)
cpu_mreq Input From Core SM83 Core memory request signal
sync_reset Output To Core Synchronized reset signal
reset Input From /RES Pad System reset signal
osc_stable Input From MMIO Oscillator stability signal
n_test_reset Input From MMIO Active-low test reset signal
n_clk_in Input From CK1_CK2 Pad Active-low external clock input
n_reset2 Output To Ser,MMIO,Arb,PPU,APU Active-low Global reset signal
clk1 Output To Core Generated clock signals for various CPU and peripheral components. (Aka BOWA,ADR_CLK_N)
clk2 Output To Core,MMIO,Arb,APU (Aka DATA_VALID,ADR_CLK_P)
clk3 Output To Core (Aka CPU_PHI,DATA_CLK_P)
clk4 Output To Core,MMIO,APU,PHI Pad (Aka #CPU_PHI,DATA_CLK_N)
clk5 Output To Core (Aka INC_CLK_N)
clk6 Output To Core,MMIO,PPU,APU (Aka INC_CLK_P)
clk7 Output To Core,HRAM,APU (Aka BUKE,LATCH_CLK)
clk8 Output To Core (Aka BOMA_1MHZ,MAIN_CLK_N)
clk9 Output To Core,MMIO,APU (Aka BOGA_1MHZ,MAIN_CLK_P)
cclk Output To APU,PPU Input clk complement (same as n_clk_in) (Aka AZOF)

Signal flow:

Phase pattern of all CLK outputs:

clkgen1

If you see a picture like that, then you're good.

Measured phase table (issue #396, HDL/soc/icarus/soc/tb_clkgen)

Measured in simulation with the real ClkGen netlist (WSL-native Icarus; see clkgen_phases.py in the testbench folder). The M-cycle is 4 oscillator cycles and all clocks toggle once per M-cycle except n_clk_in/cclk, which follow the oscillator.

Signal posedge offset inside the M-cycle
n_clk_in / cclk every oscillator half-cycle (phases 32/96/160/224 ns at 4.19 MHz-ish osc)
clk1, clk3, clk5, clk9 0 (T-cycle 0 edge)
clk2, clk8 +1 oscillator cycle
clk4 +2 oscillator cycles
clk6, clk7 +3 oscillator cycles

Verified behaviour (tb_clkgen, all PASS):

The older hypothesis below is kept for history; treat the measured table as authoritative.

Assignment of Clocks (hypothesis, older):

To get the "middle" T-cycles (1 and 2) you can use a bit of logic, for instance "If clk4=1 and clk6=0, then the 2nd T-cycle is now being executed".

Netlist structure (issue #396 analysis)

The ClkGen netlist is small (~56 cells) and splits into functional blocks:

Map

Row Cells
1 not, not, not2(unused), not3, nand, nor, not2(unused), not3, nor, oan, not, not2, or, dffrnq_comp, nor_latch, nor, not, not, dffrnq_comp, not, dffrnq_comp, not, dffrnq_comp, not, dffrnq_comp, not, not2, nand, nand, not, not6
2 not6, not6, or, not, not, nand3, not, not2(unused), not2(unused), not2(unused), not2(unused), not2(unused), not, not, nand4, not6, not, not, nor3, (not4+not6){not10}, (not4+not6){not10}, not2, nor3, (not4+not6){not10}, (not4+not6){not10}, not2, nor, not6, not6, and, not, not