Урок 5. «Игра в хаос»: треугольник из случайности

В картинках

После этого урока на втором экране тот же треугольник Серпинского вырастет из случайных точек. Схема бросает «кубик», делает шаг на полпути к выпавшей вершине и ставит точку — и ни одна точка не ложится мимо.


5.1. Идея: шаг на полпути

Возьми три вершины треугольника и любую точку. Брось кубик: выпала вершина — шагни на полпути к ней и поставь точку. Повторяй. Кажется, что точки лягут как попало, — а они складываются в треугольник Серпинского.

(0, 0)(64, 0)(0, 64)старт1. брось кубик — вершина2. шаг на полпути к ней3. поставь точку, повториточки ложатся толькона треугольник Серпинского
«Игра в хаос»: из случайной вершины — шаг на полпути. После нескольких шагов точка уже не может уйти с треугольника Серпинского, и случайные точки закрашивают его целиком.

5.2. Идея: шаг — это сдвиг

Шаг на полпути — (x + v) / 2, нужен бы сумматор. Но если поставить вершины в (0, 0), (64, 0) и (0, 64), то (x + 64) / 2 и x / 2 — просто сдвиг вправо, а сверху вталкивается бит вершины: 1 — к 64, 0 — к нулю.

x = 22010110x5 … x0к (64, 0)1010111младший уходит(22 + 64) / 2 = 43= 101011к (0, 0): вталкивается 0 → 11
Шаг на полпути к вершине 64 — это сдвиг вправо, а сверху вталкивается 1; к вершине 0 — вталкивается 0. Поэтому координата — сдвиговый регистр, сумматор не нужен.

Единица никогда не вталкивается в x и y сразу — поэтому у точки нет общих разрядов с единицей: это ровно правило урока 4 (x AND y) = 0.

Откуда случайность. LFSR — сдвиговый регистр, который сам себя подпитывает: новый бит — XOR нескольких разрядов. 12 разрядов перебирают все 4095 ненулевых значений в «случайном» порядке. Короче не хватит: точка зависит от шести последних бросков, и короткий генератор не выдаст всех сочетаний — треугольник не закрасится.

5.3. Сборка

Тот же проект: развёртка и треугольник урока 4 остаются, рядом встаёт второй экран.

Игра. Возьми три вершины треугольника и любую точку. Брось кубик: выпала вершина — сделай шаг на полпути к ней и поставь точку. Повторяй. Кажется, что точки лягут как попало, — а складываются в треугольник Серпинского.

Как это в железе. Шаг на полпути — это (x + v) / 2, нужен бы сумматор. Но если поставить вершины в (0, 0), (64, 0) и (0, 64), то (x + 64) / 2 и x / 2 — просто сдвиг вправо, а сверху вталкивается бит вершины: 1 — к 64, 0 — к нулю. Координата — сдвиговый регистр, сумматор не нужен.

abВершинаЧто вталкивается: xy
10(64, 0)10
01(0, 64)01
00(0, 0)00
11(0, 0)00

Единица никогда не вталкивается в x и y сразу — поэтому у точки нет общих разрядов с единицей: это ровно условие урока 4 (x AND y) = 0. Тот же треугольник — из логики слева и из случайности справа.

Откуда случайность. LFSR — сдвиговый регистр, который сам себя подпитывает: новый бит — XOR нескольких разрядов. Он перебирает все 4095 ненулевых значений в «случайном» порядке. Короче 12 разрядов не хватит: точка зависит от шести последних бросков, и короткий генератор не успеет выдать все их сочетания — треугольник не закрасится.

Шаг 1. LFSR12 — генератор случайных бит

