module dut_top;
wire [31:0] ctrl_32bit;
wire ctrl_1bit;
assign ctrl_32bit = 0;
assign ctrl_1bit=0;
initial begin #1000ns; end
endmodule
program automatic test;
initial begin
repeat(5) begin
#100ns;
force dut_top.ctrl_32bit[0] =~ dut_top.ctrl_32bit[0]; //LINE 1
force dut_top.ctrl_1bit =~ dut_top.ctrl_1bit; //LINE 2
force dut_top.ctrl_32bit[0] = dut_top.ctrl_1bit; //LINE 3
end
end
endprogram
My code is shown above. LINE 1 gets stuck. But after commenting out LINE 1, LINE 2 and LINE 3 work fine.
I want to force a single bit in an array of bits every once in a while.
The force
statement does not deposit the value, it forcefully applies the expression to the target. It behaves similar to the concurrent assignment of an assign
statement. Therefore force dut_top.ctrl_32bit[0] = ~dut_top.ctrl_32bit[0];
has zero-time feedback to itself.
To understand how force works when the right-hand-side is a variable, consider the following:
module force_example;
reg [3:0] a,b;
initial begin
$monitor("a:%b b:%b @ %2t", $time);
force b = a;
for(a=0; a<5; a=a+1) #1;
#1 $finish();
end
endmodule
b
will equal a
even as a
changes. Regardless of the simulator, it will will display the following:
a:0000 b:0000 @ 0
a:0001 b:0001 @ 1
a:0010 b:0010 @ 2
a:0011 b:0011 @ 3
a:0100 b:0100 @ 4
a:0101 b:0101 @ 5
You need to break the feedback loop to resolve your force issue. There are two ways to do this:
Conditional logic and force to a constant:
program automatic test;
initial begin
repeat(5) begin
#100ns;
if (dut_top.ctrl_32bit[0])
force dut_top.ctrl_32bit[0] = 1'b0;
else
force dut_top.ctrl_32bit[0] = 1'b1;
if (dut_top.ctrl_1bit)
force dut_top.ctrl_1bit = 1'b0;
else
force dut_top.ctrl_1bit = 1'b1;
force dut_top.ctrl_32bit[0] = dut_top.ctrl_1bit; // This is okay
end
end
endprogram
Intermediate variables:
program automatic test;
logic [31:0] tb_ctrl_32bit;
logic tb_ctrl_1bit;
initial begin
tb_ctrl_32bit = dut_top.ctrl_32bit;
tb_ctrl_1bit = dut_top.ctrl_1bit;
force dut_top.ctrl_32bit[0] =~ tb_ctrl_32bit[0]; //LINE 1
force dut_top.ctrl_1bit =~ tb_ctrl_1bit; //LINE 2
force dut_top.ctrl_32bit[0] = tb_ctrl_1bit; //LINE 3
repeat(5) begin
#100ns;
tb_ctrl_32bit[0] =~ dut_top.ctrl_32bit[0];
tb_ctrl_1bit =~ dut_top.ctrl_1bit;
tb_ctrl_32bit[0] = dut_top.ctrl_1bit;
end
end
endprogram