输出直到下一个时钟周期才更新

时间:2010-05-04 21:57:37

标签: verilog

我有下面的代码模块

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不是在时钟上升沿而不是在下一个上升时钟边沿上更新...为什么这?如何解决,以便在相同的正上升时钟边沿更新输出?

这就是我的意思: alt text http://img693.imageshack.us/img693/8660/timing.jpg

ForwardA在下一个上升时钟沿更新为2,而不是在同一个上升时钟沿

1 个答案:

答案 0 :(得分:2)

我期待这个操作。这与您的输入信号MEMWBRegWrite等的驱动方式有关。你必须记住,如果你从一个时钟启动一些东西,那么其他时钟块在下一个时钟边缘之前就不会看到它,即使你的波形查看器看起来可能看起来很重合。

想一想正在发生的事情的现实是有帮助的。一旦从时钟边缘启动某些东西,就不会马上发生这种情况,会有一点延迟。你不会在RTL sim波形中看到这些小的延迟,但它们以delta周期的形式存在。

        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在时钟边缘2被设置为'B',但这需要时间来传播。任何@(posedge clk)块在时钟边缘2上看到q的值为'A',在下一个边缘之前不会看到'B',3。看起来你是什么样的看到。

如果你需要的话,你几乎可以直接发出信号。但要做到这一点,你需要使用组合逻辑(上面n1)。

 wire n1;
 assign n1 = q + 1;

 reg n1;
 always @(*)
     n1 = q + 1;

使用顺序逻辑(就像你一样):

 reg n2;
 always @(posedge clk)
     n2 <= q + 1;

注意'&lt; ='。这是一个非阻塞任务 - 建议使用它来分配你想要在你的设计中注册或触发的东西。请查看Sunburst Design论文,以获得更好的解释。