ДетальНогаМетка
Порт входавыходCLK
Порт входавыходRST
NOTI0
O0
RST
nRST
XORI0
I1
O0
r11
r5
f1
XORI0
I1
O0
f1
r3
f2
XOR (обратная связь)I0
I1
O0
f2
r0
fb
ANDI0
I1
O0
fb
nRST
g0
OR (сброс в 1)I0
I1
O0
g0
RST
d0
DFF (разряд 0)D
CLK
Q
nQ
d0
CLK
r0
— (свободна)
AND (разряд 1)I0
I1
O0
r0
nRST
d1
DFF (разряд 1)D
CLK
Q
nQ
d1
CLK
r1
— (свободна)
AND (разряд 2)I0
I1
O0
r1
nRST
d2
DFF (разряд 2)D
CLK
Q
nQ
d2
CLK
r2
— (свободна)
AND (разряд 3)I0
I1
O0
r2
nRST
d3
DFF (разряд 3)D
CLK
Q
nQ
d3
CLK
r3
— (свободна)
AND (разряд 4)I0
I1
O0
r3
nRST
d4
DFF (разряд 4)D
CLK
Q
nQ
d4
CLK
r4
— (свободна)
AND (разряд 5)I0
I1
O0
r4
nRST
d5
DFF (разряд 5)D
CLK
Q
nQ
d5
CLK
r5
— (свободна)
AND (разряд 6)I0
I1
O0
r5
nRST
d6
DFF (разряд 6)D
CLK
Q
nQ
d6
CLK
r6
— (свободна)
AND (разряд 7)I0
I1
O0
r6
nRST
d7
DFF (разряд 7)D
CLK
Q
nQ
d7
CLK
r7
— (свободна)
AND (разряд 8)I0
I1
O0
r7
nRST
d8
DFF (разряд 8)D
CLK
Q
nQ
d8
CLK
r8
— (свободна)
AND (разряд 9)I0
I1
O0
r8
nRST
d9
DFF (разряд 9)D
CLK
Q
nQ
d9
CLK
r9
— (свободна)
AND (разряд 10)I0
I1
O0
r9
nRST
d10
DFF (разряд 10)D
CLK
Q
nQ
d10
CLK
r10
— (свободна)
AND (разряд 11)I0
I1
O0
r10
nRST
d11
DFF (разряд 11)D
CLK
Q
nQ
d11
CLK
r11
— (свободна)
OR (выход A)I0
I1
O0
r0
r0
A
OR (выход B)I0
I1
O0
r6
r6
B
Порт выходавходA
Порт выходавходB

Ctrl+G → имя LFSR12. Ноги: входы CLK, RST; выходы A (разряд 0), B (разряд 6). OR с одинаковыми входами — просто «провод» от внутренней метки к порту.

Шаг 2. SHIFT6 — сдвиговый регистр координаты

ДетальНогаМетка
Порт входавыходCLK
Порт входавыходRST
Порт входавыходIN
NOTI0
O0
RST
nRST
AND (разряд 5)I0
I1
O0
IN
nRST
d5
DFF (разряд 5)D
CLK
Q
nQ
d5
CLK
Q5
— (свободна)
AND (разряд 4)I0
I1
O0
Q5
nRST
d4
DFF (разряд 4)D
CLK
Q
nQ
d4
CLK
Q4
— (свободна)
AND (разряд 3)I0
I1
O0
Q4
nRST
d3
DFF (разряд 3)D
CLK
Q
nQ
d3
CLK
Q3
— (свободна)
AND (разряд 2)I0
I1
O0
Q3
nRST
d2
DFF (разряд 2)D
CLK
Q
nQ
d2
CLK
Q2
— (свободна)
AND (разряд 1)I0
I1
O0
Q2
nRST
d1
DFF (разряд 1)D
CLK
Q
nQ
d1
CLK
Q1
— (свободна)
AND (разряд 0)I0
I1
O0
Q1
nRST
d0
DFF (разряд 0)D
CLK
Q
nQ
d0
CLK
Q0
— (свободна)
Порт выходавходQ0
Порт выходавходQ1
Порт выходавходQ2
Порт выходавходQ3
Порт выходавходQ4
Порт выходавходQ5

Ctrl+G → имя SHIFT6. Ноги: входы CLK, RST, IN; выходы Q0–Q5.

Шаг 3. Холст: случайность, вершина, координаты, второй экран

ДетальНогаМетка
LFSR12CLK
RST
A
B
CLK
RST
ra
rb
NOTI0
O0
ra
nra
NOTI0
O0
rb
nrb
AND (вершина x)I0
I1
O0
ra
nrb
kx
AND (вершина y)I0
I1
O0
rb
nra
ky
SHIFT6 (координата x)CLK
RST
IN
Q0
Q1
Q2
Q3
Q4
Q5
CLK
RST
kx
px0
px1
px2
px3
px4
px5
SHIFT6 (координата y)CLK
RST
IN
Q0
Q1
Q2
Q3
Q4
Q5
CLK
RST
ky
py0
py1
py2
py3
py4
py5
Dot display (второй)X0
X1
X2
X3
X4
X5
Y0
Y1
Y2
Y3
Y4
Y5
D0
WE
CLK
CLR
px0
px1
px2
px3
px4
px5
py0
py1
py2
py3
py4
py5
VCC
VCC
nCLK
GND

CLK, nCLK и RST — те же метки, что у развёртки урока 3.

5.4. Проверка

№Что сделатьЧто видно
1второй экран — те же настройки, что первый (Dots, 64 × 64, 1 dot)—
2RST = 1, один такт, RST = 0; генератор 60Hzна втором экране точки появляются по одной, в случайных местах
3присмотрись: ни одна точка не встала «мимо»каждая — на месте треугольника, хотя место выбрано случайно
4генератор 4kHz или быстрее, подождать пару секундвторой экран закрасился — тот же треугольник, что на первом

