Уровень 52: Память по правилам

Открыть уровень →

Задание

Цель: собрать память данных DMEM 32×32: банк слов-регистров, дешифратор записи по addr[6:2] и мьюкс чтения. Это load/store-архитектура: арифметика живёт в регистрах, память доступна только через lw/sw. Вкладка «Ассемблер» освоила S-формат — соберите sw и lw и загляните, как смещение разрезано на две половины. И проверьте словную индексацию: младшие биты адреса (addr[1:0]) не входят в индекс слова, поэтому 0x1002 попадает в то же слово, что 0x1000. Саму проверку выравнивания выполняет не память, а интерфейс процессора — она появится на интеграции ядра.

До сих пор процессор мог получать данные только из регистров и immediate. Теперь он научится обращаться к отдельной памяти данных и сразу по правилам load/store-архитектуры: арифметика работает только с регистрами, память доступна строго через две команды, загрузку lw и сохранение sw.

Вы соберёте три вещи:

  • Кодирование load/store. lw берёт 12-битное смещение из I-формата, sw — из S-формата, где смещение разрезано на два куска: imm[11:5] в старших битах слова и imm[4:0] — отдельно, на месте поля rd. Ассемблер уровня пополняется S-кодированием: вы учитесь собирать смещение из двух половинок.
  • Память данных dmem.v — 256 слов по 32 бита.
  • Адресацию rs1 + imm. Обе команды вычисляют адрес одинаково: базовый регистр плюс расширенное смещение. АЛУ уже умеет складывать, и путь данных почти готов.

Разница команд — в направлении данных. lw rd, imm(rs1): адрес → память → значение → в rd. sw rs2, imm(rs1): адрес → память, данные из rs2 → в память; регистры при этом не меняются.

Проверка включает сценарий «перепутаны поля смещения»: если склеить imm[11:5] и imm[4:0] в неправильном порядке, адрес получится мусорным — тест обязан это поймать. Отдельно проверяется выравнивание: lw/sw работают только по адресам, кратным четырём; невыровненный доступ в учебной модели — ошибка ERR_DATA_ADDRESS_MISALIGNED.

Решение для самопроверки

Сначала проследите пути данных обеих команд на бумаге. Решение ниже — контрольный список.

Что должно получиться: sw и lw пишут и читают DMEM по адресу rs1 + imm: значение из регистра доезжает до памяти и возвращается в другой регистр без изменений; невыровненный адрес ловится как ERR_DATA_ADDRESS_MISALIGNED, а перепутанные половинки смещения — негативным тестом.

Шаг 1 — склейте смещение. Соберите куски в одно 12-битное число: старший кусок живёт в битах [31:25], младший — в битах [11:7], затем sign-extend уровня 51 расширяет готовые 12 бит до 32. Расширять куски по отдельности нельзя: знаковый бит должен попасть на позицию 11, а не на границу своей половинки.

Шаг 2 — вычислите адрес. address = rs1 + imm — обычное сложение в АЛУ. Частая ошибка: сложить rs1 с rs2, как будто это R-команда. У sw rs2 — источник данных, а не адреса.

Шаг 3 — подключите DMEM. 256×32, чтение комбинационное, запись по тактовому фронту с разрешением MemWrite. RegFile и память данных — разные блоки: RegFile хранит рабочие регистры процессора, DMEM — содержимое, с которым работает программа.

Шаг 4 — разведите пути результата. У lw прочитанное из памяти значение становится результатом команды и записывается в rd. У sw в регистры не пишется ничего — команда изменяет только память.

Шаг 5 — тест. Запишите число в регистр, сохраните в память, загрузите в другой регистр — значения должны совпасть. Затем сохраните два слова по адресам, отличающимся на 4, и убедитесь, что они не перезаписали друг друга. И проверьте негатив: адрес 2 — ловушка выравнивания.

Проверь себя

Почему знаковый бит должен встать именно на позицию 11?

Половинки смещения склеиваются в 12-битное число до расширения: если sign-extend применить к куску, единица попадёт на границу своей половинки, а не в бит 11, и адрес получится мусорным.