Merge 23cf8fae69 into 1b93033690
This commit is contained in:
commit
746c882eda
|
|
@ -1940,6 +1940,7 @@ public:
|
|||
, m_processor{netlistp} {
|
||||
// Relies on modules already being in top-down-order
|
||||
iterate(netlistp);
|
||||
V3Width::clearTypeMap();
|
||||
}
|
||||
~ParamVisitor() override = default;
|
||||
VL_UNCOPYABLE(ParamVisitor);
|
||||
|
|
|
|||
|
|
@ -207,13 +207,16 @@ class WidthVisitor final : public VNVisitor {
|
|||
using TableMap = std::map<std::pair<const AstNodeDType*, VAttrType>, AstVar*>;
|
||||
using PatVecMap = std::map<int, AstPatMember*>;
|
||||
using DTypeMap = std::map<const std::string, AstPatMember*>;
|
||||
using ModVarExpMap = std::map<AstVar*, AstNodeExpr*>;
|
||||
|
||||
// STATE
|
||||
V3UniqueNames m_insideTempNames; // For generating unique temporary variable names for
|
||||
// `inside` expressions
|
||||
VMemberMap m_memberMap; // Member names cached for fast lookup
|
||||
ModVarExpMap m_modVarExpMap;
|
||||
V3TaskConnectState m_taskConnectState; // State to cache V3Task::taskConnects
|
||||
WidthVP* m_vup = nullptr; // Current node state
|
||||
static std::map<AstNodeDType*, AstNodeDType*> m_typeMap;
|
||||
bool m_underFork = false; // Visiting under a fork
|
||||
bool m_underSExpr = false; // Visiting under a sequence expression
|
||||
AstNode* m_seqUnsupp = nullptr; // Property has unsupported node
|
||||
|
|
@ -232,6 +235,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
const bool m_doGenerate; // Do errors later inside generate statement
|
||||
bool m_streamConcat = false; // True if visiting arguments of stream concatenation
|
||||
int m_dtTables = 0; // Number of created data type tables
|
||||
bool m_hasParamRef; // Whether there is parameter ref.
|
||||
TableMap m_tableMap; // Created tables so can remove duplicates
|
||||
std::map<const AstNodeDType*, AstQueueDType*>
|
||||
m_queueDTypeIndexed; // Queues with given index type
|
||||
|
|
@ -2095,6 +2099,11 @@ class WidthVisitor final : public VNVisitor {
|
|||
new AstConst(elementsNewFl, 1)},
|
||||
true}};
|
||||
}
|
||||
AstUnpackArrayDType* arrDtypep = VN_CAST(newp, UnpackArrayDType);
|
||||
if (m_hasParamRef && arrDtypep) {
|
||||
if (m_typeMap.find(arrDtypep) == m_typeMap.end())
|
||||
m_typeMap[arrDtypep] = arrDtypep->cloneTree(false);
|
||||
}
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
// Normally parent's iteration would cover this, but we might have entered by a specific
|
||||
|
|
@ -2708,6 +2717,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
nodep->doingWidth(false);
|
||||
}
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_modVarExpMap.find(nodep->varp()) != m_modVarExpMap.end()) { m_hasParamRef = true; }
|
||||
if (nodep->didWidth()) return;
|
||||
if (!nodep->varp()) {
|
||||
if (m_paramsOnly && VN_IS(nodep, VarXRef)) {
|
||||
|
|
@ -6193,12 +6203,26 @@ class WidthVisitor final : public VNVisitor {
|
|||
bool didWidth = false;
|
||||
if (AstPattern* const patternp = VN_CAST(nodep->exprp(), Pattern)) {
|
||||
const AstVar* const modVarp = nodep->modVarp();
|
||||
m_hasParamRef = false;
|
||||
// Convert BracketArrayDType
|
||||
userIterate(modVarp->childDTypep(),
|
||||
WidthVP{SELF, BOTH}.p()); // May relink pointed to node
|
||||
AstNodeDType* const setDtp = modVarp->childDTypep();
|
||||
if (!patternp->childDTypep()) patternp->childDTypep(setDtp->cloneTree(false));
|
||||
if (!patternp->childDTypep()) {
|
||||
if (m_typeMap.find(setDtp) != m_typeMap.end()) {
|
||||
AstNodeDType* const currentDtypep = m_typeMap[setDtp]->cloneTree(false);
|
||||
currentDtypep->foreach([&](AstNodeVarRef* nodep) {
|
||||
if (m_modVarExpMap.find(nodep->varp()) != m_modVarExpMap.end())
|
||||
nodep->replaceWith(
|
||||
m_modVarExpMap[nodep->varp()]->cloneTree(false));
|
||||
});
|
||||
patternp->childDTypep(currentDtypep);
|
||||
VL_DO_DANGLING(userIterate(currentDtypep, nullptr), currentDtypep);
|
||||
} else
|
||||
patternp->childDTypep(setDtp->cloneTree(false));
|
||||
}
|
||||
userIterateChildren(nodep, WidthVP{setDtp, BOTH}.p());
|
||||
m_hasParamRef = false;
|
||||
didWidth = true;
|
||||
}
|
||||
if (!didWidth) userIterateChildren(nodep, WidthVP{SELF, BOTH}.p());
|
||||
|
|
@ -6333,7 +6357,21 @@ class WidthVisitor final : public VNVisitor {
|
|||
if (nodep->rangep()) userIterateAndNext(nodep->rangep(), WidthVP{SELF, BOTH}.p());
|
||||
userIterateAndNext(nodep->pinsp(), nullptr);
|
||||
}
|
||||
if (nodep->paramsp()) {
|
||||
nodep->paramsp()->foreach([&](const AstPin* pinNodep) {
|
||||
if (!VN_CAST(pinNodep->exprp(), Pattern)) {
|
||||
if (AstNodeExpr* const nodeExprp = VN_CAST(pinNodep->exprp(), NodeExpr)) {
|
||||
m_modVarExpMap[pinNodep->modVarp()] = nodeExprp->cloneTree(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
userIterateAndNext(nodep->paramsp(), nullptr);
|
||||
for (auto itr = m_modVarExpMap.begin(); itr != m_modVarExpMap.end(); itr++) {
|
||||
AstNodeExpr* exprp = itr->second;
|
||||
VL_DO_DANGLING(exprp->deleteTree(), exprp);
|
||||
}
|
||||
m_modVarExpMap.clear();
|
||||
}
|
||||
void visit(AstGatePin* nodep) override {
|
||||
assertAtExpr(nodep);
|
||||
|
|
@ -9165,6 +9203,13 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
public:
|
||||
static void clearTypeMap() {
|
||||
for (auto itr = m_typeMap.begin(); itr != m_typeMap.end(); itr++) {
|
||||
AstNodeDType* nodeDTypep = itr->second;
|
||||
VL_DO_DANGLING(nodeDTypep->deleteTree(), nodeDTypep);
|
||||
}
|
||||
m_typeMap.clear();
|
||||
}
|
||||
// CONSTRUCTORS
|
||||
WidthVisitor(bool paramsOnly, // [in] TRUE if we are considering parameters only.
|
||||
bool doGenerate) // [in] TRUE if we are inside a generate statement and
|
||||
|
|
@ -9177,6 +9222,7 @@ public:
|
|||
}
|
||||
~WidthVisitor() override = default;
|
||||
};
|
||||
std::map<AstNodeDType*, AstNodeDType*> WidthVisitor::m_typeMap;
|
||||
|
||||
//######################################################################
|
||||
// Width class functions
|
||||
|
|
@ -9222,3 +9268,4 @@ AstNode* V3Width::widthGenerateParamsEdit(
|
|||
// No WidthRemoveVisitor, as don't want to drop $signed etc inside gen blocks
|
||||
return nodep;
|
||||
}
|
||||
void V3Width::clearTypeMap() { WidthVisitor::clearTypeMap(); }
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public:
|
|||
static void width(AstNetlist* nodep) VL_MT_DISABLED;
|
||||
static AstNode* widthParamsEdit(AstNode* nodep) VL_MT_DISABLED;
|
||||
static AstNode* widthGenerateParamsEdit(AstNode* nodep) VL_MT_DISABLED;
|
||||
static void clearTypeMap();
|
||||
|
||||
// For use only in WidthVisitor
|
||||
// Replace AstSelBit, etc with AstSel/AstArraySel
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
# Compile only test.
|
||||
test.compile()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2017 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t();
|
||||
parameter LEN1 = 8;
|
||||
test #(
|
||||
.LEN(LEN1),
|
||||
.LST('{LEN1{0}})
|
||||
)
|
||||
inst1();
|
||||
|
||||
parameter LEN2 = 3;
|
||||
test #(
|
||||
.LEN(LEN2*2),
|
||||
.LST('{LEN2*2{0}})
|
||||
)
|
||||
inst2();
|
||||
|
||||
test #(
|
||||
.LEN(LEN1 + LEN2),
|
||||
.LST('{(LEN1+LEN2){0}})
|
||||
)
|
||||
inst3();
|
||||
|
||||
test #(
|
||||
.LEN(LEN1 + LEN2),
|
||||
.LST('{LEN1{0}, LEN2{1}})
|
||||
)
|
||||
inst4();
|
||||
endmodule
|
||||
|
||||
module test #(
|
||||
parameter LEN = 4,
|
||||
parameter LST[LEN] = '{LEN{0}}
|
||||
)();
|
||||
endmodule
|
||||
Loading…
Reference in New Issue