Генератор случайных чисел (LFSR)
Входы (Inputs)
| Пин | Тип | Описание |
|---|---|---|
| Clock | bit | Сдвиг регистра по фронту (0→1 генерирует новое число) |
| DevAddr | bus8 | Адрес устройства: 0x1A = порт 0xFA |
| IO_SEL | bit | Выбор I/O (1 = устройство активно) |
Выходы (Outputs)
| Пин | Тип | Описание |
|---|---|---|
| Data | bus8 | Текущее псевдослучайное число (0–255) |
Логика работы
Настоящий игральный кубик честно непредсказуем. Цифровой схеме проще притворяться: LFSR — это 8-битная карусель из триггеров, где каждый такт биты сдвигаются, а на освободившееся место через XOR подмешивается сумма нескольких битов состояния. Глазу кажется хаос, хотя внутри — строгая математика.
Главное свойство — детерминированность. Стартовое значение 0x9C и полином x⁸ + x⁶ + x⁵ + x⁴ + 1 жёстко задают каждый следующий шаг: новый бит равен state[7] ⊕ state[5] ⊕ state[4] ⊕ state[3], остальные биты сдвигаются влево. Пример: 0x9C (156) → 0x39 (57) → 0x73 (115) — и так все 255 ненулевых значений подряд, после чего круг замыкается.
Нюанс: состояние 0x00 — ловушка. XOR нулей даёт ноль, и регистр застревает в нём навсегда, поэтому seed никогда не должен быть нулевым. А читается значение как обычное устройство ввода-вывода: IO_SEL = 1, DevAddr = 0x1A — порт 0xFA.
Примеры (последовательность тактов)
| Такт Clock | Data (hex) | Data (dec) | Комментарий |
|---|---|---|---|
| 0 | 0x9C | 156 | стартовое значение (seed) |
| 1 | 0x39 | 57 | первый сдвиг с XOR-обратной связью |
| 2 | 0x73 | 115 | и так далее — каждый такт новое число |
| 255 | 0x9C | 156 | последовательность замкнулась, круг повторится |
Бросок кубика из этой последовательности: LDA 250 читает порт, AND 7 обрезает до 0–7, ADD 1 поднимает до 1–8.
Применение
Уровень 26 «Бросок кубика» учит читать LFSR: LDA 250 кладёт случайный байт в аккумулятор, AND 7 обрезает его до диапазона 0–7, ADD 1 поднимает до 1–8, а лишние значения отбрасываются условным переходом. На уровне 29 так же рождаются координаты еды в Змейке: AND 15 даёт число 0–15 — ровно размер игрового поля.
Конкретное применение: тактируй LFSR каждым тактом Clock непрерывно, а читай порт только в момент выбора — тогда «случайность» зависит от того, на каком такте программа заглянула в регистр. Тот же приём годится для поведения врагов и любых случайных событий в играх на процессоре курса.
Смежные компоненты
Статьи по теме
Частые вопросы
Как LFSR генерирует случайность?
Сдвигает регистр с обратной связью через XOR. Последовательность детерминирована, но выглядит случайной.
Что будет, если seed окажется нулевым?
LFSR застрянет: XOR всех нулей снова даст ноль, и регистр никогда не сдвинется с 0x00.
Сколько разных значений выдаёт LFSR?
255: все байты от 0x01 до 0xFF по одному разу за период, после чего последовательность повторяется сначала.