1 #ifndef IVL_PScope_H
2 #define IVL_PScope_H
3 /*
4  * Copyright (c) 2008-2019 Stephen Williams (steve@icarus.com)
5  *
6  *    This source code is free software; you can redistribute it
7  *    and/or modify it in source code form under the terms of the GNU
8  *    General Public License as published by the Free Software
9  *    Foundation; either version 2 of the License, or (at your option)
10  *    any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with this program; if not, write to the Free Software
19  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 # include  "PNamedItem.h"
23 # include  "StringHeap.h"
24 # include  "pform_types.h"
25 # include  "ivl_target.h"
26 # include  <map>
27 # include  <set>
28 # include  <vector>
29 
30 class PEvent;
31 class PExpr;
32 class PFunction;
33 class PPackage;
34 class AProcess;
35 class PProcess;
36 class PClass;
37 class PTask;
38 class PWire;
39 class Statement;
40 
41 class Design;
42 class NetScope;
43 
44 /*
45  * The PScope class is a base representation of an object that
46  * represents lexical scope. For example, a module, a function/task, a
47  * named block is derived from a PScope.
48  *
49  * NOTE: This is not the same concept as the "scope" of an elaborated
50  * hierarchy. That is represented by NetScope objects after elaboration.
51  */
52 
53 class LexicalScope {
54 
55     public:
56       enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
57 
LexicalScope(LexicalScope * parent)58       explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), parent_(parent) { }
59 	// A virtual destructor is so that dynamic_cast can work.
~LexicalScope()60       virtual ~LexicalScope() { }
61 
62       lifetime_t default_lifetime;
63 
64 	// Symbols that are defined or declared in this scope.
65       std::map<perm_string,PNamedItem*>local_symbols;
66 
67 	// Symbols that are explicitly imported. Bind the imported name
68 	// to the package from which the name is imported.
69       std::map<perm_string,PPackage*>explicit_imports;
70 
71 	// Packages that are wildcard imported. When identifiers from
72 	// these packages are referenced, they will be added to the
73 	// explicit imports (IEEE 1800-2012 26.3).
74       std::set<PPackage*>potential_imports;
75 
76 	// A task or function call may reference a task or function defined
77 	// later in the scope. So here we stash the potential imports for
78 	// task and function calls. They will be added to the explicit
79 	// imports if we don't find a local definition.
80       std::map<perm_string,PPackage*>possible_imports;
81 
82       struct range_t {
83 	      // True if this is an exclude
84 	    bool exclude_flag;
85 	      // lower bound
86 	      // If low_open_flag is false and low_expr=0, then use -inf
87 	    bool low_open_flag;
88 	    PExpr*low_expr;
89 	      // upper bound
90 	      // If high_open_flag is false and high_expr=0, then use +inf
91 	    bool high_open_flag;
92 	    PExpr*high_expr;
93 	      // Next range description in list
94 	    struct range_t*next;
95       };
96 
97 	/* The scope has parameters that are evaluated when the scope
98 	   is elaborated. During parsing, I put the parameters into
99 	   this map. */
100       struct param_expr_t : public PNamedItem {
param_expr_tparam_expr_t101 	    param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
102 	      // Type information
103 	    ivl_variable_type_t type;
104 	    PExpr*msb;
105 	    PExpr*lsb;
106 	    bool signed_flag;
107 	      // Value expression
108 	    PExpr*expr;
109 	      // If there are range constraints, list them here
110 	    range_t*range;
111 
112 	    SymbolType symbol_type() const;
113       };
114       map<perm_string,param_expr_t*>parameters;
115       map<perm_string,param_expr_t*>localparams;
116 
117 	// Defined types in the scope.
118       map<perm_string,data_type_t*>typedefs;
119 
120 	// Named events in the scope.
121       map<perm_string,PEvent*>events;
122 
123 	// Nets and variables (wires) in the scope
124       map<perm_string,PWire*>wires;
125       PWire* wires_find(perm_string name);
126 
127         // Genvars in the scope. These will only be present in module
128         // scopes, but are listed here to allow them to be found when
129         // creating implicit nets.
130       map<perm_string,LineInfo*> genvars;
131 
132 	// Variable initializations in this scope
133       vector<Statement*> var_inits;
134 
135 	// Behaviors (processes) in this scope
136       list<PProcess*> behaviors;
137       list<AProcess*> analog_behaviors;
138 
139 	// Enumeration sets.
140       std::set<enum_type_t*> enum_sets;
141 
parent_scope()142       LexicalScope* parent_scope() const { return parent_; }
143 
144       virtual bool var_init_needs_explicit_lifetime() const;
145 
146     protected:
147       void dump_typedefs_(ostream&out, unsigned indent) const;
148 
149       void dump_parameters_(ostream&out, unsigned indent) const;
150 
151       void dump_localparams_(ostream&out, unsigned indent) const;
152 
153       void dump_enumerations_(ostream&out, unsigned indent) const;
154 
155       void dump_events_(ostream&out, unsigned indent) const;
156 
157       void dump_wires_(ostream&out, unsigned indent) const;
158 
159       void dump_var_inits_(ostream&out, unsigned indent) const;
160 
161       bool elaborate_var_inits_(Design*des, NetScope*scope) const;
162 
163     private:
164       LexicalScope*parent_;
165 };
166 
167 class PScope : public LexicalScope {
168 
169     public:
170 	// When created, a scope has a name and a parent. The name is
171 	// the name of the definition. For example, if this is a
172 	// module declaration, the name is the name after the "module"
173 	// keyword, and if this is a task scope, the name is the task
174 	// name. The parent is the lexical parent of this scope. Since
175 	// modules do not nest in Verilog, the parent must be nil for
176 	// modules. Scopes for tasks and functions point to their
177 	// containing module.
178       explicit PScope(perm_string name, LexicalScope*parent =0);
179       virtual ~PScope();
180 
pscope_name()181       perm_string pscope_name() const { return name_; }
182 
183 	/* These are the timescale for this scope. The value is
184 	   set by the `timescale directive or, in SystemVerilog,
185 	   by timeunit and timeprecision statements. */
186       int time_unit, time_precision;
187 
188 	/* Flags used to support warnings about timescales. */
189       bool time_unit_is_default;
190       bool time_prec_is_default;
191 
has_explicit_timescale()192       bool has_explicit_timescale() const {
193 	     return !(time_unit_is_default || time_prec_is_default);
194 	   }
195 
196     protected:
197       bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
198 
199       bool elaborate_behaviors_(Design*des, NetScope*scope) const;
200 
201     private:
202       perm_string name_;
203 };
204 
205 /*
206  * Some scopes can carry definitions. These include Modules and PClass
207  * scopes. These derive from PScopeExtra so that they hold the maps of
208  * extra definitions.
209  */
210 class PScopeExtra : public PScope {
211 
212     public:
213       explicit PScopeExtra(perm_string, LexicalScope*parent =0);
214       ~PScopeExtra();
215 
216 	/* Task definitions within this module */
217       std::map<perm_string,PTask*> tasks;
218       std::map<perm_string,PFunction*> funcs;
219 	/* Class definitions within this module. */
220       std::map<perm_string,PClass*> classes;
221 	/* This is the lexical order of the classes, and is used by
222 	   elaboration to choose an elaboration order. */
223       std::vector<PClass*> classes_lexical;
224 
225 	/* Flags used to support warnings about timescales. */
226       bool time_unit_is_local;
227       bool time_prec_is_local;
228 
229     protected:
230       void dump_classes_(ostream&out, unsigned indent) const;
231       void dump_tasks_(ostream&out, unsigned indent) const;
232       void dump_funcs_(ostream&out, unsigned indent) const;
233 };
234 
235 #endif /* IVL_PScope_H */
236