1 /*
2  * Copyright (c) 1998-2020 Stephen Williams <steve@icarus.com>
3  * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
4  *
5  *    This source code is free software; you can redistribute it
6  *    and/or modify it in source code form under the terms of the GNU
7  *    General Public License as published by the Free Software
8  *    Foundation; either version 2 of the License, or (at your option)
9  *    any later version.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with this program; if not, write to the Free Software
18  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 # include "config.h"
22 
23 # include  <iostream>
24 
25 # include  "compiler.h"
26 # include  "PExpr.h"
27 # include  "PWire.h"
28 # include  "Module.h"
29 # include  "netmisc.h"
30 # include  "util.h"
31 # include  <typeinfo>
32 
PExpr()33 PExpr::PExpr()
34 {
35       expr_type_   = IVL_VT_NO_TYPE;
36       expr_width_  = 0;
37       min_width_   = 0;
38       signed_flag_ = false;
39 }
40 
~PExpr()41 PExpr::~PExpr()
42 {
43 }
44 
declare_implicit_nets(LexicalScope *,NetNet::Type)45 void PExpr::declare_implicit_nets(LexicalScope*, NetNet::Type)
46 {
47 }
48 
has_aa_term(Design *,NetScope *) const49 bool PExpr::has_aa_term(Design*, NetScope*) const
50 {
51       return false;
52 }
53 
is_the_same(const PExpr * that) const54 bool PExpr::is_the_same(const PExpr*that) const
55 {
56       return typeid(this) == typeid(that);
57 }
58 
elaborate_lnet(Design *,NetScope *) const59 NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
60 {
61       cerr << get_fileline() << ": error: "
62            << "expression not valid in assign l-value: "
63            << *this << endl;
64       return 0;
65 }
66 
elaborate_bi_net(Design *,NetScope *) const67 NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
68 {
69       cerr << get_fileline() << ": error: "
70            << "expression not valid as argument to inout port: "
71            << *this << endl;
72       return 0;
73 }
74 
is_collapsible_net(Design *,NetScope *) const75 bool PExpr::is_collapsible_net(Design*, NetScope*) const
76 {
77       return false;
78 }
79 
80 
width_mode_name(width_mode_t mode)81 const char* PExpr::width_mode_name(width_mode_t mode)
82 {
83       switch (mode) {
84           case PExpr::SIZED:
85             return "sized";
86           case PExpr::UNSIZED:
87             return "unsized";
88           case PExpr::EXPAND:
89             return "expand";
90           case PExpr::LOSSLESS:
91             return "lossless";
92           case PExpr::UPSIZE:
93             return "upsize";
94           default:
95             return "??";
96       }
97 }
98 
PEAssignPattern()99 PEAssignPattern::PEAssignPattern()
100 {
101 }
102 
PEAssignPattern(const list<PExpr * > & p)103 PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
104 : parms_(p.size())
105 {
106       size_t idx = 0;
107       for (list<PExpr*>::const_iterator cur = p.begin()
108 		 ; cur != p.end() ; ++cur) {
109 	    parms_[idx] = *cur;
110 	    idx += 1;
111       }
112 }
113 
~PEAssignPattern()114 PEAssignPattern::~PEAssignPattern()
115 {
116 }
117 
PEBinary(char op,PExpr * l,PExpr * r)118 PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
119 : op_(op), left_(l), right_(r)
120 {
121 }
122 
~PEBinary()123 PEBinary::~PEBinary()
124 {
125 }
126 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)127 void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
128 {
129       if (left_) left_->declare_implicit_nets(scope, type);
130       if (right_) right_->declare_implicit_nets(scope, type);
131 }
132 
has_aa_term(Design * des,NetScope * scope) const133 bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
134 {
135       assert(left_ && right_);
136       return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
137 }
138 
PECastSize(PExpr * si,PExpr * b)139 PECastSize::PECastSize(PExpr*si, PExpr*b)
140 : size_(si), base_(b)
141 {
142 }
143 
~PECastSize()144 PECastSize::~PECastSize()
145 {
146 }
147 
PECastType(data_type_t * t,PExpr * b)148 PECastType::PECastType(data_type_t*t, PExpr*b)
149 : target_(t), base_(b)
150 {
151 }
152 
~PECastType()153 PECastType::~PECastType()
154 {
155 }
156 
PEBComp(char op,PExpr * l,PExpr * r)157 PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
158 : PEBinary(op, l, r)
159 {
160       l_width_ = 0;
161       r_width_ = 0;
162 }
163 
~PEBComp()164 PEBComp::~PEBComp()
165 {
166 }
167 
PEBLogic(char op,PExpr * l,PExpr * r)168 PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
169 : PEBinary(op, l, r)
170 {
171       assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q');
172 }
173 
~PEBLogic()174 PEBLogic::~PEBLogic()
175 {
176 }
177 
PEBLeftWidth(char op,PExpr * l,PExpr * r)178 PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
179 : PEBinary(op, l, r)
180 {
181 }
182 
~PEBLeftWidth()183 PEBLeftWidth::~PEBLeftWidth()
184 {
185 }
186 
PEBPower(char op,PExpr * l,PExpr * r)187 PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
188 : PEBLeftWidth(op, l, r)
189 {
190 }
191 
~PEBPower()192 PEBPower::~PEBPower()
193 {
194 }
195 
PEBShift(char op,PExpr * l,PExpr * r)196 PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
197 : PEBLeftWidth(op, l, r)
198 {
199 }
200 
~PEBShift()201 PEBShift::~PEBShift()
202 {
203 }
204 
PECallFunction(const pform_name_t & n,const vector<PExpr * > & parms)205 PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
206 : package_(0), path_(n), parms_(parms), is_overridden_(false)
207 {
208 }
209 
PECallFunction(PPackage * pkg,const pform_name_t & n,const vector<PExpr * > & parms)210 PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
211 : package_(pkg), path_(n), parms_(parms), is_overridden_(false)
212 {
213 }
214 
pn_from_ps(perm_string n)215 static pform_name_t pn_from_ps(perm_string n)
216 {
217       name_component_t tmp_name (n);
218       pform_name_t tmp;
219       tmp.push_back(tmp_name);
220       return tmp;
221 }
222 
PECallFunction(PPackage * pkg,perm_string n,const list<PExpr * > & parms)223 PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
224 : package_(pkg), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
225 {
226       int tmp_idx = 0;
227       assert(parms_.size() == parms.size());
228       for (list<PExpr*>::const_iterator idx = parms.begin()
229 		 ; idx != parms.end() ; ++idx)
230 	    parms_[tmp_idx++] = *idx;
231 }
232 
PECallFunction(perm_string n,const vector<PExpr * > & parms)233 PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
234 : package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
235 {
236 }
237 
PECallFunction(perm_string n)238 PECallFunction::PECallFunction(perm_string n)
239 : package_(0), path_(pn_from_ps(n)), is_overridden_(false)
240 {
241 }
242 
243 // NOTE: Anachronism. Try to work all use of svector out.
PECallFunction(const pform_name_t & n,const list<PExpr * > & parms)244 PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
245 : package_(0), path_(n), parms_(parms.size()), is_overridden_(false)
246 {
247       int tmp_idx = 0;
248       assert(parms_.size() == parms.size());
249       for (list<PExpr*>::const_iterator idx = parms.begin()
250 		 ; idx != parms.end() ; ++idx)
251 	    parms_[tmp_idx++] = *idx;
252 }
253 
PECallFunction(perm_string n,const list<PExpr * > & parms)254 PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
255 : package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
256 {
257       int tmp_idx = 0;
258       assert(parms_.size() == parms.size());
259       for (list<PExpr*>::const_iterator idx = parms.begin()
260 		 ; idx != parms.end() ; ++idx)
261 	    parms_[tmp_idx++] = *idx;
262 }
263 
~PECallFunction()264 PECallFunction::~PECallFunction()
265 {
266 }
267 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)268 void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
269 {
270       for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
271 	    parms_[idx]->declare_implicit_nets(scope, type);
272       }
273 }
274 
has_aa_term(Design * des,NetScope * scope) const275 bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
276 {
277       bool flag = false;
278       for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
279 	    flag = parms_[idx]->has_aa_term(des, scope) || flag;
280       }
281       return flag;
282 }
283 
PEConcat(const list<PExpr * > & p,PExpr * r)284 PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
285 : parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r)
286 {
287       int tmp_idx = 0;
288       assert(parms_.size() == p.size());
289       for (list<PExpr*>::const_iterator idx = p.begin()
290 		 ; idx != p.end() ; ++idx)
291 	    parms_[tmp_idx++] = *idx;
292 
293       tested_scope_ = 0;
294       repeat_count_ = 1;
295 }
296 
~PEConcat()297 PEConcat::~PEConcat()
298 {
299       delete repeat_;
300 }
301 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)302 void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
303 {
304       for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
305 	    parms_[idx]->declare_implicit_nets(scope, type);
306       }
307 }
308 
has_aa_term(Design * des,NetScope * scope) const309 bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
310 {
311       bool flag = false;
312       for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
313 	    flag = parms_[idx]->has_aa_term(des, scope) || flag;
314       }
315       if (repeat_)
316             flag = repeat_->has_aa_term(des, scope) || flag;
317 
318       return flag;
319 }
320 
PEEvent(PEEvent::edge_t t,PExpr * e)321 PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
322 : type_(t), expr_(e)
323 {
324 }
325 
~PEEvent()326 PEEvent::~PEEvent()
327 {
328 }
329 
type() const330 PEEvent::edge_t PEEvent::type() const
331 {
332       return type_;
333 }
334 
has_aa_term(Design * des,NetScope * scope) const335 bool PEEvent::has_aa_term(Design*des, NetScope*scope) const
336 {
337       assert(expr_);
338       return expr_->has_aa_term(des, scope);
339 }
340 
expr() const341 PExpr* PEEvent::expr() const
342 {
343       return expr_;
344 }
345 
PENull(void)346 PENull::PENull(void)
347 {
348 }
349 
~PENull()350 PENull::~PENull()
351 {
352 }
353 
PEFNumber(verireal * v)354 PEFNumber::PEFNumber(verireal*v)
355 : value_(v)
356 {
357 }
358 
~PEFNumber()359 PEFNumber::~PEFNumber()
360 {
361       delete value_;
362 }
363 
value() const364 const verireal& PEFNumber::value() const
365 {
366       return *value_;
367 }
368 
PEIdent(const pform_name_t & that)369 PEIdent::PEIdent(const pform_name_t&that)
370 : package_(0), path_(that), no_implicit_sig_(false)
371 {
372 }
373 
PEIdent(perm_string s,bool no_implicit_sig)374 PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
375 : package_(0), no_implicit_sig_(no_implicit_sig)
376 {
377       path_.push_back(name_component_t(s));
378 }
379 
PEIdent(PPackage * pkg,const pform_name_t & that)380 PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
381 : package_(pkg), path_(that), no_implicit_sig_(true)
382 {
383 }
384 
~PEIdent()385 PEIdent::~PEIdent()
386 {
387 }
388 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)389 void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
390 {
391         /* We create an implicit wire if:
392 	   - this is a simple identifier
393            - an identifier of that name has not already been declared in
394              any enclosing scope.
395 	   - this is not an implicit named port connection */
396      if (no_implicit_sig_)
397 	    return;
398      if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
399             perm_string name = path_.front().name;
400             LexicalScope*ss = scope;
401             while (ss) {
402                   if (ss->wires.find(name) != ss->wires.end())
403                         return;
404                   if (ss->localparams.find(name) != ss->localparams.end())
405                         return;
406                   if (ss->parameters.find(name) != ss->parameters.end())
407                         return;
408                   if (ss->genvars.find(name) != ss->genvars.end())
409                         return;
410                   if (ss->events.find(name) != ss->events.end())
411                         return;
412                   /* Strictly speaking, we should also check for name clashes
413                      with tasks, functions, named blocks, module instances,
414                      and generate blocks. However, this information is not
415                      readily available. As these names would not be legal in
416                      this context, we can declare implicit nets here and rely
417                      on later checks for name clashes to report the error. */
418 
419                   ss = ss->parent_scope();
420             }
421             PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
422             net->set_file(get_file());
423             net->set_lineno(get_lineno());
424             net->set_range_scalar(SR_NET);
425             scope->wires[name] = net;
426             if (warn_implicit) {
427                   cerr << get_fileline() << ": warning: implicit "
428                        "definition of wire '" << name << "'." << endl;
429             }
430       }
431 }
432 
has_aa_term(Design * des,NetScope * scope) const433 bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
434 {
435       NetNet*       net = 0;
436       const NetExpr*par = 0;
437       NetEvent*     eve = 0;
438 
439       const NetExpr*ex1, *ex2;
440 
441       scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
442 
443       if (scope)
444             return scope->is_auto();
445       else
446             return false;
447 }
448 
PENewArray(PExpr * size_expr,PExpr * init_expr)449 PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
450 : size_(size_expr), init_(init_expr)
451 {
452 }
453 
~PENewArray()454 PENewArray::~PENewArray()
455 {
456       delete size_;
457 }
458 
PENewClass(void)459 PENewClass::PENewClass(void)
460 {
461 }
462 
PENewClass(const list<PExpr * > & p)463 PENewClass::PENewClass(const list<PExpr*>&p)
464 : parms_(p.size())
465 {
466       size_t tmp_idx = 0;
467       for (list<PExpr*>::const_iterator cur = p.begin()
468 		 ; cur != p.end() ; ++ cur) {
469 	    parms_[tmp_idx++] = *cur;
470       }
471 }
472 
~PENewClass()473 PENewClass::~PENewClass()
474 {
475 }
476 
PENewCopy(PExpr * src)477 PENewCopy::PENewCopy(PExpr*src)
478 : src_(src)
479 {
480 }
481 
~PENewCopy()482 PENewCopy::~PENewCopy()
483 {
484 }
485 
PENumber(verinum * vp)486 PENumber::PENumber(verinum*vp)
487 : value_(vp)
488 {
489       assert(vp);
490 }
491 
~PENumber()492 PENumber::~PENumber()
493 {
494       delete value_;
495 }
496 
value() const497 const verinum& PENumber::value() const
498 {
499       return *value_;
500 }
501 
is_the_same(const PExpr * that) const502 bool PENumber::is_the_same(const PExpr*that) const
503 {
504       const PENumber*obj = dynamic_cast<const PENumber*>(that);
505       if (obj == 0)
506 	    return false;
507 
508       return *value_ == *obj->value_;
509 }
510 
PEString(char * s)511 PEString::PEString(char*s)
512 : text_(s)
513 {
514 }
515 
~PEString()516 PEString::~PEString()
517 {
518       delete[]text_;
519 }
520 
value() const521 string PEString::value() const
522 {
523       return text_;
524 }
525 
PETernary(PExpr * e,PExpr * t,PExpr * f)526 PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f)
527 : expr_(e), tru_(t), fal_(f)
528 {
529 }
530 
~PETernary()531 PETernary::~PETernary()
532 {
533 }
534 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)535 void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
536 {
537       assert(expr_ && tru_ && fal_);
538       expr_->declare_implicit_nets(scope, type);
539       tru_->declare_implicit_nets(scope, type);
540       fal_->declare_implicit_nets(scope, type);
541 }
542 
has_aa_term(Design * des,NetScope * scope) const543 bool PETernary::has_aa_term(Design*des, NetScope*scope) const
544 {
545       assert(expr_ && tru_ && fal_);
546       return expr_->has_aa_term(des, scope)
547            || tru_->has_aa_term(des, scope)
548            || fal_->has_aa_term(des, scope);
549 }
550 
PETypename(data_type_t * dt)551 PETypename::PETypename(data_type_t*dt)
552 : data_type_(dt)
553 {
554 }
555 
~PETypename()556 PETypename::~PETypename()
557 {
558 }
559 
PEUnary(char op,PExpr * ex)560 PEUnary::PEUnary(char op, PExpr*ex)
561 : op_(op), expr_(ex)
562 {
563 }
564 
~PEUnary()565 PEUnary::~PEUnary()
566 {
567 }
568 
declare_implicit_nets(LexicalScope * scope,NetNet::Type type)569 void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
570 {
571       assert(expr_);
572       expr_->declare_implicit_nets(scope, type);
573 }
574 
has_aa_term(Design * des,NetScope * scope) const575 bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
576 {
577       assert(expr_);
578       return expr_->has_aa_term(des, scope);
579 }
580 
PEVoid()581 PEVoid::PEVoid()
582 {
583 }
584 
~PEVoid()585 PEVoid::~PEVoid()
586 {
587 }
588