Disable symbol from parser: Support redeclaring type as non-type; major parsing change (#2412).
This commit is contained in:
parent
2c465d9741
commit
6bb16d6c52
|
@ -1,11 +0,0 @@
|
|||
.. comment: generated by t_lint_pkgnodecl_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
module t;
|
||||
initial Pkg::hello(); //<--- Warning
|
||||
endmodule
|
||||
package Pkg;
|
||||
function void hello(); endfunction
|
||||
endpackage
|
|
@ -1,4 +0,0 @@
|
|||
.. comment: generated by t_lint_pkgnodecl_bad
|
||||
.. code-block::
|
||||
|
||||
%Error-PKGNODECL: example.v:1:12 Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
|
@ -1401,23 +1401,11 @@ List Of Warnings
|
|||
|
||||
.. option:: PKGNODECL
|
||||
|
||||
An error that a package/class appears to have been referenced that has
|
||||
not yet been declared. According to IEEE 1800-2023 26.3, all packages
|
||||
must be declared before being used.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
|
||||
|
||||
Often the package is declared in its own header file. In this case add
|
||||
an include of that package header file to the referencing file. (And
|
||||
make sure you have header guards in the package's header file to prevent
|
||||
multiple declarations of the package.)
|
||||
|
||||
Never issued since version 5.038. Historically an error that a
|
||||
package/class appears to have been referenced that has not yet been
|
||||
declared. According to IEEE 1800-2023 26.3, all packages must be
|
||||
declared before being used. However, several standard libraries
|
||||
including UVM violate this, and other tools do not warn.
|
||||
|
||||
.. option:: PORTSHORT
|
||||
|
||||
|
|
|
@ -2128,6 +2128,9 @@ protected:
|
|||
|
||||
// Use instead isSame(), this is for each Ast* class, and assumes node is of same type
|
||||
virtual bool sameNode(const AstNode*) const { return true; }
|
||||
// Generated by 'astgen'. If do an oldp->replaceNode(newp), would cause a broken()
|
||||
virtual bool wouldBreakGen(const AstNode* const oldp,
|
||||
const AstNode* const newp) const = 0; // Generated by 'astgen'
|
||||
|
||||
public:
|
||||
// ACCESSORS
|
||||
|
@ -2527,6 +2530,8 @@ public:
|
|||
virtual const char* broken() const { return nullptr; }
|
||||
// Generated by 'astgen'. Calls 'broken()', which can be used to add extra checks
|
||||
virtual const char* brokenGen() const = 0; // Generated by 'astgen'
|
||||
// If do a this->replaceNode(newp), would cause a broken()
|
||||
bool wouldBreak(const AstNode* const newp) const { return backp()->wouldBreakGen(this, newp); }
|
||||
|
||||
// INVOKERS
|
||||
virtual void accept(VNVisitorConst& v) = 0;
|
||||
|
|
|
@ -742,10 +742,10 @@ public:
|
|||
class AstCellRef final : public AstNodeExpr {
|
||||
// As-of-yet unlinkable reference into a cell
|
||||
// @astgen op1 := cellp : AstNode
|
||||
// @astgen op2 := exprp : AstNodeExpr
|
||||
// @astgen op2 := exprp : AstNode<AstNodeExpr|AstNodeDType>
|
||||
string m_name; // Cell name
|
||||
public:
|
||||
AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNodeExpr* exprp)
|
||||
AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp)
|
||||
: ASTGEN_SUPER_CellRef(fl)
|
||||
, m_name{name} {
|
||||
this->cellp(cellp);
|
||||
|
@ -1206,8 +1206,8 @@ public:
|
|||
class AstDot final : public AstNodeExpr {
|
||||
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
||||
// These are eliminated in the link stage
|
||||
// @astgen op1 := lhsp : AstNodeExpr
|
||||
// @astgen op2 := rhsp : AstNodeExpr
|
||||
// @astgen op1 := lhsp : AstNode<AstNodeExpr|AstNodeDType>
|
||||
// @astgen op2 := rhsp : AstNode<AstNodeExpr|AstNodeDType>
|
||||
//
|
||||
// We don't have a list of elements as it's probably legal to do '(foo.bar).(baz.bap)'
|
||||
const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)
|
||||
|
|
|
@ -529,7 +529,10 @@ public:
|
|||
"Unsupported: Interfaced port on top level module");
|
||||
}
|
||||
ifacerefp->v3error("Parent instance's interface is not found: "
|
||||
<< AstNode::prettyNameQ(ifacerefp->ifaceName()));
|
||||
<< AstNode::prettyNameQ(ifacerefp->ifaceName()) << '\n'
|
||||
<< ifacerefp->warnMore()
|
||||
<< "... Perhaps intended an interface instantiation but "
|
||||
"are missing parenthesis (IEEE 1800-2023 25.3)?");
|
||||
} else {
|
||||
ifacerefp->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
|
@ -1550,11 +1553,11 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
if (tdefp && tdefp->name() == nodep->name() && m_statep->forPrimary()) {
|
||||
UINFO(8, "Replacing type of" << nodep << endl
|
||||
<< " with " << tdefp << endl);
|
||||
AstNodeDType* const newType = tdefp->childDTypep();
|
||||
AstNodeDType* const oldType = nodep->childDTypep();
|
||||
AstNodeDType* const newDtp = tdefp->childDTypep();
|
||||
AstNodeDType* const oldDtp = nodep->childDTypep();
|
||||
|
||||
oldType->replaceWith(newType->cloneTree(false));
|
||||
oldType->deleteTree();
|
||||
oldDtp->replaceWith(newDtp->cloneTree(false));
|
||||
oldDtp->deleteTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2477,7 +2480,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
}
|
||||
void checkNoDot(AstNode* nodep) {
|
||||
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
|
||||
// UINFO(9, indent() << "ds=" << m_ds.ascii() << endl);
|
||||
UINFO(9, indent() << "ds=" << m_ds.ascii() << endl);
|
||||
nodep->v3error("Syntax error: Not expecting "
|
||||
<< nodep->type() << " under a " << nodep->backp()->type()
|
||||
<< " in dotted expression\n"
|
||||
|
@ -2608,6 +2611,15 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
symIterateNull(nodep, m_statep->getNodeSym(nodep));
|
||||
}
|
||||
|
||||
void replaceWithCheckBreak(AstNode* oldp, AstNodeDType* newp) {
|
||||
// Flag now to avoid V3Broken throwing an internal error
|
||||
if (oldp->wouldBreak(newp)) {
|
||||
newp->v3error(
|
||||
"Data type used where a non-data type is expected: " << newp->prettyNameQ());
|
||||
}
|
||||
oldp->replaceWith(newp);
|
||||
}
|
||||
|
||||
// Marks the current module to be revisited after the initial AST iteration
|
||||
void revisitLater(AstNode* deferredNodep) {
|
||||
// Need to revisit entire module to build up all the necessary context
|
||||
|
@ -2951,7 +2963,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else { // Dot midpoint
|
||||
AstNodeExpr* newp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* newp = nodep->rhsp()->unlinkFrBack();
|
||||
if (m_ds.m_unresolvedCell) {
|
||||
AstCellRef* const crp = new AstCellRef{
|
||||
nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp};
|
||||
|
@ -3059,7 +3071,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
return;
|
||||
} else if (m_ds.m_dotPos == DP_MEMBER) {
|
||||
// Found a Var, everything following is membership. {scope}.{var}.HERE {member}
|
||||
AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr);
|
||||
AstNodeExpr* const newp
|
||||
= new AstMemberSel{nodep->fileline(), varEtcp, VFlagChildDType{}, nodep->name()};
|
||||
if (m_ds.m_dotErr) {
|
||||
|
@ -3348,6 +3360,14 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
ok = true;
|
||||
m_ds.m_dotPos = DP_MEMBER;
|
||||
m_ds.m_dotText = "";
|
||||
} else if (AstClass* const defp = VN_CAST(foundp->nodep(), Class)) {
|
||||
if (allowVar) {
|
||||
AstRefDType* const newp = new AstRefDType{nodep->fileline(), nodep->name()};
|
||||
replaceWithCheckBreak(nodep, newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
ok = true;
|
||||
m_ds.m_dotText = "";
|
||||
}
|
||||
} else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) {
|
||||
if (allowVar) {
|
||||
AstNode* const newp
|
||||
|
@ -3386,6 +3406,22 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
} else if (AstTypedef* const defp = VN_CAST(foundp->nodep(), Typedef)) {
|
||||
ok = m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE;
|
||||
if (ok) {
|
||||
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
|
||||
refp->typedefp(defp);
|
||||
replaceWithCheckBreak(nodep, refp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
} else if (AstParamTypeDType* const defp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
||||
ok = (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE);
|
||||
if (ok) {
|
||||
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
|
||||
refp->refDTypep(defp);
|
||||
replaceWithCheckBreak(nodep, refp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
if (m_insideClassExtParam) {
|
||||
|
@ -3795,7 +3831,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
|
||||
// Found a Var, everything following is method call.
|
||||
// {scope}.{var}.HERE {method} ( ARGS )
|
||||
AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr);
|
||||
AstNodeExpr* argsp = nullptr;
|
||||
if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
|
||||
AstNode* const newp = new AstMethodCall{nodep->fileline(), varEtcp, VFlagChildDType{},
|
||||
|
@ -4373,7 +4409,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
}
|
||||
VL_DO_DANGLING(cpackagep->unlinkFrBack()->deleteTree(), cpackagep);
|
||||
}
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
if (m_ds.m_dotp && (m_ds.m_dotPos == DP_PACKAGE || m_ds.m_dotPos == DP_SCOPE)) {
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
|
||||
"Bad package link");
|
||||
auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||
|
|
|
@ -196,7 +196,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name,
|
|||
if (GRAMMARP->m_varIO == VDirection::NONE // In non-ANSI port list
|
||||
&& GRAMMARP->m_varDecl == VVarType::PORT) {
|
||||
// Just a port list with variable name (not v2k format); AstPort already created
|
||||
if (dtypep) fileline->v3warn(E_UNSUPPORTED, "Unsupported: Ranges ignored in port-lists");
|
||||
if (arrayp) VL_DO_DANGLING(arrayp->deleteTree(), arrayp);
|
||||
if (attrsp) {
|
||||
// TODO: Merge attributes across list? Or warn attribute is ignored
|
||||
|
|
|
@ -429,6 +429,35 @@ size_t V3ParseImp::tokenPipeScanIdInst(size_t depthIn) {
|
|||
return depth;
|
||||
}
|
||||
|
||||
size_t V3ParseImp::tokenPipeScanIdType(size_t depthIn) {
|
||||
// Search around IEEE data type identifier
|
||||
// Return location of following token, or input if not found
|
||||
// tokenPipeScanIdCell has precedence over this search
|
||||
// yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yaID/*identifier*/
|
||||
// assignment_pattern_expression:
|
||||
// yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yP_TICKBRA
|
||||
// class_type parameter_value_assignment // often followed by ) as in e.g. ClsA#(ClsB#(...))
|
||||
// yaID/*type_identifier*/ '#' '('...')' [^ '::']
|
||||
// and caller must check does NOT match tokenPipeScanIdCell
|
||||
size_t depth = depthIn;
|
||||
// UINFO(9, "tokenPipeScanType START d="
|
||||
// << depth << " " << V3ParseImp::tokenName(tokenPeekp(depth)->token) << endl);
|
||||
if (tokenPeekp(depth)->token == '#' && tokenPeekp(depth + 1)->token == '(') {
|
||||
depth = tokenPipeScanParam(depth, false);
|
||||
// Not :: as then it's a yaID__CC, we'll parse that in tokenPipeScanId
|
||||
if (tokenPeekp(depth)->token != yP_COLONCOLON) return depth;
|
||||
}
|
||||
|
||||
depth = tokenPipeScanBracket(depth); // [ '['..']' ]*
|
||||
|
||||
if (tokenPeekp(depth)->token != yaID__LEX && tokenPeekp(depth)->token != yP_TICKBRA)
|
||||
return depthIn;
|
||||
++depth;
|
||||
// UINFO(9, "tokenPipeScanType MATCH\n");
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
size_t V3ParseImp::tokenPipeScanBracket(size_t inDepth) {
|
||||
// Return location of following token, or input if not found
|
||||
// [ '['...']' ]*
|
||||
|
@ -531,6 +560,7 @@ int V3ParseImp::tokenPipelineId(int token) {
|
|||
if (m_tokenLastBison.token != '@' && m_tokenLastBison.token != '#'
|
||||
&& m_tokenLastBison.token != '.') {
|
||||
if (const size_t depth = tokenPipeScanIdInst(0)) return yaID__aINST;
|
||||
if (const size_t depth = tokenPipeScanIdType(0)) return yaID__aTYPE;
|
||||
}
|
||||
if (nexttok == '#') { // e.g. class_type parameter_value_assignment '::'
|
||||
const size_t depth = tokenPipeScanParam(0, false);
|
||||
|
@ -683,6 +713,8 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp));
|
||||
}
|
||||
if (!foundp && !m_afterColonColon) { // Check if the symbol can be found in std
|
||||
// The following keywords from this file are hardcoded for detection in the parser:
|
||||
// "mailbox", "process", "randomize", "semaphore", "std"
|
||||
AstPackage* const stdpkgp = v3Global.rootp()->stdPackagep();
|
||||
if (stdpkgp) {
|
||||
VSymEnt* const stdsymp = stdpkgp->user4u().toSymEnt();
|
||||
|
@ -694,36 +726,11 @@ void V3ParseImp::tokenPipelineSym() {
|
|||
yylval.scp = scp;
|
||||
UINFO(7, " tokenPipelineSym: Found " << scp << endl);
|
||||
if (token == yaID__LEX) { // i.e. not yaID__CC
|
||||
if (VN_IS(scp, Typedef)) {
|
||||
token = yaID__aTYPE;
|
||||
} else if (VN_IS(scp, TypedefFwd)) {
|
||||
token = yaID__aTYPE;
|
||||
} else if (VN_IS(scp, Class)) {
|
||||
token = yaID__aTYPE;
|
||||
} else if (VN_IS(scp, Package)) {
|
||||
token = yaID__ETC;
|
||||
} else {
|
||||
token = yaID__ETC;
|
||||
}
|
||||
token = yaID__ETC;
|
||||
}
|
||||
} else { // Not found
|
||||
yylval.scp = nullptr;
|
||||
if (token == yaID__CC) {
|
||||
if (!m_afterColonColon && !v3Global.opt.bboxUnsup()) {
|
||||
// IEEE does require this, but we may relax this as UVM breaks it, so allow
|
||||
// bbox for today
|
||||
// We'll get a parser error eventually but might not be obvious
|
||||
// is missing package, and this confuses people
|
||||
static int warned = false;
|
||||
if (!warned++) {
|
||||
yylval.fl->v3warn(PKGNODECL, "Package/class '" + *yylval.strp
|
||||
+ "' not found, and needs to be "
|
||||
"predeclared (IEEE 1800-2023 26.3)");
|
||||
}
|
||||
}
|
||||
} else if (token == yaID__LEX) {
|
||||
token = yaID__ETC;
|
||||
}
|
||||
if (token == yaID__LEX) token = yaID__ETC;
|
||||
}
|
||||
}
|
||||
m_afterColonColon = token == yP_COLONCOLON;
|
||||
|
|
|
@ -316,6 +316,7 @@ private:
|
|||
int tokenPipelineId(int token) VL_MT_DISABLED;
|
||||
void tokenPipelineSym() VL_MT_DISABLED;
|
||||
size_t tokenPipeScanIdInst(size_t depth) VL_MT_DISABLED;
|
||||
size_t tokenPipeScanIdType(size_t depth) VL_MT_DISABLED;
|
||||
size_t tokenPipeScanBracket(size_t depth) VL_MT_DISABLED;
|
||||
size_t tokenPipeScanParam(size_t depth, bool forInst) VL_MT_DISABLED;
|
||||
size_t tokenPipeScanTypeEq(size_t depth) VL_MT_DISABLED;
|
||||
|
|
27
src/astgen
27
src/astgen
|
@ -968,7 +968,31 @@ def write_ast_impl(filename):
|
|||
emitBlock("));\n")
|
||||
# Node's broken rules can be specialized by declaring broken()
|
||||
emitBlock(" return Ast{t}::broken();\n", t=node.name)
|
||||
emitBlock("}}\n", t=node.name)
|
||||
emitBlock("}}\n")
|
||||
|
||||
emitBlock(
|
||||
"bool Ast{t}::wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const {{\n",
|
||||
t=node.name)
|
||||
for i in range(1, 5):
|
||||
op = node.getOp(i)
|
||||
if op is None:
|
||||
continue
|
||||
name, _, _, legals = op
|
||||
if legals != '':
|
||||
# 'this' is a parent, where oldp replacing newp as op1p, must follow op1p's rules
|
||||
# Could also be on a list, we don't check for speed reasons and as V3Broken doesn't
|
||||
emitBlock(" if (oldp == op{i}p() && !(", i=i)
|
||||
eor = ""
|
||||
for legal in legals.split('|'):
|
||||
emitBlock("{eor}privateTypeTest<Ast{legal}>(newp)",
|
||||
eor=eor,
|
||||
name=name,
|
||||
legal=legal)
|
||||
eor = " || "
|
||||
emitBlock(")) return true;\n")
|
||||
# Node's broken rules can be specialized by declaring broken()
|
||||
emitBlock(" return false;\n")
|
||||
emitBlock("}}\n")
|
||||
|
||||
emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name)
|
||||
if node.superClass.name != 'Node':
|
||||
|
@ -1042,6 +1066,7 @@ def write_ast_macros(filename):
|
|||
Ast{t}* clonep() const {{ return static_cast<Ast{t}*>(AstNode::clonep()); }}
|
||||
Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast<Ast{t}*>(AstNode::addNext(this, nodep)); }}
|
||||
const char* brokenGen() const override;
|
||||
bool wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const override;
|
||||
void cloneRelinkGen() override;
|
||||
void dumpTreeJsonOpGen(std::ostream& str, const string& indent) const override;
|
||||
void dumpJsonGen(std::ostream& str) const;
|
||||
|
|
|
@ -1552,15 +1552,11 @@ port<nodep>: // ==IEEE: port
|
|||
// // IEEE: interface_port_header port_identifier { unpacked_dimension }
|
||||
// // Expanded interface_port_header
|
||||
// // We use instantCb here because the non-port form looks just like a module instantiation
|
||||
portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
|
||||
{ // VAR for now, but V3LinkCells may call setIfcaeRef on it later
|
||||
$$ = $3; VARDECL(VAR); VARIO(NONE);
|
||||
// Although know it's an interface, use AstRefDType for forward compatibility
|
||||
// with future parser. V3LinkCells will convert to AstIfaceRefDType.
|
||||
AstNodeDType* const dtp = new AstRefDType{$<fl>2, *$2};
|
||||
VARDTYPE(dtp);
|
||||
addNextNull($$, VARDONEP($$, $4, $5)); }
|
||||
| portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
|
||||
//
|
||||
// // Looks identical to variable_declaration, so V3LinkDot must resolve when ID known
|
||||
// // NO: portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
|
||||
//
|
||||
portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
|
||||
{ // VAR for now, but V3LinkCells may call setIfcaeRef on it later
|
||||
$$ = $5; VARDECL(VAR); VARIO(NONE);
|
||||
AstNodeDType* const dtp = new AstIfaceRefDType{$<fl>2, $<fl>4, "", *$2, *$4};
|
||||
|
@ -1615,17 +1611,20 @@ port<nodep>: // ==IEEE: port
|
|||
// // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr.
|
||||
//
|
||||
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $3; VARDTYPE($2); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); }
|
||||
{ $$ = $3; VARDTYPE($2); VARIOANSI();
|
||||
addNextNull($$, VARDONEP($$, $4, $5)); }
|
||||
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$ = $3; VARDTYPE($2); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } }
|
||||
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
|
||||
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
addNextNull($$, VARDONEP($$, $5, $6)); }
|
||||
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
|
||||
{ $$ = $4; VARDTYPE($3); VARIOANSI();
|
||||
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
|
||||
|
@ -2105,13 +2104,10 @@ port_declaration<nodep>: // ==IEEE: port_declaration
|
|||
//
|
||||
// // IEEE: interface_port_declaration
|
||||
// // IEEE: interface_identifier list_of_interface_identifiers
|
||||
| id/*interface*/
|
||||
/*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF);
|
||||
AstIfaceRefDType* const dtp = new AstIfaceRefDType{$<fl>1, "", *$1};
|
||||
dtp->isPortDecl(true);
|
||||
VARDTYPE(dtp); }
|
||||
/*cont*/ mpInstnameList
|
||||
{ $$ = VARDONEP($3, nullptr, nullptr); }
|
||||
//
|
||||
// // Identical to variable_declaration, resolve in V3LinkDot when id known
|
||||
// // NO: id/*interface*/ mpInstnameList
|
||||
//
|
||||
// // IEEE: interface_port_declaration
|
||||
// // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers
|
||||
| id/*interface*/ '.' idAny/*modport*/
|
||||
|
@ -4585,9 +4581,10 @@ exprOrDataType<nodep>: // expr | data_type: combined to prevent conflic
|
|||
// // data_type includes id that overlaps expr, so special flavor
|
||||
// // data_type expanded:
|
||||
| data_typeNoRef { $$ = $1; }
|
||||
| packageClassScopeE idType packed_dimensionListE
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr};
|
||||
$$ = GRAMMARP->createArray(refp, $3, true); }
|
||||
//
|
||||
// // Conflicts with non-type id, resolved in V3LinkDot
|
||||
// // NO: packageClassScopeE idType packed_dimensionListE
|
||||
//
|
||||
| packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE
|
||||
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
|
||||
$$ = GRAMMARP->createArray(refp, $4, true); }
|
||||
|
@ -5153,8 +5150,8 @@ expr<nodeExprp>: // IEEE: part of expression/constant_expression/
|
|||
{ $$ = new AstCast{$2, $4, VFlagChildDType{}, $1}; }
|
||||
// // expanded from simple_type ps_type_identifier (part of simple_type)
|
||||
// // expanded from simple_type ps_parameter_identifier (part of simple_type)
|
||||
| packageClassScopeE idType yP_TICK '(' expr ')'
|
||||
{ $$ = new AstCastParse{$3, $5, new AstRefDType{$<fl>2, *$2, $1, nullptr}}; }
|
||||
// // Causes conflict, so handled post-parse
|
||||
// // NO: packageClassScopeE idType yP_TICK '(' expr ')'
|
||||
//
|
||||
| yTYPE__ETC '(' exprOrDataType ')' yP_TICK '(' expr ')'
|
||||
{ $$ = new AstCast{$1, $7, VFlagChildDType{},
|
||||
|
|
|
@ -405,11 +405,8 @@
|
|||
%Warning-COVERIGN: t/t_covergroup_unsup.v:164:18: Ignoring unsupported: covergroup within class
|
||||
164 | covergroup cov1 @m_z;
|
||||
| ^~~~
|
||||
%Error: t/t_covergroup_unsup.v:169:28: syntax error, unexpected '=', expecting IDENTIFIER or do or final or randomize
|
||||
%Error: t/t_covergroup_unsup.v:169:23: Can't find definition of variable: 'cov1'
|
||||
169 | function new(); cov1 = new; endfunction
|
||||
| ^
|
||||
| ^~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Internal Error: t/t_covergroup_unsup.v:160:4: ../V3ParseSym.h:#: Symbols suggest ending FUNC 'new' but parser thinks ending CLASS 'CgCls'
|
||||
160 | class CgCls;
|
||||
| ^~~~~
|
||||
... This fatal error may be caused by the earlier error(s); resolve those first.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -53,11 +53,14 @@ for s in [
|
|||
'Illegal +: or -: select; type already selected, or bad dimension: ',
|
||||
'Illegal bit or array select; type already selected, or bad dimension: ',
|
||||
'Illegal range select; type already selected, or bad dimension: ',
|
||||
'Interface port ',
|
||||
'Interface port declaration ',
|
||||
'Modport item is not a function/task: ',
|
||||
'Modport item is not a variable: ',
|
||||
'Modport item not found: ',
|
||||
'Modport not referenced as <interface>.',
|
||||
'Modport not referenced from underneath an interface: ',
|
||||
'Non-interface used as an interface: ',
|
||||
'Parameter type pin value isn\'t a type: Param ',
|
||||
'Parameter type variable isn\'t a type: Param ',
|
||||
'Pattern replication value of 0 is not legal.',
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
%Error: t/t_inst_paren_bad.v:11:4: Non-interface used as an interface: 'sub'
|
||||
: ... Perhaps intended an instantiation but are missing parenthesis (IEEE 1800-2023 23.3.2)?
|
||||
11 | sub sub_inst;
|
||||
| ^~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Warning-MULTITOP: t/t_inst_paren_bad.v:10:8: Multiple top level modules
|
||||
: ... Suggest see manual; fix the duplicates, or use --top-module to select top.
|
||||
... For warning description see https://verilator.org/warn/MULTITOP?v=latest
|
||||
|
@ -13,4 +8,8 @@
|
|||
: ... Top module 't'
|
||||
10 | module t( );
|
||||
| ^
|
||||
%Error: t/t_inst_paren_bad.v:11:4: Can't find typedef/interface: 'sub'
|
||||
11 | sub sub_inst;
|
||||
| ^~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
%Error: t/t_interface_missing_bad.v:14:13: Pin is not an in/out/inout/interface: 'foo'
|
||||
14 | foo_intf foo
|
||||
| ^~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_interface_missing_bad.v:14:4: Can't find typedef/interface: 'foo_intf'
|
||||
14 | foo_intf foo
|
||||
| ^~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_interface_missing_bad.v:20:4: Cannot find file containing interface: 'foo_intf'
|
||||
20 | foo_intf the_foo ();
|
||||
| ^~~~~~~~
|
||||
%Error: t/t_interface_missing_bad.v:25:15: Found definition of 'the_foo' as a CELL but expected a variable
|
||||
25 | .foo (the_foo)
|
||||
| ^~~~~~~
|
||||
%Error: t/t_interface_missing_bad.v:25:10: Instance attempts to connect to 'foo', but it is a variable
|
||||
25 | .foo (the_foo)
|
||||
| ^~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%Error: t/t_interface_paren_missing_bad.v:13:9: Interface port declaration 'intf_i' doesn't have corresponding port
|
||||
%Error: t/t_interface_paren_missing_bad.v:13:4: Parent instance's interface is not found: 'intf'
|
||||
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
|
||||
13 | intf intf_i;
|
||||
| ^~~~~~
|
||||
| ^~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
| ^~~~~~
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: t/t_interface_top_bad.v:17:4: Parent instance's interface is not found: 'ifc'
|
||||
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
|
||||
17 | ifc.counter_mp c_data
|
||||
| ^~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
|
@ -2,8 +2,4 @@
|
|||
46 | typedef ifc_if.struct_t struct_t;
|
||||
| ^~~~~~~
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: t/t_interface_typedef.v:51:16: syntax error, unexpected IDENTIFIER
|
||||
51 | struct_t substruct;
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
%Error: t/t_interface_typo_bad.v:14:4: Parent instance's interface is not found: 'foo_intf'
|
||||
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
|
||||
14 | foo_intf foo
|
||||
| ^~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
%Error: t/t_lint_implicit_type_bad.v:15:11: syntax error, unexpected IDENTIFIER-for-type
|
||||
%Error: t/t_lint_implicit_type_bad.v:15:11: Data type used where a non-data type is expected: 'imp_typedef_conflict'
|
||||
15 | assign imp_typedef_conflict = 1'b1;
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_lint_implicit_type_bad.v:16:11: Data type used where a non-data type is expected: 'imp_Cls_conflict'
|
||||
16 | assign imp_Cls_conflict = 1'b1;
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
%Error: t/t_lint_implicit_type_bad.v:17:11: Data type used where a non-data type is expected: 'imp_PARAM_conflict'
|
||||
17 | assign imp_PARAM_conflict = 1'b1;
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -12,7 +12,7 @@ import vltest_bootstrap
|
|||
test.scenarios('vlt')
|
||||
|
||||
# --debug-check adds extra internal message, otherwise golden log would vary
|
||||
test.lint(verilator_flags2=["--lint-only --debug-check -Wall -Wno-DECLFILENAME"],
|
||||
test.lint(verilator_flags2=["--lint-only --no-debug-check -Wall -Wno-DECLFILENAME"],
|
||||
fails=True,
|
||||
expect_filename=test.golden_filename)
|
||||
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
%Error-PKGNODECL: t/t_lint_import_name2_bad.v:7:8: Package/class 'missing' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
7 | import missing::sigs;
|
||||
| ^~~~~~~
|
||||
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
|
||||
%Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing'
|
||||
7 | import missing::sigs;
|
||||
| ^~~~~~~
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
%Error-PKGNODECL: t/t_lint_pkg_colon_bad.v:7:17: Package/class 'mispkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
7 | module t (input mispkg::foo_t a);
|
||||
| ^~~~~~
|
||||
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
|
||||
%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting IDENTIFIER-for-type
|
||||
7 | module t (input mispkg::foo_t a);
|
||||
| ^~~~~
|
||||
%Error: t/t_lint_pkg_colon_bad.v:8:8: syntax error, unexpected IDENTIFIER-::, expecting IDENTIFIER or do or final or randomize
|
||||
8 | reg mispkgb::bar_t b;
|
||||
| ^~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
%Error-PKGNODECL: t/t_lint_pkgnodecl_bad.v:8:12: Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
8 | initial Pkg::hello();
|
||||
| ^~~
|
||||
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
|
||||
%Error: Exiting due to
|
|
@ -1,29 +0,0 @@
|
|||
#!/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('linter')
|
||||
|
||||
root = ".."
|
||||
|
||||
if not os.path.exists(root + "/.git"):
|
||||
test.skip("Not in a git repository")
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.extract(in_filename=test.top_filename,
|
||||
out_filename=root + "/docs/gen/ex_PKGNODECL_faulty.rst",
|
||||
lines="7-12")
|
||||
|
||||
test.extract(in_filename=test.golden_filename,
|
||||
out_filename=root + "/docs/gen/ex_PKGNODECL_msg.rst",
|
||||
lines="1")
|
||||
|
||||
test.passes()
|
|
@ -1,12 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2012 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
initial Pkg::hello(); //<--- Warning
|
||||
endmodule
|
||||
package Pkg;
|
||||
function void hello(); endfunction
|
||||
endpackage
|
|
@ -1,7 +1,3 @@
|
|||
%Error-PKGNODECL: t/t_no_std_bad.v:9:11: Package/class 'std' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
9 | import std::*;
|
||||
| ^~~
|
||||
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
|
||||
%Error: t/t_no_std_bad.v:9:11: Importing from missing package 'std'
|
||||
9 | import std::*;
|
||||
| ^~~
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
%Error-PKGNODECL: t/t_package_alone_bad.v:7:8: Package/class 'pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
%Error: t/t_package_alone_bad.v:7:13: Export package not found: 'pkg'
|
||||
7 | export pkg::something;
|
||||
| ^~~
|
||||
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
%Error: t/t_parse_sync_bad2.v:17:16: syntax error, unexpected IDENTIFIER
|
||||
17 | Invalid1 invalid1;
|
||||
| ^~~~~~~~
|
||||
%Error: t/t_parse_sync_bad2.v:9:15: Can't find typedef/interface: 'unknown'
|
||||
9 | typedef unknown defu;
|
||||
| ^~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_parse_sync_bad2.v:20:16: syntax error, unexpected IDENTIFIER
|
||||
%Error: t/t_parse_sync_bad2.v:17:7: Can't find typedef/interface: 'Invalid1'
|
||||
17 | Invalid1 invalid1;
|
||||
| ^~~~~~~~
|
||||
%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:18:12: Unsupported: Multiple '::' package/class reference
|
||||
18 | pkg::cls::defi valid1;
|
||||
| ^~~
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: t/t_parse_sync_bad2.v:18:17: Can't find typedef/interface: 'defi'
|
||||
18 | pkg::cls::defi valid1;
|
||||
| ^~~~
|
||||
%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:19:12: Unsupported: Multiple '::' package/class reference
|
||||
19 | pkg::cls::defu valid2;
|
||||
| ^~~
|
||||
%Error: t/t_parse_sync_bad2.v:19:17: Can't find typedef/interface: 'defu'
|
||||
19 | pkg::cls::defu valid2;
|
||||
| ^~~~
|
||||
%Error: t/t_parse_sync_bad2.v:20:7: Can't find typedef/interface: 'Invalid2'
|
||||
20 | Invalid2 invalid2;
|
||||
| ^~~~~~~~
|
||||
| ^~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_pp_circ_subst_bad.v:8:80001: Too many preprocessor tokens on a line (>40000); perhaps recursive `define
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_pp_circ_subst_bad.v:8:40002: Too many preprocessor tokens on a line (>20000); perhaps recursive `define
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER
|
||||
%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
|
||||
%Error: Exiting due to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting IDENTIFIER or randomize
|
||||
%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting '('
|
||||
11 | endmodule
|
||||
| ^~~~~~~~~
|
||||
t/t_preproc_inc_bad.v:10:1: ... note: In file included from 't_preproc_inc_bad.v'
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
|
@ -0,0 +1,49 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Use this file as a template for submitting bugs, etc.
|
||||
// This module takes a single clock input, and should either
|
||||
// $write("*-* All Finished *-*\n");
|
||||
// $finish;
|
||||
// on success, or $stop.
|
||||
//
|
||||
// The code as shown applies a random vector to the Test
|
||||
// module, then calculates a CRC on the Test module's outputs.
|
||||
//
|
||||
// **If you do not wish for your code to be released to the public
|
||||
// please note it here, otherwise:**
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Cls;
|
||||
endclass
|
||||
|
||||
package Pkg;
|
||||
// Issue #2956
|
||||
typedef string STYPE;
|
||||
typedef string line;
|
||||
task automatic testf;
|
||||
inout STYPE line;
|
||||
endtask
|
||||
endpackage
|
||||
|
||||
module t;
|
||||
localparam type T = Cls;
|
||||
|
||||
// Issue #2412
|
||||
typedef T this_thing; // this_thing now a type
|
||||
|
||||
function T newer();
|
||||
T this_thing; // this_thing now a class reference
|
||||
this_thing = new;
|
||||
return this_thing;
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
Cls c;
|
||||
c = newer();
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
|
@ -2,7 +2,7 @@
|
|||
12 | int above;
|
||||
| ^~~~~
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER or randomize
|
||||
%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting '('
|
||||
12 | int above;
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
Loading…
Reference in New Issue