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