mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Add creating __inputs.vpp file with --debug (#4177).
This commit is contained in:
parent
444020f7c7
commit
d269fbb446
1
Changes
1
Changes
@ -19,6 +19,7 @@ Verilator 5.011 devel
|
||||
**Minor:**
|
||||
|
||||
* Support get_randstate/set_randstate class method function.
|
||||
* Add creating __inputs.vpp file with --debug (#4177). [Tudor Timi]
|
||||
* Optimize VPI callValueCbs (#4155). [Hennadii Chernyshchyk]
|
||||
* Fix crash on duplicate imported modules (#3231). [Robert Balas]
|
||||
* Fix false WIDTHEXPAND on array declarations (#3959). [JOTEGO]
|
||||
|
@ -126,8 +126,10 @@ In specific debug and other modes, it also creates:
|
||||
- Debugging graph files (from --debug)
|
||||
* - *{prefix}{misc}*\ .tree
|
||||
- Debugging files (from --debug)
|
||||
* - {mod_prefix}_{each_verilog_base_filename}*\ .vpp
|
||||
- Pre-processed verilog (from --debug)
|
||||
* - *{prefix}*\ __inputs\ .vpp
|
||||
- Pre-processed verilog for all files (from --debug)
|
||||
* - *{prefix}*\ _ *{each_verilog_base_filename}*\ .vpp
|
||||
- Pre-processed verilog for each file (from --debug)
|
||||
|
||||
After running Make, the C++ compiler may produce the following:
|
||||
|
||||
|
@ -1503,8 +1503,19 @@ debug level 5, with the V3Width.cpp file at level 9.
|
||||
--debug
|
||||
-------
|
||||
|
||||
When you run with ``--debug``, there are two primary output file types
|
||||
placed into the obj_dir, .tree and .dot files.
|
||||
When you run with ``--debug``, there are three primary output file types
|
||||
placed into the obj_dir, .vpp, .tree and .dot files.
|
||||
|
||||
.vpp Output
|
||||
-----------
|
||||
|
||||
Verilator creates a *{mod_prefix}*\ __inputs\ .vpp file containing all the
|
||||
files that were read, filtered by preprocessing. This file can be fed back
|
||||
into Verilator, replacing on the command line all of the previous input
|
||||
files, to enable simplification of test cases.
|
||||
|
||||
Verilator also creates .vpp files for each individual file passed on the
|
||||
command line.
|
||||
|
||||
|
||||
.dot Output
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "V3Os.h"
|
||||
#include "V3ParseBison.h" // Generated by bison
|
||||
#include "V3PreShell.h"
|
||||
#include "V3Stats.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -247,24 +248,22 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
|
||||
return got;
|
||||
}
|
||||
|
||||
void V3ParseImp::preprocDumps(std::ostream& os) {
|
||||
if (v3Global.opt.dumpDefines()) {
|
||||
V3PreShell::dumpDefines(os);
|
||||
} else {
|
||||
const bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine();
|
||||
for (auto& buf : m_ppBuffers) {
|
||||
if (noblanks) {
|
||||
bool blank = true;
|
||||
for (string::iterator its = buf.begin(); its != buf.end(); ++its) {
|
||||
if (!std::isspace(*its) && *its != '\n') {
|
||||
blank = false;
|
||||
break;
|
||||
}
|
||||
void V3ParseImp::preprocDumps(std::ostream& os, bool forInputs) {
|
||||
bool noblanks = forInputs || (v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine());
|
||||
bool nolines = forInputs;
|
||||
for (auto& buf : m_ppBuffers) {
|
||||
if (noblanks) {
|
||||
bool blank = true;
|
||||
for (string::iterator its = buf.begin(); its != buf.end(); ++its) {
|
||||
if (!std::isspace(*its) && *its != '\n') {
|
||||
blank = false;
|
||||
break;
|
||||
}
|
||||
if (blank) continue;
|
||||
}
|
||||
os << buf;
|
||||
if (blank) continue;
|
||||
if (nolines && buf.rfind("`line ", 0) == 0) continue;
|
||||
}
|
||||
os << buf;
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +291,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
|
||||
// Create output file with all the preprocessor output we buffered up
|
||||
const string vppfilename = v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix()
|
||||
+ "_" + nondirname + ".vpp";
|
||||
+ "__" + nondirname + ".vpp";
|
||||
std::ofstream* ofp = nullptr;
|
||||
std::ostream* osp;
|
||||
if (v3Global.opt.preprocOnly()) {
|
||||
@ -303,15 +302,20 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||
if (osp->fail()) {
|
||||
fileline->v3error("Cannot write preprocessor output: " + vppfilename);
|
||||
return;
|
||||
}
|
||||
if (v3Global.opt.dumpDefines()) {
|
||||
V3PreShell::dumpDefines(*osp);
|
||||
} else {
|
||||
preprocDumps(*osp);
|
||||
if (ofp) {
|
||||
ofp->close();
|
||||
VL_DO_DANGLING(delete ofp, ofp);
|
||||
}
|
||||
preprocDumps(*osp, false);
|
||||
}
|
||||
if (ofp) {
|
||||
ofp->close();
|
||||
VL_DO_DANGLING(delete ofp, ofp);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug() && modfilename != V3Options::getStdPackagePath()) dumpInputsFile();
|
||||
|
||||
// Parse it
|
||||
if (!v3Global.opt.preprocOnly()) {
|
||||
lexFile(modfilename);
|
||||
@ -320,6 +324,31 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||
}
|
||||
}
|
||||
|
||||
void V3ParseImp::dumpInputsFile() {
|
||||
// Create output file with joined preprocessor output we buffered up,
|
||||
// Useful for debug to feed back into Verilator
|
||||
static bool append = false;
|
||||
const string vppfilename
|
||||
= v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix() + "__inputs.vpp";
|
||||
std::ofstream* ofp = V3File::new_ofstream(vppfilename, append);
|
||||
if (ofp->fail()) {
|
||||
v3error("Cannot write preprocessor output: " + vppfilename);
|
||||
return;
|
||||
}
|
||||
if (!append) {
|
||||
append = true;
|
||||
UINFO(1, "Writing all preprocessed output to " << vppfilename << endl);
|
||||
*ofp << "// Dump of all post-preprocessor input\n";
|
||||
*ofp << "// Blank lines and `line directives have been removed\n";
|
||||
*ofp << "//\n";
|
||||
V3Stats::infoHeader(*ofp, "// ");
|
||||
}
|
||||
*ofp << "\n";
|
||||
preprocDumps(*ofp, true);
|
||||
ofp->close();
|
||||
VL_DO_DANGLING(delete ofp, ofp);
|
||||
}
|
||||
|
||||
void V3ParseImp::lexFile(const string& modname) {
|
||||
// Prepare for lexing
|
||||
UINFO(3, "Lexing " << modname << endl);
|
||||
|
@ -295,6 +295,7 @@ public:
|
||||
|
||||
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
|
||||
const string& errmsg);
|
||||
void dumpInputsFile();
|
||||
|
||||
private:
|
||||
void lexFile(const string& modname);
|
||||
@ -305,7 +306,7 @@ private:
|
||||
size_t tokenPipeScanParam(size_t depth);
|
||||
size_t tokenPipeScanType(size_t depth);
|
||||
const V3ParseBisonYYSType* tokenPeekp(size_t depth);
|
||||
void preprocDumps(std::ostream& os);
|
||||
void preprocDumps(std::ostream& os, bool forInputs);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
@ -121,6 +121,8 @@ public:
|
||||
static void statsFinalAll(AstNetlist* nodep);
|
||||
/// Called by the top level to dump the statistics
|
||||
static void statsReport();
|
||||
/// Called by debug dumps
|
||||
static void infoHeader(std::ofstream& os, const string& prefix);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
@ -40,18 +40,8 @@ class StatsReport final {
|
||||
std::ofstream& os; ///< Output stream
|
||||
static StatColl s_allStats; ///< All statistics
|
||||
|
||||
void header() {
|
||||
os << "Verilator Statistics Report\n\n";
|
||||
|
||||
os << "Information:\n";
|
||||
os << " " << V3Options::version() << '\n';
|
||||
os << " Arguments: " << v3Global.opt.allArgsString() << '\n';
|
||||
os << " Build jobs: " << v3Global.opt.buildJobs() << '\n';
|
||||
os << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n';
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
void sumit() {
|
||||
os << '\n';
|
||||
// If sumit is set on a statistic, combine with others of same name
|
||||
std::multimap<std::string, V3Statistic*> byName;
|
||||
// * is always first
|
||||
@ -179,7 +169,8 @@ public:
|
||||
// CONSTRUCTORS
|
||||
explicit StatsReport(std::ofstream* aofp)
|
||||
: os(*aofp) { // Need () or GCC 4.8 false warning
|
||||
header();
|
||||
os << "Verilator Statistics Report\n\n";
|
||||
V3Stats::infoHeader(os, "");
|
||||
sumit();
|
||||
stars();
|
||||
stages();
|
||||
@ -222,6 +213,14 @@ void V3Stats::statsStage(const string& name) {
|
||||
V3Stats::addStatPerf("Stage, Memory (MB), " + digitName, memory);
|
||||
}
|
||||
|
||||
void V3Stats::infoHeader(std::ofstream& os, const string& prefix) {
|
||||
os << prefix << "Information:\n";
|
||||
os << prefix << " " << V3Options::version() << '\n';
|
||||
os << prefix << " Arguments: " << v3Global.opt.allArgsString() << '\n';
|
||||
os << prefix << " Build jobs: " << v3Global.opt.buildJobs() << '\n';
|
||||
os << prefix << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n';
|
||||
}
|
||||
|
||||
void V3Stats::statsReport() {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
|
||||
|
22
test_regress/t/t_debug_inputs.pl
Executable file
22
test_regress/t/t_debug_inputs.pl
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
lint(
|
||||
v_flags => ["--debug --debugi 1 -Wno-MULTITOP t/t_debug_inputs_b.v"],
|
||||
);
|
||||
|
||||
file_grep("$Self->{obj_dir}/V$Self->{name}__inputs.vpp", qr/module t_debug_inputs /);
|
||||
file_grep("$Self->{obj_dir}/V$Self->{name}__inputs.vpp", qr/module t_debug_inputs_a /);
|
||||
file_grep("$Self->{obj_dir}/V$Self->{name}__inputs.vpp", qr/module t_debug_inputs_b /);
|
||||
|
||||
ok(1);
|
||||
1;
|
11
test_regress/t/t_debug_inputs.v
Normal file
11
test_regress/t/t_debug_inputs.v
Normal file
@ -0,0 +1,11 @@
|
||||
// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference
|
||||
// as the select expression
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`include "t/t_debug_inputs_a.v"
|
||||
|
||||
module t_debug_inputs (/*AUTOARG*/);
|
||||
endmodule
|
9
test_regress/t/t_debug_inputs_a.v
Normal file
9
test_regress/t/t_debug_inputs_a.v
Normal file
@ -0,0 +1,9 @@
|
||||
// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference
|
||||
// as the select expression
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t_debug_inputs_a (/*AUTOARG*/);
|
||||
endmodule
|
9
test_regress/t/t_debug_inputs_b.v
Normal file
9
test_regress/t/t_debug_inputs_b.v
Normal file
@ -0,0 +1,9 @@
|
||||
// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference
|
||||
// as the select expression
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t_debug_inputs_b (/*AUTOARG*/);
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user