Fix clearing trigger of events with no sentrees (#5426)

Signed-off-by: Arkadiusz Kozdra <akozdra@antmicro.com>
This commit is contained in:
Arkadiusz Kozdra 2024-09-02 18:19:49 +02:00 committed by GitHub
parent 088862d449
commit d3fcec3e84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 29 deletions

View File

@ -720,9 +720,18 @@ class DelayedVisitor final : public VNVisitor {
void visit(AstFireEvent* nodep) override {
UASSERT_OBJ(v3Global.hasEvents(), nodep, "Inconsistent");
FileLine* const flp = nodep->fileline();
AstNodeExpr* const eventp = nodep->operandp()->unlinkFrBack();
// Enqueue for clearing 'triggered' state on next eval
AstTextBlock* const blockp = new AstTextBlock{flp};
blockp->addText(flp, "vlSymsp->fireEvent(", true);
blockp->addNodesp(eventp);
blockp->addText(flp, ");\n", true);
AstNode* newp = new AstCStmt{flp, blockp};
if (nodep->isDelayed()) {
AstVarRef* const vrefp = VN_AS(nodep->operandp(), VarRef);
vrefp->unlinkFrBack();
AstVarRef* const vrefp = VN_AS(eventp, VarRef);
const std::string newvarname = "__Vdly__" + vrefp->varp()->shortName();
AstVarScope* const dlyvscp = createNewVarScope(vrefp->varScopep(), newvarname, 1);
@ -736,24 +745,17 @@ class DelayedVisitor final : public VNVisitor {
{
AstIf* const ifp = new AstIf{flp, dlyRef(VAccess::READ)};
postp->addStmtsp(ifp);
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "fire"};
callp->dtypeSetVoid();
ifp->addThensp(callp->makeStmt());
ifp->addThensp(newp);
}
AstActive* const activep = createActiveLike(flp, m_activep);
activep->addStmtsp(prep);
activep->addStmtsp(postp);
AstAssign* const assignp = new AstAssign{flp, dlyRef(VAccess::WRITE),
new AstConst{flp, AstConst::BitTrue{}}};
nodep->replaceWith(assignp);
} else {
AstCMethodHard* const callp
= new AstCMethodHard{flp, nodep->operandp()->unlinkFrBack(), "fire"};
callp->dtypeSetVoid();
nodep->replaceWith(callp->makeStmt());
newp = new AstAssign{flp, dlyRef(VAccess::WRITE),
new AstConst{flp, AstConst::BitTrue{}}};
}
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
}

View File

@ -550,22 +550,19 @@ void EmitCSyms::emitSymHdr() {
if (v3Global.hasEvents()) {
if (v3Global.assignsEvents()) {
puts("void enqueueTriggeredEventForClearing(VlAssignableEvent& event) {\n");
puts("void fireEvent(VlAssignableEvent& event) {\n");
} else {
puts("void enqueueTriggeredEventForClearing(VlEvent& event) {\n");
puts("void fireEvent(VlEvent& event) {\n");
}
puts("#ifdef VL_DEBUG\n");
puts("if (VL_UNLIKELY(!event.isTriggered())) {\n");
puts("VL_FATAL_MT(__FILE__, __LINE__, __FILE__, \"event passed to "
"'enqueueTriggeredEventForClearing' was not triggered\");\n");
puts("}\n");
puts("#endif\n");
puts("if (VL_LIKELY(!event.isTriggered())) {\n");
if (v3Global.assignsEvents()) {
puts("__Vm_triggeredEvents.push_back(event);\n");
} else {
puts("__Vm_triggeredEvents.push_back(&event);\n");
}
puts("}\n");
puts("event.fire();\n");
puts("}\n");
puts("void clearTriggeredEvents() {\n");
if (v3Global.assignsEvents()) {
puts("for (auto& event : __Vm_triggeredEvents) event.clearTriggered();\n");

View File

@ -192,14 +192,6 @@ class SenExprBuilder final {
AstCMethodHard* const clearp = new AstCMethodHard{flp, currp(), "clearFired"};
clearp->dtypeSetVoid();
ifp->addThensp(clearp->makeStmt());
// Enqueue for clearing 'triggered' state on next eval
AstTextBlock* const blockp = new AstTextBlock{flp};
ifp->addThensp(blockp);
const auto add = [&](const string& text) { blockp->addText(flp, text, true); };
add("vlSymsp->enqueueTriggeredEventForClearing(");
blockp->addNodesp(currp());
add(");\n");
}
// Get 'fired' state

View File

@ -18,6 +18,7 @@ module t(/*AUTOARG*/
event e1;
event e2;
event e3;
`ifndef IVERILOG
event ev [3:0];
`endif
@ -50,16 +51,21 @@ module t(/*AUTOARG*/
if (last_event != 0) $stop;
-> e1;
if (!e1.triggered) $stop;
if (e3.triggered) $stop;
-> e3;
if (!e3.triggered) $stop;
end
11: begin
if (last_event != 32'b10) $stop;
last_event = 0;
if (e3.triggered) $stop;
end
//
13: begin
if (last_event != 0) $stop;
->> e2;
if (e2.triggered) $stop;
if (e3.triggered) $stop;
end
14: begin
if (last_event != 32'b100) $stop;