Skip to content

Маршрутизация и Граф Активации

Соседи формируют эстафету, данные идут через шину


🗺️ RoutingFlags16

Карта Битов (LSB-first)

Бит Флаг Описание
bit0 N Север: активация соседа сверху
bit1 E Восток: активация соседа справа
bit2 S Юг: активация соседа снизу
bit3 W Запад: активация соседа слева
bit4 NE Северо-восток: диагональ
bit5 SE Юго-восток: диагональ
bit6 SW Юго-запад: диагональ
bit7 NW Северо-запад: диагональ
bit8 BUS_R Читать шину (источник ACTIVE)
bit9 BUS_W Писать в шину (WRITE фаза)
bit10..15 reserved Должны быть 0

Пример

routing_flags16 = 0x0301
# binary: 0000 0011 0000 0001
# биты: N(0) + BUS_R(8) + BUS_W(9)

🧭 Топология Соседей

Массив Тайлов

tile_id = y * tile_w + x

Кардинальные Соседи

Направление Формула Условие
N(x,y) (x, y-1) y > 0
S(x,y) (x, y+1) y < tile_h-1
W(x,y) (x-1, y) x > 0
E(x,y) (x+1, y) x < tile_w-1

Диагонали

Направление Формула Условие
NE(x,y) (x+1, y-1) x < tile_w-1 и y > 0
SE(x,y) (x+1, y+1) x < tile_w-1 и y < tile_h-1
SW(x,y) (x-1, y+1) x > 0 и y < tile_h-1
NW(x,y) (x-1, y-1) x > 0 и y > 0

🔗 Рёбра Активации

Правило

Если у тайла A установлен флаг Dir и сосед B = neighbor(A, Dir) существует
→ ребро A → B

Важные Свойства

Свойство Описание
Только ACTIVE Рёбра влияют только на вычисление ACTIVE
Данные не передаются Соседи данные не отправляют
Мульти-родители Разрешены
Циклы Разрешены (детерминизм через locked_before)

🌳 Граф Активации (ACTIVE Closure)

Вычисление ACTIVE

# Seed: источники (корни цепочки)
ACTIVE[t] = 1 если BUS_R[t] == 1

# Propagate: замыкание по графу
ACTIVE[t] = 1 если существует p ∈ Parents(t) такой что:
           ACTIVE[p] == 1 И locked_before[p] == 1

# Least fixed point до стабилизации

Пример Эстафеты

Тик N:
  Tile A (BUS_R=1): ACTIVE=1, вычисляется, locked_after=1
  Tile B (родитель A, флаг N): ACTIVE=0 (пока locked_before[A]=0)

Тик N+1:
  Tile A: locked_before=1, драйвит шину
  Tile B: ACTIVE=1 (т.к. ACTIVE[A]=1 и locked_before[A]=1)
          → читает VSB_INGRESS → вычисляется

🎯 Parents(t) — Множество Родителей

Parents(t) = { p | у тайла p есть флаг Dir и neighbor(p, Dir) = t }

Пример

Tile(5,5) имеет родителей:
- Tile(5,6) если у него установлен флаг N
- Tile(4,5) если у него установлен флаг E
- Tile(5,4) если у него установлен флаг S
- Tile(6,5) если у него установлен флаг W
- Tile(6,4) если у него установлен флаг NE
- Tile(6,6) если у него установлен флаг NW
- Tile(4,6) если у него установлен флаг SE
- Tile(4,4) если у него установлен флаг SW

🚨 Схлоп Ветки

Если корневой/промежуточный тайл расфюжен (reset/collide):

Тик N:   тайл A: locked_before=1, драйвит шину
Тик N+1: тайл A: reset → locked=0
Тик N+2: тайл B (потомок A): ACTIVE=0 → принудительно в 0

Принудительный Ноль

if ACTIVE[t] == 0:
  thr_cur16 := 0
  locked := 0
  drive_vec := {0, 0, 0, 0, 0, 0, 0, 0}
  # веса/row/decay не применяются

📐 Пример Конфигурации

Массив 4×4

┌─────┬─────┬─────┬─────┐
│ 0,0 │ 0,1 │ 0,2 │ 0,3 │  BUS_R=1 (источник)
├─────┼─────┼─────┼─────┤
│ 1,0 │ 1,1 │ 1,2 │ 1,3 │  N=1 (активация снизу)
├─────┼─────┼─────┼─────┤
│ 2,0 │ 2,1 │ 2,2 │ 2,3 │  N=1
├─────┼─────┼─────┼─────┤
│ 3,0 │ 3,1 │ 3,2 │ 3,3 │  N=1
└─────┴─────┴─────┴─────┘

Граф Активации

(0,0) BUS_R=1 → ACTIVE seed
  │
  ▼ (N у 1,0)
(1,0) → ACTIVE если locked_before[(0,0)]=1
  │
  ▼ (N у 2,0)
(2,0) → ACTIVE если locked_before[(1,0)]=1
  │
  ▼ (N у 3,0)
(3,0) → ACTIVE если locked_before[(2,0)]=1

🔗 BUS_R / BUS_W

BUS_R (Read)

Параметр Значение
Бит bit8 (0x0100)
Назначение Источник ACTIVE (seed графа)
Эффект ACTIVE[t]=1 независимо от родителей

BUS_W (Write)

Параметр Значение
Бит bit9 (0x0200)
Назначение Разрешение записи в BUS16
Условие locked self ИЛИ locked_ancestor

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