steveicarus / iverilog

Icarus Verilog
https://steveicarus.github.io/iverilog/
GNU General Public License v2.0
2.85k stars 530 forks source link

Possible infinite loop in output evaluation #1127

Open NickOveracker opened 5 months ago

NickOveracker commented 5 months ago

I generated Verilog from the CMOS stick diagram shown below. It is intentionally a useless, nonsense, and broken circuit; I made it to test for infinite loops in the diagramming tool.

I wanted to check the Verilog output against the diagrammer's output, but the evaluation does not terminate for the final step in the included test bench below. It's not clear whether the loop is infinite, but it did not terminate after several minutes.

This is probably very low-priority because it was triggered by a circuit that could only be made by a very bad mistake or to intentionally trigger an infinite loop. But, I am reporting it just in case it's useful to know about.

Relation to #1122

I rebuilt the program from source, so https://github.com/steveicarus/iverilog/issues/1122 is patched on the computer exhibiting the infinite loop behavior. The infinite loop does not occur on a second device with an older build of iverilog.

Output

iverilog t04.v test21.v; vvp a.out
VCD info: dumpfile Sim.vcd opened for output.
         0 a=1 b=1 y=1
        10 a=0 b=0 y=1
        20 a=0 b=1 y=1

CMOS stick diagram

image

Screenshot 2024-05-17 at 1 35 11

Module code

module t04(A, B, Y);
  input A;
  input B;
  output Y;
  supply1 vdd;
  supply0 gnd;
  wire wire_0;
  wire wire_1;
  wire wire_2;
  wire wire_3;
  wire wire_4;
  wire wire_5;
  wire wire_6;
  wire wire_7;
  wire wire_8;
  wire wire_9;
  wire wire_10;
  wire wire_11;
  wire wire_12;
  wire wire_13;
  wire wire_14;
  wire wire_15;
  wire wire_16;
  wire wire_17;
  wire wire_18;
  wire wire_19;
  wire wire_20;
  wire wire_21;
  wire wire_22;
  wire wire_23;
  wire wire_24;
  assign wire_2 = A;
  assign wire_3 = B;
  assign Y = wire_9;
  assign wire_21 = vdd;
  assign wire_24 = gnd;

  tranif1 nmos_0(wire_7, gnd, wire_3);
  tranif1 nmos_1(wire_4, gnd, wire_3);
  tranif1 nmos_2(gnd, wire_5, wire_4);
  tranif1 nmos_3(wire_5, wire_6, wire_2);
  tranif1 nmos_4(wire_8, wire_7, wire_2);
  tranif1 nmos_5(gnd, wire_11, wire_9);
  tranif1 nmos_6(wire_9, wire_13, wire_8);
  tranif1 nmos_7(wire_14, gnd, wire_6);
  tranif1 nmos_8(wire_10, gnd, wire_6);
  tranif1 nmos_9(wire_11, wire_12, wire_6);
  tranif1 nmos_10(wire_13, gnd, wire_12);
  tranif1 nmos_11(wire_17, wire_16, wire_9);
  tranif1 nmos_12(wire_15, wire_14, wire_9);
  tranif1 nmos_13(gnd, wire_17, wire_10);
  tranif1 nmos_14(gnd, wire_22, wire_18);
  tranif1 nmos_15(wire_18, wire_23, wire_15);
  tranif1 nmos_16(wire_22, wire_20, wire_16);
  tranif1 nmos_17(wire_23, gnd, wire_20);

  tranif0 pmos_0(wire_6, vdd, wire_4);
  tranif0 pmos_1(wire_4, vdd, wire_3);
  tranif0 pmos_2(vdd, wire_8, wire_3);
  tranif0 pmos_3(vdd, wire_6, wire_2);
  tranif0 pmos_4(wire_8, vdd, wire_2);
  tranif0 pmos_5(wire_12, vdd, wire_9);
  tranif0 pmos_6(wire_9, vdd, wire_8);
  tranif0 pmos_7(vdd, wire_9, wire_12);
  tranif0 pmos_8(vdd, wire_12, wire_6);
  tranif0 pmos_9(vdd, wire_15, wire_6);
  tranif0 pmos_10(wire_10, vdd, wire_6);
  tranif0 pmos_11(vdd, wire_16, wire_9);
  tranif0 pmos_12(wire_15, vdd, wire_9);
  tranif0 pmos_13(wire_16, vdd, wire_10);
  tranif0 pmos_14(wire_19, vdd, wire_18);
  tranif0 pmos_15(wire_18, vdd, wire_15);
  tranif0 pmos_16(vdd, wire_18, wire_20);
  tranif0 pmos_17(vdd, wire_20, wire_16);

endmodule

Testbench code

module test21;
reg a, b;
wire y;

initial begin
    $dumpfile("Sim.vcd");
    $dumpvars(0, test21);
end

t04 dut(a, b, y);

initial
begin
        // This is the order of input vectors that triggers the infinite loop.
        // Other orders I tested have no problem.
        a = 1'b1; b=1'b1;
    #10 a = 1'b0; b=1'b0;
    #10 a = 1'b0; b=1'b1;
    #10 a = 1'b1; b=1'b0;

    #10 $finish;
end

initial
begin
    $monitor($stime,,"a=%b b=%b y=%b", a, b, y);
end
endmodule
martinwhitaker commented 5 months ago

I tested this example using the simulator that comes with my FPGA design tools. It detected and reported the infinite loop. I'll have to see if I can make vvp do the same, as it took a kill -9 to stop it.

caryr commented 5 months ago

I think loops in a continuous assignment or primitives like this may never get to a point where the keyboard Ctrl-C is noticed. Also see #1131.