Пересобрал диаграммы с действительно нужными сигналами, а не со запрошенной свалкой.
Код тоже немного поменял, интересно как оно себя дальше ведет:
Код:
180 000434 012700 000001 tst0: mov #1, R0 ; тест ошибки предвыборки
181 000440 012701 000002 mov #2, R1 ;
182 000444 012702 000003 mov #3, R2 ;
183 000450 012703 000004 mov #4, R3 ;
184 000454 070400 mul R0, R4 ;
185 000456 011704 mov @PC, R4 ;
186 000460 005200 inc R0 ;
187 000462 005201 inc R1 ;
188 ; inc R2 ;
189 ; inc R3 ;
190 000464 000401 br 1$ ;
191 000466 000000 halt ;
192 000470 000000 1$: halt ;
193 ;_____________________________________________________________________________
194 ;
195 000472 012700 000001 tst1: mov #1, R0 ; тест ошибки предвыборки
196 000476 012701 000002 mov #2, R1 ;
Процессор здорового человека:
Скрытый текст
[свернуть]
Процессор курильщика.
Скрытый текст
[свернуть]
Там проблема в фазах bir_stb и ir_stb.
Последовательность на шине такая:
- исполняется mov @PC, R4
- читаем 460, предвыборка inc R0
- читаем 460, это чтение по @PC из ьщм @PC, R4
- читаем 460, снова запущенная предвыборка inc R0
И тут начинается самое интересное, мы приходим на 00 (77 на диаграмме), и там формируется Конец Команды (set_cend).
Если предвыборка 460 завершилась, то все хорошо, код inc R0 попадет в регистр инструкций и все исполнится как обычно.
Но если предвыборка НЕ завершилась, то процессор все равно берет код инструкции из буферного регистра (там был inc R0 от предыдущей предвыборки) и выполняет его. Следующая инструкция будет по результатам второй предвыборки 460 которая перед этим не завершилась. Таким образом, в IREG inc R0 попадает дважды. А дальше оно уже по факту смещено. Процессор запускает предвыборку по адресу 462, но на самом деле еще выполняется предвыборка по адресу 460, и вместо помещенной в конвейер запущенной 462 будут получены сначала 460-ые и исполнены, и только затем 462-ые.