1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilator: Common headers
4 //
5 // Code available from: https://verilator.org
6 //
7 //*************************************************************************
8 //
9 // Copyright 2003-2021 by Wilson Snyder. This program is free software; you
10 // can redistribute it and/or modify it under the terms of either the GNU
11 // Lesser General Public License Version 3 or the Perl Artistic License
12 // Version 2.0.
13 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
14 //
15 //*************************************************************************
16 
17 #ifndef VERILATOR_V3GLOBAL_H_
18 #define VERILATOR_V3GLOBAL_H_
19 
20 // clang-format off
21 #include "config_build.h"
22 #ifndef HAVE_CONFIG_BUILD
23 # error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
24 #endif
25 // clang-format on
26 
27 #include "verilatedos.h"
28 
29 #include "V3Error.h"
30 #include "V3FileLine.h"
31 #include "V3Options.h"
32 
33 #include <string>
34 #include <unordered_map>
35 
36 class AstNetlist;
37 class V3HierBlockPlan;
38 
39 //======================================================================
40 // Restorer
41 
42 /// Save a given variable's value on the stack, restoring it at
43 /// end-of-stope.
44 // Object must be named, or it will not persist until end-of-scope.
45 // Constructor needs () or GCC 4.8 false warning.
46 #define VL_RESTORER(var) const VRestorer<decltype(var)> restorer_##var(var);
47 
48 // Object used by VL_RESTORER.  This object must be an auto variable, not
49 // allocated on the heap or otherwise.
50 template <typename T> class VRestorer {
51     T& m_ref;  // Reference to object we're saving and restoring
52     const T m_saved;  // Value saved, for later restore
53 
54 public:
VRestorer(T & permr)55     explicit VRestorer(T& permr)
56         : m_ref{permr}
57         , m_saved{permr} {}
~VRestorer()58     ~VRestorer() { m_ref = m_saved; }
59     VL_UNCOPYABLE(VRestorer);
60 };
61 
62 //######################################################################
63 
64 class VWidthMinUsage final {
65 public:
66     enum en : uint8_t { LINT_WIDTH, MATCHES_WIDTH, VERILOG_WIDTH };
67     enum en m_e;
VWidthMinUsage()68     VWidthMinUsage()
69         : m_e{LINT_WIDTH} {}
70     // cppcheck-suppress noExplicitConstructor
VWidthMinUsage(en _e)71     VWidthMinUsage(en _e)
72         : m_e{_e} {}
VWidthMinUsage(int _e)73     explicit VWidthMinUsage(int _e)
74         : m_e(static_cast<en>(_e)) {}  // Need () or GCC 4.8 false warning
en()75     operator en() const { return m_e; }
76 };
77 inline bool operator==(const VWidthMinUsage& lhs, const VWidthMinUsage& rhs) {
78     return lhs.m_e == rhs.m_e;
79 }
80 inline bool operator==(const VWidthMinUsage& lhs, VWidthMinUsage::en rhs) {
81     return lhs.m_e == rhs;
82 }
83 inline bool operator==(VWidthMinUsage::en lhs, const VWidthMinUsage& rhs) {
84     return lhs == rhs.m_e;
85 }
86 
87 //######################################################################
88 // V3Global - The top level class for the entire program
89 
90 class V3Global final {
91     // Globals
92     AstNetlist* m_rootp;  // Root of entire netlist
93     V3HierBlockPlan* m_hierPlanp;  // Hierarchical verilation plan, nullptr unless hier_block
94     VWidthMinUsage m_widthMinUsage;  // What AstNode::widthMin() is used for
95 
96     int m_debugFileNumber = 0;  // Number to append to debug files created
97     bool m_assertDTypesResolved = false;  // Tree should have dtypep()'s
98     bool m_assertScoped = false;  // Tree is scoped
99     bool m_constRemoveXs = false;  // Const needs to strip any Xs
100     // Experimenting with always requiring heavy, see (#2701)
101     bool m_needTraceDumper = false;  // Need __Vm_dumperp in symbols
102     bool m_dpi = false;  // Need __Dpi include files
103     bool m_useParallelBuild = false;  // Use parallel build for model
104     bool m_useRandomizeMethods = false;  // Need to define randomize() class methods
105 
106     // Memory address to short string mapping (for debug)
107     std::unordered_map<const void*, std::string>
108         m_ptrToId;  // The actual 'address' <=> 'short string' bijection
109 
110 public:
111     // Options
112     V3Options opt;  // All options; let user see them directly
113 
114     // CONSTRUCTORS
V3Global()115     V3Global()
116         : m_rootp{nullptr}  // created by makeInitNetlist(} so static constructors run first
117         , m_hierPlanp{nullptr}  // Set via hierPlanp(V3HierBlockPlan*} when use hier_block
118         , m_widthMinUsage{VWidthMinUsage::LINT_WIDTH} {}
119     AstNetlist* makeNetlist();
boot()120     void boot() {
121         UASSERT(!m_rootp, "call once");
122         m_rootp = makeNetlist();
123     }
124     void clear();
125     void shutdown();  // Release allocated resorces
126     // ACCESSORS (general)
rootp()127     AstNetlist* rootp() const { return m_rootp; }
widthMinUsage()128     VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; }
assertDTypesResolved()129     bool assertDTypesResolved() const { return m_assertDTypesResolved; }
assertScoped()130     bool assertScoped() const { return m_assertScoped; }
131 
132     // METHODS
133     void readFiles();
134     void checkTree() const;
135     static void dumpCheckGlobalTree(const string& stagename, int newNumber = 0,
136                                     bool doDump = true);
assertDTypesResolved(bool flag)137     void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; }
assertScoped(bool flag)138     void assertScoped(bool flag) { m_assertScoped = flag; }
widthMinUsage(const VWidthMinUsage & flag)139     void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
constRemoveXs()140     bool constRemoveXs() const { return m_constRemoveXs; }
constRemoveXs(bool flag)141     void constRemoveXs(bool flag) { m_constRemoveXs = flag; }
142     string debugFilename(const string& nameComment, int newNumber = 0);
143     static string digitsFilename(int number);
needTraceDumper()144     bool needTraceDumper() const { return m_needTraceDumper; }
needTraceDumper(bool flag)145     void needTraceDumper(bool flag) { m_needTraceDumper = flag; }
dpi()146     bool dpi() const { return m_dpi; }
dpi(bool flag)147     void dpi(bool flag) { m_dpi = flag; }
hierPlanp()148     V3HierBlockPlan* hierPlanp() const { return m_hierPlanp; }
hierPlanp(V3HierBlockPlan * plan)149     void hierPlanp(V3HierBlockPlan* plan) {
150         UASSERT(!m_hierPlanp, "call once");
151         m_hierPlanp = plan;
152     }
useParallelBuild(bool flag)153     void useParallelBuild(bool flag) { m_useParallelBuild = flag; }
useParallelBuild()154     bool useParallelBuild() const { return m_useParallelBuild; }
useRandomizeMethods(bool flag)155     void useRandomizeMethods(bool flag) { m_useRandomizeMethods = flag; }
useRandomizeMethods()156     bool useRandomizeMethods() const { return m_useRandomizeMethods; }
157     const std::string& ptrToId(const void* p);
158 };
159 
160 extern V3Global v3Global;
161 
162 //######################################################################
163 
164 #endif  // guard
165