Я ожидаю эту операцию. Это все связано с тем, как управляют вашими входными сигналами MEMWBRegWrite
и т. Д. Вы должны помнить, что если вы запускаете что-то с часов, то другие синхронизированные блоки не увидят это до следующего фронта часов, даже если в вашей программе просмотра сигналов все может выглядеть одинаково.
Полезно подумать о реальности происходящего. Как только вы запустите что-то с нуля, это не может произойти сразу, будет небольшая задержка. Вы не увидите этих небольших задержек в сигналах симуляции RTL, но они есть в форме дельта-циклов.
1 2 3
______ ______
clk __| |______| |______|
q ----<======A======X=======B======X====
n1 -----<====A+1======X======B+1=====X===== (combinatorial/logic)
n2 ------------------X======A+1=====X=====B+1 (sequential/clocked)
Если вы посмотрите на мое довольно блестящее искусство ascii выше, q
устанавливается на 'B' на фронте тактового сигнала 2, но для его распространения требуется время. Любые блоки @(posedge clk)
увидят значение 'A' для q
на фронте тактовой частоты 2, он не увидит 'B' до следующего фронта, 3. Как это выглядит, как вы видите.
Вы можете генерировать сигнал почти сразу же, если это то, что вам нужно. Но для этого вам нужно использовать комбинаторную логику (n1
выше).
wire n1;
assign n1 = q + 1;
или
reg n1;
always @(*)
n1 = q + 1;
Использование последовательной логики (как вы):
reg n2;
always @(posedge clk)
n2 <= q + 1;
Обратите внимание на '<='. Это неблокирующее назначение - его рекомендуется использовать для назначения вещей, которые вы хотите использовать в качестве регистров или провалов в своем дизайне. Посмотрите на документы Sunburst Design для лучшего объяснения. </p>