Fix streaming of unpacked arrays concatenations (#5856)
This commit is contained in:
parent
51a97ccb90
commit
9a6598b36f
|
|
@ -198,6 +198,16 @@ class PremitVisitor final : public VNVisitor {
|
||||||
void visit(AstNodeAssign* nodep) override {
|
void visit(AstNodeAssign* nodep) override {
|
||||||
START_STATEMENT_OR_RETURN(nodep);
|
START_STATEMENT_OR_RETURN(nodep);
|
||||||
|
|
||||||
|
if (AstCvtArrayToPacked* const packedp = VN_CAST(nodep->lhsp(), CvtArrayToPacked)) {
|
||||||
|
// AstCvtArrayToPacked is converted to VL_PACK, which returns rvalue,
|
||||||
|
// so it shouldn't be on the LHS. It is now replaced with unpacking of RHS.
|
||||||
|
AstNodeExpr* const exprLhsp = packedp->fromp()->unlinkFrBack();
|
||||||
|
packedp->replaceWith(exprLhsp);
|
||||||
|
VL_DO_DANGLING(pushDeletep(packedp), packedp);
|
||||||
|
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
|
||||||
|
nodep->rhsp(new AstCvtPackedToArray{rhsp->fileline(), rhsp, exprLhsp->dtypep()});
|
||||||
|
nodep->dtypeFrom(exprLhsp);
|
||||||
|
}
|
||||||
// Direct assignment to a simple variable
|
// Direct assignment to a simple variable
|
||||||
if (VN_IS(nodep->lhsp(), VarRef) && !AstVar::scVarRecurse(nodep->lhsp())) {
|
if (VN_IS(nodep->lhsp(), VarRef) && !AstVar::scVarRecurse(nodep->lhsp())) {
|
||||||
AstNode* const rhsp = nodep->rhsp();
|
AstNode* const rhsp = nodep->rhsp();
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
const AstNodeExpr* m_randomizeFromp = nullptr; // Current randomize method call fromp
|
const AstNodeExpr* m_randomizeFromp = nullptr; // Current randomize method call fromp
|
||||||
const bool m_paramsOnly; // Computing parameter value; limit operation
|
const bool m_paramsOnly; // Computing parameter value; limit operation
|
||||||
const bool m_doGenerate; // Do errors later inside generate statement
|
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
|
int m_dtTables = 0; // Number of created data type tables
|
||||||
TableMap m_tableMap; // Created tables so can remove duplicates
|
TableMap m_tableMap; // Created tables so can remove duplicates
|
||||||
std::map<const AstNodeDType*, AstQueueDType*>
|
std::map<const AstNodeDType*, AstQueueDType*>
|
||||||
|
|
@ -238,6 +239,18 @@ class WidthVisitor final : public VNVisitor {
|
||||||
EXTEND_OFF // No extension
|
EXTEND_OFF // No extension
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void packIfUnpacked(AstNodeExpr* const nodep) {
|
||||||
|
if (AstUnpackArrayDType* const unpackDTypep = VN_CAST(nodep->dtypep(), UnpackArrayDType)) {
|
||||||
|
const int elementsNum = unpackDTypep->arrayUnpackedElements();
|
||||||
|
const int unpackMinBits = elementsNum * unpackDTypep->subDTypep()->widthMin();
|
||||||
|
const int unpackBits = elementsNum * unpackDTypep->subDTypep()->width();
|
||||||
|
VNRelinker relinker;
|
||||||
|
nodep->unlinkFrBack(&relinker);
|
||||||
|
relinker.relink(new AstCvtArrayToPacked{
|
||||||
|
nodep->fileline(), nodep,
|
||||||
|
nodep->findLogicDType(unpackBits, unpackMinBits, VSigning::UNSIGNED)});
|
||||||
|
}
|
||||||
|
}
|
||||||
// VISITORS
|
// VISITORS
|
||||||
// Naming: width_O{outputtype}_L{lhstype}_R{rhstype}_W{widthing}_S{signing}
|
// Naming: width_O{outputtype}_L{lhstype}_R{rhstype}_W{widthing}_S{signing}
|
||||||
// Where type:
|
// Where type:
|
||||||
|
|
@ -612,6 +625,11 @@ class WidthVisitor final : public VNVisitor {
|
||||||
} else {
|
} else {
|
||||||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||||
|
|
||||||
|
if (m_streamConcat) {
|
||||||
|
packIfUnpacked(nodep->lhsp());
|
||||||
|
packIfUnpacked(nodep->rhsp());
|
||||||
|
}
|
||||||
nodep->dtypeSetLogicUnsized(nodep->lhsp()->width() + nodep->rhsp()->width(),
|
nodep->dtypeSetLogicUnsized(nodep->lhsp()->width() + nodep->rhsp()->width(),
|
||||||
nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin(),
|
nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin(),
|
||||||
VSigning::UNSIGNED);
|
VSigning::UNSIGNED);
|
||||||
|
|
@ -877,8 +895,11 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(AstNodeStream* nodep) override {
|
void visit(AstNodeStream* nodep) override {
|
||||||
|
VL_RESTORER(m_streamConcat);
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
|
m_streamConcat = true;
|
||||||
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH);
|
||||||
|
m_streamConcat = false;
|
||||||
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH);
|
||||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||||
if (const AstConst* const constp = VN_CAST(nodep->rhsp(), Const)) {
|
if (const AstConst* const constp = VN_CAST(nodep->rhsp(), Const)) {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,12 @@ module t (/*AUTOARG*/);
|
||||||
bit [5:0] bit6 = 6'b111000;
|
bit [5:0] bit6 = 6'b111000;
|
||||||
bit [5:0] ans;
|
bit [5:0] ans;
|
||||||
enum_t ans_enum;
|
enum_t ans_enum;
|
||||||
|
logic [1:0] a [3] = {1, 0, 3};
|
||||||
|
logic [1:0] b [3] = {1, 2, 0};
|
||||||
|
logic c [4] = {1, 1, 0, 0};
|
||||||
|
logic [15:0] d;
|
||||||
|
logic [3:0] e [2];
|
||||||
|
logic f [8];
|
||||||
|
|
||||||
{ >> bit {arr}} = bit6;
|
{ >> bit {arr}} = bit6;
|
||||||
`checkp(arr, "'{'h1, 'h1, 'h1, 'h0, 'h0, 'h0} ");
|
`checkp(arr, "'{'h1, 'h1, 'h1, 'h0, 'h0, 'h0} ");
|
||||||
|
|
@ -76,6 +82,20 @@ module t (/*AUTOARG*/);
|
||||||
ans_enum = enum_t'({ << bit[5:0] {arr6} });
|
ans_enum = enum_t'({ << bit[5:0] {arr6} });
|
||||||
`checkh(ans_enum, bit6);
|
`checkh(ans_enum, bit6);
|
||||||
|
|
||||||
|
d = { >> {a, b, c}};
|
||||||
|
`checkh(d, 16'b0100110110001100);
|
||||||
|
|
||||||
|
{ >> {e, f}} = d;
|
||||||
|
`checkp(e, "'{'h4, 'hd} ");
|
||||||
|
`checkp(f, "'{'h1, 'h0, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0} ");
|
||||||
|
|
||||||
|
d = { << 4 {a, b, c}};
|
||||||
|
`checkh(d, 16'b1100100011010100);
|
||||||
|
|
||||||
|
{ << 2 {e, f}} = d;
|
||||||
|
`checkp(e, "'{'h1, 'h7} ");
|
||||||
|
`checkp(f, "'{'h0, 'h0, 'h1, 'h0, 'h0, 'h0, 'h1, 'h1} ");
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue