为什么我的 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
确实,您很可能有一个组合循环。
我可以搜索它在哪里,但我更愿意给你一个解决这些问题的通用方法。如果它发生在我身上,我会使用这个(千载难逢:-)
- 确保使用足够长的时钟。例如100 或 500 个时间单位。这通常是一个很好的做法。 1 高和 1 低的时钟时间是一场灾难。您的模拟不会因此 运行 变慢
在语句之间放置一个 #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
我正在创建一个带有危险单元的流水线处理器。在仿真过程中,当 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
确实,您很可能有一个组合循环。
我可以搜索它在哪里,但我更愿意给你一个解决这些问题的通用方法。如果它发生在我身上,我会使用这个(千载难逢:-)
- 确保使用足够长的时钟。例如100 或 500 个时间单位。这通常是一个很好的做法。 1 高和 1 低的时钟时间是一场灾难。您的模拟不会因此 运行 变慢
在语句之间放置一个
#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