Verilog system function $countdrivers

Hi,

Can someone help me understand system function’s behaviour of $countdrivers()?
My two questions are listed as follow:

  1. Why @30, $countdrivers return 0 which means <=1 drivers on wire/net node? From the module two_drivers, it shows that node is driven by both ina and inb.
  2. Different outputs from different simulators on $countdrivers args - number_of_0_drivers,
    number_of_1_drivers, number_of_x_drivers, which print from d0, d1, dx @0, @10, @20. Is there race-condition here? What could cause such differences?
module two_drivers (node, ina, inb);
   output node;
   input  ina, inb;
   buf a (node, ina);               // buffers a and b
   buf b (node, inb);               // both drive output node
endmodule

module drive_contention;
   reg contention;
   reg is_forced; 
   integer driver_total, d0, d1, dx; 
   reg 	   ina, inb;
   two_drivers c (node, ina, inb);
   always @ (ina or inb)
     if (node === 1'bx)
       begin      // contention is set to 1 if there are
          // two or more drivers, and 0 otherwise
	  contention = $countdrivers (node, is_forced, 
				      driver_total, d0, d1, dx);
	  if (contention)
	    $display("Contention---\n",
		     "is_forced: %b\n", is_forced,
		     "driver_total: %0d\n", driver_total,
		     "num_0_drivers: %0d\n ", d0,
		     "num_1_drivers: %0d\n", d1,
		     "num_x_drivers: %0d\n", dx);
       end
   initial $monitor("time: %0d, ", $time, "node:%b, ", node,
                    "ina:%b, ", ina, "inb:%b", inb);
   initial
     begin
	#10 ina = 1'b1;
	#10 inb = 1'b0;
	#10 ina = 1'b0; inb = 1'b1;
	#10 $finish();
     end

   initial begin
      $dumpfile("dump.vcd");
      $dumpvars(0,drive_contention);
   end

endmodule // drive_contention

In reply to mlsxdx:

You are mixing $display and $monitor and not printing the time in $display. $monitor always prints at the end of the time slot when there has been change in any of its arguments. Your $display only prints when there is a change on ina or inb. It’s possible there is a race between the time they change, and when node changes. I would add a #1 before your if statement.

In reply to dave_59:

Thank you for your #1 reply, which is so helpful.

With that change, now the result between different simulators are totally in an opposite way.

If adding #1 works that way, which means by the end of time slot 30, the $countdrivers can detects 2 drivers.

I wonder at time slot 30 if node is evaluated x, which means the multiple drivers on wire node, why $countdrivers can only detect 1 driver rather than 2 drivers?