Support 'config' parsing, but not functionally

This commit is contained in:
Wilson Snyder 2025-06-28 20:32:19 -04:00
parent 93f447dd4a
commit 5d32fc56ac
20 changed files with 548 additions and 74 deletions

View File

@ -953,9 +953,9 @@ public:
AstClocking(FileLine* fl, const std::string& name, AstSenItem* sensesp,
AstClockingItem* itemsp, bool isDefault, bool isGlobal)
: ASTGEN_SUPER_Clocking(fl)
, m_name{name}
, m_isDefault{isDefault}
, m_isGlobal{isGlobal} {
m_name = name;
this->sensesp(sensesp);
addItemsp(itemsp);
}
@ -994,6 +994,78 @@ public:
void outputp(AstClockingItem* outputp) { m_outputp = outputp; }
bool maybePointedTo() const override VL_MT_SAFE { return true; }
};
class AstConfig final : public AstNode {
// Parents: NETLIST
// @astgen op1 := designp : List[AstConfigCell]
// @astgen op2 := itemsp : List[AstNode]
std::string m_name; // Config block name
public:
AstConfig(FileLine* fl, const std::string& name, AstNode* itemsp)
: ASTGEN_SUPER_Config(fl)
, m_name{name} {
addItemsp(itemsp);
}
ASTGEN_MEMBERS_AstConfig;
std::string name() const override VL_MT_STABLE { return m_name; }
};
class AstConfigCell final : public AstNode {
// Parents: CONFIGRULE
std::string m_libname; // Cell library, or ""
std::string m_cellname; // Cell name within library
public:
AstConfigCell(FileLine* fl, const std::string& libname, const std::string& cellname)
: ASTGEN_SUPER_ConfigCell(fl)
, m_libname{libname}
, m_cellname{cellname} {}
ASTGEN_MEMBERS_AstConfigCell;
std::string name() const override VL_MT_STABLE { return m_libname + "." + m_cellname; }
std::string libname() const VL_MT_STABLE { return m_libname; }
std::string cellname() const VL_MT_STABLE { return m_cellname; }
};
class AstConfigRule final : public AstNode {
// Parents: CONFIG
// @astgen op1 := cellp : Optional[AstNode] // Cells to apply to, or nullptr=default
// @astgen op2 := usep : List[AstNode] // Use or design to apply
const bool m_isCell; // Declared as "cell" versus "instance"
public:
AstConfigRule(FileLine* fl, AstNode* cellp, AstNode* usep, bool isCell)
: ASTGEN_SUPER_ConfigRule(fl)
, m_isCell{isCell} {
this->cellp(cellp);
addUsep(usep);
}
ASTGEN_MEMBERS_AstConfigRule;
bool isCell() const VL_MT_STABLE { return m_isCell; }
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
};
class AstConfigUse final : public AstNode {
// Parents: CONFIGRULE
// @astgen op1 := paramsp : List[AstPin]
std::string m_libname; // Use library, or ""
std::string m_cellname; // Use name within library
const bool m_isConfig; // ":config"; Config, not module/primitive name
public:
AstConfigUse(FileLine* fl, const std::string& libname, const std::string& cellname,
AstPin* paramsp, bool isConfig)
: ASTGEN_SUPER_ConfigUse(fl)
, m_libname{libname}
, m_cellname{cellname}
, m_isConfig{isConfig} {
addParamsp(paramsp);
}
ASTGEN_MEMBERS_AstConfigUse;
std::string name() const override VL_MT_STABLE { return m_libname + "." + m_cellname; }
std::string libname() const VL_MT_STABLE { return m_libname; }
std::string cellname() const VL_MT_STABLE { return m_cellname; }
bool isConfig() const VL_MT_STABLE { return m_isConfig; }
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
};
class AstConstPool final : public AstNode {
// Container for const static data
// @astgen op1 := modulep : AstModule // m_modp below TODO: fix this mess

View File

@ -1806,6 +1806,22 @@ void AstClocking::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, isGlobal);
dumpJsonGen(str);
}
void AstConfigRule::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (isCell()) str << " [CELL]";
}
void AstConfigRule::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, isCell);
dumpJsonGen(str);
}
void AstConfigUse::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (isConfig()) str << " [CONFIG]";
}
void AstConfigUse::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, isConfig);
dumpJsonGen(str);
}
void AstDisplay::dump(std::ostream& str) const {
this->AstNodeStmt::dump(str);
str << " [" << displayType().ascii() << "]";

View File

@ -562,6 +562,23 @@ class LinkCellsVisitor final : public VNVisitor {
iterateAndNextNull(nodep->attrsp());
}
void visit(AstConfig* nodep) override {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: config");
iterateChildren(nodep);
}
void visit(AstConfigCell* nodep) override {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: config cell");
iterateChildren(nodep);
}
void visit(AstConfigRule* nodep) override {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: config rule");
iterateChildren(nodep);
}
void visit(AstConfigUse* nodep) override {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: config use");
iterateChildren(nodep);
}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
// METHODS
@ -623,7 +640,9 @@ public:
}
iterate(nodep);
}
~LinkCellsVisitor() override = default;
~LinkCellsVisitor() override {
if (debug() >= 5 || dumpGraphLevel() >= 5) { m_mods.dumpFilePrefixed("linkcells"); }
}
};
//######################################################################

