为什么我的 Verilog 波形在值变为 1 时突然停止

Why does my Verilog Waveform Suddenly Stop When a Value Changes to 1

我正在创建一个带有危险单元的流水线处理器。在仿真过程中,当 Flush = 1 时,程序波形停止。我相信我的代码中存在某种无限循环,并且这个危险单元没有 return 任何值。在我附上的图片中,你可以看到在值列中,Flush 变为 1。但是在从中调用的模块中,它仍然为零,因此很可能在此处循环。

Image of Waveform

`timescale 1ns / 1ps

module Hazard_Unit(input BranchD, MtoRFSelE, MtoRFSelM, RFWEE, RFWEM, RFWEW, RST, input [4:0] RsD, RtD, RsE, RtE, RFAE, RFAM, RFAW,
                   output reg Stall, ForwardAD, ForwardBD, Flush, output reg [1:0] ForwardAE, ForwardBE);

reg LWStall, BRStall;

always @(*) begin
    if (RST) begin
        ForwardAD = 1'b0;
        ForwardBD = 1'b0;
        ForwardAE = 2'b00;
        ForwardBE = 2'b00;
        LWStall = 1'b0;
        BRStall = 1'b0;
        Stall = 1'b0;
        Flush = 1'b0;
    end

    else begin
        if ((RsE != 0) && RFWEM && (RsE == RFAM)) ForwardAE = 2'b10;
        else if ((RsE != 0) && RFWEW && (RsE == RFAW)) ForwardAE = 2'b01;
        else ForwardAE = 2'b00;

        if ((RtE != 0) && RFWEM && (RtE == RFAM)) ForwardBE = 2'b10;
        else if ((RtE != 0) && RFWEW && (RtE == RFAW)) ForwardBE = 2'b01;
        else ForwardBE = 2'b00;

        if (MtoRFSelE && ((RtE == RsD) || (RtE == RtD))) LWStall = 1'b1;
        else LWStall = 1'b0;

        if ((RsD != 0) && (RsD == RFAM) && RFWEM) ForwardAD = 1'b1;
        else ForwardAD = 1'b0;

        if ((RtD != 0) && (RtD == RFAM) && RFWEM) ForwardBD = 1'b1;
        else ForwardBD = 1'b0;

        if ((RsD == RFAE || RtD == RFAE) && BranchD && RFWEE || (RsD == RFAM || RtD == RFAM) && BranchD && MtoRFSelM) BRStall = 1'b1;
        else BRStall = 1'b0;

        if (LWStall || BRStall) begin
            Flush = 1'b1;
            Stall = 1'b0;
        end
        else begin
            Flush = 1'b0;
            Stall = 1'b1;
        end
    end
end
endmodule

确实,您很可能有一个组合循环。

我可以搜索它在哪里,但我更愿意给你一个解决这些问题的通用方法。如果它发生在我身上,我会使用这个(千载难逢:-)

  1. 确保使用足够长的时钟。例如100 或 500 个时间单位。这通常是一个很好的做法。 1 高和 1 低的时钟时间是一场灾难。您的模拟不会因此 运行 变慢
  2. 在语句之间放置一个 #5

    if ((RsE != 0) && RFWEM && (RsE == RFAM)) ForwardAE = 2'b10;
    else if ((RsE != 0) && RFWEW && (RsE == RFAW)) ForwardAE = 2'b01;
    else ForwardAE = 2'b00;
    #5;
    
    if ((RtE != 0) && RFWEM && (RtE == RFAM)) ForwardBE = 2'b10;
    else if ((RtE != 0) && RFWEW && (RtE == RFAW)) ForwardBE = 2'b01;
    else ForwardBE = 2'b00;
    #5;
    ...
    

现在您的波形可能会保持 运行ning 并向您显示振荡的位置。修复代码后,不要忘记再次删除#5。

下一点:
您的代码通常是错误的。您在该 if 语句中产生了很多锁存器。您的每个变量 ForwardAD, ForwardBD, ForwardAE ... 都必须在每个 if 语句中分配一个值。或者您应该在 else:

之后立即给它们一个默认值
else begin
    ForwardAD = ..;
    ForwardBD = ..;
    ForwardAE = .;
    ...
    if ((RsE != 0) &....

如果你不能这样做,可能整个部分都应该是一个时钟语句:

always @(posedge some_clock) begin