据我所知,任何变量(包括wire和net)都不能有多个赋值。(wire变量:允许连续赋值一次。reg变量:允许在一个块中进行一个过程赋值)
但是,我使用 Aldec Riviera Pro 2022.04 在 EDA Playground 中模拟了以下代码。
//1st testbench code
module test;
wire a;
assign a = 0;
assign a = 1;
endmodule
我相信这应该会导致多驱动错误,因为变量 a 是由两个赋值驱动的。
但是,模拟没有错误。
KERNEL:模拟已完成。不再需要模拟测试向量。 VSIM:仿真已完成。
我的结论是这个模拟有问题,其设计是不可综合的。 为了测试这一点,我修改了测试平台代码。
//2nd testbench code
module test_2;
wire a;
assign a = 0;
assign a = 1;
initial begin
#10 $finish;
end
initial begin
$dumpfiles("wave.vcd");
$dumpvars(0, test_2);
end
endmodule
结果:变量a在整个过程中给出'x'。(wave.vcd)
所以,我认为我的结论是正确的,因为“x”不是正常连续分配结果的合格值。
有什么方法可以让我的模拟工具指出错误,而不是在一个变量中进行错误的赋值过程?
//This code block also works well that is wrong since reg cannot be driven by continuous assignment.
module test_2;
reg a;
assign a = 0;
endmodule
关于reg和wire之间区别的一个非常基本的答案:
Reg 可以用一个连续的语句来赋值。
Reg 也可以在同一块中分配多个过程语句,但只会发生一个(所选语句取决于块中的某些排序规则和语法)。
电线只能用一个连续语句来分配。
您可以参考此问题以获得有关此主题的更详细答案:
“X”是模拟和模拟器中的有效值,LRM(语言参考手册)将其定义为有效值。
您可以在这里阅读更多相关信息:
此外,还有可综合的硬件单元,其中同一网络上有两个驱动程序。例如,三态缓冲器:
https://nandland.com/create-tri-state-buffer-in-vhdl-and-verilog/
底线是:
所以,除了你知道这是一个BUG之外,模拟器没有理由给出这样的错误。
如果您知道信号“a”永远不应该进入状态“X”,并且您想让模拟失败,则需要添加一个断言,表明它永远不会发生。
我也不知道任何模拟器会在配置时给出此类错误,但也许这是可以在某些模拟器中启用的选项。然而,这不可能是模拟器的默认行为,因为它与 LRM 相矛盾。
多驱动网络也可以通过针对综合的 RTL linter 或综合工具本身来识别。
如需更多信息,并扩展您对 X 在某些验证方法中的使用方式的了解,您还可以阅读下一篇博客:
https://www.techdesignforums.com/practice/technique/catch-x-propagation-issues-rtl/