выход не обновляется до следующего тактового цикла - PullRequest
1 голос
/ 05 мая 2010

У меня есть код модуля ниже

always @(posedge Clk) begin

ForwardA = 0;
ForwardB = 0;

//EX Hazard
if (EXMEMRegWrite == 1) begin
 if (EXMEMrd != 0)
    if (EXMEMrd == IDEXrs)
        ForwardA = 2'b10;
   if (EXMEMrd == IDEXrt && IDEXTest == 0)
        ForwardB = 2'b10;
end


//MEM Hazard

if (MEMWBRegWrite == 1) begin
 if (MEMWBrd != 0) begin
    if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrs)))
            if (MEMWBrd == IDEXrs)
                ForwardA = 2'b01;
    if (IDEXTest == 0) begin
        if (!(EXMEMRegWrite == 1 && EXMEMrd != 0 && (EXMEMrd == IDEXrt)))
            if (MEMWBrd == IDEXrt)
                ForwardB = 2'b01;
    end
 end
end

end

Проблема в том, что выход, который является ForwardA и ForwardB, не обновляется не по переднему фронту тактового сигнала, а по следующему переднему фронту тактового сигнала ... почему это ?? Как решить, чтобы выход обновлялся с тем же положительным нарастающим фронтом тактовой частоты?

Вот что я имею в виду: альтернативный текст http://img693.imageshack.us/img693/8660/timing.jpg

ForwardA обновляется с 2 на следующем переднем фронте тактового сигнала, а не на том же переднем фронте тактового сигнала

1 Ответ

2 голосов
/ 05 мая 2010

Я ожидаю эту операцию. Это все связано с тем, как управляют вашими входными сигналами 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>

...