Add --dump-defines.
This commit is contained in:
parent
74a92e739f
commit
e0654dc218
2
Changes
2
Changes
|
|
@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
* Verilator 4.005 devel
|
* Verilator 4.005 devel
|
||||||
|
|
||||||
|
** Add --dump-defines.
|
||||||
|
|
||||||
*** For --trace-fst, save enum decoding information, bug1358. [Sergi Granell]
|
*** For --trace-fst, save enum decoding information, bug1358. [Sergi Granell]
|
||||||
(To visualize enumeration data you must use GTKwave 3.3.95 or newer.)
|
(To visualize enumeration data you must use GTKwave 3.3.95 or newer.)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
|
||||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||||
--default-language <lang> Default language to parse
|
--default-language <lang> Default language to parse
|
||||||
+define+<var>=<value> Set preprocessor define
|
+define+<var>=<value> Set preprocessor define
|
||||||
|
--dump-defines Show preprocessor defines with -E
|
||||||
--dump-tree Enable dumping .tree files
|
--dump-tree Enable dumping .tree files
|
||||||
--dump-treei <level> Enable dumping .tree files at a level
|
--dump-treei <level> Enable dumping .tree files at a level
|
||||||
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
|
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
|
||||||
|
|
@ -718,6 +719,15 @@ Defines the given preprocessor symbol, or multiple symbols if separated by
|
||||||
plusses. Similar to -D; +define is fairly standard across Verilog tools
|
plusses. Similar to -D; +define is fairly standard across Verilog tools
|
||||||
while -D is an alias for GCC compatibility.
|
while -D is an alias for GCC compatibility.
|
||||||
|
|
||||||
|
=item --dump-defines
|
||||||
|
|
||||||
|
With -E, suppress normal output, and instead print a list of all defines
|
||||||
|
existing at the end of pre-processing the input files. Similar to GCC "-dM"
|
||||||
|
option. This also gives you a way of finding out what is predefined in
|
||||||
|
Verilator using the command:
|
||||||
|
|
||||||
|
touch foo.v ; verilator -E --dump-defines foo.v
|
||||||
|
|
||||||
=item --dump-tree
|
=item --dump-tree
|
||||||
|
|
||||||
Rarely needed. Enable writing .tree debug files with dumping level 3,
|
Rarely needed. Enable writing .tree debug files with dumping level 3,
|
||||||
|
|
|
||||||
|
|
@ -670,6 +670,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
|
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
|
||||||
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
|
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
|
||||||
else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; }
|
else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; }
|
||||||
|
else if ( onoff (sw, "-dump-defines", flag/*ref*/) ) { m_dumpDefines = flag; }
|
||||||
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei
|
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei
|
||||||
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
|
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
|
||||||
else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; }
|
else if ( onoff (sw, "-ignc", flag/*ref*/) ) { m_ignc = flag; }
|
||||||
|
|
@ -1253,6 +1254,7 @@ V3Options::V3Options() {
|
||||||
m_debugPartition = false;
|
m_debugPartition = false;
|
||||||
m_debugSelfTest = false;
|
m_debugSelfTest = false;
|
||||||
m_decoration = true;
|
m_decoration = true;
|
||||||
|
m_dumpDefines = false;
|
||||||
m_exe = false;
|
m_exe = false;
|
||||||
m_ignc = false;
|
m_ignc = false;
|
||||||
m_inhibitSim = false;
|
m_inhibitSim = false;
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ class V3Options {
|
||||||
bool m_debugPartition; // main switch: --debug-partition
|
bool m_debugPartition; // main switch: --debug-partition
|
||||||
bool m_debugSelfTest; // main switch: --debug-self-test
|
bool m_debugSelfTest; // main switch: --debug-self-test
|
||||||
bool m_decoration; // main switch: --decoration
|
bool m_decoration; // main switch: --decoration
|
||||||
|
bool m_dumpDefines; // main switch: --dump-defines
|
||||||
bool m_exe; // main switch: --exe
|
bool m_exe; // main switch: --exe
|
||||||
bool m_ignc; // main switch: --ignc
|
bool m_ignc; // main switch: --ignc
|
||||||
bool m_inhibitSim; // main switch: --inhibit-sim
|
bool m_inhibitSim; // main switch: --inhibit-sim
|
||||||
|
|
@ -282,6 +283,7 @@ class V3Options {
|
||||||
bool debugPartition() const { return m_debugPartition; }
|
bool debugPartition() const { return m_debugPartition; }
|
||||||
bool debugSelfTest() const { return m_debugSelfTest; }
|
bool debugSelfTest() const { return m_debugSelfTest; }
|
||||||
bool decoration() const { return m_decoration; }
|
bool decoration() const { return m_decoration; }
|
||||||
|
bool dumpDefines() const { return m_dumpDefines; }
|
||||||
bool exe() const { return m_exe; }
|
bool exe() const { return m_exe; }
|
||||||
bool threadsDpiPure() const { return m_threadsDpiPure; }
|
bool threadsDpiPure() const { return m_threadsDpiPure; }
|
||||||
bool threadsDpiUnpure() const { return m_threadsDpiUnpure; }
|
bool threadsDpiUnpure() const { return m_threadsDpiUnpure; }
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,24 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3ParseImp::preprocDumps(std::ostream& os) {
|
||||||
|
if (v3Global.opt.dumpDefines()) {
|
||||||
|
V3PreShell::dumpDefines(os);
|
||||||
|
} else {
|
||||||
|
bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine();
|
||||||
|
for (std::deque<string>::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) {
|
||||||
|
if (noblanks) {
|
||||||
|
bool blank = true;
|
||||||
|
for (string::iterator its = it->begin(); its != it->end(); ++its) {
|
||||||
|
if (!isspace(*its) && *its!='\n') { blank=false; break; }
|
||||||
|
}
|
||||||
|
if (blank) continue;
|
||||||
|
}
|
||||||
|
os << *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
|
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
|
||||||
const string& errmsg) { // "" for no error, make fake node
|
const string& errmsg) { // "" for no error, make fake node
|
||||||
string modname = V3Os::filenameNonExt(modfilename);
|
string modname = V3Os::filenameNonExt(modfilename);
|
||||||
|
|
@ -123,7 +141,6 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||||
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
|
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
|
||||||
std::ofstream* ofp = NULL;
|
std::ofstream* ofp = NULL;
|
||||||
std::ostream* osp;
|
std::ostream* osp;
|
||||||
bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine();
|
|
||||||
if (v3Global.opt.preprocOnly()) {
|
if (v3Global.opt.preprocOnly()) {
|
||||||
osp = &cout;
|
osp = &cout;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -133,16 +150,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||||
fileline->v3error("Cannot write preprocessor output: "+vppfilename);
|
fileline->v3error("Cannot write preprocessor output: "+vppfilename);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
for (std::deque<string>::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) {
|
preprocDumps(*osp);
|
||||||
if (noblanks) {
|
|
||||||
bool blank = true;
|
|
||||||
for (string::iterator its = it->begin(); its != it->end(); ++its) {
|
|
||||||
if (!isspace(*its) && *its!='\n') { blank=false; break; }
|
|
||||||
}
|
|
||||||
if (blank) continue;
|
|
||||||
}
|
|
||||||
*osp << *it;
|
|
||||||
}
|
|
||||||
if (ofp) {
|
if (ofp) {
|
||||||
ofp->close();
|
ofp->close();
|
||||||
delete ofp; VL_DANGLING(ofp);
|
delete ofp; VL_DANGLING(ofp);
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ private:
|
||||||
void lexFile(const string& modname);
|
void lexFile(const string& modname);
|
||||||
int yylexReadTok();
|
int yylexReadTok();
|
||||||
void lexToken(); // Internal; called from lexToBison
|
void lexToken(); // Internal; called from lexToBison
|
||||||
|
void preprocDumps(std::ostream& os);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ public:
|
||||||
void insertUnreadback(const string& text) { m_lineCmt += text; }
|
void insertUnreadback(const string& text) { m_lineCmt += text; }
|
||||||
void insertUnreadbackAtBol(const string& text);
|
void insertUnreadbackAtBol(const string& text);
|
||||||
void addLineComment(int enterExit);
|
void addLineComment(int enterExit);
|
||||||
|
void dumpDefines(std::ostream& os);
|
||||||
|
|
||||||
// METHODS, callbacks
|
// METHODS, callbacks
|
||||||
virtual void comment(const string& text); // Comment detected (if keepComments==2)
|
virtual void comment(const string& text); // Comment detected (if keepComments==2)
|
||||||
|
|
@ -798,6 +799,16 @@ void V3PreProcImp::addLineComment(int enterExit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void V3PreProcImp::dumpDefines(std::ostream& os) {
|
||||||
|
for (DefinesMap::iterator it = m_defines.begin(); it != m_defines.end(); ++it) {
|
||||||
|
os<<"`define "<<it->first;
|
||||||
|
// No need to print "()" below as already part of params()
|
||||||
|
if (!it->second.params().empty()) os<<it->second.params();
|
||||||
|
if (!it->second.value().empty()) os<<" "<<it->second.value();
|
||||||
|
os<<endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int V3PreProcImp::getRawToken() {
|
int V3PreProcImp::getRawToken() {
|
||||||
// Get a token from the file, whatever it may be.
|
// Get a token from the file, whatever it may be.
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,9 @@ public:
|
||||||
virtual string removeDefines(const string& text)=0; // Remove defines in a text string
|
virtual string removeDefines(const string& text)=0; // Remove defines in a text string
|
||||||
|
|
||||||
// UTILITIES
|
// UTILITIES
|
||||||
void error(const string& msg) { fileline()->v3error(msg); } ///< Report a error
|
void error(const string& msg) { fileline()->v3error(msg); } ///< Report an error
|
||||||
void fatal(const string& msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
|
void fatal(const string& msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
|
||||||
|
virtual void dumpDefines(std::ostream& os) = 0; ///< Print list of `defines
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
|
|
|
||||||
|
|
@ -167,3 +167,6 @@ void V3PreShell::defineCmdLine(const string& name, const string& value) {
|
||||||
void V3PreShell::undef(const string& name) {
|
void V3PreShell::undef(const string& name) {
|
||||||
V3PreShellImp::s_preprocp->undef(name);
|
V3PreShellImp::s_preprocp->undef(name);
|
||||||
}
|
}
|
||||||
|
void V3PreShell::dumpDefines(std::ostream& os) {
|
||||||
|
V3PreShellImp::s_preprocp->dumpDefines(os);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ public:
|
||||||
static string dependFiles() { return ""; } // Perl only
|
static string dependFiles() { return ""; } // Perl only
|
||||||
static void defineCmdLine(const string& name, const string& value);
|
static void defineCmdLine(const string& name, const string& value);
|
||||||
static void undef(const string& name);
|
static void undef(const string& name);
|
||||||
|
static void dumpDefines(std::ostream& os);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -948,5 +948,7 @@ predef 0 0
|
||||||
predef 1 1
|
predef 1 1
|
||||||
predef 2 2
|
predef 2 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`line 654 "t/t_preproc.v" 2
|
`line 656 "t/t_preproc.v" 2
|
||||||
|
|
|
||||||
|
|
@ -650,3 +650,5 @@ predef `SV_COV_NOCOV 0
|
||||||
predef `SV_COV_OK 1
|
predef `SV_COV_OK 1
|
||||||
predef `SV_COV_PARTIAL 2
|
predef `SV_COV_PARTIAL 2
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
// After `undefineall above, for testing --dump-defines
|
||||||
|
`define WITH_ARG(a) (a)(a)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
`define DEF_A0
|
||||||
|
`define PREDEF_COMMAND_LINE
|
||||||
|
`define SV_COV_ASSERTION 20
|
||||||
|
`define SV_COV_CHECK 3
|
||||||
|
`define SV_COV_ERROR -1
|
||||||
|
`define SV_COV_FSM_STATE 21
|
||||||
|
`define SV_COV_HIER 11
|
||||||
|
`define SV_COV_MODULE 10
|
||||||
|
`define SV_COV_NOCOV 0
|
||||||
|
`define SV_COV_OK 1
|
||||||
|
`define SV_COV_OVERFLOW -2
|
||||||
|
`define SV_COV_PARTIAL 2
|
||||||
|
`define SV_COV_RESET 2
|
||||||
|
`define SV_COV_START 0
|
||||||
|
`define SV_COV_STATEMENT 22
|
||||||
|
`define SV_COV_STOP 1
|
||||||
|
`define SV_COV_TOGGLE 23
|
||||||
|
`define SYSTEMVERILOG 1
|
||||||
|
`define TEST_OBJ_DIR obj_vlt/t_preproc_defines
|
||||||
|
`define VERILATOR 1
|
||||||
|
`define WITH_ARG(a) (a)(a)
|
||||||
|
`define coverage_block_off /*verilator coverage_block_off*/
|
||||||
|
`define systemc_clock /*verilator systemc_clock*/
|
||||||
|
`define verilator 1
|
||||||
|
`define verilator3 1
|
||||||
|
|
@ -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 => 1);
|
||||||
|
|
||||||
|
top_filename("t/t_preproc.v");
|
||||||
|
|
||||||
|
$Self->{golden_out} ||= "t/$Self->{name}.out";
|
||||||
|
my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp";
|
||||||
|
|
||||||
|
compile(
|
||||||
|
verilator_flags2 => ['-DDEF_A0 -DPREDEF_COMMAND_LINE -E --dump-defines'],
|
||||||
|
verilator_make_gcc => 0,
|
||||||
|
stdout_filename => $stdout_filename,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(files_identical($stdout_filename, $Self->{golden_out}));
|
||||||
|
|
||||||
|
1;
|
||||||
Loading…
Reference in New Issue