Add --public-flat-rw switch, bug1511.

This switch exposes VARs, PORTs and WIREs to C++ code. It must be use
with care as it has a significant performance impact and may result in
mis-simulation of generated clocks. Anyhow, it is prefered over
--public and useful for VPI.

Signed-off-by: Lukasz Dalek <ldalek@antmicro.com>
Signed-off-by: Stefan Wallentowitz <stefan@wallentowitz.de>
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Lukasz Dalek 2019-09-23 07:56:07 -04:00 committed by Wilson Snyder
parent 502bd6cbd6
commit d6ac351dcb
10 changed files with 89 additions and 14 deletions

View File

@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Support $fseek, $ftell, $frewind, bug1496. [Howard Su] *** Support $fseek, $ftell, $frewind, bug1496. [Howard Su]
*** Add --public-flat-rw, bug1511. [Stefan Wallentowitz]
**** Fix make test with no VERILATOR_ROOT, bug1494. [Ahmed El-Mahmoudy] **** Fix make test with no VERILATOR_ROOT, bug1494. [Ahmed El-Mahmoudy]
**** Make Syms file honor --output-split-cfuncs, bug1499. [Todd Strader] **** Make Syms file honor --output-split-cfuncs, bug1499. [Todd Strader]

View File

@ -354,6 +354,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
--prof-threads Enable generating gantt chart data for threads --prof-threads Enable generating gantt chart data for threads
--private Debugging; see docs --private Debugging; see docs
--public Debugging; see docs --public Debugging; see docs
--public-flat-rw Mark all variables, etc as public_flat_rw
-pvalue+<name>=<value> Overwrite toplevel parameter -pvalue+<name>=<value> Overwrite toplevel parameter
--quiet-exit Don't print the command on failure --quiet-exit Don't print the command on failure
--relative-includes Resolve includes relative to current file --relative-includes Resolve includes relative to current file
@ -1168,6 +1169,16 @@ inlining. This will also turn off inlining as if all modules had a
/*verilator public_module*/, unless the module specifically enabled it with /*verilator public_module*/, unless the module specifically enabled it with
/*verilator inline_module*/. /*verilator inline_module*/.
=item --public-flat-rw
Declares all variables, ports and wires public as if they had /*verilator
public_flat_rw*/ comments. This will make them VPI accessible by their
flat name, but not turn off module inlining. This is particularly useful
in combination with --vpi. This may also in some rare cases result in
mis-simulation of generated clocks. Instead of this global switch, marking
only those signals that need public_flat_rw is typically significantly
better performing.
=item -pvalue+I<name>=I<value> =item -pvalue+I<name>=I<value>
Overwrites the given parameter(s) of the toplevel module. See -G for a Overwrites the given parameter(s) of the toplevel module. See -G for a
@ -2916,7 +2927,8 @@ signal should be declared public_flat (see above), but read-only.
Used after an input, output, register, or wire declaration to indicate the Used after an input, output, register, or wire declaration to indicate the
signal should be declared public_flat_rd (see above), and also writable, signal should be declared public_flat_rd (see above), and also writable,
where writes should be considered to have the timing specified by the given where writes should be considered to have the timing specified by the given
sensitivity edge list. sensitivity edge list. Set for all variables, ports and wires using the
--public-flat-rw switch.
=item /*verilator public_module*/ =item /*verilator public_module*/

View File

@ -10,6 +10,7 @@ Howard Su
Jeremy Bennett Jeremy Bennett
John Coiner John Coiner
Kanad Kanhere Kanad Kanhere
Lukasz Dalek
Maarten De Braekeleer Maarten De Braekeleer
Philipp Wagner Philipp Wagner
Richard Myers Richard Myers

View File

