I tried this code
module tb;
integer r1;
wire [31:0] w1,w2;
initial for (r1=0;r1<10000;r1=r1+1) #1;
assign w1 = r1;
assign w2 = w1;
initial begin
#5; force w1 = 32'hz;
#5; release w1;
#5; $finish;
end
always @(r1) $display("r1=%h, w1=%h, w2=%h ... %s",r1,w1,w2,(w1 === w2)? "O":"X");
endmodule
The result is
r1=00000000, w1=00000000, w2=00000000 ... O
r1=00000001, w1=00000001, w2=00000001 ... O
r1=00000002, w1=00000002, w2=00000002 ... O
r1=00000003, w1=00000003, w2=00000003 ... O
r1=00000004, w1=00000004, w2=00000004 ... O
r1=00000005, w1=zzzzzzzz, w2=00000005 ... X
r1=00000006, w1=zzzzzzzz, w2=00000006 ... X
r1=00000007, w1=zzzzzzzz, w2=00000007 ... X
r1=00000008, w1=zzzzzzzz, w2=00000008 ... X
r1=00000009, w1=zzzzzzzz, w2=00000009 ... X
r1=0000000a, w1=0000000a, w2=0000000a ... O
r1=0000000b, w1=0000000b, w2=0000000b ... O
r1=0000000c, w1=0000000c, w2=0000000c ... O
r1=0000000d, w1=0000000d, w2=0000000d ... O
r1=0000000e, w1=0000000e, w2=0000000e ... O
r1=0000000f, w1=0000000f, w2=0000000f ... O
The w1 and w2 must have same value but doesn't have.
This is a part of a.out.
I think "L_0x9ca0bc0/d .functor BUFZ 32, v0x9c80b80_0,..." is wrong.
The v0x9c80b80_0 should be v0x9c80b80_0.
#! /usr/local/eda/iverilog-0.9.4/bin/vvp
:ivl_version "0.9.4 " "(v0_9_4)";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_0x9c80b00 .scope module, "tb" "tb" 2 1;
.timescale 0 0;
L_0x9ca0bc0/d .functor BUFZ 32, v0x9c80b80_0, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>, C4<00000000000000000000000000000000>;
L_0x9ca0bc0 .delay (5,5,5) L_0x9ca0bc0/d;
v0x9c80b80_0 .var/i "r1", 31 0;
v0x9ca0a78_0 .net "w1", 31 0, v0x9c80b80_0; 1 drivers
v0x9ca0ad8_0 .net "w2", 31 0, L_0x9ca0bc0; 1 drivers
E_0x9ca3778 .event edge, v0x9c80b80_0;
There are known problems with forced signals in v0.9 that have been fixed in devel. The fix required a major rework of the vvp runtime, so can't be back-ported to v0.9. I think this bug will fall in this category.
Having said this, your test case doesn't work correctly in devel either, so I'm reassigning this to devel and upping the priority.
The problem in devel is that the force is getting applied to r1 as well as to w1. I can get the correct behaviour by manually inserting a BUFZ to decouple w1 from r1 - but I don't know if this is the correct fix.
Hmm... Inserting an extra BUFZ is legal, but I'm not 100% sure we want to do that. The reason why the problem is happening is that the .net records are not real nodes, but labels. This means that w1 becomes an alias of r1. This is a common thing to do and my intent is to reduce unnecessary net nodes and improve performance. The bufz nodes are not free performance-wise, so I would like to avoid adding them gratuitously.
Perhaps a more nuanced solution is for the code generator to add the BUFZ only if there is a force somewhere in the design that makes this a problem.
I've finally had a bit of free time to look at this again. I've submitted a patch to fix the problem in devel on the patch tracker. I don't think this fix can be back-ported to v0.9.