From 6a3ec17887130f61b1ec3aaf38b786e02f6f1750 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Thu, 20 Oct 2022 14:55:17 +0100 Subject: [PATCH] DFG: Do not inline SystemC variables The emitted SystemC types (e.g. sc_bv) are not interchangeable with Verilator internal C++ types (e.g.: VlWide), so the variables themselves are not interchangeable (but can be assigned to/from each other). We can preserve correctness simply be not inlining any SystemC variables (i.e.: don't simplify any 'sc = nonSc' or 'nonSc = sc' assignments). SystemC types only appear at top level ports so this should have no significant impact. Fixes #3688 --- src/V3DfgPasses.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index e4d75371d..2abc21986 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -134,9 +134,23 @@ void V3DfgPasses::inlineVars(DfgGraph& dfg) { for (DfgVertexVar *vtxp = dfg.varVerticesBeginp(), *nextp; vtxp; vtxp = nextp) { nextp = vtxp->verticesNext(); if (DfgVarPacked* const varp = vtxp->cast()) { - if (varp->hasSinks() && varp->isDrivenFullyByDfg()) { + // Don't inline SystemC variables, as SystemC types are not interchangeable with + // internal types, and hence the variables are not interchangeable either. + if (varp->hasSinks() && varp->isDrivenFullyByDfg() && !varp->varp()->isSc()) { DfgVertex* const driverp = varp->source(0); - varp->forEachSinkEdge([=](DfgEdge& edge) { edge.relinkSource(driverp); }); + + // If driven from a SystemC variable, don't inline this variable + if (DfgVertexVar* const driverVarp = driverp->cast()) { + if (driverVarp->varp()->isSc()) continue; + } + + varp->forEachSinkEdge([=](DfgEdge& edge) { + // If sink is a SystemC variable, don't inline that sink + if (DfgVertexVar* const sinkVarp = edge.sinkp()->cast()) { + if (sinkVarp->varp()->isSc()) return; + } + edge.relinkSource(driverp); + }); } } }