Конфликты на шине и адресное пространство

В компьютере все устройства (ОЗУ, геймпад, экран) обычно сидят на одной общей информационной магистрали — системной шине данных. Представь, что будет, если два человека попытаются одновременно говорить в один микрофон: получится неразборчивый шум. В электронике это называется конфликтом на шине (bus collision): если два устройства одновременно выдадут на шину 1 и 0, произойдёт короткое замыкание или данные превратятся в мусор.

Решение уровня «Конфликт на шине»: дешифратор адреса и гейтирование RAM
Разрешение конфликта на шине: авторское решение уровня

Чтобы этого избежать, процессору нужен строгий регулировщик — Адресный дешифратор (AddrDecoder). Он смотрит, к какому адресу сейчас обращается процессор, и разрешает говорить только одному устройству: RAM — если адрес её, геймпаду — если адрес порта. Все остальные получают приказ «молчать».

На уровне 2.22 ты столкнёшься с этой проблемой вживую: шину данных делят RAM и геймпад, и без дешифратора они будут толкаться одновременно.

Что такое адресное пространство

Каждое устройство, подключённое к процессору, получает свой диапазон адресов — это называется адресным пространством. В статье о дешифраторе команд мы разбирали, как процессор понимает opcode. Теперь на очереди другой дешифратор — адресный: он отвечает не на вопрос «что делать», а на вопрос «кто будет говорить».

В компьютере Ершова адресное пространство делится так:

Диапазон адресовУстройствоСигнал выбора
0–223 (0x00–0xDF)RAM — оперативная памятьRAM_SEL = 1
224–255 (0xE0–0xFF)Устройства ввода-выводаIO_SEL = 1

Диапазон ввода-вывода дальше делится между устройствами: геймпад, генератор случайных чисел и матричный дисплей получают свои порты — об этом мы подробно поговорим в статье про memory-mapped I/O.

RAM — 224 адреса порты 0x00 0xE0 0xFF
Адресное пространство компьютера Ершова: 224 адреса RAM и 32 адреса устройств ввода-вывода

Выходы Адресного дешифратора

AddrDecoder выдаёт два сигнала. RAM_SEL8 — это шинная маска: 0xFF, когда процессор обращается к RAM, и 0x00, когда к устройствам ввода-вывода. IO_SEL — обычный бит, который сообщает, что запрос ушёл в порт ввода-вывода.

Зачем маска, а не просто разрешающий сигнал? Чтобы заставить RAM молчать аппаратно: данные RAM проходят через BusAND с маской RAM_SEL8. Если маска равна 0xFF, данные проходят как есть; если 0x00 — на выходе всегда ноль, и RAM как будто отключена от шины.

Каскад: RAM → BusAND → BusOR

Готовое решение выглядит так: RAM.DataOut → BusAND.A, AddrDecoder.RAM_SEL8 → BusAND.B, выход BusAND → BusOR, а результат BusOR — на шину данных и далее в ALU8.B. Геймпад подключается ко второму входу BusOR.

Когда адрес принадлежит RAM, маска пропускает данные RAM, а геймпад просто не активен. Когда адрес принадлежит устройству ввода-вывода, маска обнуляет данные RAM, и на шине остаётся только геймпад. Конфликт становится физически невозможен.

Два адреса на числах

Разберём два случая. Адрес 200: он лежит в диапазоне 0–223, значит, это RAM. Дешифратор выставляет RAM_SEL8 = 0xFF, данные RAM проходят через BusAND без изменений, геймпад замаскирован. АЛУ видит содержимое ячейки 200.

Теперь адрес 254: он попадает в диапазон 224–255, это порт геймпада. RAM_SEL8 = 0x00 — все биты RAM обнулены, RAM молчит. На шине остаётся только значение кнопок геймпада. Одно устройство, один источник, никакого мусора.

По шагам: 1) ROM отдаёт адрес на вход AddrDecoder.Addr; 2) дешифратор сравнивает его с диапазонами; 3) выставляет RAM_SEL8 и IO_SEL; 4) каскад BusAND/BusOR оставляет на шине ровно одного говорящего.

Частые ошибки

1. Забыть соединить AddrDecoder.Addr с ROM: дешифратор не знает, к какому адресу идёт обращение, и сигналы выбора выдаются неправильно.

2. Подключить RAM напрямую к шине без BusAND: тогда RAM будет выдавать данные даже при обращении к порту ввода-вывода.

3. Считать, что «два источника на шине — это нормально»: это короткое замыкание на уровне логики, а не соревнование, где кто-то победит.

Резюме

1. Шина данных общая, поэтому одновременно на неё может выходить только одно устройство.

2. Адресное пространство: 0–223 — RAM, 224–255 — устройства ввода-вывода.

3. AddrDecoder выдаёт маску RAM_SEL8 (0xFF или 0x00) и бит IO_SEL.

4. Каскад RAM → BusAND (с маской) → BusOR (с геймпадом) аппаратно запрещает конфликт.

5. Адрес 200 читает RAM, адрес 254 читает геймпад — и никогда одновременно.

На уровне 2.22 тебе предстоит подключить Адресный дешифратор и собрать каскад из BusAND и BusOR так, чтобы RAM и геймпад никогда не выходили на шину одновременно. После этого компьютер научится читать кнопки — и мы перейдём к вводу-выводу.

Попробовать в симуляторе →