1 /*
2 * Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com)
3 *
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "config.h"
21
22 # include "PGate.h"
23 # include "PExpr.h"
24 # include "verinum.h"
25 # include <cassert>
26
set_pins_(list<PExpr * > * pins)27 void PGate::set_pins_(list<PExpr*>*pins)
28 {
29 assert(pins);
30 assert(pins->size() == pins_.size());
31
32 for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
33 pins_[idx] = pins->front();
34 pins->pop_front();
35 }
36
37 assert(pins->empty());
38 delete pins;
39 }
40
PGate(perm_string name,list<PExpr * > * pins,const list<PExpr * > * del)41 PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
42 : name_(name), pins_(pins? pins->size() : 0)
43 {
44 if (pins) set_pins_(pins);
45 if (del) delay_.set_delays(del);
46 str0_ = IVL_DR_STRONG;
47 str1_ = IVL_DR_STRONG;
48 }
49
PGate(perm_string name,list<PExpr * > * pins,PExpr * del)50 PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
51 : name_(name), pins_(pins? pins->size() : 0)
52 {
53 if (pins) set_pins_(pins);
54 if (del) delay_.set_delay(del);
55 str0_ = IVL_DR_STRONG;
56 str1_ = IVL_DR_STRONG;
57 }
58
PGate(perm_string name,list<PExpr * > * pins)59 PGate::PGate(perm_string name, list<PExpr*>*pins)
60 : name_(name), pins_(pins? pins->size() : 0)
61 {
62 if (pins) set_pins_(pins);
63 str0_ = IVL_DR_STRONG;
64 str1_ = IVL_DR_STRONG;
65 }
66
~PGate()67 PGate::~PGate()
68 {
69 }
70
strength0() const71 ivl_drive_t PGate::strength0() const
72 {
73 return str0_;
74 }
75
strength0(ivl_drive_t s)76 void PGate::strength0(ivl_drive_t s)
77 {
78 str0_ = s;
79 }
80
strength1() const81 ivl_drive_t PGate::strength1() const
82 {
83 return str1_;
84 }
85
strength1(ivl_drive_t s)86 void PGate::strength1(ivl_drive_t s)
87 {
88 str1_ = s;
89 }
90
elaborate_scope(Design *,NetScope *) const91 void PGate::elaborate_scope(Design*, NetScope*) const
92 {
93 }
94
95 /*
96 * This method is used during elaboration to calculate the
97 * rise/fall/decay times for the gate. These values were set in pform
98 * by the constructor, so here I evaluate the expression in the given
99 * design context and save the calculated delays into the output
100 * parameters. This method understands how to handle the different
101 * numbers of expressions.
102 */
103
eval_delays(Design * des,NetScope * scope,NetExpr * & rise_expr,NetExpr * & fall_expr,NetExpr * & decay_expr,bool as_net_flag) const104 void PGate::eval_delays(Design*des, NetScope*scope,
105 NetExpr*&rise_expr,
106 NetExpr*&fall_expr,
107 NetExpr*&decay_expr,
108 bool as_net_flag) const
109 {
110 delay_.eval_delays(des, scope,
111 rise_expr, fall_expr, decay_expr,
112 as_net_flag);
113 }
114
delay_count() const115 unsigned PGate::delay_count() const
116 {
117 return delay_.delay_count();
118 }
119
symbol_type() const120 PNamedItem::SymbolType PGate::symbol_type() const
121 {
122 return INSTANCE;
123 }
124
PGAssign(list<PExpr * > * pins)125 PGAssign::PGAssign(list<PExpr*>*pins)
126 : PGate(perm_string(), pins)
127 {
128 assert(pin_count() == 2);
129 }
130
PGAssign(list<PExpr * > * pins,list<PExpr * > * dels)131 PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
132 : PGate(perm_string(), pins, dels)
133 {
134 assert(pin_count() == 2);
135 }
136
~PGAssign()137 PGAssign::~PGAssign()
138 {
139 }
140
PGBuiltin(Type t,perm_string name,list<PExpr * > * pins,list<PExpr * > * del)141 PGBuiltin::PGBuiltin(Type t, perm_string name,
142 list<PExpr*>*pins,
143 list<PExpr*>*del)
144 : PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
145 {
146 }
147
PGBuiltin(Type t,perm_string name,list<PExpr * > * pins,PExpr * del)148 PGBuiltin::PGBuiltin(Type t, perm_string name,
149 list<PExpr*>*pins,
150 PExpr*del)
151 : PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
152 {
153 }
154
155
~PGBuiltin()156 PGBuiltin::~PGBuiltin()
157 {
158 }
159
set_range(PExpr * msb,PExpr * lsb)160 void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
161 {
162 assert(msb_ == 0);
163 assert(lsb_ == 0);
164
165 msb_ = msb;
166 lsb_ = lsb;
167 }
168
gate_name() const169 const char* PGBuiltin::gate_name() const
170 {
171 switch(type_) {
172 case AND:
173 return "AND";
174 break;
175 case NAND:
176 return "NAND";
177 break;
178
179 case OR:
180 return "OR";
181 break;
182 case NOR:
183 return "NOR";
184 break;
185
186 case XOR:
187 return "XOR";
188 break;
189 case XNOR:
190 return "XNOR";
191 break;
192
193 case BUF:
194 return "BUF";
195 break;
196 case NOT:
197 return "NOT";
198 break;
199
200 case BUFIF0:
201 return "BUFIF0";
202 break;
203 case NOTIF0:
204 return "NOTIF0";
205 break;
206
207 case BUFIF1:
208 return "BUFIF1";
209 break;
210 case NOTIF1:
211 return "NOTIF1";
212 break;
213
214 case NMOS:
215 return "NMOS";
216 break;
217 case RNMOS:
218 return "RNMOS";
219 break;
220
221 case PMOS:
222 return "PMOS";
223 break;
224 case RPMOS:
225 return "RPMOS";
226 break;
227
228 case TRAN:
229 return "TRAN";
230 break;
231 case RTRAN:
232 return "RTRAN";
233 break;
234
235 case TRANIF0:
236 return "TRANIF0";
237 break;
238 case RTRANIF0:
239 return "RTRANIF0";
240 break;
241
242 case TRANIF1:
243 return "TRANIF1";
244 break;
245 case RTRANIF1:
246 return "RTRANIF1";
247 break;
248
249 case CMOS:
250 return "CMOS";
251 break;
252 case RCMOS:
253 return "RCMOS";
254 break;
255
256 case PULLUP:
257 return "PULLUP";
258 break;
259 case PULLDOWN:
260 return "PULLDOWN";
261 break;
262 }
263
264 return "<unknown>";
265 }
266
PGModule(perm_string type,perm_string name,list<PExpr * > * pins)267 PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
268 : PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
269 npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
270 {
271 }
272
PGModule(perm_string type,perm_string name,named<PExpr * > * pins,unsigned npins)273 PGModule::PGModule(perm_string type, perm_string name,
274 named<PExpr*>*pins, unsigned npins)
275 : PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
276 npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
277 {
278 }
279
PGModule(Module * type,perm_string name)280 PGModule::PGModule(Module*type, perm_string name)
281 : PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
282 npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
283 {
284 }
285
~PGModule()286 PGModule::~PGModule()
287 {
288 }
289
set_parameters(list<PExpr * > * o)290 void PGModule::set_parameters(list<PExpr*>*o)
291 {
292 assert(overrides_ == 0);
293 overrides_ = o;
294 }
295
set_parameters(named<PExpr * > * pa,unsigned npa)296 void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
297 {
298 assert(parms_ == 0);
299 assert(overrides_ == 0);
300 parms_ = pa;
301 nparms_ = npa;
302 }
303
set_range(PExpr * msb,PExpr * lsb)304 void PGModule::set_range(PExpr*msb, PExpr*lsb)
305 {
306 assert(msb_ == 0);
307 assert(lsb_ == 0);
308
309 msb_ = msb;
310 lsb_ = lsb;
311 }
312
get_type() const313 perm_string PGModule::get_type() const
314 {
315 return type_;
316 }
317