вывод, не обновляющий до следующего такта

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

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
задан Brian Carlton 5 May 2010 в 01:45
поделиться

1 ответ

Я ожидал этой операции. Все дело в том, как управляются ваши входные сигналы, MEMWBRegWrite и т. Д. Вы должны помнить, что если вы запускаете что-то из часов, то другие синхронизированные блоки не будут видеть это до следующего фронта тактового сигнала, даже если все может выглядеть совпадающим в вашем средстве просмотра сигналов.

Полезно думать о том, что происходит на самом деле. Как только вы запускаете что-то с фронта часов, это не может произойти сразу, будет небольшая задержка. Вы не увидите этих небольших задержек в сигналах RTL sim, но они есть в форме дельта-циклов.

        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 для лучшего объяснения.

2
ответ дан 3 September 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: