文章目录
-
-
- **为什么会出现仿真竞争条件?**
-
- **典型场景举例**
- **System Verilog 如何解决竞争条件?**
-
- **1. 使用 `program` 块隔离测试平台**
- **2. 使用 `clocking` 块明确时序关系**
- **3. 非阻塞赋值(`<=`)的合理使用**
- **竞争条件的根本原因**
- **总结**
- **代码结构**
-
- **1. 设计模块(`design`)**
- **2. 测试平台模块(`testbench`)**
- **竞争条件分析**
-
- **关键时间点:`#10` 后的操作**
- **仿真器的执行顺序不确定性**
- **结果不确定性**
- **竞争条件的本质**
- **如何修复?(对比 System Verilog 的改进)**
-
- **Verilog 中的临时解决方案**
- **System Verilog 的规范方案**
- **总结**
-
在数字电路仿真中, 仿真竞争条件(Simulation Race Condition) 是指多个并行的信号或事件在同一仿真时间步(time step)内因执行顺序不确定,导致仿真结果不可预测或与真实硬件行为不一致的现象。这种问题在 Verilog 中较为常见,而 System Verilog 通过引入新的机制来规避它。
为什么会出现仿真竞争条件?
仿真器是顺序执行的(非并行),但电路行为本质是并行的。当多个操作(如信号赋值、时钟边沿触发等)在同一仿真时间步内发生,仿真器需要决定它们的执行顺序。若顺序不同导致结果不同,就产生了竞争条件。
典型场景举例
假设在 always @(posedge clk)
触发时,测试平台(Testbench)同时修改输入信号:
// Verilog 示例:潜在的竞争条件
module design (input clk, input a, output reg b);
always @(posedge clk) begin
b <= a; // 在时钟上升沿将 a 的值赋给 b(非阻塞赋值)
end
endmodule
module testbench;
reg clk = 0;
reg a = 0;
design dut (clk, a, b);
initial begin
#10;
clk = 1; // 时钟上升沿
a = 1; // 同时修改输入信号 a
#10;
$display("b = %d", b); // 输出可能不确定!
end
endmodule
- 问题:在
clk
上升沿(posedge clk
)触发的同一时刻,测试平台修改了输入a
。 - 仿真器的执行顺序可能有两种:
- 先执行
clk=1
触发always
块,此时a
仍为旧值0
→b
被赋值为0
。 - 先执行
a=1
,然后clk=1
触发always
块 →b
被赋值为1
。
- 先执行
- 结果取决于仿真器的执行顺序,导致不可预测的输出。
System Verilog 如何解决竞争条件?
1. 使用 program
块隔离测试平台
System Verilog 引入了 program
块,将测试代码与设计代码的执行阶段分离:
- 设计代码(
module
):在仿真器的 Active 区域 执行。 - 测试代码(
program
):在 Reactive 区域 执行(在 Active 区域之后)。