1 #ifndef IVL_PGate_H 2 #define IVL_PGate_H 3 /* 4 * Copyright (c) 1998-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 "svector.h" 23 # include "StringHeap.h" 24 # include "named.h" 25 # include "PNamedItem.h" 26 # include "PDelays.h" 27 # include "netlist.h" 28 # include <map> 29 # include <list> 30 # include <vector> 31 # include <string> 32 class PExpr; 33 class PUdp; 34 class Module; 35 36 /* 37 * A PGate represents a Verilog gate. The gate has a name and other 38 * properties, and a set of pins that connect to wires. It is known at 39 * the time a gate is constructed how many pins the gate has. 40 * 41 * This pins of a gate are connected to expressions. The elaboration 42 * step will need to convert expressions to a network of gates in 43 * order to elaborate expression inputs, but that can easily be done. 44 * 45 * The PGate base class also carries the strength0 and strength1 46 * strengths for those gates where the driver[s] can be described by a 47 * single strength pair. There is a strength of the 0 drive, and a 48 * strength of the 1 drive. 49 */ 50 class PGate : public PNamedItem { 51 52 public: 53 explicit PGate(perm_string name, list<PExpr*>*pins, 54 const list<PExpr*>*del); 55 56 explicit PGate(perm_string name, list<PExpr*>*pins, 57 PExpr*del); 58 59 explicit PGate(perm_string name, list<PExpr*>*pins); 60 61 virtual ~PGate(); 62 get_name()63 perm_string get_name() const { return name_; } 64 65 // This evaluates the delays as far as possible, but returns 66 // an expression, and do not signal errors. 67 void eval_delays(Design*des, NetScope*scope, 68 NetExpr*&rise_time, 69 NetExpr*&fall_time, 70 NetExpr*&decay_time, 71 bool as_net_flag =false) const; 72 73 unsigned delay_count() const; 74 pin_count()75 unsigned pin_count() const { return pins_.size(); } pin(unsigned idx)76 PExpr*pin(unsigned idx) const { return pins_[idx]; } 77 78 ivl_drive_t strength0() const; 79 ivl_drive_t strength1() const; 80 81 void strength0(ivl_drive_t); 82 void strength1(ivl_drive_t); 83 84 map<perm_string,PExpr*> attributes; 85 86 virtual void dump(ostream&out, unsigned ind =4) const; 87 virtual void elaborate(Design*des, NetScope*scope) const; 88 virtual void elaborate_scope(Design*des, NetScope*sc) const; 89 virtual bool elaborate_sig(Design*des, NetScope*scope) const; 90 91 SymbolType symbol_type() const; 92 93 protected: get_pins()94 const vector<PExpr*>& get_pins() const { return pins_; } 95 96 void dump_pins(ostream&out) const; 97 void dump_delays(ostream&out) const; 98 99 private: 100 perm_string name_; 101 PDelays delay_; 102 vector<PExpr*>pins_; 103 104 ivl_drive_t str0_, str1_; 105 106 void set_pins_(list<PExpr*>*pins); 107 108 private: // not implemented 109 PGate(const PGate&); 110 PGate& operator= (const PGate&); 111 }; 112 113 /* A continuous assignment has a single output and a single input. The 114 input is passed directly to the output. This is different from a 115 BUF because elaboration may need to turn this into a vector of 116 gates. */ 117 class PGAssign : public PGate { 118 119 public: 120 explicit PGAssign(list<PExpr*>*pins); 121 explicit PGAssign(list<PExpr*>*pins, list<PExpr*>*dels); 122 ~PGAssign(); 123 124 void dump(ostream&out, unsigned ind =4) const; 125 virtual void elaborate(Design*des, NetScope*scope) const; 126 virtual bool elaborate_sig(Design*des, NetScope*scope) const; 127 128 private: 129 void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const; 130 }; 131 132 133 /* 134 * The Builtin class is specifically a gate with one of the builtin 135 * types. The parser recognizes these types during parse. These types 136 * have special properties that allow them to be treated specially. 137 * 138 * A PGBuiltin can be grouped into an array of devices. If this is 139 * done, the msb_ and lsb_ are set to the indices of the array 140 * range. Elaboration causes a gate to be created for each element of 141 * the array, and a name will be generated for each gate. 142 */ 143 class PGBuiltin : public PGate { 144 145 public: 146 enum Type { AND, NAND, OR, NOR, XOR, XNOR, BUF, BUFIF0, BUFIF1, 147 NOT, NOTIF0, NOTIF1, PULLDOWN, PULLUP, NMOS, RNMOS, 148 PMOS, RPMOS, CMOS, RCMOS, TRAN, RTRAN, TRANIF0, 149 TRANIF1, RTRANIF0, RTRANIF1 }; 150 151 public: 152 explicit PGBuiltin(Type t, perm_string name, 153 list<PExpr*>*pins, 154 list<PExpr*>*del); 155 explicit PGBuiltin(Type t, perm_string name, 156 list<PExpr*>*pins, 157 PExpr*del); 158 ~PGBuiltin(); 159 type()160 Type type() const { return type_; } 161 const char * gate_name() const; 162 void set_range(PExpr*msb, PExpr*lsb); 163 164 virtual void dump(ostream&out, unsigned ind =4) const; 165 virtual void elaborate(Design*, NetScope*scope) const; 166 virtual bool elaborate_sig(Design*des, NetScope*scope) const; 167 168 private: 169 unsigned calculate_array_count_(Design*, NetScope*, 170 long&high, long&low) const; 171 172 void calculate_gate_and_lval_count_(unsigned&gate_count, 173 unsigned&lval_count) const; 174 175 NetNode* create_gate_for_output_(Design*, NetScope*, 176 perm_string gate_name, 177 unsigned instance_width) const; 178 179 bool check_delay_count(Design*des) const; 180 181 Type type_; 182 PExpr*msb_; 183 PExpr*lsb_; 184 }; 185 186 /* 187 * This kind of gate is an instantiation of a module. The stored type 188 * is the name of a module definition somewhere in the pform. This 189 * type also handles UDP devices, because it is generally not known at 190 * parse time whether a name belongs to a module or a UDP. 191 */ 192 class PGModule : public PGate { 193 194 public: 195 // The name is the *instance* name of the gate. 196 197 // If the binding of ports is by position, this constructor 198 // builds everything all at once. 199 explicit PGModule(perm_string type, perm_string name, 200 list<PExpr*>*pins); 201 202 // If the binding of ports is by name, this constructor takes 203 // the bindings and stores them for later elaboration. 204 explicit PGModule(perm_string type, perm_string name, 205 named<PExpr*>*pins, unsigned npins); 206 207 // If the module type is known by design, then use this 208 // constructor. 209 explicit PGModule(Module*type, perm_string name); 210 211 ~PGModule(); 212 213 // Parameter overrides can come as an ordered list, or a set 214 // of named expressions. 215 void set_parameters(list<PExpr*>*o); 216 void set_parameters(named<PExpr*>*pa, unsigned npa); 217 218 // Modules can be instantiated in ranges. The parser uses this 219 // method to pass the range to the pform. 220 void set_range(PExpr*msb, PExpr*lsb); 221 222 map<perm_string,PExpr*> attributes; 223 224 virtual void dump(ostream&out, unsigned ind =4) const; 225 virtual void elaborate(Design*, NetScope*scope) const; 226 virtual void elaborate_scope(Design*des, NetScope*sc) const; 227 virtual bool elaborate_sig(Design*des, NetScope*scope) const; 228 229 // This returns the module name of this module. It is a 230 // permallocated string. 231 perm_string get_type() const; 232 233 private: 234 Module*bound_type_; 235 perm_string type_; 236 list<PExpr*>*overrides_; 237 named<PExpr*>*pins_; 238 unsigned npins_; 239 240 // These members support parameter override by name 241 named<PExpr*>*parms_; 242 unsigned nparms_; 243 244 // Arrays of modules are give if these are set. 245 PExpr*msb_; 246 PExpr*lsb_; 247 248 friend class delayed_elaborate_scope_mod_instances; 249 void elaborate_mod_(Design*, Module*mod, NetScope*scope) const; 250 void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const; 251 unsigned calculate_instance_count_(Design*, NetScope*, 252 long&high, long&low, 253 perm_string name) const; 254 void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const; 255 void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const; 256 bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const; 257 // Not currently used. 258 #if 0 259 bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const; 260 #endif 261 262 NetNet*resize_net_to_port_(Design*des, NetScope*scope, 263 NetNet*sig, unsigned port_wid, 264 NetNet::PortType dir, bool as_signed) const; 265 }; 266 267 #endif /* IVL_PGate_H */ 268