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

Verilog 输出直到下一个时钟周期才更新,verilog,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

我有下面的代码模块

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

我的意思是:


ForwardA在下一个上升时钟边缘上更新为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)

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

reg n2;
始终@(posedge clk)

对不起,我很挑剔,但是你所说的“不是在上升时钟边缘更新,而是在下一个上升时钟边缘更新”是什么意思?是否要删除其中一个not?(我应该更了解情况,但对我来说这是最后一周。我现在真的不应该在StackOverflow上,哈哈)如果你看看照片,看看ForwardA信号。。。2在下一个上升时钟边缘更新。。。我希望它在上升时钟边缘更新,黄色线在上升时钟边缘,因为在黄色线EXMEMrd==IDEXrs。。。我希望这是有意义的,但要做到这一点,我需要在always块内赋值,这是不可能的。。。因为在你上面的例子中。。我希望n1是q+1或q+2,这取决于if语句的结果。。。那么这是怎么可能的呢?最简单的方法是将上面的时钟块更改为组合块,方法是将“always@(posedge Clk)”更改为“always@(*)”。您没有非阻塞任务,因此我认为您不需要更改任何其他内容。试一试,让我知道。。。但是你真的需要“ForwardA”和“ForwardB”的新值吗?没错,只要简单地将always(posedge clk)更改为always@*就会给EquinoX带来他想要的行为。
 wire n1;
 assign n1 = q + 1;
 reg n1;
 always @(*)
     n1 = q + 1;
 reg n2;
 always @(posedge clk)
     n2 <= q + 1;