@ -189,6 +189,17 @@ private:
return; return;
} }
if (v3Global.opt.publicFlatRW()) {
switch (nodep->varType()) {
case AstVarType::VAR:
case AstVarType::PORT:
case AstVarType::WIRE:
nodep->sigUserRWPublic(true);
break;
default: break;
}
}
// We used modTrace before leveling, and we may now // We used modTrace before leveling, and we may now
// want to turn it off now that we know the levelizations // want to turn it off now that we know the levelizations
if (v3Global.opt.traceDepth() if (v3Global.opt.traceDepth()
@ -198,6 +209,7 @@ private:
nodep->trace(false); nodep->trace(false);
} }
m_varp = nodep; m_varp = nodep;
iterateChildren(nodep); iterateChildren(nodep);
m_varp = NULL; m_varp = NULL;
// temporaries under an always aren't expected to be blocking // temporaries under an always aren't expected to be blocking

View File

@ -696,6 +696,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/)) { m_profCFuncs = flag; } // Undocumented, for backward compat else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/)) { m_profCFuncs = flag; } // Undocumented, for backward compat
else if ( onoff (sw, "-prof-threads", flag/*ref*/)) { m_profThreads = flag; } else if ( onoff (sw, "-prof-threads", flag/*ref*/)) { m_profThreads = flag; }
else if ( onoff (sw, "-public", flag/*ref*/)) { m_public = flag; } else if ( onoff (sw, "-public", flag/*ref*/)) { m_public = flag; }
else if ( onoff (sw, "-public-flat-rw", flag/*ref*/) ) { m_publicFlatRW = flag; v3Global.dpi(true); }
else if (!strncmp(sw, "-pvalue+", strlen("-pvalue+"))) { addParameter(string(sw+strlen("-pvalue+")), false); } else if (!strncmp(sw, "-pvalue+", strlen("-pvalue+"))) { addParameter(string(sw+strlen("-pvalue+")), false); }
else if ( onoff (sw, "-relative-cfuncs", flag/*ref*/)) { m_relativeCFuncs = flag; } else if ( onoff (sw, "-relative-cfuncs", flag/*ref*/)) { m_relativeCFuncs = flag; }
else if ( onoff (sw, "-relative-includes", flag/*ref*/)) { m_relativeIncludes = flag; } else if ( onoff (sw, "-relative-includes", flag/*ref*/)) { m_relativeIncludes = flag; }
@ -1297,6 +1298,7 @@ V3Options::V3Options() {
m_preprocOnly = false; m_preprocOnly = false;
m_preprocNoLine = false; m_preprocNoLine = false;
m_public = false; m_public = false;
m_publicFlatRW = false;
m_relativeCFuncs = true; m_relativeCFuncs = true;
m_relativeIncludes = false; m_relativeIncludes = false;
m_reportUnoptflat = false; m_reportUnoptflat = false;

View File

@ -135,6 +135,7 @@ class V3Options {
bool m_profCFuncs; // main switch: --prof-cfuncs bool m_profCFuncs; // main switch: --prof-cfuncs
bool m_profThreads; // main switch: --prof-threads bool m_profThreads; // main switch: --prof-threads
bool m_public; // main switch: --public bool m_public; // main switch: --public
bool m_publicFlatRW; // main switch: --public-flat-rw
bool m_relativeCFuncs; // main switch: --relative-cfuncs bool m_relativeCFuncs; // main switch: --relative-cfuncs
bool m_relativeIncludes; // main switch: --relative-includes bool m_relativeIncludes; // main switch: --relative-includes
bool m_reportUnoptflat; // main switch: --report-unoptflat bool m_reportUnoptflat; // main switch: --report-unoptflat
@ -309,6 +310,7 @@ class V3Options {
bool profCFuncs() const { return m_profCFuncs; } bool profCFuncs() const { return m_profCFuncs; }
bool profThreads() const { return m_profThreads; } bool profThreads() const { return m_profThreads; }
bool allPublic() const { return m_public; } bool allPublic() const { return m_public; }
bool publicFlatRW() const { return m_publicFlatRW; }
bool lintOnly() const { return m_lintOnly; } bool lintOnly() const { return m_lintOnly; }
bool ignc() const { return m_ignc; } bool ignc() const { return m_ignc; }
bool inhibitSim() const { return m_inhibitSim; } bool inhibitSim() const { return m_inhibitSim; }

View File

@ -246,7 +246,7 @@ int main(int argc, char **argv, char **env) {
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
Verilated::debug(0); Verilated::debug(0);
VM_PREFIX* topp = new VM_PREFIX(""); // Note null name - we're flattening it out Vt_vpi_get* topp = new Vt_vpi_get(""); // Note null name - we're flattening it out
#ifdef VERILATOR #ifdef VERILATOR
# ifdef TEST_VERBOSE # ifdef TEST_VERBOSE

View File

@ -18,7 +18,7 @@ compile(
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi --no-l2name $Self->{t_dir}/t_vpi_get.cpp"], verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi --no-l2name $Self->{t_dir}/t_vpi_get.cpp"],
make_pli => 1, make_pli => 1,
iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI"], iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI"],
v_flags2 => ["+define+USE_VPI_NOT_DPI"], v_flags2 => ["+define+USE_VPI_NOT_DPI +define+VERILATOR_COMMENTS"],
); );
execute( execute(

View File

@ -11,13 +11,21 @@
import "DPI-C" context function integer mon_check(); import "DPI-C" context function integer mon_check();
`endif `endif
`ifdef VERILATOR_COMMENTS
`define PUBLIC_FLAT_RD /*verilator public_flat_rd*/
`define PUBLIC_FLAT_RW /*verilator public_flat_rw @(posedge clk)*/
`else
`define PUBLIC_FLAT_RD
`define PUBLIC_FLAT_RW
`endif
module t (/*AUTOARG*/ module t (/*AUTOARG*/
// Inputs // Inputs
input clk /*verilator public_flat_rd */, input clk `PUBLIC_FLAT_RD,
// test ports // test ports
input [15:0] testin /*verilator public_flat_rd */, input [15:0] testin `PUBLIC_FLAT_RD,
output [23:0] testout /*verilator public_flat_rw @(posedge clk) */ output [23:0] testout `PUBLIC_FLAT_RW
); );
@ -27,10 +35,10 @@ extern "C" int mon_check();
`verilog `verilog
`endif `endif
reg onebit /*verilator public_flat_rw @(posedge clk) */; reg onebit `PUBLIC_FLAT_RW;
reg [2:1] twoone /*verilator public_flat_rw @(posedge clk) */; reg [2:1] twoone `PUBLIC_FLAT_RW;
reg onetwo [1:2] /*verilator public_flat_rw @(posedge clk) */; reg onetwo [1:2] `PUBLIC_FLAT_RW;
reg [2:1] fourthreetwoone[4:3] /*verilator public_flat_rw @(posedge clk) */; reg [2:1] fourthreetwoone[4:3] `PUBLIC_FLAT_RW;
integer status; integer status;
@ -39,8 +47,8 @@ extern "C" int mon_check();
wire redundant = onebit | onetwo[1] | twoone | fourthreetwoone[3]; wire redundant = onebit | onetwo[1] | twoone | fourthreetwoone[3];
`endif `endif
wire subin /*verilator public_flat_rd*/; wire subin `PUBLIC_FLAT_RD;
wire subout /*verilator public_flat_rd*/; wire subout `PUBLIC_FLAT_RD;
sub sub(.*); sub sub(.*);
// Test loop // Test loop
@ -65,7 +73,7 @@ extern "C" int mon_check();
endmodule : t endmodule : t
module sub ( module sub (
input subin /*verilator public_flat_rd*/, input subin `PUBLIC_FLAT_RD,
output subout /*verilator public_flat_rd*/ output subout `PUBLIC_FLAT_RD
); );
endmodule : sub endmodule : sub

View File

@ -0,0 +1,36 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2010 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);
skip("Known compiler limitation")
if $Self->cxx_version =~ /\(GCC\) 4.4/;
VM_PREFIX("Vt_vpi_get");
top_filename("t/t_vpi_get.v");
pli_filename("t_vpi_get.cpp");
compile(
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --vpi"
." --public-flat-rw --prefix Vt_vpi_get --no-l2name"
." $Self->{t_dir}/t_vpi_get.cpp"],
make_pli => 1,
iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI"],
v_flags2 => ["+define+USE_VPI_NOT_DPI"],
);
execute(
iv_pli => 1,
check_finished => 1
);
ok(1);
1;