Уровень 53: Шаг на четыре

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

Задание

Цель: собрать путь счётчика команд: каждый такт pc = pc + 4, а когда beq берётся (branch & zero) — pc = pc + смещение. База смещения — адрес САМОЙ ветки, смещение задано в байтах (не в словах!), и оно разрезано по слову команды B-формата — разрезает его BImm32. Сумматор add32.v уже готов с уровня 50 — просто инстанцируйте его дважды. Во вкладке «Ассемблер» теперь beq с метками.

До этого PC просто шагал вперёд. Каждая команда занимает 4 байта, поэтому шаг равен четырём. Теперь вы научите процессор менять маршрут: если условие выполнено — прыгнуть, если нет — сделать обычный шаг на четыре.

Что добавляется:

  • PC+4 и PC+imm. Сумматор адреса ветки: PC + imm, где imm — знаковое смещение в байтах. Мультиплексор PCSrc выбирает между ними по сигналу ветки.
  • B-формат. Смещение 13 бит (с чётным шагом, младший бит всегда 0) разрезано в слове команды на два куска — и не подряд: imm[12|10:5] в старшем байте и imm[4:1|11] ниже. Разобрать это разрезание — главная головоломка уровня.
  • beq. Условие берётся из АЛУ: вычитание rs1 − rs2; если результат — ноль, регистры равны. АЛУ уровня 50 уже выдаёт сигнал zero — он наконец находит работу.
  • Метки в ассемблере. К ассемблеру добавляется B-кодирование и метки: beq x5, x6, loop — ассемблер сам считает байтовое смещение до метки.

Проверка: трасса исполнения + предсказание «куда перейдёт beq» — вперёд или назад, и на какой адрес.

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

Сначала проследите последовательность команд с веткой по тактам. Решение ниже поможет свериться.

Что должно получиться: beq верен в обоих направлениях: условие истинно — PC стал PC + imm (база — адрес самой ветки), ложно — PC + 4; трасса исполнения и предсказание «куда прыгнет beq» сходятся.

Шаг 1 — соберите смещение. Куски собираются в 13-битное число: {imm[12], imm[10:5], imm[4:1], 1'b0}, затем sign-extend до 32 бит. Младший бит нулевой всегда — все инструкции выровнены по 4 байта, смещение чётное. Перепутанные куски дают переход «куда-то не туда»: негативный тест уровня именно это и ловит.

Шаг 2 — выберите базу адреса. Смещение считается от PC текущей команды ветки, а не от «следующей» и не от нуля. Вторая классическая ошибка — смещение в словах вместо байтов: метка на 2 команды дальше — это +8 байт, а не +2.

Шаг 3 — подключите условие. АЛУ вычитает rs1 − rs2; сигнал zero означает равенство. Сигнал ветки = Branch & zero — он управляет PCSrc. Обратите внимание: вычитание для сравнения не портит регистры — результат АЛУ у ветки просто не записывается в rd.

Шаг 4 — проверьте оба направления. Переход вперёд (метка ниже по коду) и назад (метка выше — так будут выглядеть циклы). Для каждого случая проверьте: условие истинно — PC стал равен PC + imm; условие ложно — PC стал равен PC + 4.

Принцип: условный переход не изменяет порядок команд в памяти. Он изменяет адрес, по которому процессор продолжит чтение инструкций.

Проверь себя

Почему смещение B-формата разрезано непоследовательно?

Это цена компактной команды: биты смещения разложены в фиксированные поля (imm[12|10:5] в старшем байте, imm[4:1|11] ниже), общие для всех B-команд. Младший бит всегда 0 — инструкции выровнены по 4 байта, смещение чётное.