1

我有下面的代码模块

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,而不是在同一个时钟上升沿

4

1 回答 1

2

我期待这个操作。这与您的输入信号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在时钟边沿 2 上被设置为“B”,但这需要时间来传播。任何@(posedge clk)q在时钟边沿 2 上都会看到“A”值,直到下一个边沿 3 才会看到“B”。这就是你所看到的。

不过,如果您需要的话,您几乎可以立即生成信号。但要做到这一点,您需要使用组合逻辑(n1上面)。

 wire n1;
 assign n1 = q + 1;

或者

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

使用顺序逻辑(如您所愿):

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

注意'<='。这是一个非阻塞分配 - 建议使用它来分配您希望在设计中成为寄存器或触发器的东西。查看 Sunburst Design 论文以获得更好的解释。

于 2010-05-05T12:14:42.640 回答