System Timer OCTS

1. Overview

The System Timer implements Open Chiplet Time Synchronization (OCTS). A primary timer counts local clock cycles and sends load and credit pulses to secondary timers. Each secondary advances between pulses, then corrects its count at the next credit boundary.

The counter is 64 bits. Its time unit depends on the primary clock; resolution and alignment accuracy also depend on the clock ratios, pulse routing and synchronization delay. The block does not guarantee nanosecond accuracy or simultaneous sampling across chiplets.

Software configures the timer through a 32-bit AXI4-Lite interface. The is_primary_i input selects its role. The sections below cover counting, synchronization constraints, setup and register access.

2. Operation

Figure 1 shows how primary and secondary timers exchange synchronization information. The dashed groups hold the logic that acts in only one mode, as is_primary_i selects it; the enable and the 64-bit count serve both. The inbound sync-load and credit pulses cross into clk_i through a flop and a prim_edge_detector, which synchronizes them with two flops and turns each rising edge into a one-cycle pulse; an AND gate with is_primary_i on its inverted input masks each pulse in PRIMARY mode. The enable flop is sticky: an OR gate holds it set once a PRIMARY-mode TIMER_START.START or a sync-load pulse has set it. In SECONDARY mode, the sync-load pulse loads the preset, a credit pulse moves the count to the expected count plus CREDIT_VAL, and between pulses the count advances by CTRL.STEP, which drives the core’s timer_cnt_step_i, while credits are left. The credit tracking block holds the cur_credits accumulator, which adds STEP each cycle while it is below CREDIT_VAL (credits_left); the expected count, which u_adder_expected_credit advances by CREDIT_VAL on each credit pulse; and the credit_expired_o counter of cycles spent without credits. Both inbound pulses reset cur_credits and credit_expired_o. In PRIMARY mode, the count advances by one, and the credit counter and pulse state machine drive the outbound pulses. The wrapper keeps the longest credit-starved run reported by the core in a flop that loads the larger of its own value and credit_expired_o, and reads it back as CREDIT_EXPIRED; a write to CREDIT_EXPIRED clears both. In the SMC, the timer pulses use GPIO pads 55 and 56, which drive them on the primary chiplet and sample them on a secondary one.

System Timer OCTS with synchronized sync-load and credit inputs masked in primary mode, secondary credit tracking, the sticky enable flop and 64-bit count, primary credit counter and pulse state machine, the CREDIT_EXPIRED maximum-hold flop, and the AXI-Lite register block
Figure 1. System Timer OCTS primary/secondary synchronization and credit CDC

2.1. Counting and Synchronization

A write of 1 to TIMER_START.START starts the primary and loads TIMER_PRESET_HI:LO. The primary then increments by one on each clk_i cycle. It ignores synchronization inputs and generates load and credit pulses for the secondaries.

A secondary loads its own preset when it detects a rising edge on timer_sync_load_i. On each credit edge, it advances its expected count by CTRL.CREDIT_VAL and replaces its actual count with that expected value. Between edges, it increments by CTRL.STEP while credits remain. This replacement is a correction, not just a diagnostic comparison: a secondary count can move backward if its previous increments overshot the boundary.

Table 1. OCTS credit management
Role Behavior

Primary

An 8-bit interval counter generates a credit event every CREDIT_VAL cycles while enabled. START clears this interval counter.

Secondary

A 9-bit consumed-credit counter starts at zero on load or credit edges. While it is less than CREDIT_VAL, both it and the timer advance by STEP. Counting pauses once the credit limit is reached.

Choose a nonzero secondary STEP appropriate to the clock ratio. The limit is checked before adding the step, so the last increment can cross it. A lost credit pulse also leaves the expected count behind the primary; receiving a later credit does not recover the missing interval.

2.2. Pulse Generation and Clock Crossing

Table 2. OCTS pulse states
State Behavior

PULSE_IDLE

Accept START, or a credit event while enabled. START has priority.

PULSE_SYNC_LOAD

Assert the primary load output for the configured width.

PULSE_CREDIT

Assert the primary credit output for the configured width.

CTRL.PULSE_WIDTH sets the high duration in primary clock cycles; zero is treated as one. CREDIT_VAL must exceed this effective width. The FSM accepts triggers only while idle and does not queue them. In particular, START can reload the primary count while an active pulse prevents a new load pulse; use a coordinated reset and setup sequence for restarting.