Если точки ложатся вне треугольника — проверь вершины: у AND (вершина x) второй вход nrb, у AND (вершина y) — nra. Если второй экран закрашивается не весь — проверь разряды обратной связи LFSR12: r11, r5, r3, r0.


Вставка урока 5 (Cmd+I)

Нужны NOT, AND, OR, XOR, DFF; метки CLK, nCLK, RST — с урока 3.

# Урок 5 — «игра в хаос»: случайная вершина, шаг на полпути. Вершины (0,0), (64,0), (0,64) — шаг = сдвиг вправо# со вставкой бита сверху. Тот же треугольник Серпинского вырастает из случайных точек на втором экране.# Вставка: Cmd+I поверх урока 4 (нужны NOT, AND, OR, XOR, DFF; CLK, nCLK, RST — с урока 3). # --- генератор случайных бит: 12 разрядов по кругу, обратная связь XOR от разрядов 11, 5, 3, 0 ---# RST = 1 по фронту: младший разряд 1, остальные 0 (из одних нулей генератор не выйдет)chip LFSR12 {  portIn(CLK)  portIn(RST)  portOut(A)  portOut(B)  NOT(RST, nRST)  XOR(r11, r5, f1)  XOR(f1, r3, f2)  XOR(f2, r0, fb)  AND(fb, nRST, g0)  OR(g0, RST, d0)  DFF(D=d0, CLK=CLK, Q=r0)  AND(r0, nRST, d1)  DFF(D=d1, CLK=CLK, Q=r1)  AND(r1, nRST, d2)  DFF(D=d2, CLK=CLK, Q=r2)  AND(r2, nRST, d3)  DFF(D=d3, CLK=CLK, Q=r3)  AND(r3, nRST, d4)  DFF(D=d4, CLK=CLK, Q=r4)  AND(r4, nRST, d5)  DFF(D=d5, CLK=CLK, Q=r5)  AND(r5, nRST, d6)  DFF(D=d6, CLK=CLK, Q=r6)  AND(r6, nRST, d7)  DFF(D=d7, CLK=CLK, Q=r7)  AND(r7, nRST, d8)  DFF(D=d8, CLK=CLK, Q=r8)  AND(r8, nRST, d9)  DFF(D=d9, CLK=CLK, Q=r9)  AND(r9, nRST, d10)  DFF(D=d10, CLK=CLK, Q=r10)  AND(r10, nRST, d11)  DFF(D=d11, CLK=CLK, Q=r11)  OR(r0, r0, A)  OR(r6, r6, B)} # --- сдвиговый регистр: новый бит IN — в старший разряд, остальные на шаг вправо (деление на 2) ---chip SHIFT6 {  portIn(CLK)  portIn(RST)  portIn(IN)  portOut(Q0)  portOut(Q1)  portOut(Q2)  portOut(Q3)  portOut(Q4)  portOut(Q5)  NOT(RST, nRST)  AND(IN, nRST, d5)  DFF(D=d5, CLK=CLK, Q=Q5)  AND(Q5, nRST, d4)  DFF(D=d4, CLK=CLK, Q=Q4)  AND(Q4, nRST, d3)  DFF(D=d3, CLK=CLK, Q=Q3)  AND(Q3, nRST, d2)  DFF(D=d2, CLK=CLK, Q=Q2)  AND(Q2, nRST, d1)  DFF(D=d1, CLK=CLK, Q=Q1)  AND(Q1, nRST, d0)  DFF(D=d0, CLK=CLK, Q=Q0)} # --- на холст: случайные биты → вершина → две координаты точки → второй экран ---LFSR12(CLK=CLK, RST=RST, A=ra, B=rb)NOT(ra, nra)NOT(rb, nrb)# вершина (64, 0): только a; вершина (0, 64): только b; иначе вершина (0, 0)AND(ra, nrb, kx)AND(rb, nra, ky)SHIFT6(CLK=CLK, RST=RST, IN=kx, Q0=px0, Q1=px1, Q2=px2, Q3=px3, Q4=px4, Q5=px5)SHIFT6(CLK=CLK, RST=RST, IN=ky, Q0=py0, Q1=py1, Q2=py2, Q3=py3, Q4=py4, Q5=py5)dotdisplay SCR2{layout=dots, w=64, h=64}(X0=px0, X1=px1, X2=px2, X3=px3, X4=px4, X5=px5, Y0=py0, Y1=py1, Y2=py2, Y3=py3, Y4=py4, Y5=py5, D0=VCC, WE=VCC, CLK=nCLK, CLR=GND)

Не получается? Что-то не работает →