nand2tetris CPU.cmp строка 17 проблема; outM/(RAM[A]) дважды уменьшается с инструкцией MD=D-1;

Я пытаюсь работать с файлом CPU.cmp, чтобы записать инструкции и посмотреть, имеет ли смысл то, что написано в CPU.cmp.

В строке 17 (время 8)

|time| inM  |  instruction   |reset| outM  |writeM |addre| pc  |DRegiste|
|6+  |     0|0000001111101001|  0  |*******|   0   | 1000|    6|  11111 |a @1001
|7   |     0|0000001111101001|  0  |*******|   0   | 1001|    7|  11111 |a
|7+  |     0|1110001110011000|  0  |  11110|   1   | 1001|    7|  11110 |c MD = D-1; null
|8   |     0|1110001110011000|  0  |  11109|   1   | 1001|    8|  11110 |c

Как видите, значение регистра D уменьшается на 1 с (десятичных) 11111 до 11110, и значение outM отражает это. Однако затем outM снова уменьшается до 11109. Почему это происходит? Инструкция MD = D-1, поэтому она должна уменьшить D reg один раз и сохранить значение в двух местах. Как получается, что RAM[A] и D имеют разные значения?

Я ожидал, что они будут такими же...


person aNameLikeAnyOther    schedule 13.08.2019    source источник
comment
Вы, сэр, засунули баг в свой процессор, так что либо найдите его сами, либо покажите свою работу и попросите помощи.   -  person zubergu    schedule 14.08.2019
comment
Это было в файле CPU.cmp, предоставленном с проектом, а не в моем тестовом выводе CPU.hdl... так что это выглядит неправильно?   -  person aNameLikeAnyOther    schedule 14.08.2019
comment
Хорошо, я неправильно вас понял, подумал, что ваш процессор не сработал при сравнении, и вы спрашиваете, почему .cmp выглядит именно так.   -  person zubergu    schedule 14.08.2019


Ответы (1)


На tick 7+ ЦП должен выполнить инструкцию MD=D-1, как вы уже поняли.

В этот момент D=11111.

Инструкция — D-1, и ЦП вычислит это значение внутри себя, поэтому outM (выходная шина, а не фактическая память) — это D-1 (11110), а также регистр D = 11110. В tock 8 происходит запись в память, поэтому 11110 сохраняется по адресу в регистре A. ЦП по-прежнему вычисляет D-1, поэтому outM = 11109, совершенно правильное поведение ЦП, мы не используем это значение, но оно представляет собой результат последней инструкции (по-прежнему D-1).

Чтобы расширить ticks и tocks:

tick - это 1 на часах, это часть цикла, когда все выходы и регистры успевают изменить и стабилизировать свои внутренние значения. Загружаемые регистры выводят свое изменяющееся внутреннее состояние немедленно при изменении ввода.

tock — это часть, в которой тактируемые части начинают излучать свое внутреннее состояние и не будут изменять свои внутренние значения.

Вот почему DRegister имеет то же значение, что и outM на tick, ALU передает D-1 в качестве своего значения. Затем приходит tock, и D начинает выдавать свое новое значение (d-1), а ALU вычисляет новое значение (вы видите его как D-2). D не меняется, потому что в tock фазе тактовые части не меняют своего значения.

Также, чтобы ответить

Как получается, что RAM[A] и D имеют разные значения

Это не так, outM и DRegister получают разные значения. outM не тактируется, это прямой вывод АЛУ, который вычисляет out(D) - 1. DRegister имеет тот же вывод АЛУ, что и ввод, но не обновляет свое значение из-за фазы тактирования.

person zubergu    schedule 14.08.2019
comment
ЦП все еще вычисляет D-1, поэтому outM = 11109, совершенно правильное поведение ЦП. Я еще чего-то не понимаю. Если это совершенно нормально, что линия outM снова меняется, то почему Dregister также не меняется на такке 8? Разве Dregister не питается напрямую от outM? Кажется, я чего-то не понимаю насчет клещей и таксов. Отмечается ли тик, когда происходит выборка инструкции, и отметка выполнения? - person aNameLikeAnyOther; 14.08.2019
comment
Пожалуйста, смотрите обновленный ответ. Я все же рекомендую пройти проект. Этот курс использует удивительный поэтапный подход, и таким образом проекты в значительной степени говорят сами за себя. - person zubergu; 14.08.2019