Fix parameter types of user defined arrays (#6042)
This commit is contained in:
parent
66259d8909
commit
76aced4d40
|
@ -2353,6 +2353,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||||
std::map<AstNode*, AstPin*> m_usedPins; // Pin used in this cell, map to duplicate
|
std::map<AstNode*, AstPin*> m_usedPins; // Pin used in this cell, map to duplicate
|
||||||
std::map<std::string, AstNodeModule*> m_modulesToRevisit; // Modules to revisit a second time
|
std::map<std::string, AstNodeModule*> m_modulesToRevisit; // Modules to revisit a second time
|
||||||
AstNode* m_lastDeferredp = nullptr; // Last node which requested a revisit of its module
|
AstNode* m_lastDeferredp = nullptr; // Last node which requested a revisit of its module
|
||||||
|
bool m_maybePackedArray
|
||||||
|
= false; // Array select parse trees may actually be packed array datatypes
|
||||||
|
AstNodeDType* m_packedArrayDtp = nullptr; // Datatype reference for packed array
|
||||||
|
|
||||||
struct DotStates final {
|
struct DotStates final {
|
||||||
DotPosition m_dotPos; // Scope part of dotted resolution
|
DotPosition m_dotPos; // Scope part of dotted resolution
|
||||||
|
@ -3401,8 +3404,12 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
|
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
|
||||||
refp->typedefp(defp);
|
refp->typedefp(defp);
|
||||||
replaceWithCheckBreak(nodep, refp);
|
if (m_maybePackedArray) {
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
m_packedArrayDtp = refp;
|
||||||
|
} else {
|
||||||
|
replaceWithCheckBreak(nodep, refp);
|
||||||
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (AstParamTypeDType* const defp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
} else if (AstParamTypeDType* const defp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
||||||
ok = (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE);
|
ok = (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE);
|
||||||
|
@ -4048,22 +4055,48 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||||
m_ds.m_dotErr = true;
|
m_ds.m_dotErr = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iterateAndNextNull(nodep->fromp());
|
AstNodeDType* packedArrayDtp = nullptr; // Datatype reference for packed array
|
||||||
symIterateNull(nodep->rhsp(), m_curSymp);
|
{
|
||||||
symIterateNull(nodep->thsp(), m_curSymp);
|
VL_RESTORER(m_packedArrayDtp);
|
||||||
|
{
|
||||||
|
VL_RESTORER(m_maybePackedArray);
|
||||||
|
m_maybePackedArray = true;
|
||||||
|
iterateAndNextNull(nodep->fromp());
|
||||||
|
}
|
||||||
|
symIterateNull(nodep->rhsp(), m_curSymp);
|
||||||
|
symIterateNull(nodep->thsp(), m_curSymp);
|
||||||
|
|
||||||
if (nodep->attrp()) {
|
if (m_packedArrayDtp) {
|
||||||
AstNode* const attrp = nodep->attrp()->unlinkFrBack();
|
AstRange* const newRangep
|
||||||
VL_DO_DANGLING(attrp->deleteTree(), attrp);
|
= new AstRange(nodep->fileline(), nodep->rhsp()->unlinkFrBack(),
|
||||||
}
|
nodep->thsp()->unlinkFrBack());
|
||||||
AstNode* const basefromp = AstArraySel::baseFromp(nodep, false);
|
AstPackArrayDType* newArrayTypep
|
||||||
if (VN_IS(basefromp, Replicate)) {
|
= new AstPackArrayDType(nodep->fileline(), m_packedArrayDtp, newRangep);
|
||||||
// From {...}[...] syntax in IEEE 2017
|
newArrayTypep->childDTypep(m_packedArrayDtp);
|
||||||
if (basefromp) UINFO(9, indent() << " Related node: " << basefromp);
|
newArrayTypep->refDTypep(nullptr);
|
||||||
} else {
|
if (m_maybePackedArray) {
|
||||||
nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE,
|
packedArrayDtp = newArrayTypep;
|
||||||
basefromp->cloneTree(false)});
|
} else {
|
||||||
|
replaceWithCheckBreak(nodep, newArrayTypep);
|
||||||
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nodep->attrp()) {
|
||||||
|
AstNode* const attrp = nodep->attrp()->unlinkFrBack();
|
||||||
|
VL_DO_DANGLING(attrp->deleteTree(), attrp);
|
||||||
|
}
|
||||||
|
AstNode* const basefromp = AstArraySel::baseFromp(nodep, false);
|
||||||
|
if (VN_IS(basefromp, Replicate)) {
|
||||||
|
// From {...}[...] syntax in IEEE 2017
|
||||||
|
if (basefromp) UINFO(9, indent() << " Related node: " << basefromp);
|
||||||
|
} else {
|
||||||
|
nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE,
|
||||||
|
basefromp->cloneTree(false)});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packedArrayDtp) { m_packedArrayDtp = packedArrayDtp; }
|
||||||
}
|
}
|
||||||
void visit(AstMemberSel* nodep) override {
|
void visit(AstMemberSel* nodep) override {
|
||||||
// checkNoDot not appropriate, can be under a dot
|
// checkNoDot not appropriate, can be under a dot
|
||||||
|
|
|
@ -40,6 +40,20 @@ module t();
|
||||||
foo #(.bar (logic [ $bits(qux3) - 1 : 0]))
|
foo #(.bar (logic [ $bits(qux3) - 1 : 0]))
|
||||||
foo_inst3 (.bar_size (bar_size3));
|
foo_inst3 (.bar_size (bar_size3));
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic foo;
|
||||||
|
logic bar;
|
||||||
|
} some_struct_t;
|
||||||
|
int bar_size4;
|
||||||
|
|
||||||
|
foo #(.bar (some_struct_t [7:0]))
|
||||||
|
foo_inst4 (.bar_size (bar_size4));
|
||||||
|
|
||||||
|
int bar_size5;
|
||||||
|
|
||||||
|
foo #(.bar (some_struct_t [2:0] [5:0]))
|
||||||
|
foo_inst5 (.bar_size (bar_size5));
|
||||||
|
|
||||||
localparam bar_bits = 13;
|
localparam bar_bits = 13;
|
||||||
int bar_size_wrapper;
|
int bar_size_wrapper;
|
||||||
|
|
||||||
|
@ -82,6 +96,16 @@ module t();
|
||||||
bar_size3, $bits(qux3));
|
bar_size3, $bits(qux3));
|
||||||
$stop();
|
$stop();
|
||||||
end
|
end
|
||||||
|
if (bar_size4 != $bits(some_struct_t)*8) begin
|
||||||
|
$display("%m: bar_size4 != bits of some_struct_t * 8 (%0d, %0d)",
|
||||||
|
bar_size4, $bits(some_struct_t) * 8);
|
||||||
|
$stop();
|
||||||
|
end
|
||||||
|
if (bar_size5 != $bits(some_struct_t)*3*6) begin
|
||||||
|
$display("%m: bar_size5 != bits of some_struct_t * 3 * 6 (%0d, %0d)",
|
||||||
|
bar_size5, $bits(some_struct_t) * 3 * 6);
|
||||||
|
$stop();
|
||||||
|
end
|
||||||
if (bar_size_wrapper != bar_bits) begin
|
if (bar_size_wrapper != bar_bits) begin
|
||||||
$display("%m: bar_size_wrapper != bar_bits (%0d, %0d)",
|
$display("%m: bar_size_wrapper != bar_bits (%0d, %0d)",
|
||||||
bar_size_wrapper, bar_bits);
|
bar_size_wrapper, bar_bits);
|
||||||
|
|
Loading…
Reference in New Issue