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