forked from github/verilator
Add --lib-create, similar to --protect-lib but without protections (#3200).
This commit is contained in:
parent
4b593f8eb3
commit
899de9a282
6
Changes
6
Changes
@ -11,11 +11,15 @@ contributors that suggested a given feature are shown in []. Thanks!
|
||||
Verilator 4.215 devel
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Add --lib-create, similar to --protect-lib but without protections.
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Internal code cleanups and improvements. [Geza Lore]
|
||||
* Improve --thread verilation-time performance.
|
||||
* Fix array method names with parens (#3181) (#3183). [Teng Huang]
|
||||
* Fix array method names with parenthesis (#3181) (#3183). [Teng Huang]
|
||||
* Fix split_var assign merging (#3177) (#3179). [Yutetsu TAKATSUKASA]
|
||||
* Fix nested generate if genblk naming (#3189). [yanx21]
|
||||
|
||||
|
@ -336,6 +336,7 @@ detailed descriptions of these arguments.
|
||||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||
--l2-name <value> Verilog scope name of the top module
|
||||
--language <lang> Default language standard to parse
|
||||
--lib-create <name> Create a DPI library
|
||||
+libext+<ext>+[ext]... Extensions for finding modules
|
||||
--lint-only Lint, but do not make output
|
||||
-MAKEFLAGS <flags> Arguments to pass to make during --build
|
||||
|
@ -575,6 +575,23 @@ Summary:
|
||||
"+libext+" is fairly standard across Verilog tools. Defaults to
|
||||
".v+.sv".
|
||||
|
||||
.. option:: --lib-create <name>
|
||||
|
||||
Produces C++, Verilog wrappers and a Makefile which can in turn produce
|
||||
a DPI library which can be used by Verilator or other simulators along
|
||||
with the corresponding Verilog wrapper. The Makefile will build both a
|
||||
static and dynamic version of the library named :file:`lib<name>.a` and
|
||||
:file:`lib<name>.so` respectively. This is done because some simulators
|
||||
require a dynamic library, but the static library is arguably easier to
|
||||
use if possible. :vlopt:`--protect-lib` implies :vlopt:`--protect-ids`.
|
||||
|
||||
When using :vlopt:`--lib-create` it is advised to also use
|
||||
:vlopt:`--timescale-override /1fs <--timescale-override>` to ensure the
|
||||
model has a time resolution that is always compatible with the time
|
||||
precision of the upper instantiating module.
|
||||
|
||||
See also :vlopt:`--protect-lib`.
|
||||
|
||||
.. option:: --lint-only
|
||||
|
||||
Check the files for lint violations only, do not create any other
|
||||
@ -872,24 +889,15 @@ Summary:
|
||||
|
||||
.. option:: --protect-lib <name>
|
||||
|
||||
Produces C++, Verilog wrappers and a Makefile which can in turn produce
|
||||
a DPI library which can be used by Verilator or other simulators along
|
||||
with the corresponding Verilog wrapper. The Makefile will build both a
|
||||
static and dynamic version of the library named :file:`lib<name>.a` and
|
||||
:file:`lib<name>.so` respectively. This is done because some simulators
|
||||
require a dynamic library, but the static library is arguably easier to
|
||||
use if possible. :vlopt:`--protect-lib` implies :vlopt:`--protect-ids`.
|
||||
Produces a DPI library similar to :vlopt:`--lib-create`, but hides
|
||||
internal design details. :vlopt:`--protect-lib` implies
|
||||
:vlopt:`--protect-ids`, and :vlopt:`--lib-create`.
|
||||
|
||||
This allows for the secure delivery of sensitive IP without the need for
|
||||
encrypted RTL (i.e. IEEE P1735). See :file:`examples/make_protect_lib`
|
||||
in the distribution for a demonstration of how to build and use the DPI
|
||||
library.
|
||||
|
||||
When using :vlopt:`--protect-lib` it is advised to also use
|
||||
:vlopt:`--timescale-override /1fs <--timescale-override>` to ensure the
|
||||
model has a time resolution that is always compatible with the time
|
||||
precision of the upper instantiating module.
|
||||
|
||||
.. option:: --private
|
||||
|
||||
Opposite of :vlopt:`--public`. Is the default; this option exists for
|
||||
|
@ -70,10 +70,9 @@ Verilator is run in hierarchical mode on the whole SoC. Verilator will
|
||||
make two models, one for the CPU hierarchy block, and one for the SoC. The
|
||||
Verialted code for the SoC will automatically call the CPU Verilated model.
|
||||
|
||||
The current hierarchical Verilation is based on protect-lib. Each hierarchy
|
||||
block is Verilated to a protect-lib. User modules of the hierarchy blocks
|
||||
will see a tiny wrapper generated by protect-lib instead of the actual
|
||||
design.
|
||||
The current hierarchical Verilation is based on :vlopt:`--lib-create`. Each
|
||||
hierarchy block is Verilated into a library. User modules of the hierarchy
|
||||
blocks will see a tiny wrapper generated by :vlopt:`--lib-create`.
|
||||
|
||||
|
||||
Usage
|
||||
|
@ -25,7 +25,7 @@
|
||||
//=========================================================================
|
||||
// Internal note:
|
||||
//
|
||||
// verilated.o may exist both in protect-lib (incrementally linked .a/.so)
|
||||
// verilated.o may exist both in --lib-create (incrementally linked .a/.so)
|
||||
// and the main module. Both refer the same instance of static
|
||||
// variables/VL_THREAD_LOCAL in verilated.o such as Verilated, or
|
||||
// VerilatedImpData. This is important to share that state, but the
|
||||
|
@ -178,8 +178,8 @@ class CMakeEmitter final {
|
||||
if (v3Global.opt.mtasks()) {
|
||||
global.emplace_back("${VERILATOR_ROOT}/include/verilated_threads.cpp");
|
||||
}
|
||||
if (!v3Global.opt.protectLib().empty()) {
|
||||
global.emplace_back(v3Global.opt.makeDir() + "/" + v3Global.opt.protectLib() + ".cpp");
|
||||
if (!v3Global.opt.libCreate().empty()) {
|
||||
global.emplace_back(v3Global.opt.makeDir() + "/" + v3Global.opt.libCreate() + ".cpp");
|
||||
}
|
||||
|
||||
*of << "# Global classes, need linked once per executable\n";
|
||||
@ -238,7 +238,7 @@ class CMakeEmitter final {
|
||||
// with .so
|
||||
<< ")\n";
|
||||
}
|
||||
*of << "\n# Verilate the top module that refers protect-lib wrappers of above\n";
|
||||
*of << "\n# Verilate the top module that refers to lib-create wrappers of above\n";
|
||||
*of << "verilate(${TOP_TARGET_NAME} PREFIX " << v3Global.opt.prefix() << " TOP_MODULE "
|
||||
<< v3Global.rootp()->topModulep()->name() << " DIRECTORY "
|
||||
<< deslash(v3Global.opt.makeDir()) << " SOURCES ";
|
||||
|
@ -145,8 +145,8 @@ public:
|
||||
|
||||
if (v3Global.opt.exe()) {
|
||||
of.puts("default: " + v3Global.opt.exeName() + "\n");
|
||||
} else if (!v3Global.opt.protectLib().empty()) {
|
||||
of.puts("default: lib" + v3Global.opt.protectLib() + "\n");
|
||||
} else if (!v3Global.opt.libCreate().empty()) {
|
||||
of.puts("default: lib" + v3Global.opt.libCreate() + "\n");
|
||||
} else {
|
||||
of.puts("default: " + v3Global.opt.prefix() + "__ALL.a\n");
|
||||
}
|
||||
@ -188,7 +188,7 @@ public:
|
||||
|
||||
of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n");
|
||||
of.puts("VM_USER_CFLAGS = \\\n");
|
||||
if (!v3Global.opt.protectLib().empty()) of.puts("\t-fPIC \\\n");
|
||||
if (!v3Global.opt.libCreate().empty()) of.puts("\t-fPIC \\\n");
|
||||
const V3StringList& cFlags = v3Global.opt.cFlags();
|
||||
for (const string& i : cFlags) of.puts("\t" + i + " \\\n");
|
||||
of.puts("\n");
|
||||
@ -243,19 +243,19 @@ public:
|
||||
of.puts("\n");
|
||||
}
|
||||
|
||||
if (!v3Global.opt.protectLib().empty()) {
|
||||
const string protectLibDeps = "$(VK_OBJS) $(VK_GLOBAL_OBJS) "
|
||||
+ v3Global.opt.protectLib() + ".o $(VM_HIER_LIBS)";
|
||||
of.puts("\n### Library rules from --protect-lib\n");
|
||||
if (!v3Global.opt.libCreate().empty()) {
|
||||
const string libCreateDeps = "$(VK_OBJS) $(VK_GLOBAL_OBJS) " + v3Global.opt.libCreate()
|
||||
+ ".o $(VM_HIER_LIBS)";
|
||||
of.puts("\n### Library rules from --lib-create\n");
|
||||
// The rule to create .a is defined in verilated.mk, so just define dependency here.
|
||||
of.puts(v3Global.opt.protectLibName(false) + ": " + protectLibDeps + "\n");
|
||||
of.puts(v3Global.opt.libCreateName(false) + ": " + libCreateDeps + "\n");
|
||||
of.puts("\n");
|
||||
if (v3Global.opt.hierChild()) {
|
||||
// Hierarchical child does not need .so because hierTop() will create .so from .a
|
||||
of.puts("lib" + v3Global.opt.protectLib() + ": "
|
||||
+ v3Global.opt.protectLibName(false) + "\n");
|
||||
of.puts("lib" + v3Global.opt.libCreate() + ": " + v3Global.opt.libCreateName(false)
|
||||
+ "\n");
|
||||
} else {
|
||||
of.puts(v3Global.opt.protectLibName(true) + ": " + protectLibDeps + "\n");
|
||||
of.puts(v3Global.opt.libCreateName(true) + ": " + libCreateDeps + "\n");
|
||||
// Linker on mac emits an error if all symbols are not found here,
|
||||
// but some symbols that are referred as "DPI-C" can not be found at this moment.
|
||||
// So add dynamic_lookup
|
||||
@ -267,9 +267,8 @@ public:
|
||||
"\t$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -shared -o $@ $^\n");
|
||||
of.puts("endif\n");
|
||||
of.puts("\n");
|
||||
of.puts("lib" + v3Global.opt.protectLib() + ": "
|
||||
+ v3Global.opt.protectLibName(false) + " "
|
||||
+ v3Global.opt.protectLibName(true) + "\n");
|
||||
of.puts("lib" + v3Global.opt.libCreate() + ": " + v3Global.opt.libCreateName(false)
|
||||
+ " " + v3Global.opt.libCreateName(true) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,9 @@
|
||||
// - time and memory for Verilation
|
||||
// - compilation time especially when a hierarchical block is used many times
|
||||
//
|
||||
// Hierarchical Verilation internally creates protect-lib for each hierarchical block.
|
||||
// Upper modules read wrapper for the protect-lib instead of the actual design.
|
||||
// Hierarchical Verilation internally uses --lib-create for each
|
||||
// hierarchical block. Upper modules read the wrapper from --lib-create
|
||||
// instead of the Verilog design.
|
||||
//
|
||||
// Hierarchical Verilation runs as the following step
|
||||
// 1) Find modules marked by /*verilator hier_block*/ metacomment
|
||||
@ -29,7 +30,7 @@
|
||||
//
|
||||
// There are 3 kinds of Verilator run.
|
||||
// a) To create ${prefix}_hier.mk (--hierarchical)
|
||||
// b) To create protect-lib for each hierarchical block (--hierarchical-child)
|
||||
// b) To --lib-create on each hierarchical block (--hierarchical-child)
|
||||
// c) To load wrappers and Verilate the top module (... what primary flags?)
|
||||
//
|
||||
// Then user can build Verilated module as usual.
|
||||
@ -52,7 +53,7 @@
|
||||
// 4) V3LinkDot.cpp checks dotted access across hierarchical block boundary.
|
||||
// 5) In V3Dead.cpp, some parameters of parameterized modules are protected not to be deleted even
|
||||
// if the parameter is not referred. This protection is necessary to match step 6) below.
|
||||
// 6) In V3Param.cpp, use protect-lib wrapper of parameterized module made in b) and c).
|
||||
// 6) In V3Param.cpp, use --lib-create wrapper of the parameterized module made in b) and c).
|
||||
// If a hierarchical block is a parameterized module and instantiated in multiple locations,
|
||||
// all parameters must exactly match.
|
||||
// 7) In V3HierBlock.cpp, relationship among hierarchical blocks are checked in run a).
|
||||
@ -152,8 +153,9 @@ V3StringList V3HierBlock::commandArgs(bool forCMake) const {
|
||||
opts.push_back(" --mod-prefix " + prefix);
|
||||
opts.push_back(" --top-module " + modp()->name());
|
||||
}
|
||||
opts.push_back(" --protect-lib " + modp()->name()); // mangled name
|
||||
opts.push_back(" --protect-key " + v3Global.opt.protectKeyDefaulted());
|
||||
opts.push_back(" --lib-create " + modp()->name()); // possibly mangled name
|
||||
if (v3Global.opt.protectKeyProvided())
|
||||
opts.push_back(" --protect-key " + v3Global.opt.protectKeyDefaulted());
|
||||
opts.push_back(" --hierarchical-child");
|
||||
|
||||
const StrGParams gparamsStr = stringifyParams(gparams(), true);
|
||||
@ -418,8 +420,10 @@ void V3HierBlockPlan::writeCommandArgsFiles(bool forCMake) const {
|
||||
*of << it->second->hierBlockArgs().front() << "\n";
|
||||
}
|
||||
|
||||
if (!v3Global.opt.protectLib().empty()) {
|
||||
*of << "--protect-lib " << v3Global.opt.protectLib() << "\n";
|
||||
if (!v3Global.opt.libCreate().empty()) {
|
||||
*of << "--lib-create " << v3Global.opt.libCreate() << "\n";
|
||||
}
|
||||
if (v3Global.opt.protectKeyProvided()) {
|
||||
*of << "--protect-key " << v3Global.opt.protectKeyDefaulted() << "\n";
|
||||
}
|
||||
if (v3Global.opt.threads() > 0) {
|
||||
|
@ -263,9 +263,9 @@ private:
|
||||
virtual void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == AstPragmaType::HIER_BLOCK) {
|
||||
UASSERT_OBJ(m_modp, nodep, "HIER_BLOCK not under a module");
|
||||
// If this is hierarchical mode which is to create protect-lib,
|
||||
// If this is hierarchical mode which is to lib-create,
|
||||
// sub modules do not have hier_block meta comment in the source code.
|
||||
// But .vlt files may still mark a module which is actually a protect-lib wrapper
|
||||
// But .vlt files may still mark a module which is actually a lib-create wrapper
|
||||
// hier_block. AstNodeModule::hierBlock() can be true only when --hierarchical is
|
||||
// specified.
|
||||
m_modp->hierBlock(v3Global.opt.hierarchical());
|
||||
|
@ -500,9 +500,9 @@ string V3Options::filePathCheckOneDir(const string& modname, const string& dirna
|
||||
// 1: Delete the option which has no argument
|
||||
// 2: Delete the option and its argument
|
||||
int V3Options::stripOptionsForChildRun(const string& opt, bool forTop) {
|
||||
if (opt == "Mdir" || opt == "clk" || opt == "f" || opt == "j" || opt == "l2-name"
|
||||
|| opt == "mod-prefix" || opt == "prefix" || opt == "protect-lib" || opt == "protect-key"
|
||||
|| opt == "threads" || opt == "top-module" || opt == "v") {
|
||||
if (opt == "Mdir" || opt == "clk" || opt == "lib-create" || opt == "f" || opt == "j"
|
||||
|| opt == "l2-name" || opt == "mod-prefix" || opt == "prefix" || opt == "protect-lib"
|
||||
|| opt == "protect-key" || opt == "threads" || opt == "top-module" || opt == "v") {
|
||||
return 2;
|
||||
}
|
||||
if (opt == "build" || (!forTop && (opt == "cc" || opt == "exe" || opt == "sc"))
|
||||
@ -732,11 +732,6 @@ void V3Options::notify() {
|
||||
if (m_hierChild && m_hierBlocks.empty()) {
|
||||
cmdfl->v3error("--hierarchical-block must be set when --hierarchical-child is set");
|
||||
}
|
||||
if (m_hierarchical && m_protectLib.empty() && m_protectKey.empty()) {
|
||||
// Key for hierarchical Verilation is fixed to be ccache friendly when the aim of this run
|
||||
// is not to create protec-lib.
|
||||
m_protectKey = "VL-KEY-HIERARCHICAL";
|
||||
}
|
||||
|
||||
if (protectIds()) {
|
||||
if (allPublic()) {
|
||||
@ -1121,6 +1116,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
};
|
||||
DECL_OPTION("-default-language", CbVal, setLang);
|
||||
DECL_OPTION("-language", CbVal, setLang);
|
||||
DECL_OPTION("-lib-create", Set, &m_libCreate);
|
||||
DECL_OPTION("-lint-only", OnOff, &m_lintOnly);
|
||||
DECL_OPTION("-l2-name", Set, &m_l2Name);
|
||||
DECL_OPTION("-no-l2name", CbCall, [this]() { m_l2Name = ""; }).undocumented(); // Historical
|
||||
@ -1237,7 +1233,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
DECL_OPTION("-protect-ids", OnOff, &m_protectIds);
|
||||
DECL_OPTION("-protect-key", Set, &m_protectKey);
|
||||
DECL_OPTION("-protect-lib", CbVal, [this](const char* valp) {
|
||||
m_protectLib = valp;
|
||||
m_libCreate = valp;
|
||||
m_protectIds = true;
|
||||
});
|
||||
DECL_OPTION("-public", OnOff, &m_public);
|
||||
|
@ -321,12 +321,12 @@ private:
|
||||
string m_exeName; // main switch: -o {name}
|
||||
string m_flags; // main switch: -f {name}
|
||||
string m_l2Name; // main switch: --l2name; "" for top-module's name
|
||||
string m_libCreate; // main switch: --lib-create {lib_name}
|
||||
string m_makeDir; // main switch: -Mdir
|
||||
string m_modPrefix; // main switch: --mod-prefix
|
||||
string m_pipeFilter; // main switch: --pipe-filter
|
||||
string m_prefix; // main switch: --prefix
|
||||
string m_protectKey; // main switch: --protect-key
|
||||
string m_protectLib; // main switch: --protect-lib {lib_name}
|
||||
string m_topModule; // main switch: --top-module
|
||||
string m_unusedRegexp; // main switch: --unused-regexp
|
||||
string m_waiverOutput; // main switch: --waiver-output {filename}
|
||||
@ -526,14 +526,9 @@ public:
|
||||
|
||||
string exeName() const { return m_exeName != "" ? m_exeName : prefix(); }
|
||||
string l2Name() const { return m_l2Name; }
|
||||
string makeDir() const { return m_makeDir; }
|
||||
string modPrefix() const { return m_modPrefix; }
|
||||
string pipeFilter() const { return m_pipeFilter; }
|
||||
string prefix() const { return m_prefix; }
|
||||
string protectKeyDefaulted(); // Set default key if not set by user
|
||||
string protectLib() const { return m_protectLib; }
|
||||
string protectLibName(bool shared) {
|
||||
string libName = "lib" + protectLib();
|
||||
string libCreate() const { return m_libCreate; }
|
||||
string libCreateName(bool shared) {
|
||||
string libName = "lib" + libCreate();
|
||||
if (shared) {
|
||||
libName += ".so";
|
||||
} else {
|
||||
@ -541,6 +536,13 @@ public:
|
||||
}
|
||||
return libName;
|
||||
}
|
||||
string makeDir() const { return m_makeDir; }
|
||||
string modPrefix() const { return m_modPrefix; }
|
||||
string pipeFilter() const { return m_pipeFilter; }
|
||||
string prefix() const { return m_prefix; }
|
||||
// Not just called protectKey() to avoid bugs of not using protectKeyDefaulted()
|
||||
bool protectKeyProvided() const { return !m_protectKey.empty(); }
|
||||
string protectKeyDefaulted(); // Set default key if not set by user
|
||||
string topModule() const { return m_topModule; }
|
||||
string unusedRegexp() const { return m_unusedRegexp; }
|
||||
string waiverOutput() const { return m_waiverOutput; }
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
if (m_hierBlockOptsByOrigName.find(origName) == m_hierBlockOptsByOrigName.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
// This module is a hierarchical block. Need to replace it by the protect-lib wrapper.
|
||||
// This module is a hierarchical block. Need to replace it by the --lib-create wrapper.
|
||||
const std::pair<HierMapIt, HierMapIt> candidates
|
||||
= m_hierBlockOptsByOrigName.equal_range(origName);
|
||||
const auto paramsIt = m_modParams.find(origName);
|
||||
@ -168,7 +168,7 @@ public:
|
||||
}
|
||||
if (found && paramIdx == hierIt->second->params().size()) break;
|
||||
}
|
||||
UASSERT_OBJ(hierIt != candidates.second, firstPinp, "No protect-lib wrapper found");
|
||||
UASSERT_OBJ(hierIt != candidates.second, firstPinp, "No --lib-create wrapper found");
|
||||
// parameter settings will be removed in the bottom of caller visitCell().
|
||||
const HierBlockModMap::const_iterator modIt
|
||||
= m_hierBlockMod.find(hierIt->second->mangledName());
|
||||
@ -258,7 +258,7 @@ class ParamProcessor final {
|
||||
|
||||
AstNodeModule* m_modp = nullptr; // Current module being processed
|
||||
|
||||
// Database to get protect-lib wrapper that matches parameters in hierarchical Verilation
|
||||
// Database to get lib-create wrapper that matches parameters in hierarchical Verilation
|
||||
ParameterizedHierBlocks m_hierBlocks;
|
||||
// Default parameter values key:parameter name, value:default value (can be nullptr)
|
||||
using DefaultValueMap = std::map<std::string, AstConst*>;
|
||||
|
@ -57,8 +57,8 @@ private:
|
||||
AstTextBlock* m_cSeqClksp = nullptr; // Sequential clock copy list
|
||||
AstTextBlock* m_cSeqOutsp = nullptr; // Sequential output copy list
|
||||
AstTextBlock* m_cIgnoreParamsp = nullptr; // Combo ignore parameter list
|
||||
string m_libName;
|
||||
string m_topName;
|
||||
const string m_libName;
|
||||
const string m_topName;
|
||||
bool m_foundTop = false; // Have seen the top module
|
||||
bool m_hasClk = false; // True if the top module has sequential logic
|
||||
|
||||
@ -396,7 +396,7 @@ private:
|
||||
} else if (nodep->direction() == VDirection::OUTPUT) {
|
||||
handleOutput(nodep);
|
||||
} else {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: protect-lib port direction: "
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: --lib-create port direction: "
|
||||
<< nodep->direction().ascii());
|
||||
}
|
||||
}
|
||||
@ -484,7 +484,7 @@ private:
|
||||
|
||||
public:
|
||||
explicit ProtectVisitor(AstNode* nodep)
|
||||
: m_libName{v3Global.opt.protectLib()}
|
||||
: m_libName{v3Global.opt.libCreate()}
|
||||
, m_topName{v3Global.opt.prefix()} {
|
||||
iterate(nodep);
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ static void process() {
|
||||
}
|
||||
|
||||
// Output DPI protected library files
|
||||
if (!v3Global.opt.protectLib().empty()) {
|
||||
if (!v3Global.opt.libCreate().empty()) {
|
||||
V3ProtectLib::protect();
|
||||
V3EmitV::emitvFiles();
|
||||
V3EmitC::emitcFiles();
|
||||
|
70
test_regress/t/t_lib.pl
Executable file
70
test_regress/t/t_lib.pl
Executable file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env perl
|
||||
# Makes the test run with tracing enabled by default, can be overridden
|
||||
# with --notrace
|
||||
unshift(@ARGV, "--trace");
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2019 by Todd Strader. 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,
|
||||
xsim => 1,
|
||||
);
|
||||
|
||||
top_filename("t/t_lib_prot.v");
|
||||
|
||||
$Self->{sim_time} = $Self->{benchmark} * 100 if $Self->{benchmark};
|
||||
|
||||
my $secret_prefix = "secret";
|
||||
my $secret_dir = "$Self->{obj_dir}/$secret_prefix";
|
||||
mkdir $secret_dir;
|
||||
|
||||
while (1) {
|
||||
# Always compile the secret file with Verilator no matter what simulator
|
||||
# we are testing with
|
||||
run(logfile => "$secret_dir/vlt_compile.log",
|
||||
cmd => ["perl",
|
||||
"$ENV{VERILATOR_ROOT}/bin/verilator",
|
||||
"--prefix",
|
||||
"Vt_lib_prot_secret",
|
||||
"-cc",
|
||||
"-Mdir",
|
||||
$secret_dir,
|
||||
"--lib-create",
|
||||
$secret_prefix,
|
||||
"t/t_lib_prot_secret.v"],
|
||||
verilator_run => 1,
|
||||
);
|
||||
last if $Self->{errors};
|
||||
|
||||
run(logfile => "$secret_dir/secret_gcc.log",
|
||||
cmd=>[$ENV{MAKE},
|
||||
"-C",
|
||||
$secret_dir,
|
||||
"-f",
|
||||
"Vt_lib_prot_secret.mk"]);
|
||||
last if $Self->{errors};
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["$secret_dir/secret.sv",
|
||||
"-LDFLAGS",
|
||||
"$secret_prefix/libsecret.a"],
|
||||
xsim_flags2 => ["$secret_dir/secret.sv"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
xsim_run_flags2 => ["--sv_lib",
|
||||
"$secret_dir/libsecret",
|
||||
"--dpi_absolute"],
|
||||
);
|
||||
|
||||
ok(1);
|
||||
last;
|
||||
}
|
||||
1;
|
@ -1,4 +1,4 @@
|
||||
%Error-UNSUPPORTED: t/t_lib_prot_inout_bad.v:9:28: Unsupported: protect-lib port direction: INOUT
|
||||
%Error-UNSUPPORTED: t/t_lib_prot_inout_bad.v:9:28: Unsupported: --lib-create port direction: INOUT
|
||||
9 | inout z,
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
|
Loading…
Reference in New Issue
Block a user