mirror of
https://github.com/verilator/verilator.git
synced 2026-10-07 02:23:19 +02:00
Make incorrect soft ordering constraint into a hard constraint. (#5520)
An ordering constraint between NBA commit blocks ('Post' logic) and the
written variable were previously added as soft constraints (cutable
edges). However these are required for correctness, so if it ever is
cut we will have incorrect simulation results.
Change these into hard constraints instead. This necessitates adding a
flag on AstVar to ignore special variables constructed during V3Delayed
that might otherwise appear as degenerate logic loops. E.g.:
if (VdlySet) {
VdlySet = 0; // <- This write to VdlySet can and must be ignored
LHS = VdlyVal;
}
No functional change, but you might get an error if this constraint was
ever violated. (Theoretically it should never be, as these variables
were inserted in a way that does not require violating these constraints
...)
This commit is contained in:
+11
-15
@@ -215,24 +215,20 @@ class OrderGraphBuilder final : public VNVisitor {
|
||||
// Update VarUsage
|
||||
varscp->user2(varscp->user2() | VU_GEN);
|
||||
// Add edges for produced variables
|
||||
if (!m_inClocked || m_inPost) {
|
||||
// Combinational logic
|
||||
OrderVarVertex* const varVxp = getVarVertex(varscp, VarVertexType::STD);
|
||||
// Add edge from producing LogicVertex -> produced VarStdVertex
|
||||
if (m_inPost) {
|
||||
m_graphp->addSoftEdge(m_logicVxp, varVxp, WEIGHT_COMBO);
|
||||
} else {
|
||||
if (m_inPost) {
|
||||
if (!varscp->varp()->ignorePostWrite()) {
|
||||
// Add edge from producing LogicVertex -> produced VarStdVertex
|
||||
OrderVarVertex* const varVxp = getVarVertex(varscp, VarVertexType::STD);
|
||||
m_graphp->addHardEdge(m_logicVxp, varVxp, WEIGHT_NORMAL);
|
||||
}
|
||||
|
||||
OrderVarVertex* const postVxp = getVarVertex(varscp, VarVertexType::POST);
|
||||
// Add edge from produced VarPostVertex -> to producing LogicVertex
|
||||
m_graphp->addHardEdge(postVxp, m_logicVxp, WEIGHT_POST);
|
||||
} else if (!m_inClocked) { // Combinational logic
|
||||
// Add edge from producing LogicVertex -> produced VarStdVertex
|
||||
OrderVarVertex* const varVxp = getVarVertex(varscp, VarVertexType::STD);
|
||||
m_graphp->addHardEdge(m_logicVxp, varVxp, WEIGHT_NORMAL);
|
||||
// Add edge from produced VarPostVertex -> to producing LogicVertex
|
||||
|
||||
// For m_inPost:
|
||||
// Add edge consumed_var_POST->logic_vertex
|
||||
// This prevents a consumer of the "early" value to be scheduled
|
||||
// after we've changed to the next-cycle value
|
||||
// ALWAYS do it:
|
||||
// There maybe a wire a=b; between the two blocks
|
||||
OrderVarVertex* const postVxp = getVarVertex(varscp, VarVertexType::POST);
|
||||
m_graphp->addHardEdge(postVxp, m_logicVxp, WEIGHT_POST);
|
||||
} else if (m_inPre) { // AstAssignPre
|
||||
|
||||
Reference in New Issue
Block a user