Опять возникла проблема с процессором ВМ2. Только теперь без помощи общества я сходу не разберусь.
Как я уже писал, я начал делать FPGA-версию платы МС1201.02, для замены окончательно сдохшего контроллера в нашем оборудовании. Не точную, конечно, версию, а функциональный аналог, на основе wishbone-варианта ВМ2. Описал схему, подключил в теневое адресное пространство ПЗУ 055. Схема заработала, и я начал развлекаться с пультовыми командами. И тут оказалось, что тесты, начиная с Т3 (тест процессора) нормально не идут:
Код:
@T0
*** test sistemnoj pamqti ***
prowerka okon~ena
*** test ozu ***
pamqtx 020000 -157776
pamqtx 000600 -017776
prowerka okon~ena
*** test prc ***
defekt nezaplanirowannoe prerywanie
170406
@
И вот такой дефект - НЕЗАПЛАНИРОВАННОЕ ПРЕРЫВАНИЕ, вылезает и на всех последующих тестах. Пришлось брать в зубы IDA и разбираться в коде 055. В конце концов причина была найдена, и она оказалась настолько странной, что приходится обращаться к общественности.
Проблема оказалась в обработке прерывания по зависанию шины. Если после выдачи строба данных процессор не получит ответа в течении 128 тактов, он должен вызвать прерывание по вектору 4. И вот этот процесс происходит неправильно. Вот тестовая программа, моделирующая такую ситуацию. Это упрощенный вариант одного из тестов, выполняемых по Т3.
Код:
6 000000 000010 .WORD START ; вектор начального пуска
7 000002 000000 .WORD 0
8
9 000010 .= 10
10 START:
11 000010 012706 000410 MOV #410,SP ; рабочий стек
12 000014 012737 000036 000004 MOV #trap4, @#4 ; устанавливаем новый обработчик trap4
13 000022 005037 000006 CLR @#6
14 000026 005037 177776 CLR @#177776 ; обращемся к отсутствующему адресу
15 RADR:
16 000032 000167 000106' JMP ERR0 ; сюда приходим, если не произошло прерывание
17 ;----------------------------------------------------------------------
18 trap4:
19 000036 022716 000032 CMP #RADR, (SP) ; проверяем сохраненный в стеке адрес
20 000042 001005 BNE ERR1
21 ; Тест успешно завершен
22 000044 012703 000246 MOV #MSGOK,R3
23 000050 004767 000120' CALL printstr
24 000054 000420 BR STOP
25 ; Адреса не совпали
26 ERR1:
27 000056 011603 MOV (SP), R3 ; это адрес из стека
28 000060 004767 000172' CALL PNUM
29 000064 012703 000032 MOV #RADR,R3 ; а вот такой он должен быть
30 000070 004767 000172' CALL PNUM
Здесь устанавливается обработчик прерывания 4, а затем происходит обращение к отсутствующему адресу 177776. Согласно документации, процессор должен при этом затолкать в стек текущий PS, затем адрес следующей команды, то есть 000032. Однако в реальности тест завершается так:
Код:
000034 000032 COMPARE ERROR
То есть в стек затолкалось не 000032, а 000034! В результате адрес возврата стал указывать аж на середину следующей команды. Возврат по такому вектору приведет к непредсказуемому результату.
Эту ситуацию легко повторить, используя тестовый стенд de0_top, идущий в комплекте с wishbone-вариантом процессора. Достаточно прогрузить в его память RAM16K вышеприведенную программу (я ее прикладываю к этому сообщению) и запустить ее - в консоль тут же будут выведены оба адреса, реальный и ожидаемый . На всякий случай я, используя этот же испытательный стенд, промоделировал работу программы в Modelsim. Вот осциллограмма выполнения интересующей нас части программы:
Поскольку этот форум портит картинки, то я включил этот же файл в нормальном разрешении в приложенный архив. Осциллограмма начинается с момента окончания длинной паузы при обращении к адресу 177776. На картинке можно увидеть такие этапы:
0. Процессору надоело ждать ответа, и он снимает строб данных wb_stb.
1. Зачем-то выставляется строб UNA и процессор читает безадресный регистр начального запуска. Зачем - я в упор не понимаю. Вот если бы это было специальное прерывание пультового режима - тогда понятно. А у нас обычное прерывание 4.
2. Процессор заталкивает в стек PS (в данном случае 4) по адресу 406.
3. Затем в стек заталкивается PC возврата по адресу 404. И его значение - 34, а не 32. Что и требовалось доказать.
4. Далее читается вектор 4 и по нему передается управление, как обычно. Это уже нам не интересно.
В результате мы имеем воспроизводимую странность в поведении процессора. Конечно, все можно было бы списать на мои кривые руки и глюки FPGA. Но я использовал для тестов образцовую схему от VSLAV, а ошибка воспроизводится и в симуляторе. Может быть, я плохо понимаю работу процессора, и он по какой-то причине как раз и должен формировать такой вот странный адрес? Но авторы теста T3 так не считают, да и на реальных платах Т3 проходит без ошибок. Получается, что процессор действительно ведет себя неправильно.
Но вот чтобы разобраться в проблеме дальше, надо понимать, как устроены кишки процессора. А там всякие конвейеры, микропрограммные автоматы и прочая жуть, в которой за пару вечеров не разобраться. Поэтому я и прошу помощи у людей, которые уже разобрались в кишках процессора и понимают, как там все работает. Можно просимулировать мою тестовую программу в modelsim и посмотреть, что там внутри процессора происходит и почему он формирует такой странный адрес.
Прикладываю архив, который содержит:
- исходник и листинг тестовой программы
- mif-файл для загрузки в память FPGA
- mem-файл для загрузки в симулятор
- приведенную ранее осциллограмму в полном разрешении.