steveicarus/iverilog

Delayed transmission from tranif0/tranif1 primitives

Closed this issue · 3 comments

(Discussed in #1121)

Description of issue

The 'output' (for lack of a better word) of multi-stage tranif networks doesn't appear at the correct or expected time. A demo testbench, along with its expected and actual outputs, are listed below.

Expected testbench output

         0 a=0 b=0 Y=0
        10 a=0 b=1 Y=1
        20 a=1 b=0 Y=1
        30 a=1 b=1 Y=1

Actual testbench output

         0 a=0 b=0 Y=x
        10 a=0 b=1 Y=0
        20 a=1 b=0 Y=1
        30 a=1 b=1 Y=1

Testbench code

module tranif_test;
reg a, b;
wire y;

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

tranif_or dut(a, b, y);

initial
begin
	a = 0; b = 0;
	#10 a = 0; b = 1;
	#10 a = 1; b = 0;
	#10 a = 1; b = 1;
	#10 $finish;
end

initial
begin
	$monitor($stime,,"a=%b b=%b Y=%b", a, b, y);
end
endmodule

module tranif_or(a, b, y);
	input a, b;
	inout y;

	supply1 vdd;
	supply0 vss;

	wire w1, w2;

        // I added this part after reading
        // https://github.com/steveicarus/iverilog/issues/560#issue-1046681362
        // It has no effect on the output
	initial begin
		force y = 1'bx;
		force w1 = 1'bx;
		force w2 = 1'bx;
		release y;
		release w1;
		release w2;
	end

	// NOR
	tranif0(w1, vdd, a);
	tranif0(w2, w1,  b);
	tranif1(w2, vss, a);
	tranif1(w2, vss, b);

	// OR
	tranif0(y, vdd, w2);
	tranif1(y, vss, w2);
endmodule

For now you could work around this bug by

	// OR
        buf(w3, w2);
	tranif0(y, vdd, w3);
	tranif1(y, vss, w3);

This turned out to be easier to fix than I feared. Fixed in the master branch.

GitHub actions are failing on MacOS, but that's unrelated to this change. Closing