Add --flaten for use with --xml-only (#2270).

This commit is contained in:
James Hanlon 2020-04-21 18:14:08 -04:00 committed by Wilson Snyder
parent 65cd4f6047
commit 97cbc10925
9 changed files with 170 additions and 8 deletions

View File

@ -20,6 +20,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
** Fix DPI import/export to be standard compliant, #2236. [Geza Lore]
*** Add --flatten for use with --xml-only, #2270. [James Hanlon]
**** Support $ferror, and $fflush without arguments, #1638.
**** Add error if use SystemC 2.2 and earlier (pre-2011) as is deprecated.

View File

@ -303,6 +303,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
-F <file> Parse options from a file, relatively
-f <file> Parse options from a file
-FI <file> Force include of a file
--flatten Force inlining of all modules, tasks and functions
-G<name>=<value> Overwrite toplevel parameter
--gdb Run Verilator under GDB interactively
--gdbbt Run Verilator under GDB for backtrace
@ -847,6 +848,12 @@ specified file might be used to contain define prototypes of custom
VL_VPRINTF functions, and may need to include verilatedos.h as this file is
included before any other standard includes.
=item --flatten
Force flattening of the design's hierarchy, with all modules, tasks and
functions inlined. Typically used with C<--xml-only>. Note flattening
large designs may require significant CPU time, memory and storage.
=item -GI<name>=I<value>
Overwrites the given parameter of the toplevel module. The value is limited

View File

@ -21,7 +21,7 @@ parser.
== Structure
The XML document is consists of 4 sections within the top level `verilator_xml`
The XML document consists of 4 sections within the top level `verilator_xml`
element:
`<files>`...`</files>`::

View File

@ -194,13 +194,15 @@ private:
int refs = modp->user3();
// Should we automatically inline this module?
// If --flatten is specified, then force everything to be inlined that can be.
// inlineMult = 2000 by default.
// If a mod*#refs is < this # nodes, can inline it
bool doit = ((allowed == CIL_USER)
|| ((allowed == CIL_MAYBE)
&& (refs == 1 || statements < INLINE_MODS_SMALLER
|| v3Global.opt.inlineMult() < 1
|| refs * statements < v3Global.opt.inlineMult())));
&& (v3Global.opt.flatten()
|| (refs == 1 || statements < INLINE_MODS_SMALLER
|| v3Global.opt.inlineMult() < 1
|| refs * statements < v3Global.opt.inlineMult()))));
// Packages aren't really "under" anything so they confuse this algorithm
if (VN_IS(modp, Package)) doit = false;
UINFO(4, " Inline=" << doit << " Possible=" << allowed << " Refs=" << refs

View File

@ -842,6 +842,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
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, "-exe", flag/*ref*/)) { m_exe = flag; }
else if ( onoff (sw, "-flatten", flag/*ref*/)) { m_flatten = flag; }
else if ( onoff (sw, "-ignc", flag/*ref*/)) { m_ignc = flag; }
else if ( onoff (sw, "-inhibit-sim", flag/*ref*/)) { m_inhibitSim = flag; }
else if ( onoff (sw, "-lint-only", flag/*ref*/)) { m_lintOnly = flag; }
@ -1525,6 +1526,7 @@ V3Options::V3Options() {
m_dpiHdrOnly = false;
m_dumpDefines = false;
m_exe = false;
m_flatten = false;
m_ignc = false;
m_inhibitSim = false;
m_lintOnly = false;

View File

@ -230,6 +230,7 @@ private:
bool m_dpiHdrOnly; // main switch: --dpi-hdr-only
bool m_dumpDefines; // main switch: --dump-defines
bool m_exe; // main switch: --exe
bool m_flatten; // main switch: --flatten
bool m_ignc; // main switch: --ignc
bool m_inhibitSim; // main switch: --inhibit-sim
bool m_lintOnly; // main switch: --lint-only
@ -424,6 +425,7 @@ public:
bool dpiHdrOnly() const { return m_dpiHdrOnly; }
bool dumpDefines() const { return m_dumpDefines; }
bool exe() const { return m_exe; }
bool flatten() const { return m_flatten; }
bool gmake() const { return m_gmake; }
bool threadsDpiPure() const { return m_threadsDpiPure; }
bool threadsDpiUnpure() const { return m_threadsDpiUnpure; }

View File

@ -160,7 +160,7 @@ static void process() {
//
V3Assert::assertAll(v3Global.rootp());
if (!v3Global.opt.xmlOnly()) {
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
// Add top level wrapper with instance pointing to old top
// Move packages to under new top
// Must do this after we know parameters and dtypes (as don't clone dtype decls)
@ -170,7 +170,7 @@ static void process() {
// Propagate constants into expressions
V3Const::constifyAllLint(v3Global.rootp());
if (!v3Global.opt.xmlOnly()) {
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
// Split packed variables into multiple pieces to resolve UNOPTFLAT.
// should be after constifyAllLint() which flattens to 1D bit vector
V3SplitVar::splitVariable(v3Global.rootp());
@ -214,7 +214,7 @@ static void process() {
//--FLATTENING---------------
if (!v3Global.opt.xmlOnly()) {
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
// We're going to flatten the hierarchy, so as many optimizations that
// can be done as possible should be before this....
@ -234,19 +234,25 @@ static void process() {
//--SCOPE BASED OPTIMIZATIONS--------------
if (!v3Global.opt.xmlOnly()) {
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
// Cleanup
V3Const::constifyAll(v3Global.rootp());
V3Dead::deadifyDTypesScoped(v3Global.rootp());
v3Global.checkTree();
}
if (!v3Global.opt.xmlOnly()) {
// Convert case statements to if() blocks. Must be after V3Unknown
// Must be before V3Task so don't need to deal with task in case value compares
V3Case::caseAll(v3Global.rootp());
}
if (!(v3Global.opt.xmlOnly() && !v3Global.opt.flatten())) {
// Inline all tasks
V3Task::taskAll(v3Global.rootp());
}
if (!v3Global.opt.xmlOnly()) {
// Add __PVT's
// After V3Task so task internal variables will get renamed
V3Name::nameAll(v3Global.rootp());

View File

@ -0,0 +1,114 @@
<?xml version="1.0" ?>
<!-- DESCRIPTION: Verilator output: XML representation of netlist -->
<verilator_xml>
<files>
<file id="a" filename="&lt;built-in&gt;" language="1800-2017"/>
<file id="b" filename="&lt;command-line&gt;" language="1800-2017"/>
<file id="c" filename="input.vc" language="1800-2017"/>
<file id="d" filename="t/t_xml_first.v" language="1800-2017"/>
</files>
<module_files>
<file id="d" filename="t/t_xml_first.v" language="1800-2017"/>
</module_files>
<cells>
<cell fl="d7" loc="d,7,8,7,9" name="TOP" submodname="TOP" hier="TOP"/>
</cells>
<netlist>
<module fl="d7" loc="d,7,8,7,9" name="TOP" origName="TOP" topModule="1" public="true">
<var fl="d13" loc="d,13,10,13,13" name="clk" dtype_id="1" dir="input" vartype="logic" origName="clk" clocker="true" public="true"/>
<var fl="d14" loc="d,14,16,14,17" name="d" dtype_id="2" dir="input" vartype="logic" origName="d" public="true"/>
<var fl="d15" loc="d,15,22,15,23" name="q" dtype_id="2" dir="output" vartype="logic" origName="q" public="true"/>
<var fl="d13" loc="d,13,10,13,13" name="t.clk" dtype_id="1" vartype="logic" origName="clk"/>
<var fl="d14" loc="d,14,16,14,17" name="t.d" dtype_id="2" vartype="logic" origName="d"/>
<var fl="d15" loc="d,15,22,15,23" name="t.q" dtype_id="2" vartype="logic" origName="q"/>
<var fl="d17" loc="d,17,22,17,29" name="t.between" dtype_id="2" vartype="logic" origName="between"/>
<var fl="d32" loc="d,32,15,32,20" name="t.cell1.WIDTH" dtype_id="3" vartype="logic" origName="WIDTH" param="true">
<const fl="d19" loc="d,19,18,19,19" name="32&apos;sh4" dtype_id="3"/>
</var>
<var fl="d34" loc="d,34,24,34,27" name="t.cell1.clk" dtype_id="1" vartype="logic" origName="clk"/>
<var fl="d35" loc="d,35,30,35,31" name="t.cell1.d" dtype_id="2" vartype="logic" origName="d"/>
<var fl="d36" loc="d,36,30,36,31" name="t.cell1.q" dtype_id="2" vartype="logic" origName="q"/>
<var fl="d39" loc="d,39,15,39,22" name="t.cell1.IGNORED" dtype_id="3" vartype="logic" origName="IGNORED" localparam="true">
<const fl="d39" loc="d,39,25,39,26" name="32&apos;sh1" dtype_id="3"/>
</var>
<var fl="d48" loc="d,48,10,48,13" name="t.cell2.clk" dtype_id="1" vartype="logic" origName="clk"/>
<var fl="d49" loc="d,49,16,49,17" name="t.cell2.d" dtype_id="2" vartype="logic" origName="d"/>
<var fl="d50" loc="d,50,22,50,23" name="t.cell2.q" dtype_id="2" vartype="logic" origName="q"/>
<topscope fl="d7" loc="d,7,8,7,9">
<scope fl="d7" loc="d,7,8,7,9" name="TOP">
<varscope fl="d13" loc="d,13,10,13,13" name="clk" dtype_id="1"/>
<varscope fl="d14" loc="d,14,16,14,17" name="d" dtype_id="2"/>
<varscope fl="d15" loc="d,15,22,15,23" name="q" dtype_id="2"/>
<varscope fl="d13" loc="d,13,10,13,13" name="t.clk" dtype_id="1"/>
<varscope fl="d14" loc="d,14,16,14,17" name="t.d" dtype_id="2"/>
<varscope fl="d15" loc="d,15,22,15,23" name="t.q" dtype_id="2"/>
<varscope fl="d17" loc="d,17,22,17,29" name="t.between" dtype_id="2"/>
<varscope fl="d32" loc="d,32,15,32,20" name="t.cell1.WIDTH" dtype_id="3"/>
<varscope fl="d34" loc="d,34,24,34,27" name="t.cell1.clk" dtype_id="1"/>
<varscope fl="d35" loc="d,35,30,35,31" name="t.cell1.d" dtype_id="2"/>
<varscope fl="d36" loc="d,36,30,36,31" name="t.cell1.q" dtype_id="2"/>
<varscope fl="d39" loc="d,39,15,39,22" name="t.cell1.IGNORED" dtype_id="3"/>
<varscope fl="d48" loc="d,48,10,48,13" name="t.cell2.clk" dtype_id="1"/>
<varscope fl="d49" loc="d,49,16,49,17" name="t.cell2.d" dtype_id="2"/>
<varscope fl="d50" loc="d,50,22,50,23" name="t.cell2.q" dtype_id="2"/>
<assignalias fl="d13" loc="d,13,10,13,13" dtype_id="1">
<varref fl="d13" loc="d,13,10,13,13" name="clk" dtype_id="1"/>
<varref fl="d13" loc="d,13,10,13,13" name="clk" dtype_id="1"/>
</assignalias>
<assignalias fl="d14" loc="d,14,16,14,17" dtype_id="2">
<varref fl="d14" loc="d,14,16,14,17" name="d" dtype_id="2"/>
<varref fl="d14" loc="d,14,16,14,17" name="d" dtype_id="2"/>
</assignalias>
<assignalias fl="d15" loc="d,15,22,15,23" dtype_id="2">
<varref fl="d15" loc="d,15,22,15,23" name="q" dtype_id="2"/>
<varref fl="d15" loc="d,15,22,15,23" name="q" dtype_id="2"/>
</assignalias>
<assignalias fl="d34" loc="d,34,24,34,27" dtype_id="1">
<varref fl="d34" loc="d,34,24,34,27" name="t.clk" dtype_id="1"/>
<varref fl="d34" loc="d,34,24,34,27" name="cell1.clk" dtype_id="1"/>
</assignalias>
<assignalias fl="d35" loc="d,35,30,35,31" dtype_id="2">
<varref fl="d35" loc="d,35,30,35,31" name="t.d" dtype_id="2"/>
<varref fl="d35" loc="d,35,30,35,31" name="cell1.d" dtype_id="2"/>
</assignalias>
<assignalias fl="d36" loc="d,36,30,36,31" dtype_id="2">
<varref fl="d36" loc="d,36,30,36,31" name="t.between" dtype_id="2"/>
<varref fl="d36" loc="d,36,30,36,31" name="cell1.q" dtype_id="2"/>
</assignalias>
<always fl="d41" loc="d,41,4,41,10">
<sentree fl="d41" loc="d,41,11,41,12">
<senitem fl="d41" loc="d,41,13,41,20" edgeType="POS">
<varref fl="d41" loc="d,41,21,41,24" name="clk" dtype_id="1"/>
</senitem>
</sentree>
<assigndly fl="d42" loc="d,42,8,42,10" dtype_id="2">
<varref fl="d42" loc="d,42,11,42,12" name="d" dtype_id="2"/>
<varref fl="d42" loc="d,42,6,42,7" name="t.between" dtype_id="2"/>
</assigndly>
</always>
<assignalias fl="d48" loc="d,48,10,48,13" dtype_id="1">
<varref fl="d48" loc="d,48,10,48,13" name="t.clk" dtype_id="1"/>
<varref fl="d48" loc="d,48,10,48,13" name="cell2.clk" dtype_id="1"/>
</assignalias>
<assignalias fl="d49" loc="d,49,16,49,17" dtype_id="2">
<varref fl="d49" loc="d,49,16,49,17" name="t.between" dtype_id="2"/>
<varref fl="d49" loc="d,49,16,49,17" name="cell2.d" dtype_id="2"/>
</assignalias>
<assignalias fl="d50" loc="d,50,22,50,23" dtype_id="2">
<varref fl="d50" loc="d,50,22,50,23" name="t.q" dtype_id="2"/>
<varref fl="d50" loc="d,50,22,50,23" name="cell2.q" dtype_id="2"/>
</assignalias>
<contassign fl="d53" loc="d,53,13,53,14" dtype_id="2">
<varref fl="d53" loc="d,53,15,53,16" name="t.between" dtype_id="2"/>
<varref fl="d53" loc="d,53,11,53,12" name="q" dtype_id="2"/>
</contassign>
</scope>
</topscope>
</module>
<typetable fl="a0" loc="a,0,0,0,0">
<basicdtype fl="d48" loc="d,48,10,48,13" id="1" name="logic"/>
<basicdtype fl="d14" loc="d,14,10,14,11" id="2" name="logic" left="3" right="0"/>
<basicdtype fl="d19" loc="d,19,18,19,19" id="3" name="logic" left="31" right="0"/>
</typetable>
</netlist>
</verilator_xml>

27
test_regress/t/t_xml_flat.pl Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2012 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);
my $out_filename = "$Self->{obj_dir}/V$Self->{name}.xml";
top_filename("t/t_xml_first.v");
compile(
verilator_flags2 => ['--xml-only', '--flatten'],
verilator_make_gmake => 0,
make_top_shell => 0,
make_main => 0,
);
files_identical("$out_filename", $Self->{golden_filename});
ok(1);
1;