我想将信号从我的测试平台强制传递到层次结构中。这些模块是根据原理图自动创建的(不可能更改设计),并且它们大多基于
wire
类型。
代码示例可以在EDA playground找到,重点是Questa模拟器。
//top level module
module dummy1(input A, output B);
dummy2 u_dummy2(A, B);
always @(A)
begin
assert (A == 1'b0) else $error("Force reached this level");
end
endmodule
module dummy2(input A, output B);
dummy3 u_dummy3(A, B);
endmodule
module dummy3(input A, output B);
assign B = A;
endmodule
如果我在
A
中强制 dummy3
,它将改变 A
中的 dummy2
和 dummy1
,这是预期的。我想知道是否有办法将 A
中的 dummy3
与 A
中的 dummy2
分开,这样力就不会施加到顶级模块。
module dummy_tb;
logic A, B;
dummy1 u_dummy1(A, B);
initial
begin
A = 0;
$display("step0: A=%b B=%b", u_dummy1.A,u_dummy1.B);
#1;
//force A1 to 1
force u_dummy1.u_dummy2.u_dummy3.A = 1'b1;
#1;
$display("step1: A=%b B=%b", u_dummy1.A,u_dummy1.B);
release u_dummy1.u_dummy2.u_dummy3.A;
#1;
$display("step2: A=%b B=%b", u_dummy1.A,u_dummy1.B);
//TODO: find something to separate A in u_dummy3 from A in u_dummy2, then force
end
endmodule
我认为这种行为是由标准中的几句话引起的:
23.3.3 端口连接规则: 每个端口连接应是源到宿的连续分配,其中一个连接项应为 一个是信号源,另一个是信号接收器。该分配应是连续分配 输入或输出端口的源到接收器。
这使得 dummy3.A 成为接收器,dummy_tb.A 成为源。
10.6.2 强制和释放程序语句:网络上的强制程序语句应覆盖网络的所有驱动程序——门输出、模块输出、 以及连续赋值——直到在网络上执行释放程序语句。当被释放时, 网络应立即分配由网络驱动程序确定的值。
这使得 dummy_tb.A 成为 dummy3.A 的驱动程序;因此,基本上 verilog 被迫强制所有输入端口。
因此,如果不强制上述层次结构中的端口为不同的值或强制输出低级模块中的连续分配(强制 dummy3.B),就无法执行您想要的操作。
我想不出一种方法可以在不更改设计模块的 Verilog 源代码的情况下“分离”网络,但是您也可以通过在
A
中强制 dummy2
来实现类似的效果:
#1;
//force A1 to 1
force u_dummy1.u_dummy2.u_dummy3.A = 1'b1;
force u_dummy1.u_dummy2.A = 1'b0; // <-------- add this line
#1;