1 /*
2  * Copyright (c) 1998-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  "Module.h"
23 # include  "PGate.h"
24 # include  "PWire.h"
25 # include  <cassert>
26 
27 list<Module::named_expr_t> Module::user_defparms;
28 
29 /* n is a permallocated string. */
Module(LexicalScope * parent,perm_string n)30 Module::Module(LexicalScope*parent, perm_string n)
31 : PScopeExtra(n, parent)
32 {
33       library_flag = false;
34       is_cell = false;
35       is_interface = false;
36       program_block = false;
37       uc_drive = UCD_NONE;
38 }
39 
~Module()40 Module::~Module()
41 {
42 }
43 
add_gate(PGate * gate)44 void Module::add_gate(PGate*gate)
45 {
46       gates_.push_back(gate);
47 }
48 
port_count() const49 unsigned Module::port_count() const
50 {
51       return ports.size();
52 }
53 
54 /*
55  * Return the array of PEIdent object that are at this port of the
56  * module. If the port is internally unconnected, return an empty
57  * array.
58  */
get_port(unsigned idx) const59 const vector<PEIdent*>& Module::get_port(unsigned idx) const
60 {
61       assert(idx < ports.size());
62       static const vector<PEIdent*> zero;
63 
64       if (ports[idx])
65 	    return ports[idx]->expr;
66       else
67 	    return zero;
68 }
69 
find_port(const char * name) const70 unsigned Module::find_port(const char*name) const
71 {
72       assert(name != 0);
73       for (unsigned idx = 0 ;  idx < ports.size() ;  idx += 1) {
74 	    if (ports[idx] == 0) {
75 		    /* It is possible to have undeclared ports. These
76 		       are ports that are skipped in the declaration,
77 		       for example like so: module foo(x ,, y); The
78 		       port between x and y is unnamed and thus
79 		       inaccessible to binding by name. */
80 		  continue;
81 	    }
82 	    assert(ports[idx]);
83 	    if (ports[idx]->name == name)
84 		  return idx;
85       }
86 
87       return ports.size();
88 }
89 
get_port_name(unsigned idx) const90 perm_string Module::get_port_name(unsigned idx) const
91 {
92 
93       assert(idx < ports.size());
94       if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
95               /* It is possible to have undeclared ports. These
96                  are ports that are skipped in the declaration,
97                  for example like so: module foo(x ,, y); The
98                  port between x and y is unnamed and thus
99                  inaccessible to binding by name. Port references
100 		 that aren't simple or escaped identifiers are
101 		 also inaccessible to binding by name. */
102             return perm_string::literal("unnamed");
103       }
104       return ports[idx]->name;
105 }
106 
107 
108 
get_gate(perm_string name)109 PGate* Module::get_gate(perm_string name)
110 {
111       for (list<PGate*>::iterator cur = gates_.begin()
112 		 ; cur != gates_.end() ; ++ cur ) {
113 
114 	    if ((*cur)->get_name() == name)
115 		  return *cur;
116       }
117 
118       return 0;
119 }
120 
get_gates() const121 const list<PGate*>& Module::get_gates() const
122 {
123       return gates_;
124 }
125 
symbol_type() const126 PNamedItem::SymbolType Module::symbol_type() const
127 {
128       if (program_block)
129             return PROGRAM;
130       if (is_interface)
131             return INTERFACE;
132 
133       return MODULE;
134 }
135