分析
这个问题是当前 Verilator 仿真(eval)顺序引起的,Verilator 会把 initial 块和 always 块的仿真完全隔离开, 生成的 C++ 代码是这样的:
void Vtest::eval_step() {
// ...
if (!vlSymsp->__Vm_didInit) {
vlSymsp->__Vm_didInit = true;
Vtest___024root___eval_static(&(vlSymsp->TOP));
Vtest___024root___eval_initial(&(vlSymsp->TOP));
Vtest___024root___eval_settle(&(vlSymsp->TOP));
}
Vtest___024root___eval(&(vlSymsp->TOP));
// ...
}
其中 _eval_initial
的实现如下:
VlCoroutine Vtest___024root___eval_initial__TOP__Vtiming__0(Vtest___024root* vlSelf) {
// ...
auto &vlSelfRef = std::ref(*vlSelf).get();
vlSelfRef.test__DOT__a = 1U;
co_await vlSelfRef.__VdlySched.delay(1ULL, nullptr,
"verilator-issues/5499/test.sv",
9);
VL_WRITEF_NX("b = %b\n",0,1,vlSelfRef.test__DOT__b);
VL_FINISH_MT("verilator-issues/5499/test.sv", 15, "");
}
void Vtest___024root___eval_initial(Vtest___024root* vlSelf) {
// ...
auto &vlSelfRef = std::ref(*vlSelf).get();
Vtest___024root___eval_initial__TOP__Vtiming__0(vlSelf);
vlSelfRef.__Vtrigprevexpr___TOP__test__DOT__a__0
= vlSelfRef.test__DOT__a;
}
函数 Vtest_024root_eval_initialTOPVtiming0
就对应于 sv design 中的 initial
块,
注意到 Vtrigprevexpr_TOPtestDOTa__0
的值会是 1
,这意味着在 always 不会看到 a
的上升沿,
因此不会执行。