Уровень 60: Лаборатория верификации
Задание
Цель: спроектировать сценарии верификации — теперь их пишете вы. Два ядра — эталон и подопытное с ОДНИМ подсаженным дефектом; симптом — в баг-репорте карточки подопытного. Сценарий — программа + начальное состояние + таблица ожиданий (такт/поле/значение); добейтесь четырёх условий: в наборе не меньше трёх сценариев и хотя бы одно ожидание на промежуточном такте; весь набор проходит на эталоне; хотя бы один сценарий ловит подопытное (проходит на эталоне — падает на нём); после «исправления» регрессия снова зелёная на всём наборе. Это проектирование тестов, а не Verilog-тестбенч: начальное состояние фиксируйте сами, промежуточные состояния проверяйте по дороге.
Программа может выдать правильный ответ на одном примере и при этом содержать ошибку, которая проявится на другом наборе данных. Поэтому инженеры не только запускают готовые тесты, но и сами проектируют проверку: выбирают воздействия, формулируют ожидания, ловят известные дефекты. Этот уровень — про проектирование тестов, а не про сборку схем.
Все уровни RISC Lab проверяют вас сценарием — последовательностью шагов со стимулами и ожиданиями. Теперь роль меняется: сценарии пишете вы. Сценарий умеет:
- задать входы — например, значения регистров и код операции;
- продвинуть такт — выполнить шаг симуляции;
- проверить состояние — не только выходы, но и промежуточные значения регистров и памяти;
- сравнить с ожиданием — расхождение фиксируется как провал.
Задания уровня:
- Сформулируйте ожидаемое поведение. Для короткой последовательности команд запишите, какими должны быть PC, регистры и память после каждого такта.
- Проверьте граничные случаи. Ноль, отрицательные числа, переполнение, равные операнды, запись в x0, невыровненный адрес.
- Напишите тест, который обязан падать. Платформа подсаживает в процессор известный баг — по образцу уровня 43 с перепутанным проводом. Ваш сценарий должен его обнаружить: тест, который проходит и на правильной, и на сломанной схеме, ничего не проверяет.
- Соберите регрессию. Сохраните свои сценарии и прогоните весь набор после «исправления» — все должны пройти.
Итог уровня: вы учитесь проектировать сценарии верификации цифровых блоков — выбирать воздействия, формулировать ожидания, находить дефекты и вести регрессию. Это не написание Verilog-тестбенча: директивы initial, $display и задержки в диалекте курса запрещены сознательно — сценарная проверка делается средствами платформы.
Решение для самопроверки
Сначала составьте собственные сценарии. Решение ниже — контрольный список верификатора.
Что должно получиться: четыре условия зачёта выполнены: в наборе не меньше трёх сценариев и хотя бы одно ожидание на промежуточном такте; весь набор зелёный на эталоне; хотя бы один сценарий ловит подсаженный дефект; после «исправления» регрессия снова зелёная на всём наборе.
Шаг 1 — фиксируйте начальное состояние. Хороший сценарий не оставляет «пустых» регистров: определите, какие значения лежат в регистрах и памяти перед запуском. Иначе тест проверяет случайное.
Шаг 2 — проверяйте по дороге, а не только в конце. Финальное значение может оказаться правильным при неправильном пути. Добавьте проверку промежуточного состояния: например, после первого такта сложения x5 уже должно быть 42 — задолго до halt.
Шаг 3 — граничные случаи как список. Минимальный набор для блоков, которые вы собрали: 0 и −1 в арифметике; 0x80000000 для slt/sltu; запись 42 в x0 (после такта x0 = 0); we=0 (значение регистра не изменилось); смещение с единицей в бите 11 для S-формата.
Шаг 4 — тест-ловушка. Подсаженный баг проявляется на конкретном векторе. Прежде чем писать сценарий, ответьте: на каком входе правильная и сломанная схемы обязаны разойтись? Затем напишите сценарий ровно на этот вход и убедитесь: на эталоне он проходит, на мутанте — падает.
Шаг 5 — регрессия. Верните схему в правильное состояние и прогоните все свои сценарии подряд. Это и есть регрессионный набор: после каждого будущего изменения процессора он запускается снова — на уровнях 58–67 вам не раз пригодится собственная коллекция тестов.
Проверь себя
Почему тест, проходящий и на эталоне, и на мутанте, ничего не проверяет?
Он не различает правильное и неправильное поведение: ценность сценария — в способности упасть на известном дефекте. Поэтому набор прогоняется на эталоне (зелёный), на подопытном (ловит), а «исправление» закрывается регрессией на всём наборе.