Fixes #6364
This commit is contained in:
parent
7d3c58d21c
commit
63993436c9
|
|
@ -131,12 +131,27 @@ class TraceDriver final : public DfgVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
// Create temporary capable of holding the result of 'vtxp'
|
||||
DfgVertexVar* createTmp(const char* prefix, DfgVertex* vtxp) {
|
||||
AstNode* nodep = m_dfg.modulep();
|
||||
if (!nodep) nodep = v3Global.rootp();
|
||||
const std::string name = m_dfg.makeUniqueName(prefix, nodep->user2Inc());
|
||||
FileLine* const flp = vtxp->fileline();
|
||||
AstNodeDType* const dtypep = vtxp->dtypep();
|
||||
DfgVertex::ScopeCache scopeCache;
|
||||
AstScope* const scopep = m_dfg.modulep() ? nullptr : vtxp->scopep(scopeCache);
|
||||
DfgVertexVar* const varp = m_dfg.makeNewVar(flp, name, dtypep, scopep);
|
||||
varp->varp()->isInternal(true);
|
||||
varp->tmpForp(varp->nodep());
|
||||
return varp;
|
||||
}
|
||||
|
||||
// Continue tracing drivers of the given vertex, at the given LSB. Every
|
||||
// visitor should call this to continue the traversal, then immediately
|
||||
// return after the call. 'visit' methods should not call 'iterate', call
|
||||
// this method instead, which checks for cycles.
|
||||
DfgVertex* trace(DfgVertex* const vtxp, const uint32_t msb, const uint32_t lsb) {
|
||||
UASSERT_OBJ(!vtxp->is<DfgVarArray>(), vtxp, "Cannot trace array variables");
|
||||
UASSERT_OBJ(!vtxp->isArray(), vtxp, "Cannot trace array type vertices");
|
||||
UASSERT_OBJ(vtxp->width() > msb, vtxp, "Traced Vertex too narrow");
|
||||
|
||||
// Push to stack
|
||||
|
|
@ -163,22 +178,24 @@ class TraceDriver final : public DfgVisitor {
|
|||
// Trace the vertex
|
||||
onStackr = true;
|
||||
|
||||
// If the currently traced vertex is in a different component, then we
|
||||
// found what we were looking for. However, keep going past a splice,
|
||||
// or a unit as they cannot be use directly (they must always feed into
|
||||
// a variable, so we can't make them drive arbitrary logic)
|
||||
if (m_vtx2Scc[vtxp] != m_component //
|
||||
&& !vtxp->is<DfgVertexSplice>() //
|
||||
&& !vtxp->is<DfgUnitArray>()) {
|
||||
if (msb != vtxp->width() - 1 || lsb != 0) {
|
||||
// Apply a Sel to extract the relevant bits if only a part is needed
|
||||
DfgSel* const selp = make<DfgSel>(vtxp, msb - lsb + 1);
|
||||
selp->fromp(vtxp);
|
||||
// If the currently traced vertex is in a different component,
|
||||
// then we found what we were looking for.
|
||||
if (m_vtx2Scc[vtxp] != m_component) {
|
||||
m_resp = vtxp;
|
||||
// If the result is a splice, we need to insert a temporary for it
|
||||
// as a splice cannot be fed into arbitray logic
|
||||
if (DfgVertexSplice* const splicep = m_resp->cast<DfgVertexSplice>()) {
|
||||
DfgVertexVar* const tmpp = createTmp("TraceDriver", splicep);
|
||||
splicep->replaceWith(tmpp);
|
||||
tmpp->srcp(splicep);
|
||||
m_resp = tmpp;
|
||||
}
|
||||
// Apply a Sel to extract the relevant bits if only a part is needed
|
||||
if (msb != m_resp->width() - 1 || lsb != 0) {
|
||||
DfgSel* const selp = make<DfgSel>(m_resp, msb - lsb + 1);
|
||||
selp->fromp(m_resp);
|
||||
selp->lsb(lsb);
|
||||
m_resp = selp;
|
||||
} else {
|
||||
// Otherwise just return the vertex
|
||||
m_resp = vtxp;
|
||||
}
|
||||
} else {
|
||||
// Otherwise visit the vertex
|
||||
|
|
@ -1290,6 +1307,9 @@ V3DfgPasses::breakCycles(const DfgGraph& dfg, V3DfgContext& ctx) {
|
|||
return {nullptr, false};
|
||||
}
|
||||
|
||||
// AstNetlist/AstNodeModule user2 used as sequence numbers for temporaries
|
||||
const VNUser2InUse user2InUse;
|
||||
|
||||
// Show input for debugging
|
||||
dump(7, dfg, "input");
|
||||
|
||||
|
|
|
|||
|
|
@ -227,4 +227,26 @@ module t (
|
|||
`signal(ALWAYS_2, 4); // UNOPTFLAT
|
||||
assign ALWAYS_2 = always_2;
|
||||
// verilator lint_on ALWCOMBORDER
|
||||
|
||||
logic [31:0] array_4[3]; // UNOPTFLAT
|
||||
// Input
|
||||
assign array_4[0] = rand_a[31:0];
|
||||
// Sums 1
|
||||
assign array_4[1][ 0 +: 3] = array_4[0][ 2 +: 2] + array_4[0][ 0 +: 2];
|
||||
assign array_4[1][ 3 +: 3] = array_4[0][ 6 +: 2] + array_4[0][ 4 +: 2];
|
||||
assign array_4[1][ 6 +: 3] = array_4[0][10 +: 2] + array_4[0][ 8 +: 2];
|
||||
assign array_4[1][ 9 +: 3] = array_4[0][14 +: 2] + array_4[0][12 +: 2];
|
||||
assign array_4[1][12 +: 3] = array_4[0][18 +: 2] + array_4[0][16 +: 2];
|
||||
assign array_4[1][15 +: 3] = array_4[0][22 +: 2] + array_4[0][20 +: 2];
|
||||
assign array_4[1][18 +: 3] = array_4[0][26 +: 2] + array_4[0][24 +: 2];
|
||||
assign array_4[1][21 +: 3] = array_4[0][30 +: 2] + array_4[0][28 +: 2];
|
||||
// Sums 2
|
||||
assign array_4[2][ 0 +: 4] = array_4[1][ 3 +: 3] + array_4[1][ 0 +: 3];
|
||||
assign array_4[2][ 4 +: 4] = array_4[1][ 9 +: 3] + array_4[1][ 6 +: 3];
|
||||
assign array_4[2][ 8 +: 4] = array_4[1][15 +: 3] + array_4[1][12 +: 3];
|
||||
assign array_4[2][12 +: 4] = array_4[1][21 +: 3] + array_4[1][18 +: 3];
|
||||
// Outupt
|
||||
`signal(ARRAY_4, 32);
|
||||
assign ARRAY_4 = array_4[2];
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue