mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Change MULTITOP to warning to help linting, see manual.
This commit is contained in:
parent
5f27c41ee3
commit
f7641d2ecc
2
Changes
2
Changes
@ -4,6 +4,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
* Verilator 4.017 devel
|
||||
|
||||
*** Change MULTITOP to warning to help linting, see manual.
|
||||
|
||||
**** Show included-from filenames in warnings, bug1439. [Todd Strader]
|
||||
|
||||
**** Fix not reporting some duplicate signals/ports, bug1462. [Peter Gerst]
|
||||
|
@ -1280,7 +1280,7 @@ good value.
|
||||
When the input Verilog contains more than one top level module, specifies
|
||||
the name of the top level Verilog module to become the top, and sets the
|
||||
default for if --prefix is not used. This is not needed with standard
|
||||
designs with only one top.
|
||||
designs with only one top. See also the MULTITOP warning section.
|
||||
|
||||
=item --trace
|
||||
|
||||
@ -3718,14 +3718,31 @@ correctly.
|
||||
|
||||
=item MULTITOP
|
||||
|
||||
Error that there are multiple top level modules, that is modules not
|
||||
instantiated by any other module. Verilator only supports a single top
|
||||
level, if you need more, create a module that wraps all of the top modules.
|
||||
Warns that there are multiple top level modules, that is modules not
|
||||
instantiated by any other module, and both modules were put on the command
|
||||
line (not in a library). Three likely cases:
|
||||
|
||||
Often this error is because some low level cell is being read in, but is
|
||||
not really needed. The best solution is to insure that each module is in a
|
||||
unique file by the same name. Otherwise, make sure all library files are
|
||||
read in as libraries with -v, instead of automatically with -y.
|
||||
1. A single module is intended to be the top. This warning then occurs
|
||||
because some low level cell is being read in, but is not really needed as
|
||||
part of the design. The best solution for this situation is to ensure that
|
||||
only the top module is put on the command line without any flags, and all
|
||||
remaining library files are read in as libraries with -v, or are
|
||||
automatically resolved by having filenames that match the module names.
|
||||
|
||||
2. A single module is intended to be the top, the name of it is known, and
|
||||
all other modules should be ignored if not part of the design. The best
|
||||
solution is to use the --top-module option to specify the top module's
|
||||
name. All other modules that are not part of the design will be for the
|
||||
most part ignored (they must be clean in syntax and their contents will be
|
||||
removed as part of the Verilog module elaboration process.)
|
||||
|
||||
3. Multiple modules are intended to be design tops, e.g. when linting a
|
||||
library file. As multiple modules are desired, disable the MULTITOP
|
||||
warning. All input/outputs will go uniquely to each module, with any
|
||||
conflicting and identical signal names being uniquified by adding a prefix
|
||||
based on the top module name followed by __02E (a Verilator-encoded ASCII
|
||||
".'). This renaming is done even if the two modules' signals seem
|
||||
identical, e.g. multiple modules with a "clk" input.
|
||||
|
||||
=item PINCONNECTEMPTY
|
||||
|
||||
|
@ -106,7 +106,7 @@ private:
|
||||
//######################################################################
|
||||
|
||||
void V3CCtors::evalAsserts() {
|
||||
AstNodeModule* modp = v3Global.rootp()->modulesp(); // Top module
|
||||
AstNodeModule* modp = v3Global.rootp()->modulesp(); // Top module wrapper
|
||||
AstCFunc* funcp = new AstCFunc(modp->fileline(), "_eval_debug_assertions", NULL, "void");
|
||||
funcp->declPrivate(true);
|
||||
funcp->isStatic(false);
|
||||
|
@ -49,7 +49,6 @@ public:
|
||||
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
|
||||
// Error codes:
|
||||
E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable
|
||||
E_MULTITOP, // Error: Multiple top level modules
|
||||
E_PORTSHORT, // Error: Output port is connected to a constant, electrical short
|
||||
E_TASKNSVAR, // Error: Task I/O not simple
|
||||
//
|
||||
@ -89,6 +88,7 @@ public:
|
||||
LITENDIAN, // Little bit endian vector
|
||||
MODDUP, // Duplicate module
|
||||
MULTIDRIVEN, // Driven from multiple blocks
|
||||
MULTITOP, // Multiple top level modules
|
||||
PINMISSING, // Cell pin not specified
|
||||
PINNOCONNECT, // Cell pin not connected
|
||||
PINCONNECTEMPTY,// Cell pin connected by name with empty reference
|
||||
@ -131,7 +131,7 @@ public:
|
||||
// Boolean
|
||||
" I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE",
|
||||
// Errors
|
||||
"DETECTARRAY", "MULTITOP", "PORTSHORT", "TASKNSVAR",
|
||||
"DETECTARRAY", "PORTSHORT", "TASKNSVAR",
|
||||
// Warnings
|
||||
" EC_FIRST_WARN",
|
||||
"ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN",
|
||||
@ -144,7 +144,7 @@ public:
|
||||
"IMPERFECTSCH", "IMPLICIT", "IMPORTSTAR", "IMPURE",
|
||||
"INCABSPATH", "INFINITELOOP", "INITIALDLY",
|
||||
"LITENDIAN", "MODDUP",
|
||||
"MULTIDRIVEN",
|
||||
"MULTIDRIVEN", "MULTITOP",
|
||||
"PINMISSING", "PINNOCONNECT", "PINCONNECTEMPTY", "PROCASSWIRE",
|
||||
"REALCVT", "REDEFMACRO",
|
||||
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
|
@ -141,7 +141,8 @@ private:
|
||||
// We'll throw the error when we know the module will really be needed.
|
||||
string prettyName = AstNode::prettyName(modName);
|
||||
V3Parse parser (v3Global.rootp(), m_filterp, m_parseSymp);
|
||||
parser.parseFile(nodep->fileline(), prettyName, false, "");
|
||||
// true below -> other simulators treat modules in link-found files as library cells
|
||||
parser.parseFile(nodep->fileline(), prettyName, true, "");
|
||||
V3Error::abortIfErrors();
|
||||
// We've read new modules, grab new pointers to their names
|
||||
readModNames();
|
||||
|
@ -674,18 +674,20 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||
// packages before using packages
|
||||
iterateChildrenBackwards(nodep);
|
||||
|
||||
// The first module in the list is always the top module (sorted before this is called).
|
||||
// The first modules in the list are always the top modules
|
||||
// (sorted before this is called).
|
||||
// This may not be the module with isTop() set, as early in the steps,
|
||||
// wrapTop may have not been created yet.
|
||||
AstNodeModule* topmodp = nodep->modulesp();
|
||||
if (!topmodp) {
|
||||
if (!nodep->modulesp()) {
|
||||
nodep->v3error("No top level module found");
|
||||
} else {
|
||||
UINFO(8,"Top Module: "<<topmodp<<endl);
|
||||
}
|
||||
for (AstNodeModule* modp = nodep->modulesp(); modp && modp->level() <= 2;
|
||||
modp = VN_CAST(modp->nextp(), NodeModule)) {
|
||||
UINFO(8,"Top Module: "<<modp<<endl);
|
||||
m_scope = "TOP";
|
||||
m_curSymp = m_modSymp = m_statep->insertTopCell(topmodp, m_scope);
|
||||
m_curSymp = m_modSymp = m_statep->insertTopCell(modp, m_scope);
|
||||
{
|
||||
iterate(topmodp);
|
||||
iterate(modp);
|
||||
}
|
||||
m_scope = "";
|
||||
m_curSymp = m_modSymp = NULL;
|
||||
|
@ -60,17 +60,18 @@ void V3LinkLevel::modSortByLevel() {
|
||||
if (nodep->level()<=2) {
|
||||
if (topp) {
|
||||
static int warnedOnce = 0;
|
||||
nodep->v3warn(E_MULTITOP, "Unsupported: Multiple top level modules: "
|
||||
<<nodep->prettyName()<<" and "<<topp->prettyName()<<endl
|
||||
nodep->v3warn(MULTITOP, "Multiple top level modules: "
|
||||
<<nodep->prettyName()<<" and "<<topp->prettyName()
|
||||
<<(!warnedOnce++
|
||||
? (nodep->warnMore()
|
||||
+"... Fix, or use --top-module option to select which you want.")
|
||||
? ("\n"+nodep->warnMore()
|
||||
+"... Suggest see manual; fix the duplicates, or use --top-module to select top.")
|
||||
: ""));
|
||||
}
|
||||
topp = nodep;
|
||||
}
|
||||
vec.push_back(nodep);
|
||||
}
|
||||
// Reorder the netlist's modules to have modules in level sorted order
|
||||
stable_sort(vec.begin(), vec.end(), CmpLevel()); // Sort the vector
|
||||
UINFO(9,"modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666
|
||||
for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) {
|
||||
@ -95,7 +96,10 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
// We do ONLY the top module
|
||||
AstNodeModule* oldmodp = rootp->modulesp();
|
||||
if (!oldmodp) rootp->v3fatalSrc("No module found to process");
|
||||
if (!oldmodp) { // Later V3LinkDot will warn
|
||||
UINFO(1,"No module found to wrap\n");
|
||||
return;
|
||||
}
|
||||
AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), string("TOP"));
|
||||
// Make the new module first in the list
|
||||
oldmodp->unlinkFrBackWithNext();
|
||||
@ -108,62 +112,10 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
||||
// the rest must be done after data type resolution
|
||||
wrapTopCell(rootp);
|
||||
|
||||
V3Global::dumpCheckGlobalTree("wraptop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
|
||||
}
|
||||
|
||||
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
AstNodeModule* newmodp = rootp->modulesp();
|
||||
if (!newmodp || !newmodp->isTop()) rootp->v3fatalSrc("No TOP module found to process");
|
||||
AstNodeModule* oldmodp = VN_CAST(newmodp->nextp(), NodeModule);
|
||||
if (!oldmodp) rootp->v3fatalSrc("No module found to process");
|
||||
|
||||
// Add instance
|
||||
AstCell* cellp = new AstCell(newmodp->fileline(),
|
||||
(!v3Global.opt.l2Name().empty()
|
||||
? v3Global.opt.l2Name() : oldmodp->name()),
|
||||
oldmodp->name(),
|
||||
NULL, NULL, NULL);
|
||||
cellp->modp(oldmodp);
|
||||
newmodp->addStmtp(cellp);
|
||||
|
||||
// Add pins
|
||||
for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) {
|
||||
UINFO(8,"VARWRAP "<<oldvarp<<endl);
|
||||
if (oldvarp->isIO()) {
|
||||
AstVar* varp = oldvarp->cloneTree(false);
|
||||
newmodp->addStmtp(varp);
|
||||
varp->sigPublic(true); // User needs to be able to get to it...
|
||||
if (oldvarp->isIO()) {
|
||||
oldvarp->primaryIO(false);
|
||||
varp->primaryIO(true);
|
||||
}
|
||||
if (varp->direction().isRefOrConstRef()) {
|
||||
varp->v3error("Unsupported: ref/const ref as primary input/output: "
|
||||
<<varp->prettyName());
|
||||
}
|
||||
if (varp->isIO() && v3Global.opt.systemC()) {
|
||||
varp->sc(true);
|
||||
// User can see trace one level down from the wrapper
|
||||
// Avoids packing & unpacking SC signals a second time
|
||||
varp->trace(false);
|
||||
}
|
||||
|
||||
AstPin* pinp = new AstPin(oldvarp->fileline(), 0, oldvarp->name(),
|
||||
new AstVarRef(varp->fileline(),
|
||||
varp, oldvarp->isWritable()));
|
||||
// Skip length and width comp; we know it's a direct assignment
|
||||
pinp->modVarp(oldvarp);
|
||||
cellp->addPinsp(pinp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate all packages under the top wrapper
|
||||
// This way all later SCOPE based optimizations can ignore packages
|
||||
for (AstNodeModule* modp = rootp->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
|
||||
if (VN_IS(modp, Package)
|
||||
&& modp != oldmodp) { // Don't duplicate if didn't find a top module
|
||||
if (VN_IS(modp, Package)) {
|
||||
AstCell* cellp = new AstCell(modp->fileline(),
|
||||
// Could add __03a__03a="::" to prevent conflict
|
||||
// with module names/"v"
|
||||
@ -174,4 +126,89 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
newmodp->addStmtp(cellp);
|
||||
}
|
||||
}
|
||||
|
||||
V3Global::dumpCheckGlobalTree("wraptop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
|
||||
}
|
||||
|
||||
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
AstNodeModule* newmodp = rootp->modulesp();
|
||||
if (!newmodp || !newmodp->isTop()) rootp->v3fatalSrc("No TOP module found to insert under");
|
||||
|
||||
// Find all duplicate signal names (if multitop)
|
||||
typedef vl_unordered_set<std::string> NameSet;
|
||||
NameSet ioNames;
|
||||
NameSet dupNames;
|
||||
// For all modulues, skipping over new top
|
||||
for (AstNodeModule* oldmodp = VN_CAST(rootp->modulesp()->nextp(), NodeModule);
|
||||
oldmodp && oldmodp->level() <= 2;
|
||||
oldmodp = VN_CAST(oldmodp->nextp(), NodeModule)) {
|
||||
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) {
|
||||
if (oldvarp->isIO()) {
|
||||
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
|
||||
//UINFO(8, "Multitop dup I/O found: "<<oldvarp<<endl);
|
||||
dupNames.insert(oldvarp->name());
|
||||
} else {
|
||||
ioNames.insert(oldvarp->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For all modulues, skipping over new top
|
||||
for (AstNodeModule* oldmodp = VN_CAST(rootp->modulesp()->nextp(), NodeModule);
|
||||
oldmodp && oldmodp->level() <= 2;
|
||||
oldmodp = VN_CAST(oldmodp->nextp(), NodeModule)) {
|
||||
if (VN_IS(oldmodp, Package)) continue;
|
||||
// Add instance
|
||||
UINFO(5,"LOOP "<<oldmodp<<endl);
|
||||
AstCell* cellp = new AstCell(newmodp->fileline(),
|
||||
(!v3Global.opt.l2Name().empty()
|
||||
? v3Global.opt.l2Name() : oldmodp->name()),
|
||||
oldmodp->name(),
|
||||
NULL, NULL, NULL);
|
||||
cellp->modp(oldmodp);
|
||||
newmodp->addStmtp(cellp);
|
||||
|
||||
// Add pins
|
||||
for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) {
|
||||
UINFO(8,"VARWRAP "<<oldvarp<<endl);
|
||||
if (oldvarp->isIO()) {
|
||||
string name = oldvarp->name();
|
||||
if (dupNames.find(name) != dupNames.end()) {
|
||||
// __02E=. while __DOT__ looks nicer but will break V3LinkDot
|
||||
name = oldmodp->name()+"__02E"+name;
|
||||
}
|
||||
|
||||
AstVar* varp = oldvarp->cloneTree(false);
|
||||
varp->name(name);
|
||||
newmodp->addStmtp(varp);
|
||||
varp->sigPublic(true); // User needs to be able to get to it...
|
||||
if (oldvarp->isIO()) {
|
||||
oldvarp->primaryIO(false);
|
||||
varp->primaryIO(true);
|
||||
}
|
||||
if (varp->direction().isRefOrConstRef()) {
|
||||
varp->v3error("Unsupported: ref/const ref as primary input/output: "
|
||||
<<varp->prettyName());
|
||||
}
|
||||
if (varp->isIO() && v3Global.opt.systemC()) {
|
||||
varp->sc(true);
|
||||
// User can see trace one level down from the wrapper
|
||||
// Avoids packing & unpacking SC signals a second time
|
||||
varp->trace(false);
|
||||
}
|
||||
|
||||
AstPin* pinp = new AstPin(oldvarp->fileline(), 0, varp->name(),
|
||||
new AstVarRef(varp->fileline(),
|
||||
varp, oldvarp->isWritable()));
|
||||
// Skip length and width comp; we know it's a direct assignment
|
||||
pinp->modVarp(oldvarp);
|
||||
cellp->addPinsp(pinp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ private:
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) {
|
||||
AstNodeModule* modp = nodep->topModulep();
|
||||
if (!modp) { nodep->v3error("No root module specified"); return; }
|
||||
if (!modp) { nodep->v3error("No top level module found"); return; }
|
||||
// Operate starting at the top of the hierarchy
|
||||
m_aboveCellp = NULL;
|
||||
m_aboveScopep = NULL;
|
||||
|
@ -1,4 +1,5 @@
|
||||
%Error-MULTITOP: t/t_flag_topmodule.v:14: Unsupported: Multiple top level modules: a2 and a
|
||||
t/t_flag_topmodule.v:14: ... Fix, or use --top-module option to select which you want.
|
||||
%Error-MULTITOP: t/t_flag_topmodule.v:21: Unsupported: Multiple top level modules: b and a2
|
||||
%Warning-MULTITOP: t/t_flag_topmodule.v:14: Multiple top level modules: a2 and a
|
||||
t/t_flag_topmodule.v:14: ... Suggest see manual; fix the duplicates, or use --top-module to select top.
|
||||
... Use "/* verilator lint_off MULTITOP */" and lint_on around source to disable this message.
|
||||
%Warning-MULTITOP: t/t_flag_topmodule.v:21: Multiple top level modules: b and a2
|
||||
%Error: Exiting due to
|
||||
|
@ -1,6 +1,6 @@
|
||||
%Warning-MODDUP: t/t_mod_dup_bad.v:13: Duplicate declaration of module: a
|
||||
t/t_mod_dup_bad.v:6: ... Location of original declaration
|
||||
... Use "/* verilator lint_off MODDUP */" and lint_on around source to disable this message.
|
||||
%Error-MULTITOP: t/t_mod_dup_bad.v:16: Unsupported: Multiple top level modules: b and test
|
||||
t/t_mod_dup_bad.v:16: ... Fix, or use --top-module option to select which you want.
|
||||
%Warning-MULTITOP: t/t_mod_dup_bad.v:16: Multiple top level modules: b and test
|
||||
t/t_mod_dup_bad.v:16: ... Suggest see manual; fix the duplicates, or use --top-module to select top.
|
||||
%Error: Exiting due to
|
||||
|
25
test_regress/t/t_multitop1.pl
Executable file
25
test_regress/t/t_multitop1.pl
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 0,
|
||||
);
|
||||
|
||||
# Order of lines is unspecified, so don't use a golden file
|
||||
file_grep($Self->{run_log_filename}, qr!In 'top.t'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'top.t.s'!);
|
||||
file_grep_not($Self->{run_log_filename}, qr!in_subfile!);
|
||||
|
||||
ok(1);
|
||||
1;
|
17
test_regress/t/t_multitop1.v
Normal file
17
test_regress/t/t_multitop1.v
Normal file
@ -0,0 +1,17 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
t_multitop1s s ();
|
||||
initial $display("In '%m'");
|
||||
always @(posedge clk) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
12
test_regress/t/t_multitop1s.v
Normal file
12
test_regress/t/t_multitop1s.v
Normal file
@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t_multitop1s;
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
||||
|
||||
module in_subfile;
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
44
test_regress/t/t_multitop_sig.cpp
Normal file
44
test_regress/t/t_multitop_sig.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2006 by Wilson Snyder.
|
||||
|
||||
#include <iostream>
|
||||
#include <verilated.h>
|
||||
#include "Vt_multitop_sig.h"
|
||||
|
||||
|
||||
// Use cout to avoid issues with %d/%lx etc
|
||||
#define CHECK_RESULT(got, exp) \
|
||||
if ((got) != (exp)) { \
|
||||
std::cout<<std::dec<<"%Error: "<<__FILE__<<":"<<__LINE__ \
|
||||
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<std::endl; \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Vt_multitop_sig *topp = new Vt_multitop_sig("");
|
||||
|
||||
Verilated::debug(0);
|
||||
|
||||
{
|
||||
topp->a__02Ein = 0;
|
||||
topp->b__02Ein = 0;
|
||||
topp->uniq_in = 0;
|
||||
topp->eval();
|
||||
CHECK_RESULT(topp->a__02Eout, 1);
|
||||
CHECK_RESULT(topp->b__02Eout, 0);
|
||||
CHECK_RESULT(topp->uniq_out, 1);
|
||||
topp->a__02Ein = 1;
|
||||
topp->b__02Ein = 1;
|
||||
topp->uniq_in = 1;
|
||||
topp->eval();
|
||||
CHECK_RESULT(topp->a__02Eout, 0);
|
||||
CHECK_RESULT(topp->b__02Eout, 1);
|
||||
CHECK_RESULT(topp->uniq_out, 0);
|
||||
}
|
||||
printf("*-* All Finished *-*\n");
|
||||
}
|
30
test_regress/t/t_multitop_sig.pl
Executable file
30
test_regress/t/t_multitop_sig.pl
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
verilator_flags2 => ["-Wno-MULTITOP --exe $Self->{t_dir}/$Self->{name}.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
file_grep($Self->{run_log_filename}, qr!In 'a'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'a.sub'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'b'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'b.sub'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'c'!);
|
||||
file_grep($Self->{run_log_filename}, qr!In 'c.sub'!);
|
||||
|
||||
ok(1);
|
||||
1;
|
32
test_regress/t/t_multitop_sig.v
Normal file
32
test_regress/t/t_multitop_sig.v
Normal file
@ -0,0 +1,32 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module a(in, out);
|
||||
input in;
|
||||
output out;
|
||||
assign out = !in;
|
||||
sub sub ();
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
||||
|
||||
module b(in, out);
|
||||
input in;
|
||||
output out;
|
||||
assign out = in;
|
||||
sub sub ();
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
||||
|
||||
module c(uniq_in, uniq_out);
|
||||
input uniq_in;
|
||||
output uniq_out;
|
||||
assign uniq_out = !uniq_in;
|
||||
sub sub ();
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
||||
|
||||
module sub;
|
||||
initial $display("In '%m'");
|
||||
endmodule
|
5
test_regress/t/t_multitop_sig_bad.out
Normal file
5
test_regress/t/t_multitop_sig_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
%Warning-MULTITOP: t/t_multitop_sig.v:14: Multiple top level modules: b and a
|
||||
t/t_multitop_sig.v:14: ... Suggest see manual; fix the duplicates, or use --top-module to select top.
|
||||
... Use "/* verilator lint_off MULTITOP */" and lint_on around source to disable this message.
|
||||
%Warning-MULTITOP: t/t_multitop_sig.v:22: Multiple top level modules: c and b
|
||||
%Error: Exiting due to
|
20
test_regress/t/t_multitop_sig_bad.pl
Executable file
20
test_regress/t/t_multitop_sig_bad.pl
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_multitop_sig.v");
|
||||
|
||||
compile(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
Loading…
Reference in New Issue
Block a user