Skip to content

Tile Model v0.2

Tile = minimal programmable entity of Decima-8


📊 Tile Structure

Baked State

Parameter Type Range Description
thr_lo16 i16 -32768..+32767 Lower fuse threshold
thr_hi16 i16 -32768..+32767 Upper fuse threshold
decay16 u16 0..32767 Decay to zero
domain_id4 u8 0..15 Reset group
priority8 u8 0..255 Collision priority
pattern_id16 u16 0..32767 Pattern ID
routing_flags16 u16 10 bits Activation directions
W[8][8] SignedWeight5 mag3(0..7)+sign1 Weight matrix 8×8 (-7..+7)
reset_on_fire_mask16 u16 16 bits Auto-reset domains on fire

Runtime

Parameter Type Description
thr_cur16 i16 Current accumulator (-32768..+32767)
locked 0/1 Fuse latched
drive_vec[8] u8[8] Output values (0..15)

Note: Decay is always applied (if decay16 > 0), even on locked tiles.


🔄 ACTIVE Closure (Activation Graph)

A tile is ACTIVE if it's "in the live chain" and can read BUS16, compute, apply decay.

Activation Rules

Seed: ACTIVE[t] = 1 if BUS_R == 1 (source/root of chain)

Propagate: ACTIVE[t] = 1 if exists p ∈ Parents(t) such that:
           ACTIVE[p] == 1 AND locked_before[p] == 1

This is computed as monotonic closure until stabilization (least fixed point).

Branch Collapse

If ACTIVE[t] == 0, tile is considered "dead zone":

thr_cur16 := 0
locked := 0
drive_vec := {0, 0, 0, 0, 0, 0, 0, 0}

Weights, decay, drive are not applied in this tick.


📥 Tile Input (VSB_INGRESS)

If ACTIVE[t] == 1, tile reads only VSB_INGRESS16 (all 8 lanes):

for i in 0..7:
  in16[t][i] = clamp15(VSB_INGRESS16[i])
  IN_CLIP[t][i] = (VSB_INGRESS16[i] > 15)

Important: BUS16 is not summed with VSB. The only role of BUS16 in READ phase is semantic: tiles with BUS_R flag become activation graph sources (ACTIVE seed).

Relay (2 ticks)

Tick N:   Ancestor fuses → drives bus in PHASE_WRITE
Tick N+1: Descendant activates via BUS_R → reads VSB_INGRESS → computes

🔒 FUSE-LOCK Mechanism

Decay-to-Zero + Fuse-by-Range

Decay is always applied (if decay16 > 0), even on locked tiles.

If locked_before == 0:

# 1. Compute row-pipeline
delta_raw = Σ row16_signed[r]  # range [-6720..+6720]

# 2. Update accumulator
thr_tmp = thr_cur16 + delta_raw

# 3. Decay pulls to 0, doesn't jump over
if decay16 > 0:
  if thr_tmp > 0:
    thr_tmp = max(thr_tmp - decay16, 0)
  elif thr_tmp < 0:
    thr_tmp = min(thr_tmp + decay16, 0)

thr_cur16 = clamp_range(thr_tmp, -32768, 32767)

# 4. Fuse by range
range_active = (thr_lo16 < thr_hi16)
in_range = range_active AND (thr_lo16 <= thr_cur16) AND (thr_cur16 <= thr_hi16)

has_signal = (delta_raw != 0)
entered_by_decay = (decay16 > 0) AND (in_range == true) AND (in_range_before_decay == false)

locked_after = (BAKE_APPLIED == 1) AND in_range AND (has_signal OR entered_by_decay)

If locked_before == 1:

locked_after := 1
# Weights not applied (passthrough)

# Decay is always applied (if decay16 > 0)
if decay16 > 0:
  if thr_cur16 > 0:
    thr_cur16 = max(thr_cur16 - decay16, 0)
  elif thr_cur16 < 0:
    thr_cur16 = min(thr_cur16 + decay16, 0)

Locked Passthrough

If locked_after == 1, tile acts as "copper bridge":

  • Weight matrix W is not applied
  • drive_vec[i] = in16[i] for all i=0..7 (passthrough)
  • Decay is applied (if decay16 > 0, pulls thr_cur16 to 0)

Latched State

If locked_before == 1:

  • locked_after := 1
  • Weights not applied (passthrough)
  • Decay is always applied (if decay16 > 0)
# Decay pulls to 0 even on locked tiles
if decay16 > 0:
  if thr_cur16 > 0:
    thr_cur16 = max(thr_cur16 - decay16, 0)
  elif thr_cur16 < 0:
    thr_cur16 = min(thr_cur16 + decay16, 0)

🧮 RowOut Pipeline (PHASE_READ)

For each row r=0..7:

Signed Multiplication

row_raw_signed[r] = Σ_{i=0..7} (in16[i] * Wmag[r][i] * sign)
# Range: [-840..+840]

For Lines/Drive (no negatives)

row16_out[r] = clamp15((max(row_raw_signed[r], 0) + 7) / 8)
# Range: 0..15

For Accumulator (signed)

row16_signed[r] = row_raw_signed[r]
# Range: [-840..+840]

🚗 Drive Selection (WRITE)

At end of READ:

if locked_after == 1:
  drive_vec[i] = in16[i]  # passthrough
else:
  drive_vec[i] = row16_out[i]  # computed from weights

🎯 Tile Events

Event Condition
LOCK_TRANSITION(t) locked_before==0 && locked_after==1
FIRE(t) LOCK_TRANSITION(t)

Invariant v0.2

locked == 1 ⇒ thr_lo16 <= thr_cur16 <= thr_hi16

📐 SignedWeight5

Weight: mag3∈[0..7], sign1∈{0,1} (1="+", 0="−").

mul_signed_raw(a, mag, sign) = (sign ? +1 : -1) * (a * mag)
# a∈[0..15], mag∈[0..7] → [-105..+105] per term
# 8 terms per row → [-840..+840] per row

🧩 State Example

{
  "baked": {
    "thr_lo16": 100,
    "thr_hi16": 200,
    "decay16": 5,
    "domain_id4": 0,
    "priority8": 128,
    "pattern_id16": 42,
    "routing_flags16": 0x0301,  // N + BUS_R
    "reset_on_fire_mask16": 0x0001
  },
  "runtime": {
    "thr_cur16": 150,
    "locked": 1
  }
}

Bake the Future. Build the Substrate. 🛠️⚡️