2012-04-13 03:08:20 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 13:35:28 +02:00
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Command line options
|
|
|
|
|
//
|
2019-11-08 04:33:59 +01:00
|
|
|
// Code available from: https://verilator.org
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2024-01-01 09:19:59 +01:00
|
|
|
// Copyright 2003-2024 by Wilson Snyder. This program is free software; you
|
2020-03-21 16:24:24 +01:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 23:07:57 +02:00
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2020-03-21 16:24:24 +01:00
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
2019-10-05 02:17:11 +02:00
|
|
|
|
2021-03-04 03:57:07 +01:00
|
|
|
#ifndef VERILATOR_V3OPTIONS_H_
|
|
|
|
|
#define VERILATOR_V3OPTIONS_H_
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2006-12-18 20:20:45 +01:00
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2022-01-08 17:18:23 +01:00
|
|
|
#include "V3Error.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
#include "V3LangCode.h"
|
2023-09-25 04:12:23 +02:00
|
|
|
#include "V3ThreadSafety.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2009-01-21 22:56:50 +01:00
|
|
|
#include <map>
|
2006-08-26 13:35:28 +02:00
|
|
|
#include <set>
|
2018-10-15 00:39:33 +02:00
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
class V3OptionsImp;
|
|
|
|
|
class FileLine;
|
|
|
|
|
|
2018-08-28 12:41:17 +02:00
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class VOptionBool final {
|
2019-11-01 01:59:52 +01:00
|
|
|
// Class to track options that are either not specified (and default
|
|
|
|
|
// true/false), versus user setting the option to true or false
|
|
|
|
|
public:
|
2021-03-08 03:05:15 +01:00
|
|
|
enum en : uint8_t { OPT_DEFAULT_FALSE = 0, OPT_DEFAULT_TRUE, OPT_TRUE, OPT_FALSE };
|
2019-11-01 01:59:52 +01:00
|
|
|
enum en m_e;
|
2022-09-16 14:17:38 +02:00
|
|
|
VOptionBool()
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{OPT_DEFAULT_FALSE} {}
|
2019-11-01 01:59:52 +01:00
|
|
|
// cppcheck-suppress noExplicitConstructor
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr VOptionBool(en _e)
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{_e} {}
|
2022-09-16 14:17:38 +02:00
|
|
|
explicit VOptionBool(int _e)
|
2020-08-18 14:10:44 +02:00
|
|
|
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr operator en() const { return m_e; }
|
2019-11-01 01:59:52 +01:00
|
|
|
bool isDefault() const { return m_e == OPT_DEFAULT_FALSE || m_e == OPT_DEFAULT_TRUE; }
|
|
|
|
|
bool isTrue() const { return m_e == OPT_TRUE || m_e == OPT_DEFAULT_TRUE; }
|
2020-04-10 05:26:03 +02:00
|
|
|
bool isSetTrue() const { return m_e == OPT_TRUE; }
|
|
|
|
|
bool isSetFalse() const { return m_e == OPT_FALSE; }
|
2019-11-01 01:59:52 +01:00
|
|
|
void setTrueOrFalse(bool flag) { m_e = flag ? OPT_TRUE : OPT_FALSE; }
|
2020-02-02 16:34:29 +01:00
|
|
|
};
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const VOptionBool& lhs, const VOptionBool& rhs) {
|
2020-02-02 16:34:29 +01:00
|
|
|
return lhs.m_e == rhs.m_e;
|
|
|
|
|
}
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const VOptionBool& lhs, VOptionBool::en rhs) { return lhs.m_e == rhs; }
|
|
|
|
|
constexpr bool operator==(VOptionBool::en lhs, const VOptionBool& rhs) { return lhs == rhs.m_e; }
|
2019-11-01 01:59:52 +01:00
|
|
|
|
2022-09-23 11:57:01 +02:00
|
|
|
// ######################################################################
|
2019-11-01 01:59:52 +01:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class VTimescale final {
|
2020-04-16 01:39:03 +02:00
|
|
|
public:
|
2020-08-16 18:05:35 +02:00
|
|
|
enum en : uint8_t {
|
2020-04-16 01:39:03 +02:00
|
|
|
// clang-format off
|
2020-05-11 14:15:52 +02:00
|
|
|
TS_100S = 0, TS_10S = 1, TS_1S = 2,
|
|
|
|
|
TS_100MS = 3, TS_10MS = 4, TS_1MS = 5,
|
|
|
|
|
TS_100US = 6, TS_10US = 7, TS_1US = 8,
|
|
|
|
|
TS_100NS = 9, TS_10NS = 10, TS_1NS = 11,
|
|
|
|
|
TS_100PS = 12, TS_10PS = 13, TS_1PS = 14,
|
|
|
|
|
TS_100FS = 15, TS_10FS = 16, TS_1FS = 17,
|
2020-04-16 01:39:03 +02:00
|
|
|
// clang-format on
|
2020-05-11 14:15:52 +02:00
|
|
|
NONE = 18,
|
2020-04-16 01:39:03 +02:00
|
|
|
_ENUM_END
|
|
|
|
|
};
|
2020-08-16 18:05:35 +02:00
|
|
|
enum : uint8_t { TS_DEFAULT = TS_1PS };
|
2020-04-16 01:39:03 +02:00
|
|
|
enum en m_e;
|
|
|
|
|
// CONSTRUCTOR
|
2022-09-16 14:17:38 +02:00
|
|
|
VTimescale()
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{NONE} {}
|
2020-04-16 01:39:03 +02:00
|
|
|
// cppcheck-suppress noExplicitConstructor
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr VTimescale(en _e)
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{_e} {}
|
2022-09-16 14:17:38 +02:00
|
|
|
explicit VTimescale(int _e)
|
2020-08-18 14:10:44 +02:00
|
|
|
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
2020-04-16 01:39:03 +02:00
|
|
|
// Construct from string
|
|
|
|
|
VTimescale(const string& value, bool& badr);
|
|
|
|
|
VTimescale(double value, bool& badr) {
|
|
|
|
|
badr = false;
|
2021-03-08 03:05:15 +01:00
|
|
|
for (int i = TS_100S; i < _ENUM_END; ++i) {
|
|
|
|
|
m_e = static_cast<en>(i);
|
|
|
|
|
if (multiplier() == value) break;
|
|
|
|
|
}
|
|
|
|
|
if (multiplier() != value) {
|
2020-04-16 01:39:03 +02:00
|
|
|
m_e = NONE;
|
|
|
|
|
badr = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool isNone() const { return m_e == NONE; }
|
|
|
|
|
// Parse a "unit/precision" string into two VTimescales, with error checking
|
|
|
|
|
static void parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr, VTimescale& precr,
|
|
|
|
|
bool allowEmpty = false);
|
|
|
|
|
const char* ascii() const {
|
|
|
|
|
static const char* const names[]
|
2020-05-11 14:15:52 +02:00
|
|
|
= {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us", "100ns",
|
|
|
|
|
"10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs", "NONE"};
|
2020-04-16 01:39:03 +02:00
|
|
|
return names[m_e];
|
|
|
|
|
}
|
2020-06-02 05:16:02 +02:00
|
|
|
int powerOfTen() const { return 2 - static_cast<int>(m_e); }
|
2020-04-16 01:39:03 +02:00
|
|
|
double multiplier() const {
|
2020-05-29 03:04:36 +02:00
|
|
|
static const double values[]
|
|
|
|
|
= {100, 10, 1, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7,
|
|
|
|
|
1e-8, 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 0};
|
2020-04-16 01:39:03 +02:00
|
|
|
return values[m_e];
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const VTimescale& lhs, const VTimescale& rhs) {
|
|
|
|
|
return lhs.m_e == rhs.m_e;
|
|
|
|
|
}
|
|
|
|
|
constexpr bool operator==(const VTimescale& lhs, VTimescale::en rhs) { return lhs.m_e == rhs; }
|
|
|
|
|
constexpr bool operator==(VTimescale::en lhs, const VTimescale& rhs) { return lhs == rhs.m_e; }
|
2020-04-16 01:39:03 +02:00
|
|
|
// Comparisons are based on time, not enum values, so seconds > milliseconds
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator<(const VTimescale& lhs, const VTimescale& rhs) {
|
|
|
|
|
return lhs.m_e > rhs.m_e;
|
|
|
|
|
}
|
2020-04-16 01:39:03 +02:00
|
|
|
inline std::ostream& operator<<(std::ostream& os, const VTimescale& rhs) {
|
|
|
|
|
return os << rhs.ascii();
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-23 11:57:01 +02:00
|
|
|
// ######################################################################
|
2020-04-16 01:39:03 +02:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class TraceFormat final {
|
2018-08-28 12:41:17 +02:00
|
|
|
public:
|
2020-08-16 18:05:35 +02:00
|
|
|
enum en : uint8_t { VCD = 0, FST } m_e;
|
2020-04-04 04:31:54 +02:00
|
|
|
// cppcheck-suppress noExplicitConstructor
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr TraceFormat(en _e = VCD)
|
2020-08-16 17:40:42 +02:00
|
|
|
: m_e{_e} {}
|
2022-09-16 14:17:38 +02:00
|
|
|
explicit TraceFormat(int _e)
|
2020-08-18 14:10:44 +02:00
|
|
|
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr operator en() const { return m_e; }
|
2020-04-22 00:49:07 +02:00
|
|
|
bool fst() const { return m_e == FST; }
|
2022-05-20 17:02:43 +02:00
|
|
|
bool vcd() const { return m_e == VCD; }
|
2023-12-19 17:07:06 +01:00
|
|
|
string classBase() const VL_MT_SAFE {
|
2020-04-22 00:49:07 +02:00
|
|
|
static const char* const names[] = {"VerilatedVcd", "VerilatedFst"};
|
2018-08-28 12:41:17 +02:00
|
|
|
return names[m_e];
|
|
|
|
|
}
|
2022-10-18 23:07:09 +02:00
|
|
|
string sourceName() const VL_MT_SAFE {
|
2020-04-22 00:49:07 +02:00
|
|
|
static const char* const names[] = {"verilated_vcd", "verilated_fst"};
|
2018-08-28 12:41:17 +02:00
|
|
|
return names[m_e];
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const TraceFormat& lhs, const TraceFormat& rhs) {
|
2020-02-02 16:34:29 +01:00
|
|
|
return lhs.m_e == rhs.m_e;
|
|
|
|
|
}
|
2022-09-23 11:57:01 +02:00
|
|
|
constexpr bool operator==(const TraceFormat& lhs, TraceFormat::en rhs) { return lhs.m_e == rhs; }
|
|
|
|
|
constexpr bool operator==(TraceFormat::en lhs, const TraceFormat& rhs) { return lhs == rhs.m_e; }
|
2018-08-28 12:41:17 +02:00
|
|
|
|
2021-03-13 00:10:45 +01:00
|
|
|
using V3StringList = std::vector<std::string>;
|
|
|
|
|
using V3StringSet = std::set<std::string>;
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2022-09-23 11:57:01 +02:00
|
|
|
// ######################################################################
|
2020-08-15 15:43:53 +02:00
|
|
|
|
|
|
|
|
// Information given by --hierarchical-block option
|
2020-11-19 03:32:16 +01:00
|
|
|
class V3HierarchicalBlockOption final {
|
2020-08-15 15:43:53 +02:00
|
|
|
public:
|
|
|
|
|
// key:parameter name, value:value (as string)
|
2021-03-13 00:10:45 +01:00
|
|
|
using ParamStrMap = std::map<const std::string, std::string>;
|
2020-08-15 15:43:53 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
string m_origName; // module name
|
|
|
|
|
// module name after uniquified
|
|
|
|
|
// same as m_origName for non-parameterized module
|
|
|
|
|
string m_mangledName;
|
|
|
|
|
// overriding parameter values specified by -G option
|
|
|
|
|
ParamStrMap m_parameters;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit V3HierarchicalBlockOption(const string& optstring);
|
|
|
|
|
const string& origName() const { return m_origName; }
|
|
|
|
|
const string& mangledName() const { return m_mangledName; }
|
|
|
|
|
const ParamStrMap params() const { return m_parameters; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-13 00:10:45 +01:00
|
|
|
using V3HierBlockOptSet = std::map<const std::string, V3HierarchicalBlockOption>;
|
2020-08-15 15:43:53 +02:00
|
|
|
|
2018-08-28 12:41:17 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// V3Options - Command line options
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class V3Options final {
|
2020-04-15 01:55:00 +02:00
|
|
|
public:
|
|
|
|
|
private:
|
2009-01-21 22:56:50 +01:00
|
|
|
// TYPES
|
2022-09-18 21:53:42 +02:00
|
|
|
using DebugLevelMap = std::map<const std::string, unsigned>;
|
2009-01-21 22:56:50 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// MEMBERS (general options)
|
2020-04-15 01:55:00 +02:00
|
|
|
V3OptionsImp* m_impp; // Slow hidden options
|
2019-05-19 22:13:13 +02:00
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
// clang-format off
|
2019-05-19 22:13:13 +02:00
|
|
|
V3StringSet m_cppFiles; // argument: C++ files to link against
|
|
|
|
|
V3StringList m_cFlags; // argument: user CFLAGS
|
|
|
|
|
V3StringList m_ldLibs; // argument: user LDFLAGS
|
2020-04-15 23:44:21 +02:00
|
|
|
V3StringList m_makeFlags; // argument: user MAKEFLAGS
|
2019-05-19 22:13:13 +02:00
|
|
|
V3StringSet m_futures; // argument: -Wfuture- list
|
2022-08-20 20:01:13 +02:00
|
|
|
V3StringSet m_future0s; // argument: -future list
|
|
|
|
|
V3StringSet m_future1s; // argument: -future1 list
|
2019-05-19 22:13:13 +02:00
|
|
|
V3StringSet m_libraryFiles; // argument: Verilog -v files
|
|
|
|
|
V3StringSet m_clockers; // argument: Verilog -clk signals
|
|
|
|
|
V3StringSet m_noClockers; // argument: Verilog -noclk signals
|
|
|
|
|
V3StringList m_vFiles; // argument: Verilog files to read
|
|
|
|
|
V3StringList m_forceIncs; // argument: -FI
|
2022-09-18 21:53:42 +02:00
|
|
|
DebugLevelMap m_debugLevel; // argument: --debugi-<srcfile/tag> <level>
|
|
|
|
|
DebugLevelMap m_dumpLevel; // argument: --dumpi-<srcfile/tag> <level>
|
2020-10-30 23:00:40 +01:00
|
|
|
std::map<const string, string> m_parameters; // Parameters
|
|
|
|
|
std::map<const string, V3HierarchicalBlockOption> m_hierBlocks; // main switch: --hierarchical-block
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
V3StringSet m_fDfgPeepholeDisabled; // argument: -f[no-]dfg-peephole-<name>
|
2016-03-25 00:14:15 +01:00
|
|
|
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_preprocOnly = false; // main switch: -E
|
|
|
|
|
bool m_makePhony = false; // main switch: -MP
|
|
|
|
|
bool m_preprocNoLine = false; // main switch: -P
|
|
|
|
|
bool m_assert = false; // main switch: --assert
|
2024-02-23 15:05:53 +01:00
|
|
|
bool m_assertCase = false; // main switch: --assert-case
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_autoflush = false; // main switch: --autoflush
|
|
|
|
|
bool m_bboxSys = false; // main switch: --bbox-sys
|
|
|
|
|
bool m_bboxUnsup = false; // main switch: --bbox-unsup
|
2023-08-30 01:55:37 +02:00
|
|
|
bool m_binary = false; // main switch: --binary
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_build = false; // main switch: --build
|
|
|
|
|
bool m_cmake = false; // main switch: --make cmake
|
|
|
|
|
bool m_context = true; // main switch: --Wcontext
|
|
|
|
|
bool m_coverageLine = false; // main switch: --coverage-block
|
|
|
|
|
bool m_coverageToggle = false; // main switch: --coverage-toggle
|
|
|
|
|
bool m_coverageUnderscore = false; // main switch: --coverage-underscore
|
|
|
|
|
bool m_coverageUser = false; // main switch: --coverage-func
|
|
|
|
|
bool m_debugCheck = false; // main switch: --debug-check
|
|
|
|
|
bool m_debugCollision = false; // main switch: --debug-collision
|
2020-09-07 18:58:30 +02:00
|
|
|
bool m_debugEmitV = false; // main switch: --debug-emitv
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_debugExitParse = false; // main switch: --debug-exit-parse
|
2020-08-23 15:05:18 +02:00
|
|
|
bool m_debugExitUvm = false; // main switch: --debug-exit-uvm
|
2023-09-09 17:54:55 +02:00
|
|
|
bool m_debugExitUvm23 = false; // main switch: --debug-exit-uvm23
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_debugLeak = true; // main switch: --debug-leak
|
|
|
|
|
bool m_debugNondeterminism = false; // main switch: --debug-nondeterminism
|
|
|
|
|
bool m_debugPartition = false; // main switch: --debug-partition
|
|
|
|
|
bool m_debugProtect = false; // main switch: --debug-protect
|
|
|
|
|
bool m_debugSelfTest = false; // main switch: --debug-self-test
|
2024-01-06 22:14:58 +01:00
|
|
|
bool m_debugStackCheck = false; // main switch: --debug-stack-check
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_decoration = true; // main switch: --decoration
|
2024-01-25 03:51:47 +01:00
|
|
|
bool m_decorationNodes = false; // main switch: --decoration=nodes
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_dpiHdrOnly = false; // main switch: --dpi-hdr-only
|
|
|
|
|
bool m_exe = false; // main switch: --exe
|
|
|
|
|
bool m_flatten = false; // main switch: --flatten
|
|
|
|
|
bool m_hierarchical = false; // main switch: --hierarchical
|
|
|
|
|
bool m_ignc = false; // main switch: --ignc
|
|
|
|
|
bool m_lintOnly = false; // main switch: --lint-only
|
|
|
|
|
bool m_gmake = false; // main switch: --make gmake
|
2022-12-26 10:30:41 +01:00
|
|
|
bool m_main = false; // main switch: --main
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_outFormatOk = false; // main switch: --cc, --sc or --sp was specified
|
|
|
|
|
bool m_pedantic = false; // main switch: --Wpedantic
|
|
|
|
|
bool m_pinsScUint = false; // main switch: --pins-sc-uint
|
|
|
|
|
bool m_pinsScBigUint = false; // main switch: --pins-sc-biguint
|
|
|
|
|
bool m_pinsUint8 = false; // main switch: --pins-uint8
|
|
|
|
|
bool m_ppComments = false; // main switch: --pp-comments
|
2021-07-08 01:12:52 +02:00
|
|
|
bool m_profC = false; // main switch: --prof-c
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_profCFuncs = false; // main switch: --prof-cfuncs
|
2022-03-25 20:46:50 +01:00
|
|
|
bool m_profExec = false; // main switch: --prof-exec
|
|
|
|
|
bool m_profPgo = false; // main switch: --prof-pgo
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_protectIds = false; // main switch: --protect-ids
|
|
|
|
|
bool m_public = false; // main switch: --public
|
|
|
|
|
bool m_publicFlatRW = false; // main switch: --public-flat-rw
|
2023-03-09 01:38:26 +01:00
|
|
|
bool m_public_params = false; // main switch: --public-params
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_quietExit = false; // main switch: --quiet-exit
|
|
|
|
|
bool m_relativeIncludes = false; // main switch: --relative-includes
|
|
|
|
|
bool m_reportUnoptflat = false; // main switch: --report-unoptflat
|
|
|
|
|
bool m_savable = false; // main switch: --savable
|
2023-02-03 15:04:16 +01:00
|
|
|
bool m_std = true; // main switch: --std
|
2022-12-21 01:22:42 +01:00
|
|
|
bool m_structsPacked = false; // main switch: --structs-packed
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_systemC = false; // main switch: --sc: System C instead of simple C++
|
|
|
|
|
bool m_stats = false; // main switch: --stats
|
|
|
|
|
bool m_statsVars = false; // main switch: --stats-vars
|
|
|
|
|
bool m_threadsCoarsen = true; // main switch: --threads-coarsen
|
|
|
|
|
bool m_threadsDpiPure = true; // main switch: --threads-dpi all/pure
|
|
|
|
|
bool m_threadsDpiUnpure = false; // main switch: --threads-dpi all
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
VOptionBool m_timing; // main switch: --timing
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_trace = false; // main switch: --trace
|
|
|
|
|
bool m_traceCoverage = false; // main switch: --trace-coverage
|
|
|
|
|
bool m_traceParams = true; // main switch: --trace-params
|
|
|
|
|
bool m_traceStructs = false; // main switch: --trace-structs
|
2023-09-01 00:29:58 +02:00
|
|
|
bool m_noTraceTop = false; // main switch: --no-trace-top
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_traceUnderscore = false; // main switch: --trace-underscore
|
|
|
|
|
bool m_underlineZero = false; // main switch: --underline-zero; undocumented old Verilator 2
|
2022-12-26 10:30:41 +01:00
|
|
|
bool m_verilate = true; // main switch: --verilate
|
2020-08-16 15:55:36 +02:00
|
|
|
bool m_vpi = false; // main switch: --vpi
|
|
|
|
|
bool m_xInitialEdge = false; // main switch: --x-initial-edge
|
|
|
|
|
bool m_xmlOnly = false; // main switch: --xml-only
|
2024-02-09 23:50:09 +01:00
|
|
|
bool m_jsonOnly = false; // main switch: --json-only
|
2019-05-19 22:13:13 +02:00
|
|
|
|
2022-09-15 14:28:58 +02:00
|
|
|
int m_buildJobs = -1; // main switch: --build-jobs, -j
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_convergeLimit = 100; // main switch: --converge-limit
|
2021-03-30 00:54:51 +02:00
|
|
|
int m_coverageMaxWidth = 256; // main switch: --coverage-max-width
|
2021-06-06 16:27:01 +02:00
|
|
|
int m_expandLimit = 64; // main switch: --expand-limit
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_gateStmts = 100; // main switch: --gate-stmts
|
2022-07-18 16:32:14 +02:00
|
|
|
int m_hierChild = 0; // main switch: --hierarchical-child
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_ifDepth = 0; // main switch: --if-depth
|
|
|
|
|
int m_inlineMult = 2000; // main switch: --inline-mult
|
2021-07-25 17:10:55 +02:00
|
|
|
int m_instrCountDpi = 200; // main switch: --instr-count-dpi
|
2024-02-09 23:50:09 +01:00
|
|
|
bool m_jsonEditNums = true; // main switch: --no-json-edit-nums
|
|
|
|
|
bool m_jsonIds = true; // main switch: --no-json-ids
|
2019-11-01 01:59:52 +01:00
|
|
|
VOptionBool m_makeDepend; // main switch: -MMD
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_maxNumWidth = 65536; // main switch: --max-num-width
|
|
|
|
|
int m_moduleRecursion = 100; // main switch: --module-recursion-depth
|
|
|
|
|
int m_outputSplit = 20000; // main switch: --output-split
|
|
|
|
|
int m_outputSplitCFuncs = -1; // main switch: --output-split-cfuncs
|
|
|
|
|
int m_outputSplitCTrace = -1; // main switch: --output-split-ctrace
|
|
|
|
|
int m_pinsBv = 65; // main switch: --pins-bv
|
2023-03-10 03:48:05 +01:00
|
|
|
int m_publicDepth = 0; // main switch: --public-depth
|
2021-05-15 19:04:40 +02:00
|
|
|
int m_reloopLimit = 40; // main switch: --reloop-limit
|
2019-11-01 01:59:52 +01:00
|
|
|
VOptionBool m_skipIdentical; // main switch: --skip-identical
|
2024-02-19 13:26:58 +01:00
|
|
|
bool m_stopFail = true; // main switch: --stop-fail
|
2022-11-05 13:47:34 +01:00
|
|
|
int m_threads = 1; // main switch: --threads
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_threadsMaxMTasks = 0; // main switch: --threads-max-mtasks
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeDefaultPrec; // main switch: --timescale
|
|
|
|
|
VTimescale m_timeDefaultUnit; // main switch: --timescale
|
|
|
|
|
VTimescale m_timeOverridePrec; // main switch: --timescale-override
|
|
|
|
|
VTimescale m_timeOverrideUnit; // main switch: --timescale-override
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_traceDepth = 0; // main switch: --trace-depth
|
2018-12-07 01:06:20 +01:00
|
|
|
TraceFormat m_traceFormat; // main switch: --trace or --trace-fst
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_traceMaxArray = 32; // main switch: --trace-max-array
|
|
|
|
|
int m_traceMaxWidth = 256; // main switch: --trace-max-width
|
|
|
|
|
int m_traceThreads = 0; // main switch: --trace-threads
|
|
|
|
|
int m_unrollCount = 64; // main switch: --unroll-count
|
|
|
|
|
int m_unrollStmts = 30000; // main switch: --unroll-stmts
|
2023-01-23 03:52:52 +01:00
|
|
|
int m_verilateJobs = -1; // main switch: --verilate-jobs
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-08-16 15:55:36 +02:00
|
|
|
int m_compLimitBlocks = 0; // compiler selection; number of nested blocks
|
|
|
|
|
int m_compLimitMembers = 64; // compiler selection; number of members in struct before make anon array
|
2022-07-25 13:59:26 +02:00
|
|
|
int m_compLimitParens = 240; // compiler selection; number of nested parens
|
2007-04-19 20:20:16 +02:00
|
|
|
|
2022-09-18 16:32:43 +02:00
|
|
|
string m_buildDepBin; // main switch: --build-dep-bin {filename}
|
2019-05-19 22:13:13 +02:00
|
|
|
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
|
2021-11-14 15:39:31 +01:00
|
|
|
string m_libCreate; // main switch: --lib-create {lib_name}
|
2023-05-31 18:02:26 +02:00
|
|
|
string m_mainTopName; // main switch: --main-top-name
|
2019-05-19 22:13:13 +02:00
|
|
|
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
|
2019-10-06 19:24:21 +02:00
|
|
|
string m_protectKey; // main switch: --protect-key
|
2019-05-19 22:13:13 +02:00
|
|
|
string m_topModule; // main switch: --top-module
|
|
|
|
|
string m_unusedRegexp; // main switch: --unused-regexp
|
2020-05-26 20:38:14 +02:00
|
|
|
string m_waiverOutput; // main switch: --waiver-output {filename}
|
2019-05-19 22:13:13 +02:00
|
|
|
string m_xAssign; // main switch: --x-assign
|
|
|
|
|
string m_xInitial; // main switch: --x-initial
|
2019-11-01 02:17:05 +01:00
|
|
|
string m_xmlOutput; // main switch: --xml-output
|
2024-02-09 23:50:09 +01:00
|
|
|
string m_jsonOnlyOutput; // main switch: --json-only-output
|
|
|
|
|
string m_jsonOnlyMetaOutput; // main switch: --json-only-meta-output
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2012-11-14 02:12:23 +01:00
|
|
|
// Language is now held in FileLine, on a per-node basis. However we still
|
|
|
|
|
// have a concept of the default language at a global level.
|
2019-05-19 22:13:13 +02:00
|
|
|
V3LangCode m_defaultLanguage; // main switch: --language
|
2008-03-28 21:41:21 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// MEMBERS (optimizations)
|
2022-06-04 02:43:16 +02:00
|
|
|
bool m_fAcycSimp; // main switch: -fno-acyc-simp: acyclic pre-optimizations
|
|
|
|
|
bool m_fAssemble; // main switch: -fno-assemble: assign assemble
|
|
|
|
|
bool m_fCase; // main switch: -fno-case: case tree conversion
|
|
|
|
|
bool m_fCombine; // main switch: -fno-combine: common icode packing
|
|
|
|
|
bool m_fConst; // main switch: -fno-const: constant folding
|
2022-10-04 22:18:39 +02:00
|
|
|
bool m_fConstBeforeDfg = true; // main switch: -fno-const-before-dfg for testing only!
|
2022-06-04 02:43:16 +02:00
|
|
|
bool m_fConstBitOpTree; // main switch: -fno-const-bit-op-tree constant bit op tree
|
|
|
|
|
bool m_fDedupe; // main switch: -fno-dedupe: logic deduplication
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
bool m_fDfgPeephole = true; // main switch: -fno-dfg-peephole
|
|
|
|
|
bool m_fDfgPreInline; // main switch: -fno-dfg-pre-inline and -fno-dfg
|
|
|
|
|
bool m_fDfgPostInline; // main switch: -fno-dfg-post-inline and -fno-dfg
|
2023-12-22 22:26:51 +01:00
|
|
|
bool m_fDeadAssigns; // main switch: -fno-dead-assigns: remove dead assigns
|
|
|
|
|
bool m_fDeadCells; // main switch: -fno-dead-cells: remove dead cells
|
2022-06-04 02:43:16 +02:00
|
|
|
bool m_fExpand; // main switch: -fno-expand: expansion of C macros
|
|
|
|
|
bool m_fGate; // main switch: -fno-gate: gate wire elimination
|
|
|
|
|
bool m_fInline; // main switch: -fno-inline: module inlining
|
|
|
|
|
bool m_fLife; // main switch: -fno-life: variable lifetime
|
|
|
|
|
bool m_fLifePost; // main switch: -fno-life-post: delayed assignment elimination
|
|
|
|
|
bool m_fLocalize; // main switch: -fno-localize: convert temps to local variables
|
|
|
|
|
bool m_fMergeCond; // main switch: -fno-merge-cond: merge conditionals
|
2022-06-13 15:16:11 +02:00
|
|
|
bool m_fMergeCondMotion = true; // main switch: -fno-merge-cond-motion: perform code motion
|
|
|
|
|
bool m_fMergeConstPool = true; // main switch: -fno-merge-const-pool
|
2022-06-04 02:43:16 +02:00
|
|
|
bool m_fReloop; // main switch: -fno-reloop: reform loops
|
|
|
|
|
bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
|
|
|
|
|
bool m_fSplit; // main switch: -fno-split: always assignment splitting
|
|
|
|
|
bool m_fSubst; // main switch: -fno-subst: substitute expression temp values
|
|
|
|
|
bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution
|
|
|
|
|
bool m_fTable; // main switch: -fno-table: lookup table creation
|
2023-06-14 20:44:53 +02:00
|
|
|
bool m_fTaskifyAll = false; // main switch: --ftaskify-all-forked
|
2020-04-15 01:55:00 +02:00
|
|
|
// clang-format on
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2021-07-10 13:03:51 +02:00
|
|
|
bool m_available = false; // Set to true at the end of option parsing
|
|
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
private:
|
2006-08-26 13:35:28 +02:00
|
|
|
// METHODS
|
2018-10-15 00:39:33 +02:00
|
|
|
void addArg(const string& arg);
|
2023-09-25 04:12:23 +02:00
|
|
|
void addDefine(const string& defline, bool allowPlus) VL_MT_DISABLED;
|
2008-07-22 20:27:34 +02:00
|
|
|
void addFuture(const string& flag);
|
2022-08-20 20:01:13 +02:00
|
|
|
void addFuture0(const string& flag);
|
|
|
|
|
void addFuture1(const string& flag);
|
2011-10-29 00:57:40 +02:00
|
|
|
void addIncDirUser(const string& incdir); // User requested
|
|
|
|
|
void addIncDirFallback(const string& incdir); // Low priority if not found otherwise
|
2016-03-25 00:14:15 +01:00
|
|
|
void addParameter(const string& paramline, bool allowPlus);
|
2013-02-03 19:27:37 +01:00
|
|
|
void addLangExt(const string& langext, const V3LangCode& lc);
|
2012-02-12 02:40:58 +01:00
|
|
|
void addLibExtV(const string& libext);
|
2006-08-26 13:35:28 +02:00
|
|
|
void optimize(int level);
|
2009-06-26 01:53:26 +02:00
|
|
|
void showVersion(bool verbose);
|
2008-12-12 21:34:02 +01:00
|
|
|
void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; }
|
2020-11-11 03:40:14 +01:00
|
|
|
static bool suffixed(const string& sw, const char* arg);
|
|
|
|
|
static string parseFileArg(const string& optdir, const string& relfilename);
|
2011-10-29 00:57:40 +02:00
|
|
|
string filePathCheckOneDir(const string& modname, const string& dirname);
|
2020-11-11 03:40:14 +01:00
|
|
|
static int stripOptionsForChildRun(const string& opt, bool forTop);
|
2009-06-26 01:53:26 +02:00
|
|
|
|
2017-11-01 23:51:41 +01:00
|
|
|
// CONSTRUCTORS
|
|
|
|
|
VL_UNCOPYABLE(V3Options);
|
2020-04-15 01:55:00 +02:00
|
|
|
|
|
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
V3Options();
|
|
|
|
|
~V3Options();
|
|
|
|
|
void setDebugMode(int level);
|
2022-10-18 23:07:09 +02:00
|
|
|
unsigned debugLevel(const string& tag) const VL_MT_SAFE;
|
|
|
|
|
unsigned debugSrcLevel(const string& srcfile_path) const VL_MT_SAFE;
|
|
|
|
|
unsigned dumpLevel(const string& tag) const VL_MT_SAFE;
|
2023-03-17 00:48:56 +01:00
|
|
|
unsigned dumpSrcLevel(const string& srcfile_path) const;
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
// METHODS
|
|
|
|
|
void addCppFile(const string& filename);
|
2010-01-29 01:33:02 +01:00
|
|
|
void addCFlags(const string& filename);
|
|
|
|
|
void addLdLibs(const string& filename);
|
2020-04-15 23:44:21 +02:00
|
|
|
void addMakeFlags(const string& filename);
|
2006-08-26 13:35:28 +02:00
|
|
|
void addLibraryFile(const string& filename);
|
2015-03-13 00:20:46 +01:00
|
|
|
void addClocker(const string& signame);
|
|
|
|
|
void addNoClocker(const string& signame);
|
2008-03-19 15:22:05 +01:00
|
|
|
void addVFile(const string& filename);
|
2017-02-09 13:43:43 +01:00
|
|
|
void addForceInc(const string& filename);
|
2022-10-18 23:07:09 +02:00
|
|
|
bool available() const VL_MT_SAFE { return m_available; }
|
2022-09-15 02:18:40 +02:00
|
|
|
void ccSet();
|
2024-01-25 03:51:47 +01:00
|
|
|
void decorations(FileLine* fl, const string& filename);
|
2023-09-25 04:12:23 +02:00
|
|
|
void notify() VL_MT_DISABLED;
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
// ACCESSORS (options)
|
|
|
|
|
bool preprocOnly() const { return m_preprocOnly; }
|
2006-08-31 17:29:15 +02:00
|
|
|
bool makePhony() const { return m_makePhony; }
|
2014-06-07 02:22:20 +02:00
|
|
|
bool preprocNoLine() const { return m_preprocNoLine; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool underlineZero() const { return m_underlineZero; }
|
|
|
|
|
string flags() const { return m_flags; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool systemC() const VL_MT_SAFE { return m_systemC; }
|
|
|
|
|
bool savable() const VL_MT_SAFE { return m_savable; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool stats() const { return m_stats; }
|
2014-12-20 14:28:31 +01:00
|
|
|
bool statsVars() const { return m_statsVars; }
|
2023-02-03 15:04:16 +01:00
|
|
|
bool std() const { return m_std; }
|
2020-03-07 16:51:06 +01:00
|
|
|
bool structsPacked() const { return m_structsPacked; }
|
2009-01-21 22:56:50 +01:00
|
|
|
bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined
|
2024-02-23 15:05:53 +01:00
|
|
|
bool assertCaseOn() const { return m_assertCase || m_assert; }
|
2008-07-16 20:06:08 +02:00
|
|
|
bool autoflush() const { return m_autoflush; }
|
2009-09-16 15:28:09 +02:00
|
|
|
bool bboxSys() const { return m_bboxSys; }
|
2009-12-16 17:45:28 +01:00
|
|
|
bool bboxUnsup() const { return m_bboxUnsup; }
|
2023-08-30 01:55:37 +02:00
|
|
|
bool binary() const { return m_binary; }
|
2020-04-15 23:44:21 +02:00
|
|
|
bool build() const { return m_build; }
|
2022-09-18 16:32:43 +02:00
|
|
|
string buildDepBin() const { return m_buildDepBin; }
|
|
|
|
|
void buildDepBin(const string& flag) { m_buildDepBin = flag; }
|
2019-10-18 01:44:10 +02:00
|
|
|
bool cmake() const { return m_cmake; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool context() const VL_MT_SAFE { return m_context; }
|
|
|
|
|
bool coverage() const VL_MT_SAFE {
|
|
|
|
|
return m_coverageLine || m_coverageToggle || m_coverageUser;
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
bool coverageLine() const { return m_coverageLine; }
|
2008-12-12 21:34:02 +01:00
|
|
|
bool coverageToggle() const { return m_coverageToggle; }
|
2010-08-30 01:28:46 +02:00
|
|
|
bool coverageUnderscore() const { return m_coverageUnderscore; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool coverageUser() const { return m_coverageUser; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool debugCheck() const VL_MT_SAFE { return m_debugCheck; }
|
2019-05-18 02:50:57 +02:00
|
|
|
bool debugCollision() const { return m_debugCollision; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool debugEmitV() const VL_MT_SAFE { return m_debugEmitV; }
|
2020-06-09 04:10:55 +02:00
|
|
|
bool debugExitParse() const { return m_debugExitParse; }
|
2020-08-23 15:05:18 +02:00
|
|
|
bool debugExitUvm() const { return m_debugExitUvm; }
|
2023-09-09 17:54:55 +02:00
|
|
|
bool debugExitUvm23() const { return m_debugExitUvm23; }
|
2018-03-10 18:18:19 +01:00
|
|
|
bool debugLeak() const { return m_debugLeak; }
|
2018-07-23 02:54:28 +02:00
|
|
|
bool debugNondeterminism() const { return m_debugNondeterminism; }
|
|
|
|
|
bool debugPartition() const { return m_debugPartition; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool debugProtect() const VL_MT_SAFE { return m_debugProtect; }
|
2018-07-23 02:54:28 +02:00
|
|
|
bool debugSelfTest() const { return m_debugSelfTest; }
|
2024-01-06 22:14:58 +01:00
|
|
|
bool debugStackCheck() const { return m_debugStackCheck; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool decoration() const VL_MT_SAFE { return m_decoration; }
|
2024-01-25 03:51:47 +01:00
|
|
|
bool decorationNodes() const VL_MT_SAFE { return m_decorationNodes; }
|
2019-08-28 03:36:59 +02:00
|
|
|
bool dpiHdrOnly() const { return m_dpiHdrOnly; }
|
2022-09-18 21:53:42 +02:00
|
|
|
bool dumpDefines() const { return m_dumpLevel.count("defines") && m_dumpLevel.at("defines"); }
|
2022-10-01 17:06:12 +02:00
|
|
|
bool dumpTreeDot() const {
|
|
|
|
|
return m_dumpLevel.count("tree-dot") && m_dumpLevel.at("tree-dot");
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
bool exe() const { return m_exe; }
|
2020-04-22 00:14:08 +02:00
|
|
|
bool flatten() const { return m_flatten; }
|
2019-10-18 01:44:10 +02:00
|
|
|
bool gmake() const { return m_gmake; }
|
2018-07-23 02:54:28 +02:00
|
|
|
bool threadsDpiPure() const { return m_threadsDpiPure; }
|
|
|
|
|
bool threadsDpiUnpure() const { return m_threadsDpiUnpure; }
|
|
|
|
|
bool threadsCoarsen() const { return m_threadsCoarsen; }
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
VOptionBool timing() const { return m_timing; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool trace() const { return m_trace; }
|
2019-10-27 14:27:18 +01:00
|
|
|
bool traceCoverage() const { return m_traceCoverage; }
|
2014-03-14 01:08:43 +01:00
|
|
|
bool traceParams() const { return m_traceParams; }
|
2013-12-15 01:13:31 +01:00
|
|
|
bool traceStructs() const { return m_traceStructs; }
|
2010-08-30 01:28:46 +02:00
|
|
|
bool traceUnderscore() const { return m_traceUnderscore; }
|
2020-04-22 02:45:23 +02:00
|
|
|
bool main() const { return m_main; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool outFormatOk() const { return m_outFormatOk; }
|
2020-04-15 01:55:00 +02:00
|
|
|
bool keepTempFiles() const { return (V3Error::debugDefault() != 0); }
|
2019-11-16 17:59:21 +01:00
|
|
|
bool pedantic() const { return m_pedantic; }
|
2013-04-27 03:02:32 +02:00
|
|
|
bool pinsScUint() const { return m_pinsScUint; }
|
|
|
|
|
bool pinsScBigUint() const { return m_pinsScBigUint; }
|
2009-06-29 15:21:21 +02:00
|
|
|
bool pinsUint8() const { return m_pinsUint8; }
|
2018-10-26 03:17:25 +02:00
|
|
|
bool ppComments() const { return m_ppComments; }
|
2021-07-08 01:12:52 +02:00
|
|
|
bool profC() const { return m_profC; }
|
2018-05-20 15:12:29 +02:00
|
|
|
bool profCFuncs() const { return m_profCFuncs; }
|
2022-03-25 20:46:50 +01:00
|
|
|
bool profExec() const { return m_profExec; }
|
|
|
|
|
bool profPgo() const { return m_profPgo; }
|
|
|
|
|
bool usesProfiler() const { return profExec() || profPgo(); }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool protectIds() const VL_MT_SAFE { return m_protectIds; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool allPublic() const { return m_public; }
|
2023-03-09 01:38:26 +01:00
|
|
|
bool publicParams() const { return m_public_params; }
|
2019-09-23 13:56:07 +02:00
|
|
|
bool publicFlatRW() const { return m_publicFlatRW; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool lintOnly() const VL_MT_SAFE { return m_lintOnly; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool ignc() const { return m_ignc; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool quietExit() const VL_MT_SAFE { return m_quietExit; }
|
2013-02-27 04:26:47 +01:00
|
|
|
bool reportUnoptflat() const { return m_reportUnoptflat; }
|
2020-04-15 23:44:21 +02:00
|
|
|
bool verilate() const { return m_verilate; }
|
2015-09-26 04:57:28 +02:00
|
|
|
bool vpi() const { return m_vpi; }
|
2012-11-03 00:55:34 +01:00
|
|
|
bool xInitialEdge() const { return m_xInitialEdge; }
|
2012-03-20 21:13:10 +01:00
|
|
|
bool xmlOnly() const { return m_xmlOnly; }
|
2024-02-09 23:50:09 +01:00
|
|
|
bool jsonOnly() const { return m_jsonOnly; }
|
|
|
|
|
bool serializeOnly() const { return m_xmlOnly || m_jsonOnly; }
|
2022-10-01 16:48:37 +02:00
|
|
|
bool topIfacesSupported() const { return lintOnly() && !hierarchical(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2022-10-18 23:07:09 +02:00
|
|
|
int buildJobs() const VL_MT_SAFE { return m_buildJobs; }
|
2019-05-19 22:13:13 +02:00
|
|
|
int convergeLimit() const { return m_convergeLimit; }
|
2021-03-30 00:54:51 +02:00
|
|
|
int coverageMaxWidth() const { return m_coverageMaxWidth; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool dumpTreeAddrids() const VL_MT_SAFE;
|
2021-06-06 16:27:01 +02:00
|
|
|
int expandLimit() const { return m_expandLimit; }
|
2019-05-19 22:13:13 +02:00
|
|
|
int gateStmts() const { return m_gateStmts; }
|
|
|
|
|
int ifDepth() const { return m_ifDepth; }
|
|
|
|
|
int inlineMult() const { return m_inlineMult; }
|
2021-07-25 17:10:55 +02:00
|
|
|
int instrCountDpi() const { return m_instrCountDpi; }
|
2024-02-09 23:50:09 +01:00
|
|
|
bool jsonEditNums() const { return m_jsonEditNums; }
|
|
|
|
|
bool jsonIds() const { return m_jsonIds; }
|
2019-11-01 01:59:52 +01:00
|
|
|
VOptionBool makeDepend() const { return m_makeDepend; }
|
2020-01-21 12:17:31 +01:00
|
|
|
int maxNumWidth() const { return m_maxNumWidth; }
|
2019-05-19 22:13:13 +02:00
|
|
|
int moduleRecursionDepth() const { return m_moduleRecursion; }
|
|
|
|
|
int outputSplit() const { return m_outputSplit; }
|
|
|
|
|
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
|
|
|
|
int outputSplitCTrace() const { return m_outputSplitCTrace; }
|
|
|
|
|
int pinsBv() const { return m_pinsBv; }
|
2023-03-10 03:48:05 +01:00
|
|
|
int publicDepth() const { return m_publicDepth; }
|
2021-05-15 19:04:40 +02:00
|
|
|
int reloopLimit() const { return m_reloopLimit; }
|
2019-11-01 01:59:52 +01:00
|
|
|
VOptionBool skipIdentical() const { return m_skipIdentical; }
|
2024-02-19 13:26:58 +01:00
|
|
|
bool stopFail() const { return m_stopFail; }
|
2022-10-18 23:07:09 +02:00
|
|
|
int threads() const VL_MT_SAFE { return m_threads; }
|
2018-07-23 02:54:28 +02:00
|
|
|
int threadsMaxMTasks() const { return m_threadsMaxMTasks; }
|
2018-05-30 01:49:27 +02:00
|
|
|
bool mtasks() const { return (m_threads > 1); }
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale timeDefaultPrec() const { return m_timeDefaultPrec; }
|
|
|
|
|
VTimescale timeDefaultUnit() const { return m_timeDefaultUnit; }
|
|
|
|
|
VTimescale timeOverridePrec() const { return m_timeOverridePrec; }
|
|
|
|
|
VTimescale timeOverrideUnit() const { return m_timeOverrideUnit; }
|
|
|
|
|
VTimescale timeComputePrec(const VTimescale& flag) const;
|
|
|
|
|
VTimescale timeComputeUnit(const VTimescale& flag) const;
|
2018-08-28 12:41:17 +02:00
|
|
|
int traceDepth() const { return m_traceDepth; }
|
|
|
|
|
TraceFormat traceFormat() const { return m_traceFormat; }
|
2019-05-19 22:13:13 +02:00
|
|
|
int traceMaxArray() const { return m_traceMaxArray; }
|
|
|
|
|
int traceMaxWidth() const { return m_traceMaxWidth; }
|
2020-04-22 00:49:07 +02:00
|
|
|
int traceThreads() const { return m_traceThreads; }
|
2022-05-29 20:08:39 +02:00
|
|
|
bool useTraceOffload() const { return trace() && traceFormat().fst() && traceThreads() > 1; }
|
2022-07-18 16:32:14 +02:00
|
|
|
bool useTraceParallel() const {
|
2023-10-21 14:53:56 +02:00
|
|
|
return trace() && traceFormat().vcd() && (threads() > 1 || hierChild() > 1);
|
2022-07-18 16:32:14 +02:00
|
|
|
}
|
2022-07-20 12:27:10 +02:00
|
|
|
bool useFstWriterThread() const { return traceThreads() && traceFormat().fst(); }
|
2022-05-29 20:08:39 +02:00
|
|
|
unsigned vmTraceThreads() const {
|
|
|
|
|
return useTraceParallel() ? threads() : useTraceOffload() ? 1 : 0;
|
2020-04-25 23:38:25 +02:00
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
int unrollCount() const { return m_unrollCount; }
|
2024-01-26 13:49:07 +01:00
|
|
|
int unrollCountAdjusted(const VOptionBool& full, bool generate, bool simulate);
|
2019-05-19 22:13:13 +02:00
|
|
|
int unrollStmts() const { return m_unrollStmts; }
|
2023-01-23 03:52:52 +01:00
|
|
|
int verilateJobs() const { return m_verilateJobs; }
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
int compLimitBlocks() const { return m_compLimitBlocks; }
|
|
|
|
|
int compLimitMembers() const { return m_compLimitMembers; }
|
|
|
|
|
int compLimitParens() const { return m_compLimitParens; }
|
2007-04-19 20:20:16 +02:00
|
|
|
|
2020-04-15 01:55:00 +02:00
|
|
|
string exeName() const { return m_exeName != "" ? m_exeName : prefix(); }
|
2016-05-07 20:01:02 +02:00
|
|
|
string l2Name() const { return m_l2Name; }
|
2021-11-14 15:39:31 +01:00
|
|
|
string libCreate() const { return m_libCreate; }
|
|
|
|
|
string libCreateName(bool shared) {
|
|
|
|
|
string libName = "lib" + libCreate();
|
2019-10-09 12:47:26 +02:00
|
|
|
if (shared) {
|
|
|
|
|
libName += ".so";
|
|
|
|
|
} else {
|
|
|
|
|
libName += ".a";
|
|
|
|
|
}
|
|
|
|
|
return libName;
|
|
|
|
|
}
|
2023-05-31 18:02:26 +02:00
|
|
|
string mainTopName() const { return m_mainTopName; }
|
2022-10-18 23:07:09 +02:00
|
|
|
string makeDir() const VL_MT_SAFE { return m_makeDir; }
|
|
|
|
|
string modPrefix() const VL_MT_SAFE { return m_modPrefix; }
|
2021-11-14 15:39:31 +01:00
|
|
|
string pipeFilter() const { return m_pipeFilter; }
|
2022-10-18 23:07:09 +02:00
|
|
|
string prefix() const VL_MT_SAFE { return m_prefix; }
|
2021-11-14 15:39:31 +01:00
|
|
|
// Not just called protectKey() to avoid bugs of not using protectKeyDefaulted()
|
|
|
|
|
bool protectKeyProvided() const { return !m_protectKey.empty(); }
|
2023-03-18 01:24:15 +01:00
|
|
|
string protectKeyDefaulted() VL_MT_SAFE; // Set default key if not set by user
|
2008-03-25 20:57:41 +01:00
|
|
|
string topModule() const { return m_topModule; }
|
2023-08-19 10:51:29 +02:00
|
|
|
bool noTraceTop() const { return m_noTraceTop; }
|
2011-01-02 01:43:22 +01:00
|
|
|
string unusedRegexp() const { return m_unusedRegexp; }
|
2020-05-26 20:38:14 +02:00
|
|
|
string waiverOutput() const { return m_waiverOutput; }
|
|
|
|
|
bool isWaiverOutput() const { return !m_waiverOutput.empty(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
string xAssign() const { return m_xAssign; }
|
2017-10-02 03:31:40 +02:00
|
|
|
string xInitial() const { return m_xInitial; }
|
2019-11-01 02:17:05 +01:00
|
|
|
string xmlOutput() const { return m_xmlOutput; }
|
2024-02-09 23:50:09 +01:00
|
|
|
string jsonOnlyOutput() const { return m_jsonOnlyOutput; }
|
|
|
|
|
string jsonOnlyMetaOutput() const { return m_jsonOnlyMetaOutput; }
|
2008-07-22 20:27:34 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
const V3StringSet& cppFiles() const { return m_cppFiles; }
|
2017-02-14 00:11:40 +01:00
|
|
|
const V3StringList& cFlags() const { return m_cFlags; }
|
|
|
|
|
const V3StringList& ldLibs() const { return m_ldLibs; }
|
2020-04-15 23:44:21 +02:00
|
|
|
const V3StringList& makeFlags() const { return m_makeFlags; }
|
2006-08-26 13:35:28 +02:00
|
|
|
const V3StringSet& libraryFiles() const { return m_libraryFiles; }
|
2008-04-09 16:17:03 +02:00
|
|
|
const V3StringList& vFiles() const { return m_vFiles; }
|
2017-02-09 13:43:43 +01:00
|
|
|
const V3StringList& forceIncs() const { return m_forceIncs; }
|
2007-04-19 20:20:16 +02:00
|
|
|
|
2018-02-08 01:31:21 +01:00
|
|
|
bool hasParameter(const string& name);
|
|
|
|
|
string parameter(const string& name);
|
2016-03-25 00:14:15 +01:00
|
|
|
void checkParameters();
|
|
|
|
|
|
2008-07-22 20:27:34 +02:00
|
|
|
bool isFuture(const string& flag) const;
|
2022-08-20 20:01:13 +02:00
|
|
|
bool isFuture0(const string& flag) const;
|
|
|
|
|
bool isFuture1(const string& flag) const;
|
2010-12-30 01:34:33 +01:00
|
|
|
bool isLibraryFile(const string& filename) const;
|
2015-03-13 00:20:46 +01:00
|
|
|
bool isClocker(const string& signame) const;
|
|
|
|
|
bool isNoClocker(const string& signame) const;
|
2008-07-22 20:27:34 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// ACCESSORS (optimization options)
|
2022-06-04 02:43:16 +02:00
|
|
|
bool fAcycSimp() const { return m_fAcycSimp; }
|
|
|
|
|
bool fAssemble() const { return m_fAssemble; }
|
|
|
|
|
bool fCase() const { return m_fCase; }
|
|
|
|
|
bool fCombine() const { return m_fCombine; }
|
|
|
|
|
bool fConst() const { return m_fConst; }
|
2022-10-04 22:18:39 +02:00
|
|
|
bool fConstBeforeDfg() const { return m_fConstBeforeDfg; }
|
2022-06-04 02:43:16 +02:00
|
|
|
bool fConstBitOpTree() const { return m_fConstBitOpTree; }
|
|
|
|
|
bool fDedupe() const { return m_fDedupe; }
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
bool fDfgPeephole() const { return m_fDfgPeephole; }
|
|
|
|
|
bool fDfgPreInline() const { return m_fDfgPreInline; }
|
|
|
|
|
bool fDfgPostInline() const { return m_fDfgPostInline; }
|
|
|
|
|
bool fDfgPeepholeEnabled(const std::string& name) const {
|
|
|
|
|
return !m_fDfgPeepholeDisabled.count(name);
|
|
|
|
|
}
|
2023-12-22 22:26:51 +01:00
|
|
|
bool fDeadAssigns() const { return m_fDeadAssigns; }
|
|
|
|
|
bool fDeadCells() const { return m_fDeadCells; }
|
2022-06-04 02:43:16 +02:00
|
|
|
bool fExpand() const { return m_fExpand; }
|
|
|
|
|
bool fGate() const { return m_fGate; }
|
|
|
|
|
bool fInline() const { return m_fInline; }
|
|
|
|
|
bool fLife() const { return m_fLife; }
|
|
|
|
|
bool fLifePost() const { return m_fLifePost; }
|
|
|
|
|
bool fLocalize() const { return m_fLocalize; }
|
|
|
|
|
bool fMergeCond() const { return m_fMergeCond; }
|
2022-06-13 15:16:11 +02:00
|
|
|
bool fMergeCondMotion() const { return m_fMergeCondMotion; }
|
2022-06-04 02:43:16 +02:00
|
|
|
bool fMergeConstPool() const { return m_fMergeConstPool; }
|
|
|
|
|
bool fReloop() const { return m_fReloop; }
|
|
|
|
|
bool fReorder() const { return m_fReorder; }
|
|
|
|
|
bool fSplit() const { return m_fSplit; }
|
|
|
|
|
bool fSubst() const { return m_fSubst; }
|
|
|
|
|
bool fSubstConst() const { return m_fSubstConst; }
|
|
|
|
|
bool fTable() const { return m_fTable; }
|
2023-06-14 20:44:53 +02:00
|
|
|
bool fTaskifyAll() const { return m_fTaskifyAll; }
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2023-12-19 17:07:06 +01:00
|
|
|
string traceClassBase() const VL_MT_SAFE { return m_traceFormat.classBase(); }
|
2020-03-02 03:39:23 +01:00
|
|
|
string traceClassLang() const { return m_traceFormat.classBase() + (systemC() ? "Sc" : "C"); }
|
|
|
|
|
string traceSourceBase() const { return m_traceFormat.sourceName(); }
|
2022-10-18 23:07:09 +02:00
|
|
|
string traceSourceLang() const VL_MT_SAFE {
|
2020-03-02 03:39:23 +01:00
|
|
|
return m_traceFormat.sourceName() + (systemC() ? "_sc" : "_c");
|
|
|
|
|
}
|
2010-01-25 00:37:01 +01:00
|
|
|
|
2020-08-15 15:43:53 +02:00
|
|
|
bool hierarchical() const { return m_hierarchical; }
|
2022-07-18 16:32:14 +02:00
|
|
|
int hierChild() const { return m_hierChild; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool hierTop() const VL_MT_SAFE { return !m_hierChild && !m_hierBlocks.empty(); }
|
2020-08-15 15:43:53 +02:00
|
|
|
const V3HierBlockOptSet& hierBlocks() const { return m_hierBlocks; }
|
|
|
|
|
// Directory to save .tree, .dot, .dat, .vpp for hierarchical block top
|
2022-12-23 17:32:38 +01:00
|
|
|
// Returns makeDir() unless top module of hierarchical Verilation.
|
2022-10-18 23:07:09 +02:00
|
|
|
string hierTopDataDir() const VL_MT_SAFE {
|
2020-08-15 15:43:53 +02:00
|
|
|
return hierTop() ? (makeDir() + '/' + prefix() + "__hier.dir") : makeDir();
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// METHODS (from main)
|
2023-03-17 00:48:56 +01:00
|
|
|
static string version() VL_PURE;
|
2019-05-19 22:13:13 +02:00
|
|
|
static string argString(int argc, char** argv); ///< Return list of arguments as simple string
|
2022-10-18 23:07:09 +02:00
|
|
|
string allArgsString() const VL_MT_SAFE; ///< Return all passed arguments as simple string
|
2020-08-15 15:43:53 +02:00
|
|
|
// Return options for child hierarchical blocks when forTop==false, otherwise returns args for
|
|
|
|
|
// the top module.
|
|
|
|
|
string allArgsStringForHierBlock(bool forTop) const;
|
2023-09-25 04:12:23 +02:00
|
|
|
void parseOpts(FileLine* fl, int argc, char** argv) VL_MT_DISABLED;
|
|
|
|
|
void parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv) VL_MT_DISABLED;
|
|
|
|
|
void parseOptsFile(FileLine* fl, const string& filename, bool rel) VL_MT_DISABLED;
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2008-03-18 21:26:37 +01:00
|
|
|
// METHODS (environment)
|
|
|
|
|
// Most of these may be built into the executable with --enable-defenv,
|
|
|
|
|
// see the README. If adding new variables, also see src/Makefile_obj.in
|
2009-06-26 01:53:26 +02:00
|
|
|
// Also add to V3Options::showVersion()
|
2017-09-24 00:03:39 +02:00
|
|
|
static string getenvBuiltins(const string& var);
|
2020-04-15 23:44:21 +02:00
|
|
|
static string getenvMAKE();
|
2022-12-11 20:19:40 +01:00
|
|
|
static string getenvMAKEFLAGS();
|
2010-12-18 01:40:08 +01:00
|
|
|
static string getenvPERL();
|
2008-03-18 16:21:13 +01:00
|
|
|
static string getenvSYSTEMC();
|
|
|
|
|
static string getenvSYSTEMC_ARCH();
|
2012-01-20 02:30:41 +01:00
|
|
|
static string getenvSYSTEMC_INCLUDE();
|
|
|
|
|
static string getenvSYSTEMC_LIBDIR();
|
2008-03-18 16:21:13 +01:00
|
|
|
static string getenvVERILATOR_ROOT();
|
2022-11-28 16:53:55 +01:00
|
|
|
static string getStdPackagePath();
|
2022-10-21 03:42:30 +02:00
|
|
|
static string getSupported(const string& var);
|
2020-05-29 00:51:46 +02:00
|
|
|
static bool systemCSystemWide();
|
|
|
|
|
static bool systemCFound(); // SystemC installed, or environment points to it
|
Timing support (#3363)
Adds timing support to Verilator. It makes it possible to use delays,
event controls within processes (not just at the start), wait
statements, and forks.
Building a design with those constructs requires a compiler that
supports C++20 coroutines (GCC 10, Clang 5).
The basic idea is to have processes and tasks with delays/event controls
implemented as C++20 coroutines. This allows us to suspend and resume
them at any time.
There are five main runtime classes responsible for managing suspended
coroutines:
* `VlCoroutineHandle`, a wrapper over C++20's `std::coroutine_handle`
with move semantics and automatic cleanup.
* `VlDelayScheduler`, for coroutines suspended by delays. It resumes
them at a proper simulation time.
* `VlTriggerScheduler`, for coroutines suspended by event controls. It
resumes them if its corresponding trigger was set.
* `VlForkSync`, used for syncing `fork..join` and `fork..join_any`
blocks.
* `VlCoroutine`, the return type of all verilated coroutines. It allows
for suspending a stack of coroutines (normally, C++ coroutines are
stackless).
There is a new visitor in `V3Timing.cpp` which:
* scales delays according to the timescale,
* simplifies intra-assignment timing controls and net delays into
regular timing controls and assignments,
* simplifies wait statements into loops with event controls,
* marks processes and tasks with timing controls in them as
suspendable,
* creates delay, trigger scheduler, and fork sync variables,
* transforms timing controls and fork joins into C++ awaits
There are new functions in `V3SchedTiming.cpp` (used by `V3Sched.cpp`)
that integrate static scheduling with timing. This involves providing
external domains for variables, so that the necessary combinational
logic gets triggered after coroutine resumption, as well as statements
that need to be injected into the design eval function to perform this
resumption at the correct time.
There is also a function that transforms forked processes into separate
functions.
See the comments in `verilated_timing.h`, `verilated_timing.cpp`,
`V3Timing.cpp`, and `V3SchedTiming.cpp`, as well as the internals
documentation for more details.
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
2022-08-22 14:26:32 +02:00
|
|
|
static bool coroutineSupport(); // Compiler supports coroutines
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
// METHODS (file utilities using these options)
|
2018-08-25 15:52:45 +02:00
|
|
|
string fileExists(const string& filename);
|
2020-04-15 01:55:00 +02:00
|
|
|
string filePath(FileLine* fl, const string& modname, const string& lastpath,
|
|
|
|
|
const string& errmsg);
|
2011-10-28 02:56:38 +02:00
|
|
|
void filePathLookedMsg(FileLine* fl, const string& modname);
|
2020-04-15 01:55:00 +02:00
|
|
|
V3LangCode fileLanguage(const string& filename);
|
2018-08-25 15:52:45 +02:00
|
|
|
static bool fileStatNormal(const string& filename);
|
2011-08-05 03:58:45 +02:00
|
|
|
|
|
|
|
|
// METHODS (other OS)
|
|
|
|
|
static void throwSigsegv();
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
#endif // guard
|