diff --git a/Changes b/Changes index ece562e22..0ced35e20 100644 --- a/Changes +++ b/Changes @@ -19,7 +19,7 @@ Verilator 5.031 devel * Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill] * Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.] * Support `default disable iff` and `$inferred_disable` (#4016). [Srinivasan Venkataramanan] -* Support `pure constraint`. +* Support `extern constraint` and `pure constraint`. * Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). * Add `--no-std-package` as subset-alias of `--no-std` (#5607). * Add `lint_off --contents` in configuration files (#5606). diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index da584d4ef..7dce283ac 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -68,8 +68,6 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode { bool m_taskPublic : 1; // Public task bool m_attrIsolateAssign : 1; // User isolate_assignments attribute bool m_classMethod : 1; // Class method - bool m_externProto : 1; // Extern prototype - bool m_externDef : 1; // Extern definition bool m_prototype : 1; // Just a prototype bool m_dpiExport : 1; // DPI exported bool m_dpiImport : 1; // DPI imported @@ -77,6 +75,8 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode { bool m_dpiOpenChild : 1; // DPI import open array child wrapper bool m_dpiTask : 1; // DPI import task (vs. void function) bool m_isConstructor : 1; // Class constructor + bool m_isExternProto : 1; // Extern prototype + bool m_isExternDef : 1; // Extern definition bool m_isHideLocal : 1; // Verilog local bool m_isHideProtected : 1; // Verilog protected bool m_dpiPure : 1; // DPI import pure (vs. virtual pure) @@ -97,8 +97,6 @@ protected: , m_taskPublic{false} , m_attrIsolateAssign{false} , m_classMethod{false} - , m_externProto{false} - , m_externDef{false} , m_prototype{false} , m_dpiExport{false} , m_dpiImport{false} @@ -106,6 +104,8 @@ protected: , m_dpiOpenChild{false} , m_dpiTask{false} , m_isConstructor{false} + , m_isExternProto{false} + , m_isExternDef{false} , m_isHideLocal{false} , m_isHideProtected{false} , m_dpiPure{false} @@ -144,10 +144,10 @@ public: void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } bool classMethod() const { return m_classMethod; } void classMethod(bool flag) { m_classMethod = flag; } - bool isExternProto() const { return m_externProto; } - void isExternProto(bool flag) { m_externProto = flag; } - bool isExternDef() const { return m_externDef; } - void isExternDef(bool flag) { m_externDef = flag; } + bool isExternProto() const { return m_isExternProto; } + void isExternProto(bool flag) { m_isExternProto = flag; } + bool isExternDef() const { return m_isExternDef; } + void isExternDef(bool flag) { m_isExternDef = flag; } bool prototype() const { return m_prototype; } void prototype(bool flag) { m_prototype = flag; } bool dpiExport() const { return m_dpiExport; } @@ -1021,7 +1021,12 @@ public: class AstConstraint final : public AstNode { // Constraint // @astgen op1 := itemsp : List[AstNode] + // @astgen op2 := classOrPackagep : Optional[AstNode] string m_name; // Name of constraint + VBaseOverride m_baseOverride; // BaseOverride (inital/final/extends) + bool m_isExternDef = false; // Extern prototype definition + bool m_isExternExplicit = false; // Explicit prototype declaration (has extern) + bool m_isExternProto = false; // Prototype declaration (implicit or explicit) bool m_isKwdPure = false; // Pure constraint bool m_isStatic = false; // Static constraint public: @@ -1038,6 +1043,14 @@ public: bool isPredictOptimizable() const override { return false; } bool maybePointedTo() const override VL_MT_SAFE { return true; } bool sameNode(const AstNode* /*samep*/) const override { return true; } + void baseOverride(const VBaseOverride& flag) { m_baseOverride = flag; } + VBaseOverride baseOverride() const { return m_baseOverride; } + bool isExternDef() const { return m_isExternDef; } + void isExternDef(bool flag) { m_isExternDef = flag; } + void isExternExplicit(bool flag) { m_isExternExplicit = flag; } + bool isExternExplicit() const { return m_isExternExplicit; } + void isExternProto(bool flag) { m_isExternProto = flag; } + bool isExternProto() const { return m_isExternProto; } void isKwdPure(bool flag) { m_isKwdPure = flag; } bool isKwdPure() const { return m_isKwdPure; } void isStatic(bool flag) { m_isStatic = flag; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 4a4620450..0e1a02143 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -368,12 +368,21 @@ void AstConsQueue::dumpJson(std::ostream& str) const { } void AstConstraint::dump(std::ostream& str) const { this->AstNode::dump(str); + if (isExternDef()) str << " [EXTDEF]"; + if (isExternExplicit()) + str << " [PROTOEXP]"; + else if (isExternProto()) + str << " [PROTO]"; if (isKwdPure()) str << " [KWDPURE]"; if (isStatic()) str << " [STATIC]"; } void AstConstraint::dumpJson(std::ostream& str) const { + dumpJsonBoolFunc(str, isExternDef); + dumpJsonBoolFunc(str, isExternExplicit); + dumpJsonBoolFunc(str, isExternProto); dumpJsonBoolFunc(str, isKwdPure); dumpJsonBoolFunc(str, isStatic); + if (baseOverride().isAny()) dumpJsonStr(str, "baseOverride", baseOverride().ascii()); dumpJsonGen(str); } void AstConstraintExpr::dump(std::ostream& str) const { @@ -1657,9 +1666,11 @@ void AstCellInlineScope::dumpJson(std::ostream& str) const { dumpJsonGen(str); } bool AstClass::isCacheableChild(const AstNode* nodep) { - return (VN_IS(nodep, Var) || VN_IS(nodep, Constraint) || VN_IS(nodep, EnumItemRef) - || (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto()) - || VN_IS(nodep, CFunc)); + return VN_IS(nodep, Var) + || (VN_IS(nodep, Constraint) && !VN_AS(nodep, Constraint)->isExternProto()) + || VN_IS(nodep, EnumItemRef) + || (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto()) + || VN_IS(nodep, CFunc); } AstClass* AstClass::baseMostClassp() { AstClass* basep = this; @@ -2652,6 +2663,8 @@ void AstNodeFTask::dump(std::ostream& str) const { if (dpiImport()) str << " [DPII]"; if (dpiOpenChild()) str << " [DPIOPENCHILD]"; if (dpiOpenParent()) str << " [DPIOPENPARENT]"; + if (isExternDef()) str << " [EXTDEF]"; + if (isExternProto()) str << " [EXTPROTO]"; if (prototype()) str << " [PROTOTYPE]"; if (pureVirtual()) str << " [PUREVIRTUAL]"; if (recursive()) str << " [RECURSIVE]"; @@ -2689,6 +2702,8 @@ void AstNodeFTask::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, dpiImport); dumpJsonBoolFunc(str, dpiOpenChild); dumpJsonBoolFunc(str, dpiOpenParent); + dumpJsonBoolFunc(str, isExternDef); + dumpJsonBoolFunc(str, isExternProto); dumpJsonBoolFunc(str, prototype); dumpJsonBoolFunc(str, recursive); dumpJsonBoolFunc(str, taskPublic); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index a18cc8f39..d0cdc3903 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1207,8 +1207,7 @@ class LinkDotFindVisitor final : public VNVisitor { m_classOrPackagep = VN_AS(m_curSymp->nodep(), Class); } // Create symbol table for the task's vars - const string name - = std::string{nodep->isExternProto() ? "extern " : ""} + nodep->name(); + const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name(); m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_classOrPackagep); m_curSymp->fallbackp(upSymp); // Convert the func's range to the output variable @@ -1299,7 +1298,35 @@ class LinkDotFindVisitor final : public VNVisitor { } void visit(AstConstraint* nodep) override { VL_RESTORER(m_curSymp); - m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_classOrPackagep); + // Change to appropriate package if extern declaration (vs definition) + VSymEnt* upSymp = m_curSymp; + if (nodep->classOrPackagep()) { + AstClassOrPackageRef* const cpackagerefp + = VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef); + if (!cpackagerefp) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: extern constraint definition with class-in-class"); + } else { + if (!cpackagerefp->classOrPackageSkipp()) { + m_statep->resolveClassOrPackage(m_curSymp, cpackagerefp, false, + "External definition :: reference"); + } + AstClass* const classp = VN_CAST(cpackagerefp->classOrPackageSkipp(), Class); + if (!classp) { + nodep->v3error("Extern declaration's scope is not a defined class"); + } else { + m_curSymp = m_statep->getNodeSym(classp); + upSymp = m_curSymp; + // Move it to proper spot under the target class + nodep->unlinkFrBack(); + classp->addStmtsp(nodep); + nodep->classOrPackagep()->unlinkFrBack()->deleteTree(); + } + } + } + // Set the class as package for iteration + const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name(); + m_curSymp = m_statep->insertBlock(upSymp, name, nodep, m_classOrPackagep); iterateChildren(nodep); } void visit(AstVar* nodep) override { @@ -3287,6 +3314,31 @@ class LinkDotResolveVisitor final : public VNVisitor { UINFO(9, indent() << "set sym " << m_ds.ascii() << endl); } } + void visit(AstConstraint* nodep) override { + LINKDOT_VISIT_START(); + UINFO(5, indent() << "visit " << nodep << endl); + checkNoDot(nodep); + if (nodep->isExternDef()) { + if (const VSymEnt* const foundp + = m_curSymp->findIdFallback("extern " + nodep->name())) { + const AstConstraint* const protop = VN_AS(foundp->nodep(), Constraint); + // Copy specifiers. + // External definition cannot have any specifiers, so no value will be overwritten. + nodep->isStatic(protop->isStatic()); + } else { + nodep->v3error("extern not found that declares " + nodep->prettyNameQ()); + } + } + if (nodep->isExternProto()) { + if (!m_curSymp->findIdFallback(nodep->name()) && !nodep->isExternExplicit()) { + nodep->v3error("Definition not found for extern " + nodep->prettyNameQ()); + } + } + VL_RESTORER(m_curSymp); + VL_RESTORER(m_ds); + m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); + iterateChildren(nodep); + } void visit(AstConstraintRef* nodep) override { if (nodep->user3SetOnce()) return; LINKDOT_VISIT_START(); @@ -3819,14 +3871,14 @@ class LinkDotResolveVisitor final : public VNVisitor { if (nodep->isExternDef()) { if (const VSymEnt* const foundp = m_curSymp->findIdFallback("extern " + nodep->name())) { - const AstNodeFTask* const funcProtop = VN_AS(foundp->nodep(), NodeFTask); + const AstNodeFTask* const protop = VN_AS(foundp->nodep(), NodeFTask); // Copy specifiers. // External definition cannot have any specifiers, so no value will be overwritten. - nodep->isHideLocal(funcProtop->isHideLocal()); - nodep->isHideProtected(funcProtop->isHideProtected()); - nodep->isStatic(funcProtop->isStatic()); - nodep->isVirtual(funcProtop->isVirtual()); - nodep->lifetime(funcProtop->lifetime()); + nodep->isHideLocal(protop->isHideLocal()); + nodep->isHideProtected(protop->isHideProtected()); + nodep->isStatic(protop->isStatic()); + nodep->isVirtual(protop->isVirtual()); + nodep->lifetime(protop->lifetime()); } else { nodep->v3error("extern not found that declares " + nodep->prettyNameQ()); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 58af8051c..d6d70fef2 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -72,6 +72,16 @@ class LinkResolveVisitor final : public VNVisitor { m_classp = nodep; iterateChildren(nodep); } + void visit(AstConstraint* nodep) override { + // V3LinkDot moved the isExternDef into the class, the extern proto was + // checked to exist, and now isn't needed + nodep->isExternDef(false); + if (nodep->isExternProto()) { + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + return; + } + iterateChildren(nodep); + } void visit(AstInitialAutomatic* nodep) override { iterateChildren(nodep); // Initial assignments under function/tasks can just be simple diff --git a/src/verilog.y b/src/verilog.y index 0b761d24d..ac6b34010 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4181,7 +4181,6 @@ function_subroutine_callNoMethod: // IEEE: function_subroutine // // We implement randomize as a normal funcRef, since randomize isn't a keyword // // Note yNULL is already part of expressions, so they come for free | funcRef yWITH__CUR constraint_block { $$ = new AstWithParse{$2, $1, $3}; } - | funcRef yWITH__CUR '{' '}' { $$ = new AstWithParse{$2, $1, nullptr}; } ; system_t_call: // IEEE: system_tf_call (as task) @@ -7418,17 +7417,16 @@ memberQualOne: // IEEE: property_qualifier + me class_constraint: // ==IEEE: class_constraint // // IEEE: constraint_declaration constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew constraint_block - { $$ = $4; $$->isStatic($1); $$->addItemsp($5); SYMP->popScope($$); } - | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew '{' '}' - { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } + { $$ = $4; $$->isStatic($1); $$->baseOverride($3); $$->addItemsp($5); SYMP->popScope($$); } // // IEEE: constraint_prototype + constraint_prototype_qualifier | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';' - { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } - | yEXTERN constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $4; $$->isStatic($1); SYMP->popScope($4); - BBUNSUP($1, "Unsupported: extern constraint"); } + { $$ = $4; $$->isStatic($1); $$->baseOverride($3); + $$->isExternProto(true); SYMP->popScope($$); } + | yEXTERN constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';' + { $$ = $5; $$->isStatic($2); $$->baseOverride($4); + $$->isExternProto(true); $$->isExternExplicit(true); SYMP->popScope($$); } | yPURE constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $4; $$->isKwdPure($1); $$->isStatic($1); SYMP->popScope($4); } + { $$ = $4; $$->isKwdPure($1); $$->isStatic($2); SYMP->popScope($4); } ; constraintIdNew: // IEEE: id part of class_constraint @@ -7438,7 +7436,8 @@ constraintIdNew: // IEEE: id part of class_constraint ; constraint_block: // ==IEEE: constraint_block - '{' constraint_block_itemList '}' { $$ = $2; } + '{' '}' { $$ = nullptr; } + | '{' constraint_block_itemList '}' { $$ = $2; } // | '{' error '}' { $$ = nullptr; } | '{' constraint_block_itemList error '}' { $$ = $2; } @@ -7529,9 +7528,10 @@ dist_item: // ==IEEE: dist_item + dist_weight $$ = nullptr; } ; -extern_constraint_declaration: // ==IEEE: extern_constraint_declaration - constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE idAny constraint_block - { $$ = nullptr; BBUNSUP($2, "Unsupported: extern constraint"); } +extern_constraint_declaration: // ==IEEE: extern_constraint_declaration + constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE constraintIdNew constraint_block + { $$ = $5; $$->isStatic($1); $$->isExternDef(true); + $$->baseOverride($3); $$->classOrPackagep($4); $$->addItemsp($6); SYMP->popScope($5); } ; constraintStaticE: // IEEE: part of extern_constraint_declaration diff --git a/test_regress/t/t_constraint.v b/test_regress/t/t_constraint.v index dd700f2d9..b30f4847a 100644 --- a/test_regress/t/t_constraint.v +++ b/test_regress/t/t_constraint.v @@ -9,6 +9,8 @@ class Packet; constraint a { one > 0 && one < 2; } + constraint empty { } + endclass module t (/*AUTOARG*/); diff --git a/test_regress/t/t_constraint_extern.py b/test_regress/t/t_constraint_extern.py new file mode 100755 index 000000000..dbae8a1dc --- /dev/null +++ b/test_regress/t/t_constraint_extern.py @@ -0,0 +1,21 @@ +#!/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') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile(verilator_flags2=['-Wno-CONSTRAINTIGN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_extern.v b/test_regress/t/t_constraint_extern.v new file mode 100644 index 000000000..8a7f4602c --- /dev/null +++ b/test_regress/t/t_constraint_extern.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Packet; + rand int one; + rand int two; + + extern function void f(); + constraint cone; + extern constraint ctwo; + extern constraint cmissing; // Ok per IEEE 1800-2023 18.5.1 + +endclass + +constraint Packet::cone { one > 0 && one < 2; } + +constraint Packet::ctwo { two > 1 && two < 3; } + +function void Packet::f(); +endfunction + +module t (/*AUTOARG*/); + + Packet p; + + int v; + + initial begin + p = new; + v = p.randomize(); + if (v != 1) $stop; + if (p.one != 1) $stop; + if (p.two != 2) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_constraint_extern_bad.out b/test_regress/t/t_constraint_extern_bad.out new file mode 100644 index 000000000..da6dfe795 --- /dev/null +++ b/test_regress/t/t_constraint_extern_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_extern_bad.v:8:15: Definition not found for extern 'missing_bad' + 8 | constraint missing_bad; + | ^~~~~~~~~~~ +%Error: t/t_constraint_extern_bad.v:11:20: extern not found that declares 'missing_extern' + 11 | constraint Packet::missing_extern { } + | ^~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_extern.py b/test_regress/t/t_constraint_extern_bad.py similarity index 81% rename from test_regress/t/t_randomize_extern.py rename to test_regress/t/t_constraint_extern_bad.py index e33e10acf..30c3d4f77 100755 --- a/test_regress/t/t_randomize_extern.py +++ b/test_regress/t/t_constraint_extern_bad.py @@ -9,8 +9,8 @@ import vltest_bootstrap -test.scenarios('vlt') +test.scenarios('linter') -test.lint(fails=True, expect_filename=test.golden_filename) +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) test.passes() diff --git a/test_regress/t/t_constraint_extern_bad.v b/test_regress/t/t_constraint_extern_bad.v new file mode 100644 index 000000000..ebeab9acf --- /dev/null +++ b/test_regress/t/t_constraint_extern_bad.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Packet; + constraint missing_bad; +endclass + +constraint Packet::missing_extern { } + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_constraint_json_only.out b/test_regress/t/t_constraint_json_only.out index ae7c64ed3..a146d88be 100644 --- a/test_regress/t/t_constraint_json_only.out +++ b/test_regress/t/t_constraint_json_only.out @@ -27,7 +27,7 @@ {"type":"VAR","name":"if_state_ok","addr":"(W)","loc":"d,13:13,13:24","dtypep":"(U)","origName":"if_state_ok","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"array","addr":"(X)","loc":"d,15:13,15:18","dtypep":"(Y)","origName":"array","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"state","addr":"(Z)","loc":"d,17:11,17:16","dtypep":"(M)","origName":"state","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal", + {"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal", "fvarp": [ {"type":"VAR","name":"strings_equal","addr":"(BB)","loc":"d,61:17,61:30","dtypep":"(U)","origName":"strings_equal","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"classOrPackagep": [], @@ -48,7 +48,7 @@ {"type":"VARREF","name":"strings_equal","addr":"(JB)","loc":"d,62:7,62:13","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": []} ],"scopeNamep": []}, - {"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []}, + {"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []}, {"type":"VAR","name":"constraint","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","origName":"constraint","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": [],"extendsp": []} ],"activesp": []} diff --git a/test_regress/t/t_constraint_nosolver_bad.out b/test_regress/t/t_constraint_nosolver_bad.out index 9b379f091..2f4435757 100644 --- a/test_regress/t/t_constraint_nosolver_bad.out +++ b/test_regress/t/t_constraint_nosolver_bad.out @@ -3,5 +3,5 @@ Process::open: execvp(someimaginarysolver): No such file or directory %Warning: Unable to communicate with SAT solver, please check its installation or specify a different one in VERILATOR_SOLVER environment variable. ... Tried: $ someimaginarysolver -%Error: t/t_constraint.v:23: Verilog $stop +%Error: t/t_constraint.v:25: Verilog $stop Aborting... diff --git a/test_regress/t/t_json_only_tag.out b/test_regress/t/t_json_only_tag.out index af48c3d40..cb03e77cd 100644 --- a/test_regress/t/t_json_only_tag.out +++ b/test_regress/t/t_json_only_tag.out @@ -17,7 +17,7 @@ "lhsp": [ {"type":"VARREF","name":"dotted","addr":"(X)","loc":"d,33:16,33:22","dtypep":"(S)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": [],"strengthSpecp": []}, - {"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f", + {"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f", "fvarp": [ {"type":"VAR","name":"f","addr":"(Z)","loc":"d,35:13,35:14","dtypep":"(G)","origName":"f","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"classOrPackagep": [], diff --git a/test_regress/t/t_randomize_extern.out b/test_regress/t/t_randomize_extern.out deleted file mode 100644 index 91ae91a9d..000000000 --- a/test_regress/t/t_randomize_extern.out +++ /dev/null @@ -1,8 +0,0 @@ -%Error-UNSUPPORTED: t/t_randomize_extern.v:17:4: Unsupported: extern constraint - 17 | extern constraint ex; - | ^~~~~~ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_randomize_extern.v:21:1: Unsupported: extern constraint - 21 | constraint Packet::ex { header == 2; } - | ^~~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_randomize_extern.v b/test_regress/t/t_randomize_extern.v deleted file mode 100644 index cc74f0323..000000000 --- a/test_regress/t/t_randomize_extern.v +++ /dev/null @@ -1,42 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2020 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -class Base; - pure constraint pur; -endclass - -class Packet extends Base; - rand int header; - rand int length; - - constraint pur { length == 3; } - - extern constraint ex; - -endclass - -constraint Packet::ex { header == 2; } - -module t (/*AUTOARG*/); - - Packet p; - - initial begin - - int v; - v = p.randomize(); - if (v != 1) $stop; - if (p.header != 2) $stop; - if (p.length != 3) $stop; - v = p.randomize(1); - if (v != 1) $stop; - if (p.header != 2) $stop; - if (p.length != 3) $stop; - - $write("*-* All Finished *-*\n"); - $finish; - end -endmodule