mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Initial idea was to remodel AssignW as Assign under Alway. Trying that uncovered some issues, the most difficult of them was that a delay attached to a continuous assignment behaves differently from a delay attached to a blocking assignment statement, so we need to keep the knowledge of which flavour an assignment was until V3Timing. So instead of removing AstAssignW, we always wrap it in an AstAlways, with a special `keyword()` type. This makes it into a proper procedural statement, which is almost equivalent to AstAssign, except for the case when they contain a delay. We still gain the benefits of #6280 and can simplify some code. Every AstNodeStmt should now be under an AstNodeProcedure - which we should rename to AstProcess, or an AstNodeFTask). As a result, V3Table can now handle AssignW for free. Also uncovered and fixed a bug in handling intra-assignment delays if a function is present on the RHS of an AssignW. There is more work to be done towards #6280, and potentially simplifying AssignW handing, but this is the minimal change required to tick it off the TODO list for #6280.
This commit is contained in:
+25
-26
@@ -176,33 +176,35 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert AstAssignW to DfgLogic, return true if successful.
|
||||
bool convert(AstAssignW* nodep) {
|
||||
// Cannot handle assignment with timing control
|
||||
if (nodep->timingControlp()) return false;
|
||||
|
||||
// Potentially convertible block
|
||||
++m_ctx.m_inputs;
|
||||
// Gather written variables, give up if any are not supported
|
||||
const std::unique_ptr<std::vector<DfgVertexVar*>> oVarpsp = gatherWritten(nodep);
|
||||
if (!oVarpsp) return false;
|
||||
// Gather read variables, give up if any are not supported
|
||||
const std::unique_ptr<std::vector<DfgVertexVar*>> iVarpsp = gatherRead(nodep);
|
||||
if (!iVarpsp) return false;
|
||||
// Create the DfgLogic
|
||||
DfgLogic* const logicp = new DfgLogic{m_dfg, nodep, m_scopep};
|
||||
// Connect it up
|
||||
connect(*logicp, *iVarpsp, *oVarpsp);
|
||||
// Done
|
||||
++m_ctx.m_representable;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert AstAlways to DfgLogic, return true if successful.
|
||||
bool convert(AstAlways* nodep) {
|
||||
const VAlwaysKwd kwd = nodep->keyword();
|
||||
if (kwd == VAlwaysKwd::CONT_ASSIGN) {
|
||||
// TODO: simplify once CFG analysis can handle arrays
|
||||
if (AstAssignW* const ap = VN_CAST(nodep->stmtsp(), AssignW)) {
|
||||
if (ap->nextp()) return false;
|
||||
// Cannot handle assignment with timing control
|
||||
if (ap->timingControlp()) return false;
|
||||
// Potentially convertible block
|
||||
++m_ctx.m_inputs;
|
||||
// Gather written variables, give up if any are not supported
|
||||
const std::unique_ptr<std::vector<DfgVertexVar*>> oVarpsp = gatherWritten(ap);
|
||||
if (!oVarpsp) return false;
|
||||
// Gather read variables, give up if any are not supported
|
||||
const std::unique_ptr<std::vector<DfgVertexVar*>> iVarpsp = gatherRead(ap);
|
||||
if (!iVarpsp) return false;
|
||||
// Create the DfgLogic
|
||||
DfgLogic* const logicp = new DfgLogic{m_dfg, nodep, m_scopep, nullptr};
|
||||
// Connect it up
|
||||
connect(*logicp, *iVarpsp, *oVarpsp);
|
||||
// Done
|
||||
++m_ctx.m_representable;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Can only handle combinational logic
|
||||
if (nodep->sentreep()) return false;
|
||||
const VAlwaysKwd kwd = nodep->keyword();
|
||||
if (kwd != VAlwaysKwd::ALWAYS && kwd != VAlwaysKwd::ALWAYS_COMB) return false;
|
||||
|
||||
// Potentially convertible block
|
||||
@@ -261,9 +263,6 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
void visit(AstNodeProcedure* nodep) override { markReferenced(nodep); }
|
||||
|
||||
// Potentially representable constructs
|
||||
void visit(AstAssignW* nodep) override {
|
||||
if (!convert(nodep)) markReferenced(nodep);
|
||||
}
|
||||
void visit(AstAlways* nodep) override {
|
||||
if (!convert(nodep)) markReferenced(nodep);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user