1 // Copyright 2017-2019 VMware, Inc.
2 // SPDX-License-Identifier: BSD-2-Clause
3 //
4 // The BSD-2 license (the License) set forth below applies to all parts of the
5 // Cascade project. You may not use this file except in compliance with the
6 // License.
7 //
8 // BSD-2 License
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation
18 // and/or other materials provided with the distribution.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include "verilog/analyze/module_info.h"
32
33 #include <unordered_set>
34 #include "verilog/ast/ast.h"
35 #include "verilog/analyze/read_set.h"
36 #include "verilog/analyze/resolve.h"
37 #include "verilog/program/elaborate.h"
38 #include "verilog/program/inline.h"
39
40 using namespace std;
41
42 namespace cascade {
43
ModuleInfo(const ModuleDeclaration * md)44 ModuleInfo::ModuleInfo(const ModuleDeclaration* md) : Visitor() {
45 md_ = const_cast<ModuleDeclaration*>(md);
46 lhs_ = false;
47 }
48
invalidate()49 void ModuleInfo::invalidate() {
50 if (md_->next_update_ == 0) {
51 return;
52 }
53
54 // NOTE: It's important that we don't *just* call clear here. There's a
55 // potential for a pretty large soft-leak as we inline the user's program
56 // from leaf to root and each node's module info comes to encompass
57 // everything below it.
58
59 md_->next_update_ = 0;
60 unordered_set<const Identifier*>().swap(md_->locals_);
61 unordered_set<const Identifier*>().swap(md_->inputs_);
62 unordered_set<const Identifier*>().swap(md_->outputs_);
63 unordered_set<const Identifier*>().swap(md_->stateful_);
64 unordered_set<const Identifier*>().swap(md_->implied_wires_);
65 unordered_set<const Identifier*>().swap(md_->implied_latches_);
66 unordered_set<const Identifier*>().swap(md_->reads_);
67 unordered_set<const Identifier*>().swap(md_->writes_);
68 ModuleDeclaration::ParamSet().swap(md_->named_params_);
69 Vector<const Identifier*>().swap(md_->ordered_params_);
70 ModuleDeclaration::PortSet().swap(md_->named_ports_);
71 Vector<const Identifier*>().swap(md_->ordered_ports_);
72 ModuleDeclaration::ConnMap().swap(md_->connections_);
73 ModuleDeclaration::ChildMap().swap(md_->children_);
74 md_->uses_mixed_triggers_ = false;
75 md_->clocks_ = 0;
76 }
77
is_declaration()78 bool ModuleInfo::is_declaration() {
79 return md_->get_parent() == nullptr;
80 }
81
is_instantiated()82 bool ModuleInfo::is_instantiated() {
83 return md_->get_parent() != nullptr;
84 }
85
id()86 const Identifier* ModuleInfo::id() {
87 auto* p = md_->get_parent();
88 if (p == nullptr) {
89 return nullptr;
90 }
91 assert(p->is(Node::Tag::module_instantiation));
92 auto* mi = static_cast<ModuleInstantiation*>(p);
93 return mi->get_iid();
94 }
95
is_local(const Identifier * id)96 bool ModuleInfo::is_local(const Identifier* id) {
97 refresh();
98 const auto* r = Resolve().get_resolution(id);
99 return (r == nullptr) ? false : (md_->locals_.find(r) != md_->locals_.end());
100 }
101
is_input(const Identifier * id)102 bool ModuleInfo::is_input(const Identifier* id) {
103 refresh();
104 const auto* r = Resolve().get_resolution(id);
105 return (r == nullptr) ? false : (md_->inputs_.find(r) != md_->inputs_.end());
106 }
107
is_stateful(const Identifier * id)108 bool ModuleInfo::is_stateful(const Identifier* id) {
109 refresh();
110 const auto* r = Resolve().get_resolution(id);
111 return (r == nullptr) ? false : (md_->stateful_.find(r) != md_->stateful_.end());
112 }
113
is_implied_wire(const Identifier * id)114 bool ModuleInfo::is_implied_wire(const Identifier* id) {
115 refresh();
116 const auto* r = Resolve().get_resolution(id);
117 return (r == nullptr) ? false : (md_->implied_wires_.find(r) != md_->implied_wires_.end());
118 }
119
is_implied_latch(const Identifier * id)120 bool ModuleInfo::is_implied_latch(const Identifier* id) {
121 refresh();
122 const auto* r = Resolve().get_resolution(id);
123 return (r == nullptr) ? false : (md_->implied_latches_.find(r) != md_->implied_latches_.end());
124 }
125
is_output(const Identifier * id)126 bool ModuleInfo::is_output(const Identifier* id) {
127 refresh();
128 const auto* r = Resolve().get_resolution(id);
129 return (r == nullptr) ? false : (md_->outputs_.find(r) != md_->outputs_.end());
130 }
131
is_read(const Identifier * id)132 bool ModuleInfo::is_read(const Identifier* id) {
133 refresh();
134 const auto* r = Resolve().get_resolution(id);
135 return (r == nullptr) ? false : (md_->reads_.find(r) != md_->reads_.end());
136 }
137
is_write(const Identifier * id)138 bool ModuleInfo::is_write(const Identifier* id) {
139 refresh();
140 const auto* r = Resolve().get_resolution(id);
141 return (r == nullptr) ? false : (md_->writes_.find(r) != md_->writes_.end());
142 }
143
is_child(const Identifier * id)144 bool ModuleInfo::is_child(const Identifier* id) {
145 refresh();
146 const auto* r = Resolve().get_resolution(id);
147 return (r == nullptr) ? false : (md_->children_.find(r) != md_->children_.end());
148 }
149
uses_mixed_triggers()150 bool ModuleInfo::uses_mixed_triggers() {
151 refresh();
152 return md_->uses_mixed_triggers_;
153 }
154
uses_multiple_clocks()155 bool ModuleInfo::uses_multiple_clocks() {
156 refresh();
157 return md_->clocks_ > 1;
158 }
159
locals()160 const unordered_set<const Identifier*>& ModuleInfo::locals() {
161 refresh();
162 return md_->locals_;
163 }
164
inputs()165 const unordered_set<const Identifier*>& ModuleInfo::inputs() {
166 refresh();
167 return md_->inputs_;
168 }
169
outputs()170 const unordered_set<const Identifier*>& ModuleInfo::outputs() {
171 refresh();
172 return md_->outputs_;
173 }
174
stateful()175 const unordered_set<const Identifier*>& ModuleInfo::stateful() {
176 refresh();
177 return md_->stateful_;
178 }
179
implied_wires()180 const unordered_set<const Identifier*>& ModuleInfo::implied_wires() {
181 refresh();
182 return md_->implied_wires_;
183 }
184
implied_latches()185 const unordered_set<const Identifier*>& ModuleInfo::implied_latches() {
186 refresh();
187 return md_->implied_latches_;
188 }
189
reads()190 const unordered_set<const Identifier*>& ModuleInfo::reads() {
191 refresh();
192 return md_->reads_;
193 }
194
writes()195 const unordered_set<const Identifier*>& ModuleInfo::writes() {
196 refresh();
197 return md_->writes_;
198 }
199
children()200 const unordered_map<const Identifier*, const ModuleDeclaration*>& ModuleInfo::children() {
201 refresh();
202 return md_->children_;
203 }
204
named_params()205 const unordered_set<const Identifier*, HashId, EqId>& ModuleInfo::named_params() {
206 refresh();
207 return md_->named_params_;
208 }
209
ordered_params()210 const Vector<const Identifier*>& ModuleInfo::ordered_params() {
211 refresh();
212 return md_->ordered_params_;
213 }
214
named_ports()215 const unordered_set<const Identifier*, HashId, EqId>& ModuleInfo::named_ports() {
216 refresh();
217 return md_->named_ports_;
218 }
219
ordered_ports()220 const Vector<const Identifier*>& ModuleInfo::ordered_ports() {
221 refresh();
222 return md_->ordered_ports_;
223 }
224
connections()225 const unordered_map<const Identifier*, unordered_map<const Identifier*, const Expression*>>& ModuleInfo::connections() {
226 refresh();
227 return md_->connections_;
228 }
229
named_parent_conn(const ModuleInstantiation * mi,const PortDeclaration * pd)230 void ModuleInfo::named_parent_conn(const ModuleInstantiation* mi, const PortDeclaration* pd) {
231 for (auto i = mi->begin_ports(), ie = mi->end_ports(); i != ie; ++i) {
232 // This is a named connection, so explicit port should never be null.
233 // Typechecking should enforce this.
234 assert((*i)->is_non_null_exp());
235 // Nothing to do for an empty named connection
236 if ((*i)->is_null_imp()) {
237 continue;
238 }
239 // Nothing to do if this isn't the right port
240 const auto* r = Resolve().get_resolution((*i)->get_exp());
241 if (r != pd->get_decl()->get_id()) {
242 continue;
243 }
244
245 // Flag this variable as either a read or a write and return
246 switch (pd->get_type()) {
247 case PortDeclaration::Type::INPUT:
248 record_local_write(r);
249 return;
250 case PortDeclaration::Type::OUTPUT:
251 record_local_read(r);
252 return;
253 default:
254 record_local_read(r);
255 record_local_write(r);
256 return;
257 }
258 }
259 }
260
ordered_parent_conn(const ModuleInstantiation * mi,const PortDeclaration * pd,size_t idx)261 void ModuleInfo::ordered_parent_conn(const ModuleInstantiation* mi, const PortDeclaration* pd, size_t idx) {
262 // Do nothing if this port doesn't appear in mi's port list
263 if (idx >= mi->size_ports()) {
264 return;
265 }
266 auto* p = mi->get_ports(idx);
267
268 // This is an ordered connection, so explicit port should always be null.
269 // Typechecking should enforce this.
270 assert(p->is_null_exp());
271 // Nothing to do for an empty ordered connection
272 if (p->is_null_imp()) {
273 return;
274 }
275
276 // Flag this variable as either a read or a write
277 const auto* r = pd->get_decl()->get_id();
278 switch (pd->get_type()) {
279 case PortDeclaration::Type::INPUT:
280 record_local_write(r);
281 break;
282 case PortDeclaration::Type::OUTPUT:
283 record_local_read(r);
284 break;
285 default:
286 record_local_read(r);
287 record_local_write(r);
288 break;
289 }
290 }
291
named_child_conns(const ModuleInstantiation * mi)292 void ModuleInfo::named_child_conns(const ModuleInstantiation* mi) {
293 unordered_map<const Identifier*, const Expression*> conn;
294 for (auto i = mi->begin_ports(), ie = mi->end_ports(); i != ie; ++i) {
295 // This is a named connection, so explicit port should never be null.
296 // Typechecking should enforce this.
297 assert((*i)->is_non_null_exp());
298 // Nothing to do for an empty named connection
299 if ((*i)->is_null_imp()) {
300 continue;
301 }
302
303 // Grab the declaration that this explicit port corresponds to
304 const auto* r = Resolve().get_resolution((*i)->get_exp());
305 assert(r != nullptr);
306 // Connect the variable tot he expression in this module
307 conn.insert(make_pair(r, (*i)->get_imp()));
308
309 // Anything that appears in a module's port list must be declared as
310 // a port. Typechecking should enforce this.
311 assert(r->get_parent()->get_parent()->is(Node::Tag::port_declaration));
312 auto* pd = static_cast<const PortDeclaration*>(r->get_parent()->get_parent());
313
314 switch (pd->get_type()) {
315 case PortDeclaration::Type::INPUT:
316 record_external_read(r);
317 break;
318 case PortDeclaration::Type::OUTPUT:
319 record_external_write(r);
320 break;
321 default:
322 record_external_read(r);
323 record_external_write(r);
324 break;
325 }
326 }
327 md_->connections_.insert(make_pair(mi->get_iid(), conn));
328 }
329
ordered_child_conns(const ModuleInstantiation * mi)330 void ModuleInfo::ordered_child_conns(const ModuleInstantiation* mi) {
331 unordered_map<const Identifier*, const Expression*> conn;
332
333 auto itr = Elaborate().get_elaboration(mi)->begin_items();
334 for (size_t i = 0, ie = mi->size_ports(); i < ie; ++i) {
335 const auto* p = mi->get_ports(i);
336 // This is an ordered connection, so explicit port should always be null.
337 // Typechecking should enforce this.
338 assert(p->is_null_exp());
339
340 // Track to the first port declaration. It's kind of ugly to have to iterate
341 // over the entire text of this module every time we refresh, but it's the price
342 // we pay for not having to rely on its module info.
343 while (!(*itr)->is(Node::Tag::port_declaration)) {
344 ++itr;
345 assert(itr != Elaborate().get_elaboration(mi)->end_items());
346 }
347 // Anything that appears in a module's port list must be declared as
348 // a port. Typechecking should enforce this.
349 auto* pd = static_cast<const PortDeclaration*>(*itr++);
350
351 // Nothing to do for an empty ordered connection
352 if (p->is_null_imp()) {
353 continue;
354 }
355
356 // Grab the declaration that this port corresponds to
357 const auto* r = pd->get_decl()->get_id();
358 // Connect the variable to the expression in this module
359 conn.insert(make_pair(r, p->get_imp()));
360
361 switch (pd->get_type()) {
362 case PortDeclaration::Type::INPUT:
363 record_external_read(r);
364 break;
365 case PortDeclaration::Type::OUTPUT:
366 record_external_write(r);
367 break;
368 default:
369 record_external_read(r);
370 record_external_write(r);
371 break;
372 }
373 }
374 md_->connections_.insert(make_pair(mi->get_iid(), conn));
375 }
376
named_external_conn(const ModuleInstantiation * mi,const ArgAssign * aa,const Identifier * id)377 void ModuleInfo::named_external_conn(const ModuleInstantiation* mi, const ArgAssign* aa, const Identifier* id) {
378 // This method should never be called for an empty named connection
379 assert(aa->is_non_null_exp());
380
381 // Grab the declaration that this explicit port corresponds to
382 const auto* r = Resolve().get_resolution(aa->get_exp());
383 assert(r != nullptr);
384
385 // If this module hasn't been inlined, then we can extract the port type for
386 // this variable from its declaration
387 if (!Inline().is_inlined(mi)) {
388 assert(r->get_parent()->get_parent()->is(Node::Tag::port_declaration));
389 auto* pd = static_cast<const PortDeclaration*>(r->get_parent()->get_parent());
390
391 switch (pd->get_type()) {
392 case PortDeclaration::Type::INPUT:
393 record_local_read(id);
394 break;
395 case PortDeclaration::Type::OUTPUT:
396 record_local_write(id);
397 break;
398 default:
399 record_local_read(id);
400 record_local_write(id);
401 break;
402 }
403 }
404 // Otherwise, we'll need to extract it from the inlining annotation we generated
405 else {
406 assert(r->get_parent()->is_subclass_of(Node::Tag::declaration));
407 auto* d = static_cast<const Declaration*>(r->get_parent());
408 const auto* inl = d->get_attrs()->get<String>("__inline");
409 assert(inl != nullptr);
410
411 if (inl->eq("input")) {
412 record_local_read(id);
413 } else if (inl->eq("output")) {
414 record_local_write(id);
415 } else {
416 record_local_read(id);
417 record_local_write(id);
418 }
419 }
420 }
421
ordered_external_conn(const ModuleInstantiation * mi,const ArgAssign * aa,const Identifier * id)422 void ModuleInfo::ordered_external_conn(const ModuleInstantiation* mi, const ArgAssign* aa, const Identifier* id) {
423 // Nothing to do for modules which haven't been elaborated yet.
424 if (!Elaborate().is_elaborated(mi)) {
425 return;
426 }
427 // If this module hasn't been inlined, we'll have to scan through its declarations one at a time
428 // to determine the type of this port connection
429 if (!Inline().is_inlined(mi)) {
430 auto itr = Elaborate().get_elaboration(mi)->begin_items();
431 for (size_t i = 0, ie = (*mi->find_ports(aa) - *mi->begin_ports()); i <= ie; ++i) {
432 while (!(*itr)->is(Node::Tag::port_declaration)) {
433 ++itr;
434 assert(itr != Elaborate().get_elaboration(mi)->end_items());
435 }
436 if (i != ie) {
437 ++itr;
438 }
439 }
440 const auto* pd = static_cast<const PortDeclaration*>(*itr);
441 switch (pd->get_type()) {
442 case PortDeclaration::Type::INPUT:
443 record_external_read(id);
444 break;
445 case PortDeclaration::Type::OUTPUT:
446 record_external_write(id);
447 break;
448 default:
449 record_external_read(id);
450 record_external_write(id);
451 break;
452 }
453 }
454 // Otherwise, we'll need to pick out port declarations by inspecting inlining annotations
455 else {
456 auto itr = Inline().get_source(mi)->front_clauses()->get_then()->begin_items();
457 for (size_t i = 0, ie = (*mi->find_ports(aa) - *mi->begin_ports()); i <= ie; ++i) {
458 while ((!(*itr)->is(Node::Tag::net_declaration) && !(*itr)->is(Node::Tag::reg_declaration)) ||
459 (static_cast<const Declaration*>(*itr)->get_attrs()->get<String>("__inline") == nullptr)) {
460 ++itr;
461 assert(itr != Inline().get_source(mi)->front_clauses()->get_then()->end_items());
462 }
463 if (i != ie) {
464 ++itr;
465 }
466 }
467 const auto* d = static_cast<const Declaration*>(*itr);
468 const auto* inl = d->get_attrs()->get<String>("__inline");
469 assert(inl != nullptr);
470
471 if (inl->eq("input")) {
472 record_local_read(id);
473 } else if (inl->eq("output")) {
474 record_local_write(id);
475 } else {
476 record_local_read(id);
477 record_local_write(id);
478 }
479 }
480 }
481
record_local_read(const Identifier * id)482 void ModuleInfo::record_local_read(const Identifier* id) {
483 if (md_->reads_.find(id) == md_->reads_.end()) {
484 md_->reads_.insert(id);
485 }
486 }
487
record_external_read(const Identifier * id)488 void ModuleInfo::record_external_read(const Identifier* id) {
489 if (md_->reads_.find(id) == md_->reads_.end()) {
490 md_->reads_.insert(id);
491 }
492 }
493
record_local_write(const Identifier * id)494 void ModuleInfo::record_local_write(const Identifier* id) {
495 if (md_->writes_.find(id) == md_->writes_.end()) {
496 md_->writes_.insert(id);
497 }
498 }
499
record_external_write(const Identifier * id)500 void ModuleInfo::record_external_write(const Identifier* id) {
501 if (md_->writes_.find(id) == md_->writes_.end()) {
502 md_->writes_.insert(id);
503 }
504 }
505
record_external_use(const Identifier * id)506 void ModuleInfo::record_external_use(const Identifier* id) {
507 for (auto i = Resolve().use_begin(id), ie = Resolve().use_end(id); i != ie; ++i) {
508 // Nothing to do for expressions which aren't identifiers
509 if (!(*i)->is(Node::Tag::identifier)) {
510 continue;
511 }
512 const auto* eid = static_cast<const Identifier*>(*i);
513 // Nothing to do if this variable appears in this module
514 if (Resolve().get_parent(eid) == md_) {
515 continue;
516 }
517
518 // Grab a pointer to this identifier's parent
519 const auto* p = eid->get_parent();
520 assert(p != nullptr);
521 // Identifiers in ArgAssigns can be reads, writes, or neither
522 if (p->is(Node::Tag::arg_assign)) {
523 // Nothing to do if this is an explicit port
524 const auto* aa = static_cast<const ArgAssign*>(p);
525 if (aa->get_exp() == eid) {
526 continue;
527 }
528 const auto* pp = aa->get_parent();
529 assert(pp != nullptr);
530 // Nothing to do if this ArgAssign appears in a ModuleDeclaration
531 if (pp->is(Node::Tag::module_declaration)) {
532 continue;
533 }
534 if (pp->is(Node::Tag::module_instantiation)) {
535 const auto* mi = static_cast<const ModuleInstantiation*>(pp);
536 if (mi->find_params(aa) != mi->end_params()) {
537 record_local_read(id);
538 } else if (mi->uses_named_ports()) {
539 named_external_conn(mi, aa, id);
540 } else {
541 ordered_external_conn(mi, aa, id);
542 }
543 }
544 }
545 // Identifiers on the left hand side of VariableAssigns are writes Due to
546 // AST refactorings, we need to check the three types that used to contain
547 // VariableAssign's as well.
548 else if (p->is(Node::Tag::variable_assign) && static_cast<const VariableAssign*>(p)->get_lhs() == eid) {
549 record_local_write(id);
550 } else if (p->is(Node::Tag::continuous_assign) && static_cast<const ContinuousAssign*>(p)->get_lhs() == eid) {
551 record_local_write(id);
552 } else if (p->is(Node::Tag::blocking_assign) && static_cast<const BlockingAssign*>(p)->get_lhs() == eid) {
553 record_local_write(id);
554 } else if (p->is(Node::Tag::nonblocking_assign) && static_cast<const NonblockingAssign*>(p)->get_lhs() == eid) {
555 record_local_write(id);
556 }
557 // Everything else is a read
558 else {
559 record_local_read(id);
560 }
561 }
562 }
563
visit(const Attributes * as)564 void ModuleInfo::visit(const Attributes* as) {
565 // Does nothing. There's nothing for us in here other than the opportunity to
566 // blow a ton of time looking up variables that we can't resolve.
567 (void) as;
568 return;
569 }
570
visit(const Identifier * i)571 void ModuleInfo::visit(const Identifier* i) {
572 // Do nothing if this is a local or unresolvable variable
573 const auto* r = Resolve().get_resolution(i);
574 if (r == nullptr || (md_->locals_.find(r) != md_->locals_.end())) {
575 return;
576 }
577 // This variable must be external, record read/write
578 if (lhs_) {
579 record_external_read(r);
580 } else {
581 record_external_write(r);
582 }
583 }
584
visit(const CaseGenerateConstruct * cgc)585 void ModuleInfo::visit(const CaseGenerateConstruct* cgc) {
586 cgc->accept_cond(this);
587 if (Elaborate().is_elaborated(cgc)) {
588 Elaborate().get_elaboration(cgc)->accept(this);
589 }
590 }
591
visit(const IfGenerateConstruct * igc)592 void ModuleInfo::visit(const IfGenerateConstruct* igc) {
593 for (auto i = igc->begin_clauses(), ie = igc->end_clauses(); i != ie; ++i) {
594 (*i)->accept_if(this);
595 }
596 if (Elaborate().is_elaborated(igc)) {
597 Elaborate().get_elaboration(igc)->accept(this);
598 }
599 }
600
visit(const LoopGenerateConstruct * lgc)601 void ModuleInfo::visit(const LoopGenerateConstruct* lgc) {
602 lgc->accept_init(this);
603 lgc->accept_cond(this);
604 lgc->accept_update(this);
605 if (Elaborate().is_elaborated(lgc)) {
606 for (auto* b : Elaborate().get_elaboration(lgc)) {
607 b->accept(this);
608 }
609 }
610 }
611
visit(const ContinuousAssign * ca)612 void ModuleInfo::visit(const ContinuousAssign* ca) {
613 lhs_ = true;
614 ca->accept_lhs(this);
615 lhs_ = false;
616 ca->accept_rhs(this);
617 }
618
visit(const GenvarDeclaration * gd)619 void ModuleInfo::visit(const GenvarDeclaration* gd) {
620 md_->locals_.insert(gd->get_id());
621 // Nothing external should reference this
622 }
623
visit(const LocalparamDeclaration * ld)624 void ModuleInfo::visit(const LocalparamDeclaration* ld) {
625 md_->locals_.insert(ld->get_id());
626 record_external_use(ld->get_id());
627 }
628
visit(const NetDeclaration * nd)629 void ModuleInfo::visit(const NetDeclaration* nd) {
630 md_->locals_.insert(nd->get_id());
631 record_external_use(nd->get_id());
632 }
633
visit(const ParameterDeclaration * pd)634 void ModuleInfo::visit(const ParameterDeclaration* pd) {
635 md_->locals_.insert(pd->get_id());
636 md_->named_params_.insert(pd->get_id());
637 md_->ordered_params_.push_back(pd->get_id());
638 record_external_use(pd->get_id());
639 }
640
visit(const RegDeclaration * rd)641 void ModuleInfo::visit(const RegDeclaration* rd) {
642 md_->locals_.insert(rd->get_id());
643 record_external_use(rd->get_id());
644 }
645
visit(const ModuleInstantiation * mi)646 void ModuleInfo::visit(const ModuleInstantiation* mi) {
647 // This module has been inlined, continue descending through here rather than
648 // examine its connections.
649 if (Inline().is_inlined(mi)) {
650 return Inline().get_source(mi)->accept(this);
651 }
652
653 // Descend on implicit ports. These are syntactically part of this module.
654 for (auto i = mi->begin_params(), ie = mi->end_params(); i != ie; ++i) {
655 (*i)->accept_imp(this);
656 }
657 for (auto i = mi->begin_ports(), ie = mi->end_ports(); i != ie; ++i) {
658 (*i)->accept_imp(this);
659 }
660
661 // Nothing else to do if this module wasn't instantiated.
662 if (!Elaborate().is_elaborated(mi)) {
663 return;
664 }
665 // Otherwise, descend on port bindings to establish connections and record
666 // this child.
667 if (mi->uses_named_ports()) {
668 named_child_conns(mi);
669 } else {
670 ordered_child_conns(mi);
671 }
672 md_->children_.insert(make_pair(mi->get_iid(), Elaborate().get_elaboration(mi)));
673 }
674
visit(const PortDeclaration * pd)675 void ModuleInfo::visit(const PortDeclaration* pd) {
676 // Record input or output port
677 switch(pd->get_type()) {
678 case PortDeclaration::Type::INPUT:
679 md_->inputs_.insert(pd->get_decl()->get_id());
680 break;
681 case PortDeclaration::Type::OUTPUT:
682 md_->outputs_.insert(pd->get_decl()->get_id());
683 break;
684 default:
685 md_->inputs_.insert(pd->get_decl()->get_id());
686 md_->outputs_.insert(pd->get_decl()->get_id());
687 break;
688 }
689 // Record port name and ordering information
690 md_->named_ports_.insert(pd->get_decl()->get_id());
691 md_->ordered_ports_.push_back(pd->get_decl()->get_id());
692
693 // Descend on declaration
694 pd->accept_decl(this);
695
696 // Nothing else to do if this is a declaration
697 if (is_declaration()) {
698 return;
699 }
700 // Otherwise, update read/write information for this connection
701 assert(md_->get_parent()->is(Node::Tag::module_instantiation));
702 auto* mi = static_cast<const ModuleInstantiation*>(md_->get_parent());
703 if (mi->uses_named_ports()) {
704 named_parent_conn(mi, pd);
705 } else {
706 ordered_parent_conn(mi, pd, md_->ordered_ports_.size()-1);
707 }
708 }
709
visit(const BlockingAssign * ba)710 void ModuleInfo::visit(const BlockingAssign* ba) {
711 lhs_ = true;
712 ba->accept_lhs(this);
713 lhs_ = false;
714 ba->accept_rhs(this);
715 }
716
visit(const NonblockingAssign * na)717 void ModuleInfo::visit(const NonblockingAssign* na) {
718 lhs_ = true;
719 na->accept_lhs(this);
720 lhs_ = false;
721 na->accept_rhs(this);
722 }
723
visit(const VariableAssign * va)724 void ModuleInfo::visit(const VariableAssign* va) {
725 lhs_ = true;
726 va->accept_lhs(this);
727 lhs_ = false;
728 va->accept_rhs(this);
729 }
730
visit(const EventControl * ec)731 void ModuleInfo::visit(const EventControl* ec) {
732 Visitor::visit(ec);
733
734 // Check for the presence of both pos/neg edge and edge, and count clocks
735 auto edge = false;
736 auto var = false;
737 for (auto i = ec->begin_events(), ie = ec->end_events(); i != ie; ++i) {
738 switch ((*i)->get_type()) {
739 case Event::Type::POSEDGE:
740 case Event::Type::NEGEDGE:
741 ++md_->clocks_;
742 edge = true;
743 break;
744 case Event::Type::EDGE:
745 var = true;
746 break;
747 default:
748 assert(false);
749 break;
750 }
751 }
752 md_->uses_mixed_triggers_ = md_->uses_mixed_triggers_ || (edge && var);
753 }
754
refresh()755 void ModuleInfo::refresh() {
756 const auto size = md_->size_items();
757 if (md_->next_update_ == size) {
758 return;
759 }
760
761 for (; md_->next_update_ < size; ++md_->next_update_) {
762 md_->get_items(md_->next_update_)->accept(this);
763 }
764 for (auto* l : md_->locals_) {
765 if (!l->get_parent()->is(Node::Tag::reg_declaration)) {
766 continue;
767 }
768 switch (get_type(l)) {
769 case Type::REG:
770 md_->stateful_.insert(l);
771 break;
772 case Type::IMPLIED_WIRE:
773 md_->implied_wires_.insert(l);
774 break;
775 case Type::IMPLIED_LATCH:
776 md_->stateful_.insert(l);
777 md_->implied_latches_.insert(l);
778 break;
779 default:
780 assert(false);
781 break;
782 }
783 }
784 }
785
get_type(const Identifier * id)786 ModuleInfo::Type ModuleInfo::get_type(const Identifier* id) {
787 assert(id->get_parent()->is(Node::Tag::reg_declaration));
788 const auto* rd = static_cast<const RegDeclaration*>(id->get_parent());
789
790 // A register which is intiialized with an fopen can't be a wire
791 if (rd->is_non_null_val() && rd->get_val()->is(Node::Tag::fopen_expression)) {
792 return Type::REG;
793 }
794
795 const TimingControlStatement* tcs_use = nullptr;
796 for (auto i = Resolve().use_begin(id), ie = Resolve().use_end(id); i != ie; ++i) {
797 if (!(*i)->is(Node::Tag::identifier)) {
798 continue;
799 }
800 const auto* id = static_cast<const Identifier*>(*i);
801
802 switch(id->get_parent()->get_tag()) {
803 // Regs which appear in get statements can't be wires
804 case Node::Tag::get_statement:
805 if (static_cast<const GetStatement*>(id->get_parent())->get_var() == id) {
806 return Type::REG;
807 }
808 break;
809 // Anything which is the target of a non-blocking assignment can't be a wire
810 case Node::Tag::nonblocking_assign: {
811 const auto* na = static_cast<const NonblockingAssign*>(id->get_parent());
812 if (na->find_lhs(id) != na->end_lhs()) {
813 return Type::REG;
814 }
815 break;
816 }
817 // The hard case: variables which are the targets of blocking assigns
818 case Node::Tag::blocking_assign: {
819 const auto* ba = static_cast<const BlockingAssign*>(id->get_parent());
820 if (ba->find_lhs(id) == ba->end_lhs()) {
821 break;
822 }
823
824 // Record the dependencies of this assignment
825 ReadSet rs1(ba->get_rhs());
826 unordered_set<const Expression*> deps(rs1.begin(), rs1.end());
827
828 // Walk up the AST until we find the enclosing timing control
829 // statement. Add dependencies from conditional and case statements.
830 const auto* n = ba->get_parent();
831 for (; !n->is(Node::Tag::timing_control_statement); n = n->get_parent()) {
832 if (n->is(Node::Tag::conditional_statement)) {
833 ReadSet rs2(static_cast<const ConditionalStatement*>(n)->get_if());
834 deps.insert(rs2.begin(), rs2.end());
835 } else if (n->is(Node::Tag::case_statement)) {
836 ReadSet rs3(static_cast<const CaseStatement*>(n)->get_cond());
837 deps.insert(rs3.begin(), rs3.end());
838 } else if (n->is(Node::Tag::initial_construct)) {
839 return Type::REG;
840 }
841 }
842 unordered_set<const Identifier*> id_deps;
843 for (const auto* d : deps) {
844 if (d->is(Node::Tag::identifier)) {
845 id_deps.insert(Resolve().get_resolution(static_cast<const Identifier*>(d)));
846 }
847 }
848 const auto* tcs = static_cast<const TimingControlStatement*>(n);
849 const auto* ec = static_cast<const EventControl*>(tcs->get_ctrl());
850
851 // Walk along the event control and collect its triggers. If we see an
852 // edge trigger this can't be a wire.
853 unordered_set<const Identifier*> trigs;
854 for (auto j = ec->begin_events(), je = ec->end_events(); j != je; ++j) {
855 if ((*j)->get_type() != Event::Type::EDGE) {
856 return Type::REG;
857 }
858 if ((*j)->get_expr()->is(Node::Tag::identifier)) {
859 trigs.insert(Resolve().get_resolution(static_cast<const Identifier*>((*j)->get_expr())));
860 }
861 }
862
863 // If we're here it's because this is a value-triggered block. If we've
864 // been to a different one already, or we depend on a value that doesn't
865 // appear in its trigger list, we can't be a register.
866 if ((tcs_use != nullptr) && (tcs != tcs_use)) {
867 return Type::IMPLIED_LATCH;
868 }
869 tcs_use = tcs;
870 for (const auto* d : id_deps) {
871 if (trigs.find(d) == trigs.end()) {
872 return Type::IMPLIED_LATCH;
873 }
874 }
875 break;
876 }
877 default:
878 break;
879 }
880 }
881
882 // If control has reached here, and we saw at least one use of a wire-style
883 // assignment, then this is a wire. Otherwise, this is a register.
884 return (tcs_use != nullptr) ? Type::IMPLIED_WIRE : Type::REG;
885 }
886
887 } // namespace cascade
888