View File

@ -117,7 +117,7 @@ public:
void exported(bool flag) { m_exported = flag; }
bool imported() const { return m_imported; }
void imported(bool flag) { m_imported = flag; }
void insert(const string& name, VSymEnt* entp) {
VSymEnt* insert(const string& name, VSymEnt* entp) {
UINFO(9, " SymInsert se" << cvtToHex(this) << " '" << name << "' se" << cvtToHex(entp)
<< " " << entp->nodep());
if (name != "" && m_idNameMap.find(name) != m_idNameMap.end()) {
@ -130,6 +130,7 @@ public:
} else {
m_idNameMap.emplace(name, entp);
}
return entp;
}
void reinsert(const string& name, VSymEnt* entp) {
const auto it = m_idNameMap.find(name);
@ -150,7 +151,7 @@ public:
<< (it == m_idNameMap.end() ? "NONE"
: "se" + cvtToHex(it->second)
+ " n=" + cvtToHex(it->second->nodep())));
if (it != m_idNameMap.end()) return (it->second);
if (it != m_idNameMap.end()) return it->second;
return nullptr;
}
VSymEnt* findIdFallback(const string& name) const {

View File

@ -441,19 +441,19 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Verilog 2001 Config */
<V01C,V05,VA5,S05,S09,S12,S17,S23,SAX>{
/* Generic unsupported keywords */
"cell" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"config" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"design" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"endconfig" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"cell" { FL; return yCELL; }
"config" { FL; return yCONFIG; }
"design" { FL; return yDESIGN; }
"endconfig" { FL; return yENDCONFIG; }
"incdir" { FL; ERROR_RSVD_WORD("Verilog 2001-config lib.map"); }
"include" { FL; yylval.fl->v3warn(E_UNSUPPORTED, "Unsupported: Verilog 2001-config lib.map reserved word not implemented: 'include'\n"
<< yylval.fl->warnMore() << "... Suggest unless in a lib.map file,"
" want `include instead");
FL_BRK; }
"instance" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"liblist" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"instance" { FL; return yINSTANCE; }
"liblist" { FL; return yLIBLIST; }
"library" { FL; ERROR_RSVD_WORD("Verilog 2001-config lib.map"); }
"use" { FL; ERROR_RSVD_WORD("Verilog 2001-config"); }
"use" { FL; return yUSE; }
}
/* Verilog 2005 */

View File

@ -575,11 +575,13 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yCASE "case"
%token<fl> yCASEX "casex"
%token<fl> yCASEZ "casez"
%token<fl> yCELL "cell"
%token<fl> yCHANDLE "chandle"
%token<fl> yCHECKER "checker"
%token<fl> yCLASS "class"
%token<fl> yCLOCKING "clocking"
%token<fl> yCMOS "cmos"
%token<fl> yCONFIG "config"
%token<fl> yCONSTRAINT "constraint"
%token<fl> yCONST__ETC "const"
%token<fl> yCONST__LEX "const-in-lex"
@ -593,6 +595,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yDEASSIGN "deassign"
%token<fl> yDEFAULT "default"
%token<fl> yDEFPARAM "defparam"
%token<fl> yDESIGN "design"
%token<fl> yDISABLE "disable"
%token<fl> yDIST "dist"
%token<fl> yDO "do"
@ -603,6 +606,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yENDCHECKER "endchecker"
%token<fl> yENDCLASS "endclass"
%token<fl> yENDCLOCKING "endclocking"
%token<fl> yENDCONFIG "endconfig"
%token<fl> yENDFUNCTION "endfunction"
%token<fl> yENDGENERATE "endgenerate"
%token<fl> yENDGROUP "endgroup"
@ -650,6 +654,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yINOUT "inout"
%token<fl> yINPUT "input"
%token<fl> yINSIDE "inside"
%token<fl> yINSTANCE "instance"
%token<fl> yINT "int"
%token<fl> yINTEGER "integer"
%token<fl> yINTERCONNECT "interconnect"
@ -659,6 +664,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yJOIN_ANY "join_any"
%token<fl> yJOIN_NONE "join_none"
%token<fl> yLET "let"
%token<fl> yLIBLIST "liblist"
%token<fl> yLOCALPARAM "localparam"
%token<fl> yLOCAL__COLONCOLON "local-then-::"
%token<fl> yLOCAL__ETC "local"
@ -774,6 +780,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yUNTIL "until"
%token<fl> yUNTIL_WITH "until_with"
%token<fl> yUNTYPED "untyped"
%token<fl> yUSE "use"
%token<fl> yVAR "var"
%token<fl> yVECTORED "vectored"
%token<fl> yVIRTUAL__CLASS "virtual-then-class"
@ -1212,7 +1219,7 @@ description: // ==IEEE: description
| package_declaration { }
| package_itemTop { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
| bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
//UNSUP config_declaration { }
| config_declaration { }
// // Verilator only
| yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
| yaT_NOUNCONNECTED { PARSEP->unconnectedDrive(VOptionBool::OPT_DEFAULT_FALSE); }
@ -7720,8 +7727,140 @@ colon<fl>: // Generic colon that isn't making a label (e.g.
//**********************************************************************
// Config - config...endconfig
config_declaration: // == IEEE: config_declaration
yCONFIG idAny/*config_identifier*/ ';'
/*cont*/ configParameterListE design_statement config_rule_statementListE
/*cont*/ yENDCONFIG endLabelE
{ AstConfig* const newp = new AstConfig{$1, *$2, $4};
newp->addItemsp($5);
newp->addItemsp($6);
GRAMMARP->endLabel($<fl>7, *$2, $8);
PARSEP->rootp()->addMiscsp(newp); }
;
configParameterListE<nodep>: // IEEE: { local_parameter_declaration ';' }
/* empty */ { $$ = nullptr; }
| configParameterList { $$ = $1; }
;
configParameterList<nodep>: // IEEE: part of config_declaration
configParameter { $$ = nullptr; }
| configParameterList configParameter { $$ = addNextNull($1, $2); }
;
configParameter<nodep>: // IEEE: part of config_declaration
parameter_declaration ';'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: config localparam declaration"); }
;
design_statement<nodep>: // == IEEE: design_statement
yDESIGN configCellList ';' { $$ = $2; }
;
configCellList<configCellp>: // IEEE: part of design_statement
configCell { $$ = $1; }
| configCellList configCell { $$ = addNextNull($1, $2); }
;
configCell<configCellp>: // IEEE: part of design_statement, part of cell_clause
idAny/*cell_identifier*/
{ $$ = new AstConfigCell{$<fl>1, "", *$1}; }
| idAny/*library_identifier*/ '.' idAny/*cell_identifier*/
{ $$ = new AstConfigCell{$<fl>1, *$1, *$3}; }
;
config_rule_statementListE<nodep>: // IEEE: { config_rule }
/* empty */ { $$ = nullptr; }
| config_rule_statementList { $$ = $1; }
;
config_rule_statementList<nodep>: // IEEE: { config_rule }
config_rule_statement { $$ = $1; }
| config_rule_statementList config_rule_statement { $$ = addNextNull($1, $2); }
;
config_rule_statement<nodep>: // == IEEE: config_rule_statement
// // IEEE: default_clause
yDEFAULT liblist_clause ';'
{ $$ = new AstConfigRule{$1, nullptr, $2, false}; }
// // IEEE: inst_clause
| yINSTANCE inst_name liblist_clause ';'
{ $$ = new AstConfigRule{$1, $2, $3, false}; }
| yINSTANCE inst_name use_clause ';'
{ $$ = new AstConfigRule{$1, $2, $3, false}; }
// // IEEE: cell_clause
| yCELL configCell liblist_clause ';'
{ $$ = new AstConfigRule{$1, $2, $3, true}; }
| yCELL configCell use_clause ';'
{ $$ = new AstConfigRule{$1, $2, $3, true}; }
| error ';'
{ $$ = nullptr; }
;
inst_name<nodeExprp>: // == IEEE: inst_name
idAnyAsParseRef/*topmodule_identifier*/
{ $$ = $1; }
| idAnyAsParseRef/*topmodule_identifier*/ inst_nameInstanceList
{ $$ = new AstDot{$<fl>1, false, $1, $2}; }
;
inst_nameInstanceList<nodeExprp>: // IEEE: part of inst_name
'.' idAnyAsParseRef/*instance_identifier*/
{ $$ = $2; }
| inst_nameInstanceList '.' idAnyAsParseRef/*instance_identifier*/
{ $$ = new AstDot{$<fl>2, false, $1, $3}; }
;
liblist_clause<nodep>: // == IEEE: liblist_clause
yLIBLIST { $$ = nullptr; }
| yLIBLIST liblistLibraryList { $$ = $2; }
;
liblistLibraryList<nodeExprp>: // IEEE: part of liblist_clause
idAnyAsParseRef/*library_identifier*/
{ $$ = $1; }
| liblistLibraryList idAnyAsParseRef/*library_identifier*/
{ $$ = addNextNull($1, $2); }
;
use_clause<nodep>: // == IEEE: use_clause
yUSE idAny/*cell_identifier*/ useAssignmentListE colonConfigE
{ $$ = new AstConfigUse{$1, "", *$2, $3, $4}; }
| yUSE idAny/*library_identifier*/ '.' idAny/*cell_identifier*/ useAssignmentListE colonConfigE
{ $$ = new AstConfigUse{$1, *$2, *$4, $5, $6}; }
| yUSE useAssignmentListE colonConfigE
{ $$ = new AstConfigUse{$1, "", "", $2, $3}; }
;
useAssignmentListE<pinp>: // IEEE: part of use clause
/* empty */ { $$ = nullptr; }
// // IEEE is missing the '#' '(', but examples need it
| '#' '(' ')' { $$ = nullptr; }
| '#' '(' useAssignmentList ')' { $$ = $3; }
;
useAssignmentList<pinp>: // IEEE: part of use_clause
useAssignment { $$ = $1; }
| useAssignmentList ',' useAssignment { $$ = addNextNull($1, $3); }
;
useAssignment<pinp>: // IEEE: part of use_clause
// // IEEE: named_parameter_assignment
'.' idAny/*parameter_identifier*/ '(' ')'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: 'config use' parameter assignment"); }
| '.' idAny/*parameter_identifier*/ '(' exprOrDataType ')'
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: 'config use' parameter assignment"); }
;
colonConfigE<cbool>: // IEEE: [ ':' yCONFIG]
/* empty */ { $$ = false; }
| ':' yCONFIG { $$ = true; }
;
//**********************************************************************
// Config - lib.map
//
// TODO when implement this support, add -libmap option which takes multiple files.
//UNSUP library_text: // == IEEE: library_text (note is top-level entry point)
//UNSUP library_description { }

View File

@ -26,7 +26,4 @@
%Error-UNSUPPORTED: t/t_config_libmap.map:17:1: Unsupported: Verilog 2001-config lib.map reserved word not implemented: 'library'
17 | library gatelib .
| ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_config_libmap.map:20:1: Unsupported: Verilog 2001-config reserved word not implemented: 'config'
%Error-UNSUPPORTED: t/t_config_libmap.map:21:4: Unsupported: Verilog 2001-config reserved word not implemented: 'design'
%Error-UNSUPPORTED: t/t_config_libmap.map:22:1: Unsupported: Verilog 2001-config reserved word not implemented: 'endconfig'
%Error: Exiting due to

View File

@ -0,0 +1,20 @@
%Error-UNSUPPORTED: t/t_config_param.v:24:4: Unsupported: config localparam declaration
24 | localparam P1 = "cfg.p1";
| ^~~~~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_config_param.v:25:4: Unsupported: config localparam declaration
25 | localparam P2 = "cfg.p2";
| ^~~~~~~~~~
%Error-UNSUPPORTED: t/t_config_param.v:27:26: Unsupported: 'config use' parameter assignment
27 | instance t.u_1a use #(.P1(), .P2("override.u_a.p2"));
| ^
%Error-UNSUPPORTED: t/t_config_param.v:27:33: Unsupported: 'config use' parameter assignment
27 | instance t.u_1a use #(.P1(), .P2("override.u_a.p2"));
| ^
%Error-UNSUPPORTED: t/t_config_param.v:29:26: Unsupported: 'config use' parameter assignment
29 | instance t.u_1c use #(.P1(P1), .P2(P2));
| ^
%Error-UNSUPPORTED: t/t_config_param.v:29:35: Unsupported: 'config use' parameter assignment
29 | instance t.u_1c use #(.P1(P1), .P2(P2));
| ^
%Error: Exiting due to

View File

@ -0,0 +1,21 @@
#!/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('linter')
test.lint(verilator_flags2=["--lint-only"],
fails=test.vlt_all,
expect_filename=test.golden_filename)
# Sort so that 'initial' scheduling order is not relevant
# test.files_identical_sorted(test.run_log_filename, test.golden_filename, is_logfile=True)
test.passes()

View File

@ -0,0 +1,30 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// 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
module m1;
parameter string P1 = "p1.unchanged";
parameter string P2 = "p2.unchanged";
initial $display("m1 %%m=%m %%l=%l P1=%s P2=%s", P1, P2);
endmodule
module t;
m1 u_1a();
m1 u_1b();
m1 u_1c();
final $write("*-* All Finished *-*\n");
endmodule
config cfg1;
localparam P1 = "cfg.p1";
localparam P2 = "cfg.p2";
design t;
instance t.u_1a use #(.P1(), .P2("override.u_a.p2"));
instance t.u_1b use #(); // All parameters back to default
instance t.u_1c use #(.P1(P1), .P2(P2));
endconfig

View File

@ -0,0 +1,77 @@
%Error-UNSUPPORTED: t/t_config_unsup.v:24:1: Unsupported: config
24 | config cfg;
| ^~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_config_unsup.v:25:11: Unsupported: config cell
25 | design t;
| ^
%Error-UNSUPPORTED: t/t_config_unsup.v:28:4: Unsupported: config rule
28 | default liblist;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:29:4: Unsupported: config rule
29 | default liblist liba libb;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:32:4: Unsupported: config rule
32 | instance t.m20 liblist;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:33:4: Unsupported: config rule
33 | instance t.m21 liblist libc;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:34:4: Unsupported: config rule
34 | instance t.m22 liblist libc libd;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:35:4: Unsupported: config rule
35 | instance t.m23 liblist libc libd;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:36:4: Unsupported: config rule
36 | instance t.m24 liblist libc libd;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:39:4: Unsupported: config rule
39 | instance t.m30 use cell_identifier;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:39:19: Unsupported: config use
39 | instance t.m30 use cell_identifier;
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:40:4: Unsupported: config rule
40 | instance t.m31 use lib_id.cell_id;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:40:19: Unsupported: config use
40 | instance t.m31 use lib_id.cell_id;
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:41:4: Unsupported: config rule
41 | instance t.m32 use #();
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:41:19: Unsupported: config use
41 | instance t.m32 use #();
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:44:4: Unsupported: config rule
44 | cell m40 liblist libc libd;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:44:9: Unsupported: config cell
44 | cell m40 liblist libc libd;
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:45:4: Unsupported: config rule
45 | cell work.m41 liblist libc libd;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:45:9: Unsupported: config cell
45 | cell work.m41 liblist libc libd;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:46:4: Unsupported: config rule
46 | cell m42 use m42alt;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:46:9: Unsupported: config cell
46 | cell m42 use m42alt;
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:46:13: Unsupported: config use
46 | cell m42 use m42alt;
| ^~~
%Error-UNSUPPORTED: t/t_config_unsup.v:47:4: Unsupported: config rule
47 | cell work.m43 use work.m43alt;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:47:9: Unsupported: config cell
47 | cell work.m43 use work.m43alt;
| ^~~~
%Error-UNSUPPORTED: t/t_config_unsup.v:47:18: Unsupported: config use
47 | cell work.m43 use work.m43alt;
| ^~~
%Error: Exiting due to

View File

@ -0,0 +1,16 @@
#!/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('vlt')
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,49 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// 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
module t;
m10 u_10();
m20 u_20();
m21 u_21();
m22 u_22();
m23 u_23();
m24 u_24();
m30 u_30();
m31 u_31();
m32 u_32();
m40 u_40();
m41 u_41();
m42 u_42();
m43 u_43();
final $write("*-* All Finished *-*\n");
endmodule
config cfg;
design t;
// Test uses m10
default liblist; // Ignored
default liblist liba libb;
// Test uses m20-29
instance t.m20 liblist; // Use parent's cell library
instance t.m21 liblist libc;
instance t.m22 liblist libc libd; // m22 in libc
instance t.m23 liblist libc libd; // m23 in libd
instance t.m24 liblist libc libd; // m24 in default (libb)
// Test uses m30-39
instance t.m30 use cell_identifier;
instance t.m31 use lib_id.cell_id;
instance t.m32 use #();
// Test uses m40-49
cell m40 liblist libc libd;
cell work.m41 liblist libc libd;
cell m42 use m42alt;
cell work.m43 use work.m43alt;
endconfig

View File

@ -1,36 +0,0 @@
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:7:1: Unsupported: Verilog 2001-config reserved word not implemented: 'config'
7 | config cfgBad;
| ^~~~~~~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_lint_rsvd_bad.v:7:14: syntax error, unexpected IDENTIFIER
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:8:4: Unsupported: Verilog 2001-config reserved word not implemented: 'design'
8 | design rtlLib.top;
| ^~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:9:12: Unsupported: Verilog 2001-config reserved word not implemented: 'liblist'
9 | default liblist rtlLib;
| ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:10:4: Unsupported: Verilog 2001-config reserved word not implemented: 'instance'
10 | instance top.a2 liblist gateLib;
| ^~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:10:28: Unsupported: Verilog 2001-config reserved word not implemented: 'liblist'
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:11:4: Unsupported: Verilog 2001-config lib.map reserved word not implemented: 'include'
: ... Suggest unless in a lib.map file, want `include instead
11 | include none;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:12:4: Unsupported: Verilog 2001-config lib.map reserved word not implemented: 'library'
12 | library rtlLib *.v;
| ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:13:4: Unsupported: Verilog 2001-config lib.map reserved word not implemented: 'include'
: ... Suggest unless in a lib.map file, want `include instead
13 | include aa;
| ^~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:14:4: Unsupported: Verilog 2001-config reserved word not implemented: 'use'
14 | use gateLib;
| ^~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:15:4: Unsupported: Verilog 2001-config reserved word not implemented: 'cell'
15 | cell rtlLib.cell;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:15:20: Unsupported: Verilog 2001-config reserved word not implemented: 'cell'
%Error-UNSUPPORTED: t/t_lint_rsvd_bad.v:16:1: Unsupported: Verilog 2001-config reserved word not implemented: 'endconfig'
%Error: Exiting due to

View File

@ -1,19 +0,0 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2019 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
config cfgBad;
design rtlLib.top;
default liblist rtlLib;
instance top.a2 liblist gateLib;
include none;
library rtlLib *.v;
include aa;
use gateLib;
cell rtlLib.cell;
endconfig
module t;
endmodule

25
test_regress/t/t_mod_dot.py Executable file
View File

@ -0,0 +1,25 @@
#!/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('vlt')
# This doesn't use the general compile rule as we want to make sure we form
# prefix properly using post-escaped identifiers
test.run(cmd=[
os.environ["VERILATOR_ROOT"] + "/bin/verilator",
"--cc",
"--Mdir " + test.obj_dir + "/t_mod_dot",
"--exe --build --main",
't/t_mod_dot.v',
],
verilator_run=True)
test.passes()

View File

@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2020 by engr248.
// SPDX-License-Identifier: CC0-1.0
module \foo.bar (/*AUTOARG*/);
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,19 @@
%Warning-MODDUP: t/t_mod_dup_bad_lib.v:14:8: Duplicate declaration of module: 'a'
14 | module a();
| ^
t/t_mod_dup_bad_lib.v:7:8: ... Location of original declaration
7 | module a();
| ^
... For warning description see https://verilator.org/warn/MODDUP?v=latest
... Use "/* verilator lint_off MODDUP */" and lint_on around source to disable this message.
%Warning-MULTITOP: t/t_mod_dup_bad_lib.v:17: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
... Use "/* verilator lint_off MULTITOP */" and lint_on around source to disable this message.
: ... Top module 'test'
10 | module test();
| ^~~~
: ... Top module 'b'
17 | module b();
| ^
%Error: Exiting due to

View File

@ -9,10 +9,8 @@
import vltest_bootstrap
test.scenarios('linter')
test.scenarios('vlt')
test.lint(verilator_flags2=["--lint-only -Wwarn-REALCVT"],
fails=True,
expect_filename=test.golden_filename)
test.lint(verilator_flag2=["--work liba"], fails=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2008 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module a();
endmodule
module test();
a a();
endmodule
module a();
endmodule
module b();
endmodule