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

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

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

+1

对不起很挑剔,但是你的意思是“不是在不是上升的时钟沿而是在下一个上升的时钟沿上更新”?你想删除其中一个不是? (我应该是更重要的事情,但它是我的决赛周,我真的不应该现在在StackOverflow,lol) – 2010-05-05 01:48:48

+0

如果你看图片,并看看ForwardA信号... 2更新在下一个上升时钟边缘...我希望它在黄色线的上升时钟边缘更新,因为在黄色线EXMEMrd == IDEXrs ...我希望这是有道理的 – aherlambang 2010-05-05 03:09:18

回答

2

我期望这个操作更新。这完全取决于你的输入信号如何被驱动。你必须记住,如果你从一个时钟启动某些东西,那么其他时钟模块在下一个时钟沿之前不会看到它,尽管在你的波形查看器中看起来很重要。

考虑到发生的事情的真相很有帮助。一旦你从时钟边缘发起一些事情,这不会马上发生,会有一点延迟。你不会在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被设置为“B”的时钟边沿2,但它需要时间,这个传播。任何@(posedge clk)块在时钟边沿2将看到'A'的值为q,它将不会在下一个边缘看到'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论文,以获得更好的解释。

+0

但要做到这一点,我需要有总是在块内分配,这是不可能的......因为在你上面的例子中..我想要n1是q + 1或q + 2,这取决于if语句的结果......所以这怎么可能? – aherlambang 2010-05-05 13:20:47

+4

最简单的办法是将'always @(posedge Clk)'改为'always @(*)',将上面的时钟块更改为组合块。你没有任何非阻塞任务,所以我不认为你需要改变其他任何东西。给它一个旋风,让我知道... 但是你是否真的需要立即使用'ForwardA'和'ForwardB'的新值? – Marty 2010-05-05 13:44:37

+0

没错,只要总是将(posedge clk)永远改变为@ *,就可以让EquinoX完全符合他所期待的行为。 – Stan 2010-05-06 21:14:44