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 # include "PWire.h"
22 # include "PExpr.h"
23 # include <cassert>
24
PWire(perm_string n,NetNet::Type t,NetNet::PortType pt,ivl_variable_type_t dt)25 PWire::PWire(perm_string n,
26 NetNet::Type t,
27 NetNet::PortType pt,
28 ivl_variable_type_t dt)
29 : name_(n), type_(t), port_type_(pt), data_type_(dt),
30 signed_(false), isint_(false),
31 port_set_(false), net_set_(false), is_scalar_(false),
32 error_cnt_(0), uarray_type_(0), set_data_type_(0),
33 discipline_(0)
34 {
35 if (t == NetNet::INTEGER) {
36 type_ = NetNet::REG;
37 signed_ = true;
38 isint_ = true;
39 }
40 }
41
get_wire_type() const42 NetNet::Type PWire::get_wire_type() const
43 {
44 return type_;
45 }
46
basename() const47 perm_string PWire::basename() const
48 {
49 return name_;
50 }
51
set_wire_type(NetNet::Type t)52 bool PWire::set_wire_type(NetNet::Type t)
53 {
54 assert(t != NetNet::IMPLICIT);
55
56 switch (type_) {
57 case NetNet::IMPLICIT:
58 type_ = t;
59 return true;
60 case NetNet::IMPLICIT_REG:
61 if (t == NetNet::REG) {
62 type_ = t;
63 return true;
64 }
65 if (t == NetNet::INTEGER) {
66 type_ = NetNet::REG;
67 isint_ = true;
68 return true;
69 }
70 if (t == NetNet::IMPLICIT_REG) return true;
71 return false;
72 case NetNet::REG:
73 if (t == NetNet::INTEGER) {
74 isint_ = true;
75 return true;
76 }
77 if (t == NetNet::REG) return true;
78 return false;
79 default:
80 if (type_ != t)
81 return false;
82 else
83 return true;
84 }
85 }
86
get_port_type() const87 NetNet::PortType PWire::get_port_type() const
88 {
89 return port_type_;
90 }
91
set_port_type(NetNet::PortType pt)92 bool PWire::set_port_type(NetNet::PortType pt)
93 {
94 assert(pt != NetNet::NOT_A_PORT);
95 assert(pt != NetNet::PIMPLICIT);
96
97 switch (port_type_) {
98 case NetNet::PIMPLICIT:
99 port_type_ = pt;
100 return true;
101
102 case NetNet::NOT_A_PORT:
103 return false;
104
105 default:
106 if (port_type_ != pt)
107 return false;
108 else
109 return true;
110 }
111 }
112
set_data_type(ivl_variable_type_t dt)113 bool PWire::set_data_type(ivl_variable_type_t dt)
114 {
115 if (data_type_ != IVL_VT_NO_TYPE) {
116 if (data_type_ != dt)
117 return false;
118 else
119 return true;
120 }
121
122 assert(data_type_ == IVL_VT_NO_TYPE);
123 data_type_ = dt;
124
125 return true;
126 }
127
get_data_type() const128 ivl_variable_type_t PWire::get_data_type() const
129 {
130 return data_type_;
131 }
132
set_signed(bool flag)133 void PWire::set_signed(bool flag)
134 {
135 signed_ = flag;
136 }
137
get_signed() const138 bool PWire::get_signed() const
139 {
140 return signed_;
141 }
142
get_isint() const143 bool PWire::get_isint() const
144 {
145 if (isint_)
146 return true;
147
148 if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(set_data_type_)) {
149 return tmp->integer_flag;
150 }
151
152 return false;
153 }
154
get_scalar() const155 bool PWire::get_scalar() const
156 {
157 return is_scalar_;
158 }
159
set_range_scalar(PWSRType type)160 void PWire::set_range_scalar(PWSRType type)
161 {
162 is_scalar_ = true;
163 switch (type) {
164 case SR_PORT:
165 if (port_set_) {
166 cerr << get_fileline() << ": error: Port ``" << name_
167 << "'' has already been declared a port." << endl;
168 error_cnt_ += 1;
169 } else {
170 port_set_ = true;
171 }
172 return;
173
174 case SR_NET:
175 if (net_set_) {
176 cerr << get_fileline() << ": error: Net ``" << name_
177 << "'' has already been declared." << endl;
178 error_cnt_ += 1;
179 } else {
180 net_set_ = true;
181 }
182 return;
183
184 case SR_BOTH:
185 if (port_set_ || net_set_) {
186 if (port_set_) {
187 cerr << get_fileline() << ": error: Port ``" << name_
188 << "'' has already been declared a port." << endl;
189 error_cnt_ += 1;
190 }
191 if (net_set_) {
192 cerr << get_fileline() << ": error: Net ``" << name_
193 << "'' has already been declared." << endl;
194 error_cnt_ += 1;
195 }
196 } else {
197 port_set_ = true;
198 net_set_ = true;
199 }
200 return;
201 }
202 }
203
set_range(const list<pform_range_t> & rlist,PWSRType type)204 void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
205 {
206 switch (type) {
207 case SR_PORT:
208 if (port_set_) {
209 cerr << get_fileline() << ": error: Port ``" << name_
210 << "'' has already been declared a port." << endl;
211 error_cnt_ += 1;
212 } else {
213 port_ = rlist;
214 port_set_ = true;
215 is_scalar_ = false;
216 }
217 return;
218
219 case SR_NET:
220 if (net_set_) {
221 cerr << get_fileline() << ": error: Net ``" << name_
222 << "'' has already been declared." << endl;
223 error_cnt_ += 1;
224 } else {
225 net_ = rlist;
226 net_set_ = true;
227 is_scalar_ = false;
228 }
229 return;
230
231 case SR_BOTH:
232 if (port_set_ || net_set_) {
233 if (port_set_) {
234 cerr << get_fileline() << ": error: Port ``" << name_
235 << "'' has already been declared a port." << endl;
236 error_cnt_ += 1;
237 }
238 if (net_set_) {
239 cerr << get_fileline() << ": error: Net ``" << name_
240 << "'' has already been declared." << endl;
241 error_cnt_ += 1;
242 }
243 } else {
244 port_ = rlist;
245 port_set_ = true;
246 net_ = rlist;
247 net_set_ = true;
248 is_scalar_ = false;
249 }
250 return;
251 }
252 }
253
set_unpacked_idx(const list<pform_range_t> & ranges)254 void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
255 {
256 if (! unpacked_.empty()) {
257 cerr << get_fileline() << ": error: Array ``" << name_
258 << "'' has already been declared." << endl;
259 error_cnt_ += 1;
260 } else {
261 unpacked_ = ranges;
262 }
263 }
264
set_data_type(data_type_t * type)265 void PWire::set_data_type(data_type_t*type)
266 {
267 assert(set_data_type_ == 0);
268 set_data_type_ = type;
269
270 if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
271 if (tmp->integer_flag)
272 isint_ = true;
273 }
274 }
275
set_discipline(ivl_discipline_t d)276 void PWire::set_discipline(ivl_discipline_t d)
277 {
278 assert(discipline_ == 0);
279 discipline_ = d;
280 }
281
get_discipline(void) const282 ivl_discipline_t PWire::get_discipline(void) const
283 {
284 return discipline_;
285 }
286
symbol_type() const287 PNamedItem::SymbolType PWire::symbol_type() const
288 {
289 switch (type_) {
290 case NetNet::IMPLICIT_REG:
291 case NetNet::INTEGER:
292 case NetNet::REG:
293 return VAR;
294 default:
295 return NET;
296 }
297 }
298