Fixes #7663.
This commit is contained in:
parent
f316ec0d66
commit
38895f8f29
|
|
@ -110,6 +110,8 @@ Ilya Barkov
|
||||||
Iru Cai
|
Iru Cai
|
||||||
Ivan Vnučec
|
Ivan Vnučec
|
||||||
Iztok Jeras
|
Iztok Jeras
|
||||||
|
JAEUK LEE
|
||||||
|
Jaeuk Lee (이재욱)
|
||||||
Jake Merdich
|
Jake Merdich
|
||||||
Jakub Michalski
|
Jakub Michalski
|
||||||
Jakub Wasilewski
|
Jakub Wasilewski
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,12 @@ std::ostream& operator<<(std::ostream& str, const Determ& rhs) {
|
||||||
return str << s_det[rhs];
|
return str << s_det[rhs];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum StreamUse : uint8_t {
|
||||||
|
STREAM_USE_NONE, // Stream concatenation is not allowed in this context
|
||||||
|
STREAM_USE_ASSIGN, // Assignment-like context permits stream concatenation
|
||||||
|
STREAM_USE_CAST, // Explicit cast context permits stream concatenation
|
||||||
|
};
|
||||||
|
|
||||||
#define v3widthWarn(lhs, rhs, msg) \
|
#define v3widthWarn(lhs, rhs, msg) \
|
||||||
v3warnCode(((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \
|
v3warnCode(((lhs) < (rhs) ? V3ErrorCode::WIDTHTRUNC \
|
||||||
: (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \
|
: (lhs) > (rhs) ? V3ErrorCode::WIDTHEXPAND \
|
||||||
|
|
@ -122,21 +128,26 @@ class WidthVP final {
|
||||||
// Parameters to pass down hierarchy with visit functions.
|
// Parameters to pass down hierarchy with visit functions.
|
||||||
AstNodeDType* const m_dtypep; // Parent's data type to resolve to
|
AstNodeDType* const m_dtypep; // Parent's data type to resolve to
|
||||||
const Stage m_stage; // If true, report errors
|
const Stage m_stage; // If true, report errors
|
||||||
|
const StreamUse m_streamUse; // Current expression may be a stream concat
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WidthVP(AstNodeDType* dtypep, Stage stage)
|
WidthVP(AstNodeDType* dtypep, Stage stage, StreamUse streamUse = STREAM_USE_NONE)
|
||||||
: m_dtypep{dtypep}
|
: m_dtypep{dtypep}
|
||||||
, m_stage{stage} {
|
, m_stage{stage}
|
||||||
|
, m_streamUse{streamUse} {
|
||||||
// Prelim doesn't look at assignments, so shouldn't need a dtype,
|
// Prelim doesn't look at assignments, so shouldn't need a dtype,
|
||||||
// however AstPattern uses them
|
// however AstPattern uses them
|
||||||
}
|
}
|
||||||
WidthVP(Determ determ, Stage stage)
|
WidthVP(Determ determ, Stage stage, StreamUse streamUse = STREAM_USE_NONE)
|
||||||
: m_dtypep{nullptr}
|
: m_dtypep{nullptr}
|
||||||
, m_stage{stage} {
|
, m_stage{stage}
|
||||||
|
, m_streamUse{streamUse} {
|
||||||
if (determ != SELF && stage != PRELIM)
|
if (determ != SELF && stage != PRELIM)
|
||||||
v3fatalSrc("Context-determined width request only allowed as prelim step");
|
v3fatalSrc("Context-determined width request only allowed as prelim step");
|
||||||
}
|
}
|
||||||
WidthVP* p() { return this; }
|
WidthVP* p() { return this; }
|
||||||
bool selfDtm() const { return m_dtypep == nullptr; }
|
bool selfDtm() const { return m_dtypep == nullptr; }
|
||||||
|
StreamUse streamUse() const { return m_streamUse; }
|
||||||
AstNodeDType* dtypep() const {
|
AstNodeDType* dtypep() const {
|
||||||
// Detect where overrideDType is probably the intended call
|
// Detect where overrideDType is probably the intended call
|
||||||
UASSERT(m_dtypep, "Width dtype request on self-determined or preliminary VUP");
|
UASSERT(m_dtypep, "Width dtype request on self-determined or preliminary VUP");
|
||||||
|
|
@ -255,6 +266,12 @@ class WidthVisitor final : public VNVisitor {
|
||||||
EXTEND_OFF // No extension
|
EXTEND_OFF // No extension
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static StreamUse streamUseForDeterm(Determ determ) {
|
||||||
|
return determ == ASSIGN ? STREAM_USE_ASSIGN : STREAM_USE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamUse currentStreamUse() const { return m_vup ? m_vup->streamUse() : STREAM_USE_NONE; }
|
||||||
|
|
||||||
static void packIfUnpacked(AstNodeExpr* const nodep) {
|
static void packIfUnpacked(AstNodeExpr* const nodep) {
|
||||||
if (AstUnpackArrayDType* const unpackDTypep = VN_CAST(nodep->dtypep(), UnpackArrayDType)) {
|
if (AstUnpackArrayDType* const unpackDTypep = VN_CAST(nodep->dtypep(), UnpackArrayDType)) {
|
||||||
const int elementsNum = unpackDTypep->arrayUnpackedElements();
|
const int elementsNum = unpackDTypep->arrayUnpackedElements();
|
||||||
|
|
@ -969,6 +986,15 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->dtypeSetInteger();
|
nodep->dtypeSetInteger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool streamImplicitUseAllowed(const AstNodeStream* nodep) const {
|
||||||
|
if (m_streamConcat) return true;
|
||||||
|
if (m_vup && m_vup->streamUse() != STREAM_USE_NONE) return true;
|
||||||
|
|
||||||
|
const AstNode* const backp = nodep->backp();
|
||||||
|
if (!backp) return true; // Error elsewhere
|
||||||
|
|
||||||
|
return VN_IS(backp, NodeAssign);
|
||||||
|
}
|
||||||
void visit(AstNodeStream* nodep) override {
|
void visit(AstNodeStream* nodep) override {
|
||||||
VL_RESTORER(m_streamConcat);
|
VL_RESTORER(m_streamConcat);
|
||||||
// UINFOTREE(1, nodep, "stream-in vup" << m_vup, "stream-in ");
|
// UINFOTREE(1, nodep, "stream-in vup" << m_vup, "stream-in ");
|
||||||
|
|
@ -1002,6 +1028,12 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_vup->final()) {
|
if (m_vup->final()) {
|
||||||
|
if (!streamImplicitUseAllowed(nodep)) {
|
||||||
|
nodep->v3error(
|
||||||
|
"Streaming concatenation cannot be used in an implicitly cast context "
|
||||||
|
"(IEEE 1800-2023 11.4.17)\n"
|
||||||
|
<< nodep->warnMore() << "... Suggest use a cast");
|
||||||
|
}
|
||||||
if (!nodep->dtypep()->widthSized()) {
|
if (!nodep->dtypep()->widthSized()) {
|
||||||
// See also error in V3Number
|
// See also error in V3Number
|
||||||
nodeForUnsizedWarning(nodep)->v3warn(
|
nodeForUnsizedWarning(nodep)->v3warn(
|
||||||
|
|
@ -2071,25 +2103,25 @@ class WidthVisitor final : public VNVisitor {
|
||||||
void visit(AstCvtPackString* nodep) override {
|
void visit(AstCvtPackString* nodep) override {
|
||||||
if (nodep->didWidthAndSet()) return;
|
if (nodep->didWidthAndSet()) return;
|
||||||
// Opaque returns, so arbitrary
|
// Opaque returns, so arbitrary
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, BOTH, currentStreamUse()}.p());
|
||||||
// Type set in constructor
|
// Type set in constructor
|
||||||
}
|
}
|
||||||
void visit(AstCvtPackedToArray* nodep) override {
|
void visit(AstCvtPackedToArray* nodep) override {
|
||||||
if (nodep->didWidthAndSet()) return;
|
if (nodep->didWidthAndSet()) return;
|
||||||
// Opaque returns, so arbitrary
|
// Opaque returns, so arbitrary
|
||||||
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH, currentStreamUse()}.p());
|
||||||
// Type set in constructor
|
// Type set in constructor
|
||||||
}
|
}
|
||||||
void visit(AstCvtArrayToArray* nodep) override {
|
void visit(AstCvtArrayToArray* nodep) override {
|
||||||
if (nodep->didWidthAndSet()) return;
|
if (nodep->didWidthAndSet()) return;
|
||||||
// Opaque returns, so arbitrary
|
// Opaque returns, so arbitrary
|
||||||
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH, currentStreamUse()}.p());
|
||||||
// Type set in constructor
|
// Type set in constructor
|
||||||
}
|
}
|
||||||
void visit(AstCvtArrayToPacked* nodep) override {
|
void visit(AstCvtArrayToPacked* nodep) override {
|
||||||
if (nodep->didWidthAndSet()) return;
|
if (nodep->didWidthAndSet()) return;
|
||||||
// Opaque returns, so arbitrary
|
// Opaque returns, so arbitrary
|
||||||
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH}.p());
|
userIterateAndNext(nodep->fromp(), WidthVP{SELF, BOTH, currentStreamUse()}.p());
|
||||||
// Type set in constructor
|
// Type set in constructor
|
||||||
}
|
}
|
||||||
void visit(AstCvtUnpackedToQueue* nodep) override {
|
void visit(AstCvtUnpackedToQueue* nodep) override {
|
||||||
|
|
@ -2712,7 +2744,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
VL_DO_DANGLING(fromp->deleteTree(), fromp);
|
VL_DO_DANGLING(fromp->deleteTree(), fromp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
userIterateAndNext(nodep->fromp(), WidthVP{SELF, PRELIM}.p());
|
userIterateAndNext(nodep->fromp(), WidthVP{SELF, PRELIM, STREAM_USE_CAST}.p());
|
||||||
UINFOTREE(9, nodep, "", "CastDit");
|
UINFOTREE(9, nodep, "", "CastDit");
|
||||||
AstNodeDType* const toDtp = nodep->dtypep()->skipRefToEnump();
|
AstNodeDType* const toDtp = nodep->dtypep()->skipRefToEnump();
|
||||||
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
AstNodeDType* const fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||||
|
|
@ -2815,7 +2847,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
if (m_vup->final()) {
|
if (m_vup->final()) {
|
||||||
UINFOTREE(9, nodep, "", "CastFPit");
|
UINFOTREE(9, nodep, "", "CastFPit");
|
||||||
iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(),
|
iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(),
|
||||||
EXTEND_EXP, false);
|
EXTEND_EXP, false, STREAM_USE_CAST);
|
||||||
UINFOTREE(9, nodep, "", "CastFin");
|
UINFOTREE(9, nodep, "", "CastFin");
|
||||||
AstNodeExpr* const underp = nodep->fromp()->unlinkFrBack();
|
AstNodeExpr* const underp = nodep->fromp()->unlinkFrBack();
|
||||||
underp->dtypeFrom(nodep);
|
underp->dtypeFrom(nodep);
|
||||||
|
|
@ -2838,7 +2870,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->v3error("Size-changing cast to zero or negative size: " << width);
|
nodep->v3error("Size-changing cast to zero or negative size: " << width);
|
||||||
width = 1;
|
width = 1;
|
||||||
}
|
}
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, PRELIM}.p());
|
userIterateAndNext(nodep->lhsp(), WidthVP{SELF, PRELIM, STREAM_USE_CAST}.p());
|
||||||
castSized(nodep, nodep->lhsp(), width); // lhsp may change
|
castSized(nodep, nodep->lhsp(), width); // lhsp may change
|
||||||
}
|
}
|
||||||
if (m_vup->final()) {
|
if (m_vup->final()) {
|
||||||
|
|
@ -2851,7 +2883,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
}
|
}
|
||||||
void visit(AstCastWrap* nodep) override {
|
void visit(AstCastWrap* nodep) override {
|
||||||
// Inserted by V3Width only so we know has been resolved
|
// Inserted by V3Width only so we know has been resolved
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP{nodep->dtypep(), BOTH}.p());
|
userIterateAndNext(nodep->lhsp(), WidthVP{nodep->dtypep(), BOTH, STREAM_USE_CAST}.p());
|
||||||
}
|
}
|
||||||
void castSized(AstNode* nodep, AstNode* underp, int width) {
|
void castSized(AstNode* nodep, AstNode* underp, int width) {
|
||||||
const AstBasicDType* underDtp = VN_CAST(underp->dtypep(), BasicDType);
|
const AstBasicDType* underDtp = VN_CAST(underp->dtypep(), BasicDType);
|
||||||
|
|
@ -2872,7 +2904,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
nodep->dtypep(calcDtp);
|
nodep->dtypep(calcDtp);
|
||||||
// We ignore warnings as that is sort of the point of a cast
|
// We ignore warnings as that is sort of the point of a cast
|
||||||
iterateCheck(nodep, "Cast expr", underp, CONTEXT_DET, FINAL, calcDtp, EXTEND_EXP,
|
iterateCheck(nodep, "Cast expr", underp, CONTEXT_DET, FINAL, calcDtp, EXTEND_EXP,
|
||||||
false);
|
false, STREAM_USE_CAST);
|
||||||
VL_DANGLING(underp);
|
VL_DANGLING(underp);
|
||||||
underp = nodep->op1p(); // Above asserts that op1 was underp pre-relink
|
underp = nodep->op1p(); // Above asserts that op1 was underp pre-relink
|
||||||
}
|
}
|
||||||
|
|
@ -7534,7 +7566,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
// Output args: at return caller = callee, reverse direction.
|
// Output args: at return caller = callee, reverse direction.
|
||||||
checkClassAssign(nodep, "Function Argument", pinp, portDTypep,
|
checkClassAssign(nodep, "Function Argument", pinp, portDTypep,
|
||||||
portp->direction() == VDirection::OUTPUT);
|
portp->direction() == VDirection::OUTPUT);
|
||||||
userIterate(pinp, WidthVP{portDTypep, FINAL}.p());
|
userIterate(pinp, WidthVP{portDTypep, FINAL, STREAM_USE_ASSIGN}.p());
|
||||||
} else {
|
} else {
|
||||||
iterateCheckAssign(nodep, "Function Argument", pinp, FINAL, portDTypep);
|
iterateCheckAssign(nodep, "Function Argument", pinp, FINAL, portDTypep);
|
||||||
}
|
}
|
||||||
|
|
@ -9203,7 +9235,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
|
|
||||||
AstNode* iterateCheck(AstNode* parentp, const char* side, AstNode* underp, Determ determ,
|
AstNode* iterateCheck(AstNode* parentp, const char* side, AstNode* underp, Determ determ,
|
||||||
Stage stage, AstNodeDType* expDTypep, ExtendRule extendRule,
|
Stage stage, AstNodeDType* expDTypep, ExtendRule extendRule,
|
||||||
bool warnOn = true) {
|
bool warnOn = true, StreamUse streamUse = STREAM_USE_NONE) {
|
||||||
// Perform data type check on underp, which is underneath parentp used for error reporting
|
// Perform data type check on underp, which is underneath parentp used for error reporting
|
||||||
// Returns the new underp
|
// Returns the new underp
|
||||||
// Conversion to/from doubles and integers are before iterating.
|
// Conversion to/from doubles and integers are before iterating.
|
||||||
|
|
@ -9211,30 +9243,37 @@ class WidthVisitor final : public VNVisitor {
|
||||||
UASSERT_OBJ(underp, parentp, "Node has no child");
|
UASSERT_OBJ(underp, parentp, "Node has no child");
|
||||||
UASSERT_OBJ(underp->dtypep(), underp,
|
UASSERT_OBJ(underp->dtypep(), underp,
|
||||||
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||||
|
const StreamUse childStreamUse
|
||||||
|
= streamUse != STREAM_USE_NONE ? streamUse : streamUseForDeterm(determ);
|
||||||
if (VN_IS(underp, NodeDType)) { // Note the node itself, not node's data type
|
if (VN_IS(underp, NodeDType)) { // Note the node itself, not node's data type
|
||||||
// Must be near top of these checks as underp->dtypep() will look normal
|
// Must be near top of these checks as underp->dtypep() will look normal
|
||||||
underp->v3error(ucfirst(parentp->prettyOperatorName())
|
underp->v3error(ucfirst(parentp->prettyOperatorName())
|
||||||
<< " expected non-datatype " << side << " but "
|
<< " expected non-datatype " << side << " but "
|
||||||
<< underp->prettyNameQ() << " is a datatype.");
|
<< underp->prettyNameQ() << " is a datatype.");
|
||||||
} else if (expDTypep == underp->dtypep()) { // Perfect
|
} else if (expDTypep == underp->dtypep()) { // Perfect
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{expDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{expDTypep, FINAL, childStreamUse}.p());
|
||||||
} else if (expDTypep->isDouble() && underp->isDouble()) { // Also good
|
} else if (expDTypep->isDouble() && underp->isDouble()) { // Also good
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{expDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{expDTypep, FINAL, childStreamUse}.p());
|
||||||
} else if (expDTypep->isDouble() && !underp->isDouble()) {
|
} else if (expDTypep->isDouble() && !underp->isDouble()) {
|
||||||
AstNode* const oldp
|
AstNode* const oldp
|
||||||
= underp; // Need FINAL on children; otherwise splice would block it
|
= underp; // Need FINAL on children; otherwise splice would block it
|
||||||
spliceCvtD(VN_AS(underp, NodeExpr));
|
spliceCvtD(VN_AS(underp, NodeExpr));
|
||||||
underp = userIterateSubtreeReturnEdits(oldp, WidthVP{SELF, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
oldp, WidthVP{SELF, FINAL, childStreamUse}.p());
|
||||||
} else if (!expDTypep->isDouble() && underp->isDouble()) {
|
} else if (!expDTypep->isDouble() && underp->isDouble()) {
|
||||||
AstNode* const oldp
|
AstNode* const oldp
|
||||||
= underp; // Need FINAL on children; otherwise splice would block it
|
= underp; // Need FINAL on children; otherwise splice would block it
|
||||||
spliceCvtS(VN_AS(underp, NodeExpr), true, expDTypep->width()); // Round RHS
|
spliceCvtS(VN_AS(underp, NodeExpr), true, expDTypep->width()); // Round RHS
|
||||||
underp = userIterateSubtreeReturnEdits(oldp, WidthVP{SELF, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
oldp, WidthVP{SELF, FINAL, childStreamUse}.p());
|
||||||
} else if (expDTypep->isString() && !underp->dtypep()->isString()) {
|
} else if (expDTypep->isString() && !underp->dtypep()->isString()) {
|
||||||
AstNode* const oldp
|
AstNode* const oldp
|
||||||
= underp; // Need FINAL on children; otherwise splice would block it
|
= underp; // Need FINAL on children; otherwise splice would block it
|
||||||
spliceCvtString(VN_AS(underp, NodeExpr));
|
spliceCvtString(VN_AS(underp, NodeExpr));
|
||||||
underp = userIterateSubtreeReturnEdits(oldp, WidthVP{SELF, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
oldp, WidthVP{SELF, FINAL, childStreamUse}.p());
|
||||||
} else {
|
} else {
|
||||||
const AstBasicDType* const expBasicp = expDTypep->basicp();
|
const AstBasicDType* const expBasicp = expDTypep->basicp();
|
||||||
const AstBasicDType* const underBasicp = underp->dtypep()->basicp();
|
const AstBasicDType* const underBasicp = underp->dtypep()->basicp();
|
||||||
|
|
@ -9262,7 +9301,8 @@ class WidthVisitor final : public VNVisitor {
|
||||||
// is e.g. an ADD, the ADD will auto-adjust to the proper data type
|
// is e.g. an ADD, the ADD will auto-adjust to the proper data type
|
||||||
// or if another operation e.g. ATOI will not.
|
// or if another operation e.g. ATOI will not.
|
||||||
if (determ == SELF) {
|
if (determ == SELF) {
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{SELF, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{SELF, FINAL, childStreamUse}.p());
|
||||||
} else if (determ == ASSIGN) {
|
} else if (determ == ASSIGN) {
|
||||||
// IEEE: Signedness is solely determined by the RHS
|
// IEEE: Signedness is solely determined by the RHS
|
||||||
// (underp), not by the LHS (expDTypep)
|
// (underp), not by the LHS (expDTypep)
|
||||||
|
|
@ -9274,9 +9314,11 @@ class WidthVisitor final : public VNVisitor {
|
||||||
VSigning::fromBool(underp->isSigned()));
|
VSigning::fromBool(underp->isSigned()));
|
||||||
UINFO(9, "Assignment of opposite-signed RHS to LHS: " << parentp);
|
UINFO(9, "Assignment of opposite-signed RHS to LHS: " << parentp);
|
||||||
}
|
}
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{subDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{subDTypep, FINAL, childStreamUse}.p());
|
||||||
} else {
|
} else {
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{subDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{subDTypep, FINAL, childStreamUse}.p());
|
||||||
}
|
}
|
||||||
// Note the check uses the expected size, not the child's subDTypep as we want the
|
// Note the check uses the expected size, not the child's subDTypep as we want the
|
||||||
// child node's width to end up correct for the assignment (etc)
|
// child node's width to end up correct for the assignment (etc)
|
||||||
|
|
@ -9315,11 +9357,13 @@ class WidthVisitor final : public VNVisitor {
|
||||||
<< " interface modport on " << side << " but got "
|
<< " interface modport on " << side << " but got "
|
||||||
<< underIfaceRefp->modportp()->prettyNameQ() << " modport.");
|
<< underIfaceRefp->modportp()->prettyNameQ() << " modport.");
|
||||||
} else {
|
} else {
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{expDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{expDTypep, FINAL, childStreamUse}.p());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Hope it just works out (perhaps a cast will deal with it)
|
// Hope it just works out (perhaps a cast will deal with it)
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP{expDTypep, FINAL}.p());
|
underp = userIterateSubtreeReturnEdits(
|
||||||
|
underp, WidthVP{expDTypep, FINAL, childStreamUse}.p());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return underp;
|
return underp;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
%Error: t/t_display_stream_bad.v:19:15: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
19 | result = {<<{value}} + 1;
|
||||||
|
| ^~
|
||||||
|
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||||
|
%Error: t/t_display_stream_bad.v:20:23: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
20 | result = value + {<<{value}};
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:21:26: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
21 | result = value[0] ? {<<{value}} : other;
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:22:16: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
22 | result = {{<<{value}}};
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:23:14: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
23 | flag = ({<<{value}} == other);
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:24:15: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
24 | $display({<<{value}});
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:25:22: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
25 | $display("%0d", {<<{value}});
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:26:29: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
26 | void'($sformatf("%0d", {<<{value}}));
|
||||||
|
| ^~
|
||||||
|
%Error: t/t_display_stream_bad.v:27:27: Streaming concatenation cannot be used in an implicitly cast context (IEEE 1800-2023 11.4.17)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
: ... Suggest use a cast
|
||||||
|
27 | result = passthrough({<<{value}} + 1);
|
||||||
|
| ^~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
int value = 1;
|
||||||
|
int other = 2;
|
||||||
|
int result;
|
||||||
|
bit flag;
|
||||||
|
|
||||||
|
function automatic int passthrough(input int arg);
|
||||||
|
return arg;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
result = passthrough({<<{value}});
|
||||||
|
result = {<<{value}} + 1;
|
||||||
|
result = value + {<<{value}};
|
||||||
|
result = value[0] ? {<<{value}} : other;
|
||||||
|
result = {{<<{value}}};
|
||||||
|
flag = ({<<{value}} == other);
|
||||||
|
$display({<<{value}});
|
||||||
|
$display("%0d", {<<{value}});
|
||||||
|
void'($sformatf("%0d", {<<{value}}));
|
||||||
|
result = passthrough({<<{value}} + 1);
|
||||||
|
result = int'({<<{value}});
|
||||||
|
result = int'({<<{value}}) + 1;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -6,6 +6,13 @@
|
||||||
|
|
||||||
`define stop $stop
|
`define stop $stop
|
||||||
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%h' exp='%h'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%h' exp='%h'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||||
|
`define checks_w(width,gotv,expv) do begin \
|
||||||
|
logic [(width)-1:0] got_check; \
|
||||||
|
logic [(width)-1:0] exp_check; \
|
||||||
|
got_check = (gotv); \
|
||||||
|
exp_check = (expv); \
|
||||||
|
`checks(got_check, exp_check) \
|
||||||
|
end while(0);
|
||||||
module t;
|
module t;
|
||||||
|
|
||||||
logic [7:0] i_char;
|
logic [7:0] i_char;
|
||||||
|
|
@ -69,8 +76,8 @@ module t;
|
||||||
byte_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = byte_pkt;
|
{<<8{o_header,o_len,o_crc,o_data}} = byte_pkt;
|
||||||
|
|
||||||
`checks({>>{byte_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({i_header,i_len,i_crc,i_data},{<<8{byte_pkt}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{<<8{byte_pkt}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
// //----------- SData QUEUE --------
|
// //----------- SData QUEUE --------
|
||||||
|
|
@ -95,7 +102,7 @@ module t;
|
||||||
sdata_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
sdata_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = sdata_pkt;
|
{<<8{o_header,o_len,o_crc,o_data}} = sdata_pkt;
|
||||||
|
|
||||||
`checks({>>{sdata_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{sdata_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- IData QUEUE --------
|
//----------- IData QUEUE --------
|
||||||
|
|
@ -111,7 +118,7 @@ module t;
|
||||||
int_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
int_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = int_pkt;
|
{<<8{o_header,o_len,o_crc,o_data}} = int_pkt;
|
||||||
|
|
||||||
`checks({>>{int_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- QData QUEUE --------
|
//----------- QData QUEUE --------
|
||||||
|
|
@ -130,7 +137,7 @@ module t;
|
||||||
qdata_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = qdata_pkt;
|
{<<8{o_header,o_len,o_crc,o_data}} = qdata_pkt;
|
||||||
|
|
||||||
`checks({>>{qdata_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
// ----------- VLWide QUEUE --------
|
// ----------- VLWide QUEUE --------
|
||||||
|
|
@ -143,7 +150,7 @@ module t;
|
||||||
|
|
||||||
/* verilator lint_off WIDTHEXPAND */
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
wide129 = {<<8{i_header,i_len,i_crc,i_data}};
|
wide129 = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
`checks({>>{vlwide_pkt_129}},wide129);
|
`checks_w(129, {>>{vlwide_pkt_129}},wide129);
|
||||||
/* verilator lint_on WIDTHEXPAND */
|
/* verilator lint_on WIDTHEXPAND */
|
||||||
|
|
||||||
//------------------------------- REVERSE ENDIAN ------------------------------
|
//------------------------------- REVERSE ENDIAN ------------------------------
|
||||||
|
|
@ -167,8 +174,8 @@ module t;
|
||||||
byte_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
byte_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = byte_pkt_rev;
|
{<<8{o_header,o_len,o_crc,o_data}} = byte_pkt_rev;
|
||||||
|
|
||||||
`checks({>>{byte_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({i_header,i_len,i_crc,i_data},{<<8{byte_pkt_rev}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{<<8{byte_pkt_rev}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- SData QUEUE --------
|
//----------- SData QUEUE --------
|
||||||
|
|
@ -188,7 +195,7 @@ module t;
|
||||||
sdata_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
sdata_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = sdata_pkt_rev;
|
{<<8{o_header,o_len,o_crc,o_data}} = sdata_pkt_rev;
|
||||||
|
|
||||||
`checks({>>{sdata_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{sdata_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- IData QUEUE --------
|
//----------- IData QUEUE --------
|
||||||
|
|
@ -204,7 +211,7 @@ module t;
|
||||||
int_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
int_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = int_pkt_rev;
|
{<<8{o_header,o_len,o_crc,o_data}} = int_pkt_rev;
|
||||||
|
|
||||||
`checks({>>{int_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- QData QUEUE --------
|
//----------- QData QUEUE --------
|
||||||
|
|
@ -218,7 +225,7 @@ module t;
|
||||||
qdata_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
qdata_pkt_rev = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
{<<8{o_header,o_len,o_crc,o_data}} = qdata_pkt_rev;
|
{<<8{o_header,o_len,o_crc,o_data}} = qdata_pkt_rev;
|
||||||
|
|
||||||
`checks({>>{qdata_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt_rev}},{<<8{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
// ----------- VLWide QUEUE --------
|
// ----------- VLWide QUEUE --------
|
||||||
|
|
@ -227,7 +234,7 @@ module t;
|
||||||
/* verilator lint_off WIDTHEXPAND */
|
/* verilator lint_off WIDTHEXPAND */
|
||||||
wide129 = {<<8{i_header,i_len,i_crc,i_data}};
|
wide129 = {<<8{i_header,i_len,i_crc,i_data}};
|
||||||
/* verilator lint_on WIDTHEXPAND */
|
/* verilator lint_on WIDTHEXPAND */
|
||||||
`checks({>>{vlwide_pkt_129_rev}},wide129);
|
`checks_w(129, {>>{vlwide_pkt_129_rev}},wide129);
|
||||||
|
|
||||||
// // -------------------- STREAMR ------------------------------------
|
// // -------------------- STREAMR ------------------------------------
|
||||||
// //----------- CData QUEUE --------
|
// //----------- CData QUEUE --------
|
||||||
|
|
@ -237,21 +244,21 @@ module t;
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len}};
|
byte_pkt = {>>{i_header,i_len}};
|
||||||
{>>{o_header,o_len}} = byte_pkt;
|
{>>{o_header,o_len}} = byte_pkt;
|
||||||
`checks({>>{i_header,i_len}},{>>{o_header,o_len}});
|
`checks_w(64, {>>{i_header,i_len}},{>>{o_header,o_len}});
|
||||||
`checks({i_header,i_len},{o_header,o_len});
|
`checks({i_header,i_len},{o_header,o_len});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
{>>{o_header,o_len,o_crc,o_data}} = byte_pkt;
|
{>>{o_header,o_len,o_crc,o_data}} = byte_pkt;
|
||||||
|
|
||||||
`checks({>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- IData QUEUE --------
|
//----------- IData QUEUE --------
|
||||||
int_pkt = {>>{i_header}};
|
int_pkt = {>>{i_header}};
|
||||||
o_header = {>>{int_pkt}};
|
o_header = {>>{int_pkt}};
|
||||||
`checks(o_header,i_header);
|
`checks(o_header,i_header);
|
||||||
`checks(o_header,{>>{int_pkt}});
|
`checks_w(32, o_header,{>>{int_pkt}});
|
||||||
`checks({>>{o_header}},{>>{int_pkt}});
|
`checks_w(32, {>>{o_header}},{>>{int_pkt}});
|
||||||
|
|
||||||
//test with QData
|
//test with QData
|
||||||
int_pkt = {>>{i_header,i_len}};
|
int_pkt = {>>{i_header,i_len}};
|
||||||
|
|
@ -261,7 +268,7 @@ module t;
|
||||||
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
{>>{o_header,o_len,o_crc,o_data}} = int_pkt;
|
{>>{o_header,o_len,o_crc,o_data}} = int_pkt;
|
||||||
|
|
||||||
`checks({>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//----------- QData QUEUE --------
|
//----------- QData QUEUE --------
|
||||||
|
|
@ -274,7 +281,7 @@ module t;
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
{>>{o_header,o_len,o_crc,o_data}} = qdata_pkt;
|
{>>{o_header,o_len,o_crc,o_data}} = qdata_pkt;
|
||||||
|
|
||||||
`checks({>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
// ----------- VLWide QUEUE --------
|
// ----------- VLWide QUEUE --------
|
||||||
|
|
@ -288,84 +295,84 @@ module t;
|
||||||
vlwide_pkt_129 = {>>{i_header,i_len,i_crc,i_data}};
|
vlwide_pkt_129 = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
{>>{o_header,o_len,o_crc,o_data}} = vlwide_pkt_129;
|
{>>{o_header,o_len,o_crc,o_data}} = vlwide_pkt_129;
|
||||||
|
|
||||||
`checks({>>{vlwide_pkt_129}},{>>{1'b0,i_header,i_len,i_crc,i_data}});
|
`checks_w(129, {>>{vlwide_pkt_129}},{>>{1'b0,i_header,i_len,i_crc,i_data}});
|
||||||
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
`checks({o_header,o_len,o_crc,o_data} ,{i_header,i_len,i_crc,i_data});
|
||||||
|
|
||||||
//---------- into other queues ------
|
//---------- into other queues ------
|
||||||
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
byte_pkt = {>>{int_pkt}};
|
byte_pkt = {>>{int_pkt}};
|
||||||
`checks({>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
int_pkt = {>>{byte_pkt}};
|
int_pkt = {>>{byte_pkt}};
|
||||||
`checks({>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
int_pkt = {>>{byte_pkt}};
|
int_pkt = {>>{byte_pkt}};
|
||||||
`checks({>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
sdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
sdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
byte_pkt = {>>{sdata_pkt}};
|
byte_pkt = {>>{sdata_pkt}};
|
||||||
`checks({>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
sdata_pkt = {>>{byte_pkt}};
|
sdata_pkt = {>>{byte_pkt}};
|
||||||
`checks({>>{sdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{sdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
qdata_pkt = {>>{byte_pkt}};
|
qdata_pkt = {>>{byte_pkt}};
|
||||||
`checks({>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
byte_pkt = {>>{qdata_pkt}};
|
byte_pkt = {>>{qdata_pkt}};
|
||||||
`checks({>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
int_pkt = {>>{qdata_pkt}};
|
int_pkt = {>>{qdata_pkt}};
|
||||||
`checks({>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
qdata_pkt = {>>{int_pkt}};
|
qdata_pkt = {>>{int_pkt}};
|
||||||
`checks({>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
byte_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
vlwide_pkt_128 = {>>{byte_pkt}};
|
vlwide_pkt_128 = {>>{byte_pkt}};
|
||||||
`checks({>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
byte_pkt = {>>{vlwide_pkt_128}};
|
byte_pkt = {>>{vlwide_pkt_128}};
|
||||||
`checks({i_header,i_len,i_crc,i_data},{>>{byte_pkt}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{>>{byte_pkt}});
|
||||||
`checks({>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{byte_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
int_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
vlwide_pkt_128 = {>>{int_pkt}};
|
vlwide_pkt_128 = {>>{int_pkt}};
|
||||||
`checks({i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
||||||
`checks({>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
int_pkt = {>>{vlwide_pkt_128}};
|
int_pkt = {>>{vlwide_pkt_128}};
|
||||||
`checks({i_header,i_len,i_crc,i_data},{>>{int_pkt}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{>>{int_pkt}});
|
||||||
`checks({>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{int_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
vlwide_pkt_128 = {>>{qdata_pkt}};
|
vlwide_pkt_128 = {>>{qdata_pkt}};
|
||||||
`checks({i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
||||||
`checks({>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data}};
|
||||||
vlwide_pkt_128 = {>>{qdata_pkt}};
|
vlwide_pkt_128 = {>>{qdata_pkt}};
|
||||||
`checks({i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
`checks_w(256, {i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
||||||
`checks({>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data}});
|
`checks_w(256, {>>{vlwide_pkt_128}},{>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc,i_data}});
|
||||||
|
|
||||||
qdata_pkt = {>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc}};
|
qdata_pkt = {>>{i_header,i_len,i_crc,i_data,i_header,i_len,i_crc}};
|
||||||
vlwide_pkt_128 = {>>{qdata_pkt}};
|
vlwide_pkt_128 = {>>{qdata_pkt}};
|
||||||
`checks({32'h0,i_header,i_len,i_crc,i_data,i_header,i_len,i_crc},{>>{vlwide_pkt_128}});
|
`checks_w(256, {32'h0,i_header,i_len,i_crc,i_data,i_header,i_len,i_crc},{>>{vlwide_pkt_128}});
|
||||||
`checks({>>{vlwide_pkt_128}},{>>{32'h0,i_header,i_len,i_crc,i_data,i_header,i_len,i_crc}});
|
`checks_w(256, {>>{vlwide_pkt_128}},{>>{32'h0,i_header,i_len,i_crc,i_data,i_header,i_len,i_crc}});
|
||||||
|
|
||||||
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
vlwide_pkt_128 = {>>{i_header,i_len,i_crc,i_data}};
|
||||||
qdata_pkt = {>>{vlwide_pkt_128}};
|
qdata_pkt = {>>{vlwide_pkt_128}};
|
||||||
`checks({i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
`checks_w(128, {i_header,i_len,i_crc,i_data},{>>{vlwide_pkt_128}});
|
||||||
`checks({>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
`checks_w(128, {>>{qdata_pkt}},{>>{i_header,i_len,i_crc,i_data}});
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,14 @@ module t;
|
||||||
//this will not compile without -fno-life
|
//this will not compile without -fno-life
|
||||||
initial begin
|
initial begin
|
||||||
byte byte_pkt[$];
|
byte byte_pkt[$];
|
||||||
|
byte got_pkt;
|
||||||
//---------------------- STREAM WITH INTERFACE -------------------
|
//---------------------- STREAM WITH INTERFACE -------------------
|
||||||
//using this forces verilator to a AstSel Node into a Stream Node
|
//using this forces verilator to a AstSel Node into a Stream Node
|
||||||
#0 //make sure we dont optimize it all away in v3life
|
#0 //make sure we dont optimize it all away in v3life
|
||||||
pkt_if_init.s.extra = 8'hd;
|
pkt_if_init.s.extra = 8'hd;
|
||||||
byte_pkt = {>>{pkt_if_init.s.extra}};
|
byte_pkt = {>>{pkt_if_init.s.extra}};
|
||||||
if(8'hd == {>>{byte_pkt}}) begin
|
got_pkt = {>>{byte_pkt}};
|
||||||
|
if (8'hd == got_pkt) begin
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish();
|
$finish();
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue