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