Уровень 67: Knight Rider Pipeline
Задание
Цель: запустить финал курса — ту же программу «Knight Rider», что на 59-м, но на полном конвейерном ядре: ваши форвардинг, пузырь загрузки и flush работают на всех enable=1. Наблюдайте цену конфликтов вживую: каждый взятый переход стоит 2 такта (сброс двух призраков), каждый load-use — 1, и всё же конвейер обгоняет однотактную машину, потому что такт стал в разы короче. Сравните метрики (CPI ≈ 1.53 против 1.00) и предскажите число тактов до останова. Зачёт доказывает целостность железа 66-го — exact-step уже прошёл; после зачёта ZIP-кнопка уводит конвейерное ядро на Tang Nano 9K. Это последний уровень «Компьютера Ершова»: от провода до конвейерного процессора на FPGA.
Финал курса — та же программа «Knight Rider», что на 59-м, но на полном конвейерном ядре: ваши форвардинг, пузырь загрузки и flush работают на всех enable=1. Наблюдайте цену конфликтов вживую: каждый взятый переход стоит 2 такта (сброс двух призраков), каждый load-use — 1. Задания:
- Вставьте knight_rider с 59-го. База LED через
lui x10, 0xFFFFF, два периода «туда-обратно» по восьми огням, останов на.end. - Предскажите число тактов. 115 команд + 4 заполнения + 18 flush-тактов (9 взятых переходов × 2); load-use в KR нет. Стоп-слово такта не добавляет. Считайте сами — любое число калибровка.
- Проверьте маской. Прогон идёт на конвейерном движке: маска сверяет регистры, PC, счётчики (retired/cycles/nstall/nflush) и 30 MMIO-пар — значения совпадают с 59-м, такты нет.
- Прочитайте CPI-таблицу. Конвейер: 176/115 ≈ 1.53. Однотактное ядро на тех же словах: 115/115 = 1.00. При такте в 5 раз короче ускорение ≈ 3.3×.
- Заберите ZIP. После зачёта кнопка экспорта увозит конвейерное ядро 66 (PipeTop32, enable'ы связаны в 1) плюс ROM программы — проект Gowin для Tang Nano 9K.
Решение для самопроверки
Сначала напишите программу сами (листинг — в гайде 59-го). Ниже — контрольные точки.
Что должно получиться: Knight Rider идёт на конвейере: 115 ретайров, 176 тактов (4 заполнения + 4 опустошения + 58 flush-слотов), nstall = 0; маска сверяет регистры, PC, счётчики и 30 MMIO-пар с 59-м, финальный LED = 1; CPI ≈ 1.53 против 1.00 у однотактного ядра.
Шаг 1 — контрольные числа. 115 ретайров, 176 тактов (115 + 4 заполнения + 4 опустошения + 18 flush = 176), nstall=0, nflush=58 (58 слотов = 29 сбросов × 2; один taken — переход на halt). LED = 1 в финале.
Шаг 2 — MMIO-трейс. Те же 30 записей, что на 59-м (две волны «туда-обратно»: 1→128 и 128→1), но такты конвейерные: первая запись на такте 10, не на 4.
Шаг 3 — CPI. Конвейер 176/115 ≈ 1.53; однотактный 115/115 = 1.00. Ускорение при такте в 5 раз короче: 5 / 1.53 ≈ 3.3× — конвейер выигрывает, потому что критический путь сжат до одной стадии.
Проверь себя
Почему конвейер выигрывает, хотя тактов у него больше?
Сравнивать надо произведения, а не такты: 176 коротких тактов против 115 длинных. При такте в 5 раз короче ускорение равно 5 / 1.53 ≈ 3.3× — критический путь сжат до одной стадии, и fill/drain с конфликтами не съедают этот запас.