Each synchronization input passes through an input flop, a two-flop synchronizer and an edge detector in the receiving clock domain. Pulses must stay high long enough to be sampled and low long enough to distinguish successive events. Determine those intervals from the destination clock, routing delay and CDC analysis; the RTL defines no universal frequency ratio, nanosecond timing guarantee or fixed system-wide alignment bound.

2.3. Status and Credit Expiration

STATUS.MODE is 0 for primary and 1 for secondary. STATUS.RUNNING is set when the internal enable is set and the count is nonzero. It can therefore remain set while a secondary is paused for lack of credit, or remain clear immediately after loading a zero preset. It is not a synchronization check.

The secondary core counts cycles spent without credit. Load and credit edges clear this interval counter. The register wrapper retains the largest observed value in CREDIT_EXPIRED; writing any value clears the saved maximum, while only a load or credit pulse clears the running interval counter in the core. Normal credit reception does not clear the saved maximum. In a primary configured from reset, it stays zero.

Use this value to detect waiting for credit, with thresholds derived from the clock ratio and pulse interval. It does not directly measure timestamp error or prove that all credit pulses arrived.

2.4. Reset

rst_ni asynchronously clears the counter, enable, pulse state and registers. Reset release must meet the integration’s timing requirements; this block does not synchronize reset deassertion internally.

Enable is sticky after a PRIMARY-mode START or a received load edge. There is no stop CSR; writing START=0 does not stop counting. Configure role and timing before starting, and use system reset when a coordinated reconfiguration is needed.

3. Interface

The System Timer OCTS IP has a 32-bit AXI4-Lite register interface. The is_primary_i input selects PRIMARY or SECONDARY mode at runtime. All signals are synchronous to clk_i except timer_sync_load_i and timer_cnt_credit_i, which are synchronized internally as described in Section 2.2.

3.1. Ports

The ports of system_timer_octs are listed in system_timer_octs.

system_timer_octs has no parameters. Its AXI4-Lite request and response types, with 32-bit address and data, are defined in system_timer_octs_pkg.

3.2. OCTS Synchronization Interface

When operating in PRIMARY mode, the timer generates synchronization pulses: timer_sync_load_o is asserted for CTRL.PULSE_WIDTH cycles when the START register is written, and timer_cnt_credit_o is asserted for CTRL.PULSE_WIDTH cycles every CTRL.CREDIT_VAL cycles. Any synchronization input signals are ignored in PRIMARY mode. In contrast, SECONDARY mode relies on input from the PRIMARY: timer_sync_load_i directs the timer to initialize using a preset value, and timer_cnt_credit_i delivers credit pulses that allow continuous synchronization. In this mode, the outputs remain inactive.

3.3. Timer Count

timer_count_o is the live 64-bit count, also readable through TIMER_COUNT_LO and TIMER_COUNT_HI. A PRIMARY advances it by one each clk_i cycle. A SECONDARY advances it by CTRL.STEP each cycle while credits remain.

3.4. Timing

The RTL defines no setup, hold or clock-to-output limit, maximum clock frequency or frequency ratio between OCTS clock domains. Clock frequency, jitter, reset timing and physical timing constraints must come from the integration timing specification.

Synchronization inputs cross into clk_i as described in Section 2.2; derive the required pulse high and low intervals from the destination clock and CDC analysis. Reset behavior is described in Section 2.4.

4. Memory Map and Register Reference

4.1. Memory Map

The register bank occupies 0x00–0x23 and uses 32-bit AXI4-Lite accesses. Use the enclosing subsystem’s memory map for its base address.

Table 3. OCTS register offsets and reset values
Register Offset Reset Meaning

TIMER_START

0x00

0

START is a single-cycle command.

CTRL

0x04

0x0001020A

STEP=1, PULSE_WIDTH=2, CREDIT_VAL=10.

STATUS

0x08

0

MODE subsequently reflects the role input; RUNNING reflects enable and nonzero count.

TIMER_PRESET_LO/HI

0x0C/0x10

0

Two independently writable preset halves.

TIMER_COUNT_LO/HI

0x14/0x18

0

Live count halves, with no snapshot latch; the timestamp read sequence is in the Programmer’s Guide.

CREDIT_EXPIRED

0x1C

0

Saved maximum wait for credit; any write clears it.

TIMER_GPIO_ENABLE

0x20

0

Timer GPIO LSIO selection starts disabled.

4.2. Detailed Register Map

OCTS System Timer Address Map

Open Chiplet Time Synchronization (OCTS) System Timer Registers

Register List:

Table 4. OCTS System Timer Address Map register list
AddressNameAccessDescription
0x0TIMER_STARTRWSystem Timer Start Register
0x4CTRLRWSystem Timer Control Register
0x8STATUSRSystem Timer Status Register
0xCTIMER_PRESET_LORWSystem Timer Preset Value [31:0]
0x10TIMER_PRESET_HIRWSystem Timer Preset Value [63:32]
0x14TIMER_COUNT_LORCurrent System Timer Count [31:0]
0x18TIMER_COUNT_HIRCurrent System Timer Count [63:32]
0x1CCREDIT_EXPIREDRWCredit Expired Register
0x20TIMER_GPIO_ENABLERWSystem Timer GPIO Enable Register

Register Details:

TIMER_START

Table 5. system_timer_octs.TIMER_START fields
BitsFieldAccessResetDescription
31:1Reserved--Reserved
0STARTRW 1P0x0Start the system timer. In PRIMARY mode, a write of 1 loads the preset and pulses the sync-load output for PULSE_WIDTH cycles.
In SECONDARY mode, the write has no effect; a secondary starts on the primary's sync-load pulse, which is what loads its preset.
Ensure both primary and secondary are out of reset.

CTRL

Table 6. system_timer_octs.CTRL fields
BitsFieldAccessResetDescription
31:24Reserved--Reserved
23:16STEPRW0x1Step amount for secondary timer
15:8PULSE_WIDTHRW0x2Pulse width for sync load and credit signals. A value of 0 will be rounded up to 1. WARNING: This value must be less than CREDIT_VAL
7:0CREDIT_VALRW0xACredit value factor. WARNING: This value must be greater than PULSE_WIDTH

STATUS

Table 7. system_timer_octs.STATUS fields
BitsFieldAccessResetDescription
31:5Reserved--Reserved
4RUNNINGR0x0Timer is enabled and its count is nonzero.
3:1Reserved--Reserved
0MODER0x0Timer mode driven by the is_primary_i input: 0=PRIMARY (is_primary_i=1), 1=SECONDARY (is_primary_i=0).

TIMER_PRESET_LO

Table 8. system_timer_octs.TIMER_PRESET_LO fields
BitsFieldAccessResetDescription
31:0PRESET_LORW0x0Lower 32 bits of preset value

TIMER_PRESET_HI

Table 9. system_timer_octs.TIMER_PRESET_HI fields
BitsFieldAccessResetDescription
31:0PRESET_HIRW0x0Upper 32 bits of preset value

TIMER_COUNT_LO

Table 10. system_timer_octs.TIMER_COUNT_LO fields
BitsFieldAccessResetDescription
31:0COUNT_LOR0x0Lower 32 bits of current timer count

TIMER_COUNT_HI

Table 11. system_timer_octs.TIMER_COUNT_HI fields
BitsFieldAccessResetDescription
31:0COUNT_HIR0x0Upper 32 bits of current timer count

CREDIT_EXPIRED

Table 12. system_timer_octs.CREDIT_EXPIRED fields
BitsFieldAccessResetDescription
31:0MAX_CYCLES_EXPIREDRW0x0Maximum number of clock cycles since a count credit expired (SECONDARY only). To reset the value of this register, write anything to it.
If this number is very high (exact value depends on clock speed and credit value), this indicates that the secondary has not received a count credit pulse in a while, and is likely not syncing properly with the primary.
This register can also be used to determine the clock skew between the primary and secondary.
If PRIMARY, this field is always 0.

TIMER_GPIO_ENABLE

Table 13. system_timer_octs.TIMER_GPIO_ENABLE fields
BitsFieldAccessResetDescription
31:1Reserved--Reserved
0GPIO_ENABLERW0x0Enable the GPIO pad lsio interface for the system timer. This is done to prevent X-prop on reset into the secondary timer, which can cause the secondary timer to start counting early.