1 /*
2  * Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
3  * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
4  * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
5  *
6  *    This source code is free software; you can redistribute it
7  *    and/or modify it in source code form under the terms of the GNU
8  *    General Public License as published by the Free Software
9  *    Foundation; either version 2 of the License, or (at your option)
10  *    any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with this program; if not, write to the Free Software
19  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 # include "config.h"
23 # include  "StringHeap.h"
24 # include  "t-dll.h"
25 # include  "discipline.h"
26 # include  "netclass.h"
27 # include  "netdarray.h"
28 # include  "netenum.h"
29 # include  "netvector.h"
30 # include  <cstdlib>
31 # include  <cstdio>
32 # include  <cstring>
33 # include  "ivl_alloc.h"
34 
35 static StringHeap api_strings;
36 
37 /* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
38 
ivl_branch_island(ivl_branch_t net)39 extern "C" ivl_island_t ivl_branch_island(ivl_branch_t net)
40 {
41       assert(net);
42       return net->island;
43 }
44 
ivl_branch_terminal(ivl_branch_t net,int idx)45 extern "C" ivl_nexus_t ivl_branch_terminal(ivl_branch_t net, int idx)
46 {
47       assert(net);
48       assert(idx >= 0);
49       assert(idx < 2);
50       return net->pins[idx];
51 }
ivl_design_delay_sel(ivl_design_t des)52 extern "C" const char*ivl_design_delay_sel(ivl_design_t des)
53 {
54       assert(des);
55       assert(des->self);
56       return des->self->get_delay_sel();
57 }
58 
ivl_design_flag(ivl_design_t des,const char * key)59 extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
60 {
61       assert(des);
62       assert(des->self);
63       return des->self->get_flag(key);
64 }
65 
ivl_design_process(ivl_design_t des,ivl_process_f func,void * cd)66 extern "C" int ivl_design_process(ivl_design_t des,
67 				  ivl_process_f func,
68 				  void*cd)
69 {
70       assert(des);
71       for (ivl_process_t idx = des->threads_;  idx;  idx = idx->next_) {
72 	    int rc = (func)(idx, cd);
73 	    if (rc != 0)
74 		  return rc;
75       }
76 
77       return 0;
78 }
79 
ivl_design_root(ivl_design_t des)80 extern "C" ivl_scope_t ivl_design_root(ivl_design_t des)
81 {
82       cerr << "ANACHRONISM: ivl_design_root called. "
83        "Use ivl_design_roots instead." << endl;
84       assert(des);
85       assert (des->roots.size() > 0);
86       return des->roots[0];
87 }
88 
ivl_design_roots(ivl_design_t des,ivl_scope_t ** scopes,unsigned int * nscopes)89 extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes,
90 				 unsigned int *nscopes)
91 {
92       assert(des);
93       assert (nscopes && scopes);
94       if (des->root_scope_list.size() == 0) {
95 	    size_t fill = 0;
96 	    des->root_scope_list.resize(des->packages.size() + des->roots.size());
97 
98 	    for (size_t idx = 0 ; idx < des->packages.size() ; idx += 1)
99 		  des->root_scope_list[fill++] = des->packages[idx];
100 	    for (size_t idx = 0 ; idx < des->roots.size() ; idx += 1)
101 		  des->root_scope_list[fill++] = des->roots[idx];
102       }
103 
104       *scopes = &des->root_scope_list[0];
105       *nscopes = des->root_scope_list.size();
106 }
107 
ivl_design_time_precision(ivl_design_t des)108 extern "C" int ivl_design_time_precision(ivl_design_t des)
109 {
110       assert(des);
111       return des->time_precision;
112 }
113 
ivl_design_consts(ivl_design_t des)114 extern "C" unsigned ivl_design_consts(ivl_design_t des)
115 {
116       assert(des);
117       return des->consts.size();
118 }
119 
ivl_design_const(ivl_design_t des,unsigned idx)120 extern "C" ivl_net_const_t ivl_design_const(ivl_design_t des, unsigned idx)
121 {
122       assert(des);
123       assert(idx < des->consts.size());
124       return des->consts[idx];
125 }
126 
ivl_design_disciplines(ivl_design_t des)127 extern "C" unsigned ivl_design_disciplines(ivl_design_t des)
128 {
129       assert(des);
130       return des->disciplines.size();
131 }
132 
ivl_design_discipline(ivl_design_t des,unsigned idx)133 extern "C" ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx)
134 {
135       assert(des);
136       assert(idx < des->disciplines.size());
137       return des->disciplines[idx];
138 }
139 
ivl_discipline_domain(ivl_discipline_t net)140 extern "C" ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net)
141 {
142       assert(net);
143       return net->domain();
144 }
145 
ivl_discipline_flow(ivl_discipline_t net)146 extern "C" ivl_nature_t ivl_discipline_flow(ivl_discipline_t net)
147 {
148       assert(net);
149       return net->flow();
150 }
151 
ivl_discipline_name(ivl_discipline_t net)152 extern "C" const char* ivl_discipline_name(ivl_discipline_t net)
153 {
154       assert(net);
155       return net->name();
156 }
157 
ivl_discipline_potential(ivl_discipline_t net)158 extern "C" ivl_nature_t ivl_discipline_potential(ivl_discipline_t net)
159 {
160       assert(net);
161       return net->potential();
162 }
163 
ivl_expr_type(ivl_expr_t net)164 extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net)
165 {
166       if (net == 0)
167 	    return IVL_EX_NONE;
168       return net->type_;
169 }
170 
ivl_expr_file(ivl_expr_t net)171 extern "C" const char*ivl_expr_file(ivl_expr_t net)
172 {
173       assert(net);
174       return net->file.str();
175 }
176 
ivl_expr_lineno(ivl_expr_t net)177 extern "C" unsigned ivl_expr_lineno(ivl_expr_t net)
178 {
179       assert(net);
180       return net->lineno;
181 }
182 
ivl_const_type(ivl_net_const_t net)183 extern "C" ivl_variable_type_t ivl_const_type(ivl_net_const_t net)
184 {
185       assert(net);
186       return net->type;
187 }
188 
ivl_const_bits(ivl_net_const_t net)189 extern "C" const char*ivl_const_bits(ivl_net_const_t net)
190 {
191       assert(net);
192       switch (net->type) {
193 
194 	  case IVL_VT_BOOL:
195 	  case IVL_VT_LOGIC:
196 	  case IVL_VT_STRING:
197 	    if (net->width_ <= sizeof(net->b.bit_))
198 		  return net->b.bit_;
199 	    else
200 		  return net->b.bits_;
201 
202 	  default:
203 	    return 0;
204       }
205 }
206 
ivl_const_delay(ivl_net_const_t net,unsigned transition)207 extern "C" ivl_expr_t ivl_const_delay(ivl_net_const_t net, unsigned transition)
208 {
209       assert(net);
210       assert(transition < 3);
211       return net->delay[transition];
212 }
213 
ivl_const_file(ivl_net_const_t net)214 extern "C" const char*ivl_const_file(ivl_net_const_t net)
215 {
216       assert(net);
217       return net->file.str();
218 }
219 
ivl_const_lineno(ivl_net_const_t net)220 extern "C" unsigned ivl_const_lineno(ivl_net_const_t net)
221 {
222       assert(net);
223       return net->lineno;
224 }
225 
ivl_const_nex(ivl_net_const_t net)226 extern "C" ivl_nexus_t ivl_const_nex(ivl_net_const_t net)
227 {
228       assert(net);
229       return net->pin_;
230 }
231 
ivl_const_real(ivl_net_const_t net)232 extern "C" double ivl_const_real(ivl_net_const_t net)
233 {
234       assert(net);
235       assert(net->type == IVL_VT_REAL);
236       return net->b.real_value;
237 }
238 
ivl_const_scope(ivl_net_const_t net)239 extern "C" ivl_scope_t ivl_const_scope(ivl_net_const_t net)
240 {
241       assert(net);
242       return net->scope;
243 }
244 
ivl_const_signed(ivl_net_const_t net)245 extern "C" int ivl_const_signed(ivl_net_const_t net)
246 {
247       assert(net);
248       return net->signed_;
249 }
250 
ivl_const_width(ivl_net_const_t net)251 extern "C" unsigned ivl_const_width(ivl_net_const_t net)
252 {
253       assert(net);
254       return net->width_;
255 }
256 
ivl_enum_names(ivl_enumtype_t net)257 extern "C" unsigned ivl_enum_names(ivl_enumtype_t net)
258 {
259       assert(net);
260       return net->size();
261 }
262 
ivl_enum_name(ivl_enumtype_t net,unsigned idx)263 extern "C" const char* ivl_enum_name(ivl_enumtype_t net, unsigned idx)
264 {
265       assert(net);
266       assert(idx < net->size());
267       return net->name_at(idx);
268 }
269 
ivl_enum_bits(ivl_enumtype_t net,unsigned idx)270 extern "C" const char* ivl_enum_bits(ivl_enumtype_t net, unsigned idx)
271 {
272       assert(net);
273       assert(idx < net->size());
274       return net->bits_at(idx);
275 }
276 
ivl_enum_type(ivl_enumtype_t net)277 extern "C" ivl_variable_type_t ivl_enum_type(ivl_enumtype_t net)
278 {
279       assert(net);
280       return net->base_type();
281 }
282 
ivl_enum_width(ivl_enumtype_t net)283 extern "C" unsigned ivl_enum_width(ivl_enumtype_t net)
284 {
285       assert(net);
286       return net->packed_width();
287 }
288 
ivl_enum_signed(ivl_enumtype_t net)289 extern "C" int ivl_enum_signed(ivl_enumtype_t net)
290 {
291       assert(net);
292       return net->get_signed();
293 }
294 
ivl_enum_file(ivl_enumtype_t net)295 extern "C" const char*ivl_enum_file(ivl_enumtype_t net)
296 {
297       assert(net);
298       return net->get_file().str();
299 }
300 
ivl_enum_lineno(ivl_enumtype_t net)301 extern "C" unsigned ivl_enum_lineno(ivl_enumtype_t net)
302 {
303       assert(net);
304       return net->get_lineno();
305 }
306 
ivl_event_name(ivl_event_t net)307 extern "C" const char* ivl_event_name(ivl_event_t net)
308 {
309       assert(net);
310       static char*name_buffer = 0;
311       static unsigned name_size = 0;
312 
313       ivl_scope_t scope = net->scope;
314       const char*sn = ivl_scope_name(scope);
315 
316       unsigned need = strlen(sn) + 1 + strlen(net->name) + 1;
317       if (need > name_size) {
318 	    name_buffer = (char*)realloc(name_buffer, need);
319 	    name_size = need;
320       }
321 
322       strcpy(name_buffer, sn);
323       char*tmp = name_buffer + strlen(sn);
324       *tmp++ = '.';
325       strcpy(tmp, net->name);
326 
327       cerr << "ANACHRONISM: Call to anachronistic ivl_event_name." << endl;
328 
329       return name_buffer;
330 }
331 
ivl_event_basename(ivl_event_t net)332 extern "C" const char* ivl_event_basename(ivl_event_t net)
333 {
334       assert(net);
335       return net->name;
336 }
337 
ivl_event_file(ivl_event_t net)338 extern "C" const char*ivl_event_file(ivl_event_t net)
339 {
340       assert(net);
341       return net->file.str();
342 }
343 
ivl_event_lineno(ivl_event_t net)344 extern "C" unsigned ivl_event_lineno(ivl_event_t net)
345 {
346       assert(net);
347       return net->lineno;
348 }
349 
ivl_event_scope(ivl_event_t net)350 extern "C" ivl_scope_t ivl_event_scope(ivl_event_t net)
351 {
352       assert(net);
353       return net->scope;
354 }
355 
ivl_event_nany(ivl_event_t net)356 extern "C" unsigned ivl_event_nany(ivl_event_t net)
357 {
358       assert(net);
359       return net->nany;
360 }
361 
ivl_event_any(ivl_event_t net,unsigned idx)362 extern "C" ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx)
363 {
364       assert(net);
365       assert(idx < net->nany);
366       return net->pins[idx];
367 }
368 
ivl_event_nneg(ivl_event_t net)369 extern "C" unsigned ivl_event_nneg(ivl_event_t net)
370 {
371       assert(net);
372       return net->nneg;
373 }
374 
ivl_event_neg(ivl_event_t net,unsigned idx)375 extern "C" ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx)
376 {
377       assert(net);
378       assert(idx < net->nneg);
379       return net->pins[net->nany + idx];
380 }
381 
ivl_event_npos(ivl_event_t net)382 extern "C" unsigned ivl_event_npos(ivl_event_t net)
383 {
384       assert(net);
385       return net->npos;
386 }
387 
ivl_event_pos(ivl_event_t net,unsigned idx)388 extern "C" ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx)
389 {
390       assert(net);
391       assert(idx < net->npos);
392       return net->pins[net->nany + net->nneg + idx];
393 }
394 
ivl_expr_bits(ivl_expr_t net)395 extern "C" const char* ivl_expr_bits(ivl_expr_t net)
396 {
397       assert(net);
398       assert(net->type_ == IVL_EX_NUMBER);
399       return net->u_.number_.bits_;
400 }
401 
ivl_expr_branch(ivl_expr_t net)402 extern "C" ivl_branch_t ivl_expr_branch(ivl_expr_t net)
403 {
404       assert(net);
405       assert(net->type_ == IVL_EX_BACCESS);
406       return net->u_.branch_.branch;
407 }
408 
ivl_expr_def(ivl_expr_t net)409 extern "C" ivl_scope_t ivl_expr_def(ivl_expr_t net)
410 {
411       assert(net);
412 
413       switch (net->type_) {
414 
415 	  case IVL_EX_UFUNC:
416 	    return net->u_.ufunc_.def;
417 
418 	  default:
419 	    assert(0);
420       }
421 
422       return 0;
423 }
424 
ivl_expr_delay_val(ivl_expr_t net)425 extern "C" uint64_t ivl_expr_delay_val(ivl_expr_t net)
426 {
427       assert(net);
428       assert(net->type_ == IVL_EX_DELAY);
429       return net->u_.delay_.value;
430 }
431 
ivl_expr_dvalue(ivl_expr_t net)432 extern "C" double ivl_expr_dvalue(ivl_expr_t net)
433 {
434       assert(net);
435       assert(net->type_ == IVL_EX_REALNUM);
436       return net->u_.real_.value;
437 }
438 
ivl_expr_enumtype(ivl_expr_t net)439 extern "C" ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net)
440 {
441       assert(net);
442       assert(net->type_ == IVL_EX_ENUMTYPE);
443       return net->u_.enumtype_.type;
444 }
445 
ivl_expr_net_type(ivl_expr_t net)446 extern "C" ivl_type_t ivl_expr_net_type(ivl_expr_t net)
447 {
448       assert(net);
449       return net->net_type;
450 }
451 
ivl_expr_name(ivl_expr_t net)452 extern "C" const char* ivl_expr_name(ivl_expr_t net)
453 {
454       assert(net);
455       switch (net->type_) {
456 
457 	  case IVL_EX_SFUNC:
458 	    return net->u_.sfunc_.name_;
459 
460 	  case IVL_EX_SIGNAL:
461 	    return net->u_.signal_.sig->name_;
462 
463 	  case IVL_EX_PROPERTY:
464 	      { ivl_signal_t sig = ivl_expr_signal(net);
465 		ivl_type_t use_type = ivl_signal_net_type(sig);
466 		unsigned idx = ivl_expr_property_idx(net);
467 		return ivl_type_prop_name(use_type, idx);
468 	      }
469 
470 	  default:
471 	    assert(0);
472       }
473       return 0;
474 }
475 
ivl_expr_nature(ivl_expr_t net)476 extern "C" ivl_nature_t ivl_expr_nature(ivl_expr_t net)
477 {
478       assert(net);
479       assert(net->type_ == IVL_EX_BACCESS);
480       return net->u_.branch_.nature;
481 }
482 
ivl_expr_opcode(ivl_expr_t net)483 extern "C" char ivl_expr_opcode(ivl_expr_t net)
484 {
485       assert(net);
486       switch (net->type_) {
487 	  case IVL_EX_BINARY:
488 	    return net->u_.binary_.op_;
489 
490 	  case IVL_EX_UNARY:
491 	    return net->u_.unary_.op_;
492 
493 	  default:
494 	    assert(0);
495       }
496       return 0;
497 }
498 
ivl_expr_oper1(ivl_expr_t net)499 extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
500 {
501       assert(net);
502       switch (net->type_) {
503 	  case IVL_EX_BINARY:
504 	    return net->u_.binary_.lef_;
505 
506 	  case IVL_EX_PROPERTY:
507 	    return net->u_.property_.index;
508 
509 	  case IVL_EX_SELECT:
510 	    return net->u_.select_.expr_;
511 
512 	  case IVL_EX_UNARY:
513 	    return net->u_.unary_.sub_;
514 
515 	  case IVL_EX_MEMORY:
516 	    return net->u_.memory_.idx_;
517 
518 	  case IVL_EX_NEW:
519 	    return net->u_.new_.size;
520 
521 	  case IVL_EX_SHALLOWCOPY:
522 	    return net->u_.shallow_.dest;
523 
524 	  case IVL_EX_SIGNAL:
525 	    return net->u_.signal_.word;
526 
527 	  case IVL_EX_TERNARY:
528 	    return net->u_.ternary_.cond;
529 
530 	  default:
531 	    assert(0);
532       }
533 
534       return 0;
535 }
536 
ivl_expr_oper2(ivl_expr_t net)537 extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
538 {
539       assert(net);
540       switch (net->type_) {
541 	  case IVL_EX_BINARY:
542 	    return net->u_.binary_.rig_;
543 
544 	  case IVL_EX_NEW:
545 	    return net->u_.new_.init_val;
546 
547 	  case IVL_EX_SELECT:
548 	    return net->u_.select_.base_;
549 
550 	  case IVL_EX_SHALLOWCOPY:
551 	    return net->u_.shallow_.src;
552 
553 	  case IVL_EX_TERNARY:
554 	    return net->u_.ternary_.true_e;
555 
556 	  default:
557 	    assert(0);
558       }
559 
560       return 0;
561 }
562 
ivl_expr_oper3(ivl_expr_t net)563 extern "C" ivl_expr_t ivl_expr_oper3(ivl_expr_t net)
564 {
565       assert(net);
566       switch (net->type_) {
567 
568 	  case IVL_EX_TERNARY:
569 	    return net->u_.ternary_.false_e;
570 
571 	  default:
572 	    assert(0);
573       }
574       return 0;
575 }
576 
ivl_expr_parameter(ivl_expr_t net)577 extern "C" ivl_parameter_t ivl_expr_parameter(ivl_expr_t net)
578 {
579       assert(net);
580       switch (net->type_) {
581 	  case IVL_EX_NUMBER:
582 	    return net->u_.number_.parameter;
583 	  case IVL_EX_STRING:
584 	    return net->u_.string_.parameter;
585 	  case IVL_EX_REALNUM:
586 	    return net->u_.real_.parameter;
587 	  default:
588 	    return 0;
589       }
590 }
591 
ivl_expr_parm(ivl_expr_t net,unsigned idx)592 extern "C" ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx)
593 {
594       assert(net);
595       switch (net->type_) {
596 
597 	  case IVL_EX_ARRAY_PATTERN:
598 	    assert(idx < net->u_.array_pattern_.parms);
599 	    return net->u_.array_pattern_.parm[idx];
600 
601 	  case IVL_EX_CONCAT:
602 	    assert(idx < net->u_.concat_.parms);
603 	    return net->u_.concat_.parm[idx];
604 
605 	  case IVL_EX_SFUNC:
606 	    assert(idx < net->u_.sfunc_.parms);
607 	    return net->u_.sfunc_.parm[idx];
608 
609 	  case IVL_EX_UFUNC:
610 	    assert(idx < net->u_.ufunc_.parms);
611 	    return net->u_.ufunc_.parm[idx];
612 
613 	  default:
614 	    assert(0);
615 	    return 0;
616       }
617 }
618 
ivl_expr_parms(ivl_expr_t net)619 extern "C" unsigned ivl_expr_parms(ivl_expr_t net)
620 {
621       assert(net);
622       switch (net->type_) {
623 
624 	  case IVL_EX_ARRAY_PATTERN:
625 	    return net->u_.array_pattern_.parms;
626 
627 	  case IVL_EX_CONCAT:
628 	    return net->u_.concat_.parms;
629 
630 	  case IVL_EX_SFUNC:
631 	    return net->u_.sfunc_.parms;
632 
633 	  case IVL_EX_UFUNC:
634 	    return net->u_.ufunc_.parms;
635 
636 	  default:
637 	    assert(0);
638 	    return 0;
639       }
640 }
641 
ivl_expr_repeat(ivl_expr_t net)642 extern "C" unsigned ivl_expr_repeat(ivl_expr_t net)
643 {
644       assert(net);
645       assert(net->type_ == IVL_EX_CONCAT);
646       return net->u_.concat_.rept;
647 }
648 
ivl_expr_event(ivl_expr_t net)649 extern "C" ivl_event_t ivl_expr_event(ivl_expr_t net)
650 {
651       assert(net);
652       assert(net->type_ == IVL_EX_EVENT);
653       return net->u_.event_.event;
654 }
655 
ivl_expr_property_idx(ivl_expr_t net)656 extern "C" int ivl_expr_property_idx(ivl_expr_t net)
657 {
658       assert(net);
659       assert(net->type_ == IVL_EX_PROPERTY);
660       return net->u_.property_.prop_idx;
661 }
662 
ivl_expr_scope(ivl_expr_t net)663 extern "C" ivl_scope_t ivl_expr_scope(ivl_expr_t net)
664 {
665       assert(net);
666       assert(net->type_ == IVL_EX_SCOPE);
667       return net->u_.scope_.scope;
668 }
669 
ivl_expr_sel_type(ivl_expr_t net)670 extern "C" ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net)
671 {
672       assert(net);
673       assert(net->type_ == IVL_EX_SELECT);
674       return net->u_.select_.sel_type_;
675 }
676 
ivl_expr_signal(ivl_expr_t net)677 extern "C" ivl_signal_t ivl_expr_signal(ivl_expr_t net)
678 {
679       assert(net);
680       switch (net->type_) {
681 
682 	  case IVL_EX_SIGNAL:
683 	  case IVL_EX_ARRAY:
684 	    return net->u_.signal_.sig;
685 
686 	  case IVL_EX_PROPERTY:
687 	    return net->u_.property_.sig;
688 
689 	  default:
690 	    assert(0);
691 	    return 0;
692       }
693 }
694 
ivl_expr_signed(ivl_expr_t net)695 extern "C" int ivl_expr_signed(ivl_expr_t net)
696 {
697       assert(net);
698       return net->signed_;
699 }
700 
ivl_expr_sized(ivl_expr_t net)701 extern "C" int ivl_expr_sized(ivl_expr_t net)
702 {
703       assert(net);
704       return net->sized_;
705 }
706 
ivl_expr_string(ivl_expr_t net)707 extern "C" const char* ivl_expr_string(ivl_expr_t net)
708 {
709       assert(net);
710       assert(net->type_ == IVL_EX_STRING);
711       return net->u_.string_.value_;
712 }
713 
ivl_expr_uvalue(ivl_expr_t net)714 extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
715 {
716       assert(net);
717       switch (net->type_) {
718 
719 	  case IVL_EX_ULONG:
720 	    return net->u_.ulong_.value;
721 
722 	  case IVL_EX_NUMBER: {
723 		unsigned long val = 0;
724 		for (unsigned long idx = 0 ;  idx < net->width_ ;  idx += 1) {
725 		      if (net->u_.number_.bits_[idx] == '1')
726 			    val |= 1UL << idx;
727 		}
728 
729 		return val;
730 	  }
731 
732 	  default:
733 	    assert(0);
734       }
735 
736       assert(0);
737       return 0;
738 }
739 
ivl_expr_value(ivl_expr_t net)740 extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net)
741 {
742       assert(net);
743       return net->value_;
744 }
745 
ivl_expr_width(ivl_expr_t net)746 extern "C" unsigned ivl_expr_width(ivl_expr_t net)
747 {
748       assert(net);
749       return net->width_;
750 }
751 
752 /*
753  *  ivl_file_table_index puts entries in the map as needed and returns
754  *  the appropriate index.
755  *  ivl_file_table_size returns the number of entries in the table.
756  *  ivl_file_table_item returns the file name for the given index.
757  */
758 struct ltstr
759 {
operator ()ltstr760       bool operator()(const char*s1, const char*s2) const
761       {
762 	    return strcmp(s1, s2) < 0;
763       }
764 };
765 static map<const char*, unsigned, ltstr> fn_map;
766 static vector<const char*> fn_vector;
767 
ivl_file_table_init()768 static void ivl_file_table_init()
769 {
770         /* The first two index entries do not depend on a real
771          * file name and are always available. */
772       fn_vector.push_back("N/A");
773       fn_map["N/A"] = 0;
774       fn_vector.push_back("<interactive>");
775       fn_map["<interactive>"] = 1;
776 }
777 
ivl_file_table_item(unsigned idx)778 extern "C" const char* ivl_file_table_item(unsigned idx)
779 {
780       if (fn_vector.empty()) {
781 	    ivl_file_table_init();
782       }
783 
784       assert(idx < fn_vector.size());
785       return fn_vector[idx];
786 }
787 
ivl_file_table_index(const char * name)788 extern "C" unsigned ivl_file_table_index(const char*name)
789 {
790       if (fn_vector.empty()) {
791 	    ivl_file_table_init();
792       }
793 
794       if (name == NULL) return 0;
795 
796         /* The new index is the current map size. This is inserted only
797          * if the file name is not currently in the map. */
798       pair<map<const char*, unsigned, ltstr>::iterator, bool> result;
799       result = fn_map.insert(make_pair(name, fn_vector.size()));
800       if (result.second) {
801 	    fn_vector.push_back(name);
802       }
803       return result.first->second;
804 }
805 
ivl_file_table_size()806 extern "C" unsigned ivl_file_table_size()
807 {
808       if (fn_vector.empty()) {
809 	    ivl_file_table_init();
810       }
811 
812       return fn_vector.size();
813 }
814 
ivl_island_flag_set(ivl_island_t net,unsigned flag,int value)815 extern "C" int ivl_island_flag_set(ivl_island_t net, unsigned flag, int value)
816 {
817       assert(net);
818       if (flag >= net->flags.size()) {
819 	    if (value == 0)
820 		  return 0;
821 	    else
822 		  net->flags.resize(flag+1, false);
823       }
824 
825       int old_flag = net->flags[flag];
826       net->flags[flag] = value != 0;
827       return old_flag;
828 }
829 
ivl_island_flag_test(ivl_island_t net,unsigned flag)830 extern "C" int ivl_island_flag_test(ivl_island_t net, unsigned flag)
831 {
832       assert(net);
833       if (flag >= net->flags.size())
834 	    return 0;
835       else
836 	    return net->flags[flag];
837 }
838 
ivl_logic_file(ivl_net_logic_t net)839 extern "C" const char*ivl_logic_file(ivl_net_logic_t net)
840 {
841       assert(net);
842       return net->file.str();
843 }
844 
ivl_logic_lineno(ivl_net_logic_t net)845 extern "C" unsigned ivl_logic_lineno(ivl_net_logic_t net)
846 {
847       assert(net);
848       return net->lineno;
849 }
850 
ivl_logic_is_cassign(ivl_net_logic_t net)851 extern "C" unsigned ivl_logic_is_cassign(ivl_net_logic_t net)
852 {
853       assert(net);
854       return net->is_cassign;
855 }
856 
ivl_logic_attr(ivl_net_logic_t net,const char * key)857 extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key)
858 {
859       assert(net);
860       unsigned idx;
861 
862       for (idx = 0 ;  idx < net->nattr ;  idx += 1) {
863 
864 	    if (strcmp(net->attr[idx].key, key) == 0)
865 		  return net->attr[idx].type == IVL_ATT_STR
866 			? net->attr[idx].val.str
867 			: 0;
868       }
869 
870       return 0;
871 }
872 
ivl_logic_attr_cnt(ivl_net_logic_t net)873 extern "C" unsigned ivl_logic_attr_cnt(ivl_net_logic_t net)
874 {
875       assert(net);
876       return net->nattr;
877 }
878 
ivl_logic_attr_val(ivl_net_logic_t net,unsigned idx)879 extern "C" ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net,
880 					      unsigned idx)
881 {
882       assert(net);
883       assert(idx < net->nattr);
884       return net->attr + idx;
885 }
886 
ivl_logic_drive0(ivl_net_logic_t net)887 extern "C" ivl_drive_t ivl_logic_drive0(ivl_net_logic_t net)
888 {
889       ivl_nexus_t nex = ivl_logic_pin(net, 0);
890 
891       for (unsigned idx = 0 ;  idx < ivl_nexus_ptrs(nex) ;  idx += 1) {
892 	    ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
893 	    if (ivl_nexus_ptr_log(cur) != net)
894 		  continue;
895 	    if (ivl_nexus_ptr_pin(cur) != 0)
896 		  continue;
897 	    return ivl_nexus_ptr_drive0(cur);
898       }
899 
900       assert(0);
901       return IVL_DR_STRONG;
902 }
903 
ivl_logic_drive1(ivl_net_logic_t net)904 extern "C" ivl_drive_t ivl_logic_drive1(ivl_net_logic_t net)
905 {
906       ivl_nexus_t nex = ivl_logic_pin(net, 0);
907 
908       for (unsigned idx = 0 ;  idx < ivl_nexus_ptrs(nex) ;  idx += 1) {
909 	    ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
910 	    if (ivl_nexus_ptr_log(cur) != net)
911 		  continue;
912 	    if (ivl_nexus_ptr_pin(cur) != 0)
913 		  continue;
914 	    return ivl_nexus_ptr_drive1(cur);
915       }
916 
917       assert(0);
918       return IVL_DR_STRONG;
919 }
920 
ivl_logic_name(ivl_net_logic_t net)921 extern "C" const char* ivl_logic_name(ivl_net_logic_t net)
922 {
923       assert(net);
924       cerr << "ANACHRONISM: Call to anachronistic ivl_logic_name." << endl;
925       return net->name_;
926 }
927 
ivl_logic_basename(ivl_net_logic_t net)928 extern "C" const char* ivl_logic_basename(ivl_net_logic_t net)
929 {
930       assert(net);
931       return net->name_;
932 }
933 
ivl_logic_scope(ivl_net_logic_t net)934 extern "C" ivl_scope_t ivl_logic_scope(ivl_net_logic_t net)
935 {
936       assert(net);
937       return net->scope_;
938 }
939 
ivl_logic_type(ivl_net_logic_t net)940 extern "C" ivl_logic_t ivl_logic_type(ivl_net_logic_t net)
941 {
942       assert(net);
943       return net->type_;
944 }
945 
ivl_logic_pins(ivl_net_logic_t net)946 extern "C" unsigned ivl_logic_pins(ivl_net_logic_t net)
947 {
948       assert(net);
949       return net->npins_;
950 }
951 
ivl_logic_pin(ivl_net_logic_t net,unsigned pin)952 extern "C" ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin)
953 {
954       assert(net);
955       assert(pin < net->npins_);
956       return net->pins_[pin];
957 }
958 
ivl_logic_udp(ivl_net_logic_t net)959 extern "C" ivl_udp_t ivl_logic_udp(ivl_net_logic_t net)
960 {
961       assert(net);
962       assert(net->type_ == IVL_LO_UDP);
963       assert(net->udp);
964       return net->udp;
965 }
966 
ivl_logic_delay(ivl_net_logic_t net,unsigned transition)967 extern "C" ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition)
968 {
969       assert(net);
970       assert(transition < 3);
971       return net->delay[transition];
972 }
973 
ivl_logic_width(ivl_net_logic_t net)974 extern "C" unsigned ivl_logic_width(ivl_net_logic_t net)
975 {
976       assert(net);
977       return net->width_;
978 }
979 
ivl_udp_sequ(ivl_udp_t net)980 extern "C" int  ivl_udp_sequ(ivl_udp_t net)
981 {
982       assert(net);
983       return net->sequ;
984 }
985 
ivl_udp_nin(ivl_udp_t net)986 extern "C" unsigned ivl_udp_nin(ivl_udp_t net)
987 {
988       assert(net);
989       return net->nin;
990 }
991 
ivl_udp_init(ivl_udp_t net)992 extern "C" char ivl_udp_init(ivl_udp_t net)
993 {
994       assert(net);
995       return net->init;
996 }
997 
ivl_udp_port(ivl_udp_t net,unsigned idx)998 extern "C" const char* ivl_udp_port(ivl_udp_t net, unsigned idx)
999 {
1000       assert(net);
1001       assert(idx <= net->nin);
1002       assert(net->ports);
1003       assert(net->ports[idx].c_str());
1004       return net->ports[idx].c_str();
1005 }
1006 
ivl_udp_row(ivl_udp_t net,unsigned idx)1007 extern "C" const char* ivl_udp_row(ivl_udp_t net, unsigned idx)
1008 {
1009       assert(net);
1010       assert(idx < net->nrows);
1011       assert(net->table);
1012       assert(net->table[idx]);
1013       return net->table[idx];
1014 }
1015 
ivl_udp_rows(ivl_udp_t net)1016 extern "C" unsigned    ivl_udp_rows(ivl_udp_t net)
1017 {
1018       assert(net);
1019       return net->nrows;
1020 }
1021 
ivl_udp_name(ivl_udp_t net)1022 extern "C" const char* ivl_udp_name(ivl_udp_t net)
1023 {
1024       assert(net);
1025       assert(net->name);
1026       return net->name;
1027 }
1028 
ivl_udp_file(ivl_udp_t net)1029 extern "C" const char* ivl_udp_file(ivl_udp_t net)
1030 {
1031       assert(net);
1032       return net->file.str();
1033 }
1034 
ivl_udp_lineno(ivl_udp_t net)1035 extern "C" unsigned ivl_udp_lineno(ivl_udp_t net)
1036 {
1037       assert(net);
1038       return net->lineno;
1039 }
1040 
ivl_lpm_basename(ivl_lpm_t net)1041 extern "C" const char* ivl_lpm_basename(ivl_lpm_t net)
1042 {
1043       assert(net);
1044       return net->name;
1045 }
1046 
ivl_lpm_async_clr(ivl_lpm_t net)1047 extern "C" ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net)
1048 {
1049       assert(net);
1050       switch(net->type) {
1051 	  case IVL_LPM_FF:
1052 	    return net->u_.ff.aclr;
1053 	  default:
1054 	    assert(0);
1055 	    return 0;
1056       }
1057 }
1058 
ivl_lpm_sync_clr(ivl_lpm_t net)1059 extern "C" ivl_nexus_t ivl_lpm_sync_clr(ivl_lpm_t net)
1060 {
1061       assert(net);
1062       switch(net->type) {
1063 	  case IVL_LPM_FF:
1064 	    return net->u_.ff.sclr;
1065 	  default:
1066 	    assert(0);
1067 	    return 0;
1068       }
1069 }
1070 
ivl_lpm_delay(ivl_lpm_t net,unsigned transition)1071 extern "C" ivl_expr_t ivl_lpm_delay(ivl_lpm_t net, unsigned transition)
1072 {
1073       assert(net);
1074       assert(transition < 3);
1075       return net->delay[transition];
1076 }
1077 
ivl_lpm_async_set(ivl_lpm_t net)1078 extern "C" ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net)
1079 {
1080       assert(net);
1081       switch(net->type) {
1082 	  case IVL_LPM_FF:
1083 	    return net->u_.ff.aset;
1084 	  default:
1085 	    assert(0);
1086 	    return 0;
1087       }
1088 }
1089 
ivl_lpm_sync_set(ivl_lpm_t net)1090 extern "C" ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net)
1091 {
1092       assert(net);
1093       switch(net->type) {
1094 	  case IVL_LPM_FF:
1095 	    return net->u_.ff.sset;
1096 	  default:
1097 	    assert(0);
1098 	    return 0;
1099       }
1100 }
1101 
ivl_lpm_array(ivl_lpm_t net)1102 extern "C" ivl_signal_t ivl_lpm_array(ivl_lpm_t net)
1103 {
1104       assert(net);
1105       switch (net->type) {
1106 	  case IVL_LPM_ARRAY:
1107 	    return net->u_.array.sig;
1108 	  default:
1109 	    assert(0);
1110 	    return 0;
1111       }
1112 }
1113 
ivl_lpm_base(ivl_lpm_t net)1114 extern "C" unsigned ivl_lpm_base(ivl_lpm_t net)
1115 {
1116       assert(net);
1117       switch (net->type) {
1118 	  case IVL_LPM_PART_VP:
1119 	  case IVL_LPM_PART_PV:
1120 	    return net->u_.part.base;
1121 	  case IVL_LPM_SUBSTITUTE:
1122 	    return net->u_.substitute.base;
1123 	  default:
1124 	    assert(0);
1125 	    return 0;
1126       }
1127 }
1128 
ivl_lpm_negedge(ivl_lpm_t net)1129 extern "C" unsigned ivl_lpm_negedge(ivl_lpm_t net)
1130 {
1131       assert(net);
1132       switch (net->type) {
1133 	  case IVL_LPM_FF:
1134 	    return net->u_.ff.negedge_flag;
1135 	  default:
1136 	    assert(0);
1137 	    return 0;
1138       }
1139 }
1140 
ivl_lpm_clk(ivl_lpm_t net)1141 extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net)
1142 {
1143       assert(net);
1144       switch (net->type) {
1145 	  case IVL_LPM_FF:
1146 	    return net->u_.ff.clk;
1147 	  default:
1148 	    assert(0);
1149 	    return 0;
1150       }
1151 }
1152 
ivl_lpm_aset_value(ivl_lpm_t net)1153 extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net)
1154 {
1155       assert(net);
1156       switch (net->type) {
1157 	  case IVL_LPM_FF:
1158 	    return net->u_.ff.aset_value;
1159 	  default:
1160 	    assert(0);
1161 	    return 0;
1162       }
1163 }
ivl_lpm_sset_value(ivl_lpm_t net)1164 extern "C" ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net)
1165 {
1166       assert(net);
1167       switch (net->type) {
1168 	  case IVL_LPM_FF:
1169 	    return net->u_.ff.sset_value;
1170 	  default:
1171 	    assert(0);
1172 	    return 0;
1173       }
1174 }
1175 
ivl_lpm_define(ivl_lpm_t net)1176 extern "C" ivl_scope_t ivl_lpm_define(ivl_lpm_t net)
1177 {
1178       assert(net);
1179       switch (net->type) {
1180 	  case IVL_LPM_UFUNC:
1181 	    return net->u_.ufunc.def;
1182 	  default:
1183 	    assert(0);
1184 	    return 0;
1185       }
1186 }
1187 
ivl_lpm_enable(ivl_lpm_t net)1188 extern "C" ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net)
1189 {
1190       assert(net);
1191       switch (net->type) {
1192 	  case IVL_LPM_FF:
1193 	    return net->u_.ff.we;
1194 	  case IVL_LPM_LATCH:
1195 	    return net->u_.latch.e;
1196 	  default:
1197 	    assert(0);
1198 	    return 0;
1199       }
1200 }
1201 
ivl_lpm_file(ivl_lpm_t net)1202 extern "C" const char* ivl_lpm_file(ivl_lpm_t net)
1203 {
1204       assert(net);
1205       return net->file.str();
1206 }
1207 
ivl_lpm_lineno(ivl_lpm_t net)1208 extern "C" unsigned ivl_lpm_lineno(ivl_lpm_t net)
1209 {
1210       assert(net);
1211       return net->lineno;
1212 }
1213 
ivl_lpm_data(ivl_lpm_t net,unsigned idx)1214 extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
1215 {
1216       assert(net);
1217       switch (net->type) {
1218 	  case IVL_LPM_ABS:
1219 	  case IVL_LPM_CAST_INT:
1220 	  case IVL_LPM_CAST_INT2:
1221 	  case IVL_LPM_CAST_REAL:
1222 	    assert(idx == 0);
1223 	    return net->u_.arith.a;
1224 
1225 	  case IVL_LPM_ADD:
1226 	  case IVL_LPM_CMP_EEQ:
1227 	  case IVL_LPM_CMP_EQ:
1228 	  case IVL_LPM_CMP_EQX:
1229 	  case IVL_LPM_CMP_EQZ:
1230 	  case IVL_LPM_CMP_GE:
1231 	  case IVL_LPM_CMP_GT:
1232 	  case IVL_LPM_CMP_NE:
1233 	  case IVL_LPM_CMP_NEE:
1234 	  case IVL_LPM_CMP_WEQ:
1235 	  case IVL_LPM_CMP_WNE:
1236 	  case IVL_LPM_DIVIDE:
1237 	  case IVL_LPM_MOD:
1238 	  case IVL_LPM_MULT:
1239 	  case IVL_LPM_POW:
1240 	  case IVL_LPM_SUB:
1241 	    assert(idx <= 1);
1242 	    if (idx == 0)
1243 		  return net->u_.arith.a;
1244 	    else
1245 		  return net->u_.arith.b;
1246 
1247 	  case IVL_LPM_MUX:
1248 	    assert(idx < net->u_.mux.size);
1249 	    return net->u_.mux.d[idx];
1250 
1251 	  case IVL_LPM_RE_AND:
1252 	  case IVL_LPM_RE_OR:
1253 	  case IVL_LPM_RE_XOR:
1254 	  case IVL_LPM_RE_NAND:
1255 	  case IVL_LPM_RE_NOR:
1256 	  case IVL_LPM_RE_XNOR:
1257 	  case IVL_LPM_SIGN_EXT:
1258 	    assert(idx == 0);
1259 	    return net->u_.reduce.a;
1260 
1261 	  case IVL_LPM_SHIFTL:
1262 	  case IVL_LPM_SHIFTR:
1263 	    assert(idx <= 1);
1264 	    if (idx == 0)
1265 		  return net->u_.shift.d;
1266 	    else
1267 		  return net->u_.shift.s;
1268 
1269 	  case IVL_LPM_FF:
1270 	    assert(idx == 0);
1271 	    return net->u_.ff.d.pin;
1272 	  case IVL_LPM_LATCH:
1273 	    assert(idx == 0);
1274 	    return net->u_.latch.d.pin;
1275 
1276 	  case IVL_LPM_CONCAT:
1277 	  case IVL_LPM_CONCATZ:
1278 	    assert(idx < net->u_.concat.inputs);
1279 	    return net->u_.concat.pins[idx+1];
1280 
1281 	  case IVL_LPM_PART_VP:
1282 	  case IVL_LPM_PART_PV:
1283 	    assert(idx <= 1);
1284 	    if (idx == 0)
1285 		  return net->u_.part.a;
1286 	    else
1287 		  return net->u_.part.s;
1288 
1289 	  case IVL_LPM_REPEAT:
1290 	    assert(idx == 0);
1291 	    return net->u_.repeat.a;
1292 
1293 	  case IVL_LPM_SFUNC:
1294 	      // Skip the return port.
1295 	    assert(idx < (net->u_.sfunc.ports-1));
1296 	    return net->u_.sfunc.pins[idx+1];
1297 
1298 	  case IVL_LPM_SUBSTITUTE:
1299 	    assert(idx <= 1);
1300 	    if (idx == 0)
1301 		  return net->u_.substitute.a;
1302 	    else
1303 		  return net->u_.substitute.s;
1304 
1305 	  case IVL_LPM_UFUNC:
1306 	      // Skip the return port.
1307 	    assert(idx < (net->u_.ufunc.ports-1));
1308 	    return net->u_.ufunc.pins[idx+1];
1309 
1310 	  default:
1311 	    assert(0);
1312 	    return 0;
1313       }
1314 }
1315 
ivl_lpm_datab(ivl_lpm_t net,unsigned idx)1316 extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx)
1317 {
1318       cerr << "ANACHRONISM: Call to anachronistic ivl_lpm_datab." << endl;
1319       assert(net);
1320       switch (net->type) {
1321 
1322 	  case IVL_LPM_ADD:
1323 	  case IVL_LPM_CMP_EQ:
1324 	  case IVL_LPM_CMP_GE:
1325 	  case IVL_LPM_CMP_GT:
1326 	  case IVL_LPM_CMP_NE:
1327 	  case IVL_LPM_DIVIDE:
1328 	  case IVL_LPM_MOD:
1329 	  case IVL_LPM_MULT:
1330 	  case IVL_LPM_POW:
1331 	  case IVL_LPM_SUB:
1332 	    assert(idx == 0);
1333 	    return net->u_.arith.b;
1334 
1335 	  default:
1336 	    assert(0);
1337 	    return 0;
1338       }
1339 }
1340 
1341 
1342 /*
1343  * This function returns the hierarchical name for the LPM device. The
1344  * name needs to be built up from the scope name and the lpm base
1345  * name.
1346  *
1347  * Anachronism: This function is provided for
1348  * compatibility. Eventually, it will be removed.
1349  */
ivl_lpm_name(ivl_lpm_t net)1350 extern "C" const char* ivl_lpm_name(ivl_lpm_t net)
1351 {
1352       assert(net);
1353       static char*name_buffer = 0;
1354       static unsigned name_size = 0;
1355 
1356       ivl_scope_t scope = ivl_lpm_scope(net);
1357       const char*sn = ivl_scope_name(scope);
1358 
1359       unsigned need = strlen(sn) + 1 + strlen(net->name) + 1;
1360       if (need > name_size) {
1361 	    name_buffer = (char*)realloc(name_buffer, need);
1362 	    name_size = need;
1363       }
1364 
1365       strcpy(name_buffer, sn);
1366       char*tmp = name_buffer + strlen(sn);
1367       *tmp++ = '.';
1368       strcpy(tmp, net->name);
1369       return name_buffer;
1370 }
1371 
1372 
ivl_lpm_q(ivl_lpm_t net)1373 extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net)
1374 {
1375       assert(net);
1376 
1377       switch (net->type) {
1378 	  case IVL_LPM_ABS:
1379 	  case IVL_LPM_ADD:
1380 	  case IVL_LPM_CAST_INT:
1381 	  case IVL_LPM_CAST_INT2:
1382 	  case IVL_LPM_CAST_REAL:
1383 	  case IVL_LPM_CMP_GE:
1384 	  case IVL_LPM_CMP_GT:
1385 	  case IVL_LPM_CMP_EQ:
1386 	  case IVL_LPM_CMP_NE:
1387 	  case IVL_LPM_CMP_EEQ:
1388 	  case IVL_LPM_CMP_EQX:
1389 	  case IVL_LPM_CMP_EQZ:
1390 	  case IVL_LPM_CMP_NEE:
1391 	  case IVL_LPM_CMP_WEQ:
1392 	  case IVL_LPM_CMP_WNE:
1393 	  case IVL_LPM_DIVIDE:
1394 	  case IVL_LPM_MOD:
1395 	  case IVL_LPM_MULT:
1396 	  case IVL_LPM_POW:
1397 	  case IVL_LPM_SUB:
1398 	    return net->u_.arith.q;
1399 
1400 	  case IVL_LPM_FF:
1401 	    return net->u_.ff.q.pin;
1402 	  case IVL_LPM_LATCH:
1403 	    return net->u_.latch.q.pin;
1404 
1405 	  case IVL_LPM_MUX:
1406 	    return net->u_.mux.q;
1407 
1408 	  case IVL_LPM_RE_AND:
1409 	  case IVL_LPM_RE_OR:
1410 	  case IVL_LPM_RE_XOR:
1411 	  case IVL_LPM_RE_NAND:
1412 	  case IVL_LPM_RE_NOR:
1413 	  case IVL_LPM_RE_XNOR:
1414 	  case IVL_LPM_SIGN_EXT:
1415 	    return net->u_.reduce.q;
1416 
1417 	  case IVL_LPM_SHIFTL:
1418 	  case IVL_LPM_SHIFTR:
1419 	    return net->u_.shift.q;
1420 
1421 	  case IVL_LPM_SFUNC:
1422 	    return net->u_.sfunc.pins[0];
1423 
1424 	  case IVL_LPM_UFUNC:
1425 	    return net->u_.ufunc.pins[0];
1426 
1427 	  case IVL_LPM_CONCAT:
1428 	  case IVL_LPM_CONCATZ:
1429 	    return net->u_.concat.pins[0];
1430 
1431 	  case IVL_LPM_PART_VP:
1432 	  case IVL_LPM_PART_PV:
1433 	    return net->u_.part.q;
1434 
1435 	  case IVL_LPM_REPEAT:
1436 	    return net->u_.repeat.q;
1437 
1438 	  case IVL_LPM_SUBSTITUTE:
1439 	    return net->u_.substitute.q;
1440 
1441 	  case IVL_LPM_ARRAY:
1442 	    return net->u_.array.q;
1443 
1444 	  default:
1445 	    assert(0);
1446 	    return 0;
1447       }
1448 }
1449 
ivl_lpm_drive0(ivl_lpm_t net)1450 extern "C" ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net)
1451 {
1452       ivl_nexus_t nex = ivl_lpm_q(net);
1453 
1454       for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
1455 	    ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
1456 	    if (ivl_nexus_ptr_lpm(cur) != net)
1457 		  continue;
1458 	    if (ivl_nexus_ptr_pin(cur) != 0)
1459 		  continue;
1460 	    return ivl_nexus_ptr_drive0(cur);
1461       }
1462 
1463       assert(0);
1464       return IVL_DR_STRONG;
1465 }
1466 
ivl_lpm_drive1(ivl_lpm_t net)1467 extern "C" ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net)
1468 {
1469       ivl_nexus_t nex = ivl_lpm_q(net);
1470 
1471       for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
1472 	    ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
1473 	    if (ivl_nexus_ptr_lpm(cur) != net)
1474 		  continue;
1475 	    if (ivl_nexus_ptr_pin(cur) != 0)
1476 		  continue;
1477 	    return ivl_nexus_ptr_drive1(cur);
1478       }
1479 
1480       assert(0);
1481       return IVL_DR_STRONG;
1482 }
1483 
ivl_lpm_scope(ivl_lpm_t net)1484 extern "C" ivl_scope_t ivl_lpm_scope(ivl_lpm_t net)
1485 {
1486       assert(net);
1487       return net->scope;
1488 }
1489 
ivl_lpm_select(ivl_lpm_t net)1490 extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net)
1491 {
1492       assert(net);
1493       switch (net->type) {
1494 
1495 	  case IVL_LPM_MUX:
1496 	    return net->u_.mux.s;
1497 
1498 	  case IVL_LPM_ARRAY:
1499 	    return net->u_.array.a;
1500 
1501 	  default:
1502 	    assert(0);
1503 	    return 0;
1504       }
1505 }
1506 
ivl_lpm_selects(ivl_lpm_t net)1507 extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
1508 {
1509       assert(net);
1510       switch (net->type) {
1511 	  case IVL_LPM_MUX:
1512 	    return net->u_.mux.swid;
1513 	  case IVL_LPM_ARRAY:
1514 	    return net->u_.array.swid;
1515 	  case IVL_LPM_CONCAT:
1516 	  case IVL_LPM_CONCATZ:
1517 	    cerr << "error: ivl_lpm_selects() is no longer supported for "
1518 	            "IVL_LPM_CONCAT, use ivl_lpm_size() instead." << endl;
1519 	    // fallthrough
1520 	  default:
1521 	    assert(0);
1522 	    return 0;
1523       }
1524 }
1525 
ivl_lpm_signed(ivl_lpm_t net)1526 extern "C" int ivl_lpm_signed(ivl_lpm_t net)
1527 {
1528       assert(net);
1529       switch (net->type) {
1530 	  case IVL_LPM_FF:
1531 	  case IVL_LPM_MUX:
1532 	    return 0;
1533 	  case IVL_LPM_ABS:
1534 	  case IVL_LPM_ADD:
1535 	  case IVL_LPM_CAST_REAL:
1536 	  case IVL_LPM_CMP_EEQ:
1537 	  case IVL_LPM_CMP_EQ:
1538 	  case IVL_LPM_CMP_EQX:
1539 	  case IVL_LPM_CMP_EQZ:
1540 	  case IVL_LPM_CMP_GE:
1541 	  case IVL_LPM_CMP_GT:
1542 	  case IVL_LPM_CMP_NE:
1543 	  case IVL_LPM_CMP_NEE:
1544 	  case IVL_LPM_CMP_WEQ:
1545 	  case IVL_LPM_CMP_WNE:
1546 	  case IVL_LPM_DIVIDE:
1547 	  case IVL_LPM_MOD:
1548 	  case IVL_LPM_MULT:
1549 	  case IVL_LPM_POW:
1550 	  case IVL_LPM_SUB:
1551 	  case IVL_LPM_CAST_INT2:
1552 	    return net->u_.arith.signed_flag;
1553 	  case IVL_LPM_RE_AND:
1554 	  case IVL_LPM_RE_OR:
1555 	  case IVL_LPM_RE_XOR:
1556 	  case IVL_LPM_RE_NAND:
1557 	  case IVL_LPM_RE_NOR:
1558 	  case IVL_LPM_RE_XNOR:
1559 	    return 0;
1560 	  case IVL_LPM_SHIFTL:
1561 	  case IVL_LPM_SHIFTR:
1562 	    return net->u_.shift.signed_flag;
1563 	  case IVL_LPM_CAST_INT:
1564 	  case IVL_LPM_SIGN_EXT: // Sign extend is always signed.
1565 	    return 1;
1566 	  case IVL_LPM_SFUNC:
1567 	    return 0;
1568 	  case IVL_LPM_UFUNC:
1569 	    return 0;
1570 	  case IVL_LPM_CONCAT: // Concatenations are always unsigned
1571 	  case IVL_LPM_CONCATZ: // Concatenations are always unsigned
1572 	    return 0;
1573 	  case IVL_LPM_PART_VP:
1574 	  case IVL_LPM_PART_PV:
1575 	    return net->u_.part.signed_flag;
1576 	  case IVL_LPM_REPEAT:
1577 	  case IVL_LPM_SUBSTITUTE:
1578 	    return 0;
1579 	  case IVL_LPM_ARRAY: // Array ports take the signedness of the array.
1580 	    return net->u_.array.sig->net_type->get_signed()? 1 : 0;
1581 	  default:
1582 	    assert(0);
1583 	    return 0;
1584       }
1585 }
1586 
ivl_lpm_size(ivl_lpm_t net)1587 extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
1588 {
1589       assert(net);
1590       switch (net->type) {
1591 	  case IVL_LPM_MUX:
1592 	    return net->u_.mux.size;
1593 	  case IVL_LPM_SFUNC:
1594 	    return net->u_.sfunc.ports - 1;
1595 	  case IVL_LPM_UFUNC:
1596 	    return net->u_.ufunc.ports - 1;
1597 	  case IVL_LPM_REPEAT:
1598 	    return net->u_.repeat.count;
1599 	  case IVL_LPM_CONCAT:
1600 	  case IVL_LPM_CONCATZ:
1601 	    return net->u_.concat.inputs;
1602 	  case IVL_LPM_ABS:
1603 	  case IVL_LPM_CAST_INT:
1604 	  case IVL_LPM_CAST_INT2:
1605 	  case IVL_LPM_CAST_REAL:
1606 	  case IVL_LPM_RE_AND:
1607 	  case IVL_LPM_RE_OR:
1608 	  case IVL_LPM_RE_XOR:
1609 	  case IVL_LPM_RE_NAND:
1610 	  case IVL_LPM_RE_NOR:
1611 	  case IVL_LPM_RE_XNOR:
1612 	  case IVL_LPM_SIGN_EXT:
1613 	  case IVL_LPM_FF:
1614 	    return 1;
1615 	  case IVL_LPM_ADD:
1616 	  case IVL_LPM_CMP_EEQ:
1617 	  case IVL_LPM_CMP_EQ:
1618 	  case IVL_LPM_CMP_EQX:
1619 	  case IVL_LPM_CMP_EQZ:
1620 	  case IVL_LPM_CMP_GE:
1621 	  case IVL_LPM_CMP_GT:
1622 	  case IVL_LPM_CMP_NE:
1623 	  case IVL_LPM_CMP_NEE:
1624 	  case IVL_LPM_DIVIDE:
1625 	  case IVL_LPM_MOD:
1626 	  case IVL_LPM_MULT:
1627 	  case IVL_LPM_POW:
1628 	  case IVL_LPM_SUB:
1629 	  case IVL_LPM_SHIFTL:
1630 	  case IVL_LPM_SHIFTR:
1631 	  case IVL_LPM_PART_VP:
1632 	  case IVL_LPM_PART_PV:
1633 	    return 2;
1634 	  default:
1635 	    assert(0);
1636 	    return 0;
1637       }
1638 }
1639 
ivl_lpm_string(ivl_lpm_t net)1640 extern "C" const char* ivl_lpm_string(ivl_lpm_t net)
1641 {
1642       assert(net);
1643       assert(net->type == IVL_LPM_SFUNC);
1644       return net->u_.sfunc.fun_name;
1645 }
1646 
ivl_lpm_type(ivl_lpm_t net)1647 extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net)
1648 {
1649       assert(net);
1650       return net->type;
1651 }
1652 
ivl_lpm_width(ivl_lpm_t net)1653 extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
1654 {
1655       assert(net);
1656       return net->width;
1657 }
1658 
ivl_lpm_trigger(ivl_lpm_t net)1659 extern "C" ivl_event_t ivl_lpm_trigger(ivl_lpm_t net)
1660 {
1661       assert(net);
1662       switch (net->type) {
1663 	  case IVL_LPM_SFUNC:
1664 	    return net->u_.sfunc.trigger;
1665 	  case IVL_LPM_UFUNC:
1666 	    return net->u_.ufunc.trigger;
1667 	  default:
1668 	    assert(0);
1669 	    return 0;
1670       }
1671 }
1672 
1673 /*
1674  * Deprecated
1675  */
ivl_lval_mux(ivl_lval_t)1676 extern "C" ivl_expr_t ivl_lval_mux(ivl_lval_t)
1677 {
1678       return 0;
1679 }
1680 
ivl_lval_idx(ivl_lval_t net)1681 extern "C" ivl_expr_t ivl_lval_idx(ivl_lval_t net)
1682 {
1683       assert(net);
1684 
1685       if (net->type_ == IVL_LVAL_ARR)
1686 	    return net->idx;
1687       return 0x0;
1688 }
1689 
ivl_lval_part_off(ivl_lval_t net)1690 extern "C" ivl_expr_t ivl_lval_part_off(ivl_lval_t net)
1691 {
1692       assert(net);
1693       return net->loff;
1694 }
1695 
ivl_lval_sel_type(ivl_lval_t net)1696 extern "C" ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net)
1697 {
1698       assert(net);
1699       return net->sel_type;
1700 }
1701 
ivl_lval_width(ivl_lval_t net)1702 extern "C" unsigned ivl_lval_width(ivl_lval_t net)
1703 {
1704       assert(net);
1705       return net->width_;
1706 }
1707 
ivl_lval_property_idx(ivl_lval_t net)1708 extern "C" int ivl_lval_property_idx(ivl_lval_t net)
1709 {
1710       assert(net);
1711       return net->property_idx;
1712 }
1713 
ivl_lval_sig(ivl_lval_t net)1714 extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net)
1715 {
1716       assert(net);
1717       switch (net->type_) {
1718 	  case IVL_LVAL_REG:
1719 	  case IVL_LVAL_ARR:
1720 	    return net->n.sig;
1721 	  default:
1722 	    return 0;
1723       }
1724 }
1725 
ivl_lval_nest(ivl_lval_t net)1726 extern "C" ivl_lval_t ivl_lval_nest(ivl_lval_t net)
1727 {
1728       assert(net);
1729       if (net->type_ == IVL_LVAL_LVAL)
1730 	    return net->n.nest;
1731 
1732       return 0;
1733 }
1734 
ivl_nature_name(ivl_nature_t net)1735 extern "C" const char* ivl_nature_name(ivl_nature_t net)
1736 {
1737       assert(net);
1738       return net->name();
1739 }
1740 
1741 /*
1742  * The nexus name is rarely needed. (Shouldn't be needed at all!) This
1743  * function will calculate the name if it is not already calculated.
1744  */
ivl_nexus_name(ivl_nexus_t net)1745 extern "C" const char* ivl_nexus_name(ivl_nexus_t net)
1746 {
1747       assert(net);
1748       if (net->name_ == 0) {
1749 	    char tmp[2 * sizeof(net) + 5];
1750 	    snprintf(tmp, sizeof tmp, "n%p", (void *)net);
1751 	    net->name_ = api_strings.add(tmp);
1752       }
1753       return net->name_;
1754 }
1755 
ivl_nexus_get_private(ivl_nexus_t net)1756 extern "C" void* ivl_nexus_get_private(ivl_nexus_t net)
1757 {
1758       assert(net);
1759       return net->private_data;
1760 }
1761 
ivl_nexus_set_private(ivl_nexus_t net,void * data)1762 extern "C" void ivl_nexus_set_private(ivl_nexus_t net, void*data)
1763 {
1764       assert(net);
1765       net->private_data = data;
1766 }
1767 
ivl_nexus_ptrs(ivl_nexus_t net)1768 extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net)
1769 {
1770       assert(net);
1771       return net->ptrs_.size();
1772 }
1773 
ivl_nexus_ptr(ivl_nexus_t net,unsigned idx)1774 extern "C" ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx)
1775 {
1776       assert(net);
1777       assert(idx < net->ptrs_.size());
1778       return & net->ptrs_[idx];
1779 }
1780 
ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net)1781 extern "C" ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net)
1782 {
1783       assert(net);
1784       return (ivl_drive_t)(net->drive0);
1785 }
1786 
ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net)1787 extern "C" ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net)
1788 {
1789       assert(net);
1790       return (ivl_drive_t)(net->drive1);
1791 }
1792 
ivl_nexus_ptr_pin(ivl_nexus_ptr_t net)1793 extern "C" unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net)
1794 {
1795       assert(net);
1796       return net->pin_;
1797 }
1798 
ivl_nexus_ptr_branch(ivl_nexus_ptr_t net)1799 extern "C" ivl_branch_t ivl_nexus_ptr_branch(ivl_nexus_ptr_t net)
1800 {
1801       if (net == 0)
1802 	    return 0;
1803       if (net->type_ != __NEXUS_PTR_BRA)
1804 	    return 0;
1805       return net->l.bra;
1806 }
1807 
ivl_nexus_ptr_con(ivl_nexus_ptr_t net)1808 extern "C" ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net)
1809 {
1810       if (net == 0)
1811 	    return 0;
1812       if (net->type_ != __NEXUS_PTR_CON)
1813 	    return 0;
1814       return net->l.con;
1815 }
1816 
ivl_nexus_ptr_log(ivl_nexus_ptr_t net)1817 extern "C" ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net)
1818 {
1819       if (net == 0)
1820 	    return 0;
1821       if (net->type_ != __NEXUS_PTR_LOG)
1822 	    return 0;
1823       return net->l.log;
1824 }
1825 
ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net)1826 extern "C" ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net)
1827 {
1828       if (net == 0)
1829 	    return 0;
1830       if (net->type_ != __NEXUS_PTR_LPM)
1831 	    return 0;
1832       return net->l.lpm;
1833 }
1834 
ivl_nexus_ptr_sig(ivl_nexus_ptr_t net)1835 extern "C" ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net)
1836 {
1837       if (net == 0)
1838 	    return 0;
1839       if (net->type_ != __NEXUS_PTR_SIG)
1840 	    return 0;
1841       return net->l.sig;
1842 }
1843 
ivl_nexus_ptr_switch(ivl_nexus_ptr_t net)1844 extern "C" ivl_switch_t ivl_nexus_ptr_switch(ivl_nexus_ptr_t net)
1845 {
1846       if (net == 0)
1847 	    return 0;
1848       if (net->type_ != __NEXUS_PTR_SWI)
1849 	    return 0;
1850       return net->l.swi;
1851 }
1852 
ivl_parameter_basename(ivl_parameter_t net)1853 extern "C" const char* ivl_parameter_basename(ivl_parameter_t net)
1854 {
1855       assert(net);
1856       return net->basename;
1857 }
1858 
ivl_parameter_local(ivl_parameter_t net)1859 extern "C" int ivl_parameter_local(ivl_parameter_t net)
1860 {
1861       assert(net);
1862       return net->local;
1863 }
1864 
ivl_parameter_signed(ivl_parameter_t net)1865 extern "C" int ivl_parameter_signed(ivl_parameter_t net)
1866 {
1867       assert(net);
1868       return net->signed_flag;
1869 }
1870 
ivl_parameter_msb(ivl_parameter_t net)1871 extern "C" int ivl_parameter_msb(ivl_parameter_t net)
1872 {
1873       assert(net);
1874       return net->msb;
1875 }
1876 
ivl_parameter_lsb(ivl_parameter_t net)1877 extern "C" int ivl_parameter_lsb(ivl_parameter_t net)
1878 {
1879       assert(net);
1880       return net->lsb;
1881 }
1882 
1883 /*
1884  * No need to waste space with storing the width of the parameter since
1885  * it can easily be computed when needed.
1886  */
ivl_parameter_width(ivl_parameter_t net)1887 extern "C" unsigned ivl_parameter_width(ivl_parameter_t net)
1888 {
1889       unsigned result = 1;
1890       assert(net);
1891       if (net->msb >= net->lsb) result += net->msb - net->lsb;
1892       else result += net->lsb - net->msb;
1893       return result;
1894 }
1895 
ivl_parameter_expr(ivl_parameter_t net)1896 extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net)
1897 {
1898       assert(net);
1899       return net->value;
1900 }
1901 
ivl_parameter_file(ivl_parameter_t net)1902 extern "C" const char* ivl_parameter_file(ivl_parameter_t net)
1903 {
1904       assert(net);
1905       return net->file.str();
1906 }
1907 
ivl_parameter_lineno(ivl_parameter_t net)1908 extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net)
1909 {
1910       assert(net);
1911       return net->lineno;
1912 }
1913 
ivl_parameter_scope(ivl_parameter_t net)1914 extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net)
1915 {
1916       assert(net);
1917       return net->scope;
1918 }
1919 
ivl_path_condit(ivl_delaypath_t obj)1920 extern "C" ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj)
1921 {
1922       assert(obj);
1923       return obj->condit;
1924 }
1925 
ivl_path_is_condit(ivl_delaypath_t obj)1926 extern "C" int ivl_path_is_condit(ivl_delaypath_t obj)
1927 {
1928       assert(obj);
1929       return obj->conditional ? 1 : 0;
1930 }
1931 
ivl_path_is_parallel(ivl_delaypath_t obj)1932 extern "C" int ivl_path_is_parallel(ivl_delaypath_t obj)
1933 {
1934       assert(obj);
1935       return obj->parallel ? 1 : 0;
1936 }
1937 
ivl_path_delay(ivl_delaypath_t obj,ivl_path_edge_t edg)1938 extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t edg)
1939 {
1940       assert(obj);
1941       return obj->delay[edg];
1942 }
1943 
ivl_path_scope(ivl_delaypath_t obj)1944 extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj)
1945 {
1946       assert(obj);
1947       assert(obj->scope);
1948       return obj->scope;
1949 }
1950 
ivl_path_source(ivl_delaypath_t net)1951 extern ivl_nexus_t ivl_path_source(ivl_delaypath_t net)
1952 {
1953       assert(net);
1954       return net->src;
1955 }
1956 
ivl_path_source_posedge(ivl_delaypath_t net)1957 extern int ivl_path_source_posedge(ivl_delaypath_t net)
1958 {
1959       assert(net);
1960       return net->posedge ? 1 : 0;
1961 }
1962 
ivl_path_source_negedge(ivl_delaypath_t net)1963 extern int ivl_path_source_negedge(ivl_delaypath_t net)
1964 {
1965       assert(net);
1966       return net->negedge ? 1 : 0;
1967 }
1968 
ivl_process_file(ivl_process_t net)1969 extern "C" const char*ivl_process_file(ivl_process_t net)
1970 {
1971       assert(net);
1972       return net->file.str();
1973 }
1974 
ivl_process_lineno(ivl_process_t net)1975 extern "C" unsigned ivl_process_lineno(ivl_process_t net)
1976 {
1977       assert(net);
1978       return net->lineno;
1979 }
1980 
ivl_process_type(ivl_process_t net)1981 extern "C" ivl_process_type_t ivl_process_type(ivl_process_t net)
1982 {
1983       assert(net);
1984       return net->type_;
1985 }
1986 
ivl_process_analog(ivl_process_t net)1987 extern "C" int ivl_process_analog(ivl_process_t net)
1988 {
1989       assert(net);
1990       return net->analog_flag != 0;
1991 }
1992 
ivl_process_scope(ivl_process_t net)1993 extern "C" ivl_scope_t ivl_process_scope(ivl_process_t net)
1994 {
1995       assert(net);
1996       return net->scope_;
1997 }
1998 
ivl_process_stmt(ivl_process_t net)1999 extern "C" ivl_statement_t ivl_process_stmt(ivl_process_t net)
2000 {
2001       assert(net);
2002       return net->stmt_;
2003 }
2004 
ivl_process_attr_cnt(ivl_process_t net)2005 extern "C" unsigned ivl_process_attr_cnt(ivl_process_t net)
2006 {
2007       assert(net);
2008       return net->nattr;
2009 }
2010 
ivl_process_attr_val(ivl_process_t net,unsigned idx)2011 extern "C" ivl_attribute_t ivl_process_attr_val(ivl_process_t net,
2012 						unsigned idx)
2013 {
2014       assert(net);
2015       assert(idx < net->nattr);
2016       return net->attr + idx;
2017 }
2018 
ivl_scope_attr_cnt(ivl_scope_t net)2019 extern "C" unsigned ivl_scope_attr_cnt(ivl_scope_t net)
2020 {
2021       assert(net);
2022       return net->nattr;
2023 }
2024 
ivl_scope_attr_val(ivl_scope_t net,unsigned idx)2025 extern "C" ivl_attribute_t ivl_scope_attr_val(ivl_scope_t net,
2026 					      unsigned idx)
2027 {
2028       assert(net);
2029       assert(idx < net->nattr);
2030       return net->attr + idx;
2031 }
2032 
ivl_scope_basename(ivl_scope_t net)2033 extern "C" const char* ivl_scope_basename(ivl_scope_t net)
2034 {
2035       assert(net);
2036       return net->name_;
2037 }
2038 
ivl_scope_children(ivl_scope_t net,ivl_scope_f func,void * cd)2039 extern "C" int ivl_scope_children(ivl_scope_t net,
2040 				  ivl_scope_f func,
2041 				  void*cd)
2042 {
2043       for (map<hname_t,ivl_scope_t>::iterator cur = net->children.begin()
2044 		 ; cur != net->children.end() ; ++ cur ) {
2045 	    int rc = func(cur->second, cd);
2046 	    if (rc != 0)
2047 		  return rc;
2048       }
2049 
2050       return 0;
2051 }
2052 
ivl_scope_childs(ivl_scope_t net)2053 extern "C" size_t ivl_scope_childs(ivl_scope_t net)
2054 {
2055       assert(net);
2056       assert(net->child.size() == net->children.size());
2057       return net->child.size();
2058 }
2059 
ivl_scope_child(ivl_scope_t net,size_t idx)2060 extern "C" ivl_scope_t ivl_scope_child(ivl_scope_t net, size_t idx)
2061 {
2062       assert(net);
2063       assert(idx < net->child.size());
2064       return net->child[idx];
2065 }
2066 
ivl_scope_class(ivl_scope_t net,unsigned idx)2067 extern "C" ivl_type_t ivl_scope_class(ivl_scope_t net, unsigned idx)
2068 {
2069       assert(net);
2070       assert(idx < net->classes.size());
2071       return net->classes[idx];
2072 }
2073 
ivl_scope_classes(ivl_scope_t net)2074 extern "C" unsigned ivl_scope_classes(ivl_scope_t net)
2075 {
2076       assert(net);
2077       return net->classes.size();
2078 }
2079 
2080 
ivl_scope_def(ivl_scope_t net)2081 extern "C" ivl_statement_t ivl_scope_def(ivl_scope_t net)
2082 {
2083       assert(net);
2084       return net->def;
2085 }
2086 
ivl_scope_def_file(ivl_scope_t net)2087 extern "C" const char*ivl_scope_def_file(ivl_scope_t net)
2088 {
2089       assert(net);
2090       return net->def_file.str();
2091 }
2092 
ivl_scope_def_lineno(ivl_scope_t net)2093 extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net)
2094 {
2095       assert(net);
2096       return net->def_lineno;
2097 }
2098 
ivl_scope_enumerates(ivl_scope_t net)2099 extern "C" unsigned ivl_scope_enumerates(ivl_scope_t net)
2100 {
2101       assert(net);
2102       return net->enumerations_.size();
2103 }
2104 
ivl_scope_enumerate(ivl_scope_t net,unsigned idx)2105 extern "C" ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx)
2106 {
2107       assert(net);
2108       assert(idx < net->enumerations_.size());
2109       return net->enumerations_[idx];
2110 }
2111 
ivl_scope_events(ivl_scope_t net)2112 extern "C" unsigned ivl_scope_events(ivl_scope_t net)
2113 {
2114       assert(net);
2115       return net->nevent_;
2116 }
2117 
ivl_scope_event(ivl_scope_t net,unsigned idx)2118 extern "C" ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx)
2119 {
2120       assert(net);
2121       assert(idx < net->nevent_);
2122       return net->event_[idx];
2123 }
2124 
ivl_scope_file(ivl_scope_t net)2125 extern "C" const char*ivl_scope_file(ivl_scope_t net)
2126 {
2127       assert(net);
2128       return net->file.str();
2129 }
2130 
ivl_scope_func_type(ivl_scope_t net)2131 extern "C" ivl_variable_type_t ivl_scope_func_type(ivl_scope_t net)
2132 {
2133       assert(net);
2134       assert(net->type_ == IVL_SCT_FUNCTION);
2135       return net->func_type;
2136 }
2137 
ivl_scope_func_signed(ivl_scope_t net)2138 extern "C" int ivl_scope_func_signed(ivl_scope_t net)
2139 {
2140       assert(net);
2141       assert(net->type_==IVL_SCT_FUNCTION);
2142       assert(net->func_type==IVL_VT_LOGIC || net->func_type==IVL_VT_BOOL);
2143       return net->func_signed? 1 : 0;
2144 }
2145 
ivl_scope_func_width(ivl_scope_t net)2146 extern "C" unsigned ivl_scope_func_width(ivl_scope_t net)
2147 {
2148       assert(net);
2149       assert(net->type_ == IVL_SCT_FUNCTION);
2150       assert(net->func_type==IVL_VT_LOGIC || net->func_type==IVL_VT_BOOL);
2151       return net->func_width;
2152 }
2153 
ivl_scope_is_auto(ivl_scope_t net)2154 extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net)
2155 {
2156       assert(net);
2157       return net->is_auto;
2158 }
2159 
ivl_scope_is_cell(ivl_scope_t net)2160 extern "C" unsigned ivl_scope_is_cell(ivl_scope_t net)
2161 {
2162       assert(net);
2163       return net->is_cell;
2164 }
2165 
ivl_scope_lineno(ivl_scope_t net)2166 extern "C" unsigned ivl_scope_lineno(ivl_scope_t net)
2167 {
2168       assert(net);
2169       return net->lineno;
2170 }
2171 
ivl_scope_logs(ivl_scope_t net)2172 extern "C" unsigned ivl_scope_logs(ivl_scope_t net)
2173 {
2174       assert(net);
2175       return net->nlog_;
2176 }
2177 
ivl_scope_log(ivl_scope_t net,unsigned idx)2178 extern "C" ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx)
2179 {
2180       assert(net);
2181       assert(idx < net->nlog_);
2182       return net->log_[idx];
2183 }
2184 
ivl_scope_lpms(ivl_scope_t net)2185 extern "C" unsigned ivl_scope_lpms(ivl_scope_t net)
2186 {
2187       assert(net);
2188       return net->nlpm_;
2189 }
2190 
ivl_scope_lpm(ivl_scope_t net,unsigned idx)2191 extern "C" ivl_lpm_t ivl_scope_lpm(ivl_scope_t net, unsigned idx)
2192 {
2193       assert(net);
2194       assert(idx < net->nlpm_);
2195       return net->lpm_[idx];
2196 }
2197 
scope_name_len(ivl_scope_t net)2198 static unsigned scope_name_len(ivl_scope_t net)
2199 {
2200       unsigned len = 0;
2201 
2202       for (ivl_scope_t cur = net ;  cur ;  cur = cur->parent)
2203 	    len += strlen(cur->name_) + 1;
2204 
2205       return len;
2206 }
2207 
push_scope_basename(ivl_scope_t net,char * buf)2208 static void push_scope_basename(ivl_scope_t net, char*buf)
2209 {
2210       assert(net);
2211       if (net->parent == 0) {
2212 	    strcpy(buf, net->name_);
2213 	    return;
2214       }
2215 
2216       push_scope_basename(net->parent, buf);
2217       strcat(buf, ".");
2218       strcat(buf, net->name_);
2219 }
2220 
ivl_scope_name(ivl_scope_t net)2221 extern "C" const char* ivl_scope_name(ivl_scope_t net)
2222 {
2223       assert(net);
2224       static char*name_buffer = 0;
2225       static unsigned name_size = 0;
2226 
2227       if (net->parent == 0)
2228 	    return net->name_;
2229 
2230       unsigned needlen = scope_name_len(net);
2231 
2232       if (name_size < needlen) {
2233 	    name_buffer = (char*)realloc(name_buffer, needlen);
2234 	    name_size = needlen;
2235       }
2236 
2237 
2238       push_scope_basename(net, name_buffer);
2239 
2240       return name_buffer;
2241 }
2242 
ivl_scope_params(ivl_scope_t net)2243 extern "C" unsigned ivl_scope_params(ivl_scope_t net)
2244 {
2245       assert(net);
2246       return net->param.size();
2247 }
2248 
ivl_scope_param(ivl_scope_t net,unsigned idx)2249 extern "C" ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx)
2250 {
2251       assert(net);
2252       assert(idx < net->param.size());
2253       return & (net->param[idx]);
2254 }
2255 
ivl_scope_parent(ivl_scope_t net)2256 extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net)
2257 {
2258       assert(net);
2259       return net->parent;
2260 }
2261 
2262 
ivl_scope_mod_module_ports(ivl_scope_t net)2263 extern "C" unsigned ivl_scope_mod_module_ports(ivl_scope_t net)
2264 {
2265       assert(net);
2266       assert(net->type_ == IVL_SCT_MODULE );
2267       return static_cast<unsigned>(net->module_ports_info.size());
2268 }
2269 
ivl_scope_mod_module_port_name(ivl_scope_t net,unsigned idx)2270 extern "C" const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx )
2271 {
2272       assert(net);
2273       assert(net->type_ == IVL_SCT_MODULE );
2274       assert(idx < net->module_ports_info.size());
2275 
2276       return net->module_ports_info[idx].name;
2277 }
2278 
ivl_scope_mod_module_port_type(ivl_scope_t net,unsigned idx)2279 extern "C" ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx )
2280 {
2281       assert(net);
2282       switch( net->module_ports_info[idx].type )
2283       {
2284       case PortType::PINPUT : return IVL_SIP_INPUT;
2285       case PortType::POUTPUT : return IVL_SIP_OUTPUT;
2286       case PortType::PINOUT : return IVL_SIP_INOUT;
2287       default : return IVL_SIP_NONE;
2288       }
2289 }
2290 
ivl_scope_mod_module_port_width(ivl_scope_t net,unsigned idx)2291 extern "C" unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx )
2292 {
2293     assert(net);
2294     return net->module_ports_info[idx].width;
2295 }
2296 
2297 
ivl_scope_ports(ivl_scope_t net)2298 extern "C" unsigned ivl_scope_ports(ivl_scope_t net)
2299 {
2300       assert(net);
2301       if (net->type_ == IVL_SCT_MODULE ||
2302           net->type_ == IVL_SCT_FUNCTION ||
2303           net->type_ == IVL_SCT_TASK) return net->ports;
2304       return 0;
2305 }
2306 
ivl_scope_port(ivl_scope_t net,unsigned idx)2307 extern "C" ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx)
2308 {
2309       assert(net);
2310       assert(net->type_ == IVL_SCT_FUNCTION ||
2311              net->type_ == IVL_SCT_TASK);
2312       assert(idx < net->ports);
2313       return net->u_.port[idx];
2314 }
2315 
ivl_scope_mod_port(ivl_scope_t net,unsigned idx)2316 extern "C" ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx)
2317 {
2318       assert(net);
2319       assert(net->type_ == IVL_SCT_MODULE);
2320       assert(idx < net->ports);
2321       return net->u_.nex[idx];
2322 }
2323 
ivl_scope_sigs(ivl_scope_t net)2324 extern "C" unsigned ivl_scope_sigs(ivl_scope_t net)
2325 {
2326       assert(net);
2327       return net->sigs_.size();
2328 }
2329 
ivl_scope_sig(ivl_scope_t net,unsigned idx)2330 extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx)
2331 {
2332       assert(net);
2333       assert(idx < net->sigs_.size());
2334       return net->sigs_[idx];
2335 }
2336 
ivl_scope_switches(ivl_scope_t net)2337 extern "C" unsigned ivl_scope_switches(ivl_scope_t net)
2338 {
2339       assert(net);
2340       return net->switches.size();
2341 }
2342 
ivl_scope_switch(ivl_scope_t net,unsigned idx)2343 extern "C" ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx)
2344 {
2345       assert(net);
2346       assert(idx < net->switches.size());
2347       return net->switches[idx];
2348 }
2349 
ivl_scope_time_precision(ivl_scope_t net)2350 extern "C" int ivl_scope_time_precision(ivl_scope_t net)
2351 {
2352       assert(net);
2353       return net->time_precision;
2354 }
2355 
ivl_scope_time_units(ivl_scope_t net)2356 extern "C" int ivl_scope_time_units(ivl_scope_t net)
2357 {
2358       assert(net);
2359       return net->time_units;
2360 }
2361 
ivl_scope_type(ivl_scope_t net)2362 extern "C" ivl_scope_type_t ivl_scope_type(ivl_scope_t net)
2363 {
2364       assert(net);
2365       return net->type_;
2366 }
2367 
ivl_scope_tname(ivl_scope_t net)2368 extern "C" const char* ivl_scope_tname(ivl_scope_t net)
2369 {
2370       assert(net);
2371       return net->tname_;
2372 }
2373 
ivl_signal_array_base(ivl_signal_t net)2374 extern "C" int ivl_signal_array_base(ivl_signal_t net)
2375 {
2376       assert(net);
2377       return net->array_base;
2378 }
2379 
ivl_signal_array_count(ivl_signal_t net)2380 extern "C" unsigned ivl_signal_array_count(ivl_signal_t net)
2381 {
2382       assert(net);
2383       return net->array_words;
2384 }
2385 
ivl_signal_array_addr_swapped(ivl_signal_t net)2386 extern "C" unsigned ivl_signal_array_addr_swapped(ivl_signal_t net)
2387 {
2388       assert(net);
2389       return net->array_addr_swapped;
2390 }
2391 
ivl_signal_dimensions(ivl_signal_t net)2392 extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net)
2393 {
2394       assert(net);
2395       return net->array_dimensions_;
2396 }
2397 
ivl_signal_discipline(ivl_signal_t net)2398 extern "C" ivl_discipline_t ivl_signal_discipline(ivl_signal_t net)
2399 {
2400       assert(net);
2401       return net->discipline;
2402 }
2403 
ivl_signal_attr(ivl_signal_t net,const char * key)2404 extern "C" const char* ivl_signal_attr(ivl_signal_t net, const char*key)
2405 {
2406       assert(net);
2407       if (net->nattr == 0)
2408 	    return 0;
2409 
2410       for (unsigned idx = 0 ;  idx < net->nattr ;  idx += 1)
2411 
2412 	    if (strcmp(key, net->attr[idx].key) == 0)
2413 		  return net->attr[idx].type == IVL_ATT_STR
2414 			? net->attr[idx].val.str
2415 			: 0;
2416 
2417       return 0;
2418 }
2419 
ivl_signal_attr_cnt(ivl_signal_t net)2420 extern "C" unsigned ivl_signal_attr_cnt(ivl_signal_t net)
2421 {
2422       assert(net);
2423       return net->nattr;
2424 }
2425 
ivl_signal_attr_val(ivl_signal_t net,unsigned idx)2426 extern "C" ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx)
2427 {
2428       assert(net);
2429       assert(idx < net->nattr);
2430       return net->attr + idx;
2431 }
2432 
ivl_signal_basename(ivl_signal_t net)2433 extern "C" const char* ivl_signal_basename(ivl_signal_t net)
2434 {
2435       assert(net);
2436       return net->name_;
2437 }
2438 
ivl_signal_name(ivl_signal_t net)2439 extern "C" const char* ivl_signal_name(ivl_signal_t net)
2440 {
2441       assert(net);
2442       static char*name_buffer = 0;
2443       static unsigned name_size = 0;
2444 
2445       unsigned needlen = scope_name_len(net->scope_);
2446       needlen += strlen(net->name_) + 2;
2447 
2448       if (name_size < needlen) {
2449 	    name_buffer = (char*)realloc(name_buffer, needlen);
2450 	    name_size = needlen;
2451       }
2452 
2453       push_scope_basename(net->scope_, name_buffer);
2454       strcat(name_buffer, ".");
2455       strcat(name_buffer, net->name_);
2456 
2457       return name_buffer;
2458 }
2459 
ivl_signal_nex(ivl_signal_t net,unsigned word)2460 extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
2461 {
2462       assert(net);
2463       assert(word < net->array_words);
2464       if (net->array_words > 1) {
2465 	    if (net->pins) {
2466 		return net->pins[word];
2467 	    } else {
2468 		// net->pins can be NULL for a virtualized reg array.
2469 		assert(net->type_ == IVL_SIT_REG);
2470 		return NULL;
2471 	    }
2472       } else {
2473 	    return net->pin;
2474       }
2475 }
2476 
ivl_signal_packed_dimensions(ivl_signal_t net)2477 extern "C" unsigned ivl_signal_packed_dimensions(ivl_signal_t net)
2478 {
2479       assert(net);
2480       return net->packed_dims.size();
2481 }
2482 
ivl_signal_packed_msb(ivl_signal_t net,unsigned dim)2483 extern "C" int ivl_signal_packed_msb(ivl_signal_t net, unsigned dim)
2484 {
2485       assert(net);
2486       assert(dim < net->packed_dims.size());
2487       return net->packed_dims[dim].get_msb();
2488 }
2489 
ivl_signal_packed_lsb(ivl_signal_t net,unsigned dim)2490 extern "C" int ivl_signal_packed_lsb(ivl_signal_t net, unsigned dim)
2491 {
2492       assert(net);
2493       assert(dim < net->packed_dims.size());
2494       return net->packed_dims[dim].get_lsb();
2495 }
2496 
ivl_signal_msb(ivl_signal_t net)2497 extern "C" int ivl_signal_msb(ivl_signal_t net)
2498 {
2499       assert(net);
2500       if (net->packed_dims.empty())
2501 	    return 0;
2502 
2503       assert(net->packed_dims.size() == 1);
2504       return net->packed_dims[0].get_msb();
2505 }
2506 
ivl_signal_lsb(ivl_signal_t net)2507 extern "C" int ivl_signal_lsb(ivl_signal_t net)
2508 {
2509       assert(net);
2510       if (net->packed_dims.empty())
2511 	    return 0;
2512 
2513       assert(net->packed_dims.size() == 1);
2514       return net->packed_dims[0].get_lsb();
2515 }
2516 
ivl_signal_scope(ivl_signal_t net)2517 extern "C" ivl_scope_t ivl_signal_scope(ivl_signal_t net)
2518 {
2519       assert(net);
2520       return net->scope_;
2521 }
2522 
ivl_signal_width(ivl_signal_t net)2523 extern "C" unsigned ivl_signal_width(ivl_signal_t net)
2524 {
2525       assert(net);
2526       assert(net->net_type);
2527       return net->net_type->packed_width();
2528 }
2529 
ivl_signal_port(ivl_signal_t net)2530 extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net)
2531 {
2532       assert(net);
2533       return net->port_;
2534 }
2535 
ivl_signal_module_port_index(ivl_signal_t net)2536 extern "C" int ivl_signal_module_port_index(ivl_signal_t net)
2537 {
2538       assert(net);
2539       return net->module_port_index_;
2540 }
2541 
ivl_signal_local(ivl_signal_t net)2542 extern "C" int ivl_signal_local(ivl_signal_t net)
2543 {
2544       assert(net);
2545       return net->local_;
2546 }
2547 
ivl_signal_signed(ivl_signal_t net)2548 extern "C" int ivl_signal_signed(ivl_signal_t net)
2549 {
2550       assert(net);
2551       assert(net->net_type);
2552       return net->net_type->get_signed()? 1 : 0;
2553 }
2554 
ivl_signal_forced_net(ivl_signal_t net)2555 extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net)
2556 {
2557       assert(net);
2558       return net->forced_net_;
2559 }
2560 
ivl_signal_file(ivl_signal_t net)2561 extern "C" const char* ivl_signal_file(ivl_signal_t net)
2562 {
2563       assert(net);
2564       return net->file.str();
2565 }
2566 
ivl_signal_lineno(ivl_signal_t net)2567 extern "C" unsigned ivl_signal_lineno(ivl_signal_t net)
2568 {
2569       assert(net);
2570       return net->lineno;
2571 }
2572 
ivl_signal_integer(ivl_signal_t net)2573 extern "C" int ivl_signal_integer(ivl_signal_t net)
2574 {
2575       assert(net);
2576       if (const netvector_t*vec = dynamic_cast<const netvector_t*> (net->net_type))
2577 	    return vec->get_isint()? 1 : 0;
2578       else if (const netenum_t*enm = dynamic_cast<const netenum_t*> (net->net_type))
2579 	    return enm->get_isint()? 1 : 0;
2580       else
2581 	    return 0;
2582 }
2583 
ivl_signal_data_type(ivl_signal_t net)2584 extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net)
2585 {
2586       assert(net);
2587       assert(net->net_type);
2588       return net->net_type->base_type();
2589 }
2590 
ivl_signal_net_type(ivl_signal_t net)2591 extern "C" ivl_type_t ivl_signal_net_type(ivl_signal_t net)
2592 {
2593       assert(net);
2594       return net->net_type;
2595 }
2596 
ivl_signal_npath(ivl_signal_t net)2597 extern "C" unsigned ivl_signal_npath(ivl_signal_t net)
2598 {
2599       assert(net);
2600       return net->npath;
2601 }
2602 
ivl_signal_path(ivl_signal_t net,unsigned idx)2603 extern "C" ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx)
2604 {
2605       assert(net);
2606       assert(idx < net->npath);
2607       return net->path + idx;
2608 }
2609 
ivl_signal_type(ivl_signal_t net)2610 extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net)
2611 {
2612       assert(net);
2613       return net->type_;
2614 }
2615 
ivl_statement_type(ivl_statement_t net)2616 extern "C" ivl_statement_type_t ivl_statement_type(ivl_statement_t net)
2617 {
2618       assert(net);
2619       return net->type_;
2620 }
2621 
ivl_stmt_file(ivl_statement_t net)2622 extern "C" const char* ivl_stmt_file(ivl_statement_t net)
2623 {
2624       assert(net);
2625       return net->file.str();
2626 }
2627 
ivl_stmt_lineno(ivl_statement_t net)2628 extern "C" unsigned ivl_stmt_lineno(ivl_statement_t net)
2629 {
2630       assert(net);
2631       return net->lineno;
2632 }
2633 
ivl_stmt_block_scope(ivl_statement_t net)2634 extern "C" ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net)
2635 {
2636       assert(net);
2637       switch (net->type_) {
2638 	  case IVL_ST_BLOCK:
2639 	  case IVL_ST_FORK:
2640 	  case IVL_ST_FORK_JOIN_ANY:
2641 	  case IVL_ST_FORK_JOIN_NONE:
2642 	    return net->u_.block_.scope;
2643 	  default:
2644 	    assert(0);
2645 	    return 0;
2646       }
2647 }
2648 
ivl_stmt_block_count(ivl_statement_t net)2649 extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net)
2650 {
2651       assert(net);
2652       switch (net->type_) {
2653 	  case IVL_ST_BLOCK:
2654 	  case IVL_ST_FORK:
2655 	  case IVL_ST_FORK_JOIN_ANY:
2656 	  case IVL_ST_FORK_JOIN_NONE:
2657 	    return net->u_.block_.nstmt_;
2658 	  default:
2659 	    assert(0);
2660 	    return 0;
2661       }
2662 }
2663 
ivl_stmt_block_stmt(ivl_statement_t net,unsigned i)2664 extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
2665 					       unsigned i)
2666 {
2667       assert(net);
2668       switch (net->type_) {
2669 	  case IVL_ST_BLOCK:
2670 	  case IVL_ST_FORK:
2671 	  case IVL_ST_FORK_JOIN_ANY:
2672 	  case IVL_ST_FORK_JOIN_NONE:
2673 	    return net->u_.block_.stmt_ + i;
2674 	  default:
2675 	    assert(0);
2676 	    return 0;
2677       }
2678 }
2679 
ivl_stmt_call(ivl_statement_t net)2680 extern "C" ivl_scope_t ivl_stmt_call(ivl_statement_t net)
2681 {
2682       assert(net);
2683       switch (net->type_) {
2684 	  case IVL_ST_ALLOC:
2685 	    return net->u_.alloc_.scope;
2686 
2687 	  case IVL_ST_DISABLE:
2688 	    return net->u_.disable_.scope;
2689 
2690 	  case IVL_ST_FREE:
2691 	    return net->u_.free_.scope;
2692 
2693 	  case IVL_ST_UTASK:
2694 	    return net->u_.utask_.def;
2695 	  default:
2696 	    assert(0);
2697 	    return 0;
2698       }
2699 }
2700 
ivl_stmt_case_count(ivl_statement_t net)2701 extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
2702 {
2703       assert(net);
2704       switch (net->type_) {
2705 	  case IVL_ST_CASE:
2706 	  case IVL_ST_CASER:
2707 	  case IVL_ST_CASEX:
2708 	  case IVL_ST_CASEZ:
2709 	    return net->u_.case_.ncase;
2710 	  default:
2711 	    assert(0);
2712 	    return 0;
2713       }
2714 }
2715 
ivl_stmt_case_expr(ivl_statement_t net,unsigned idx)2716 extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx)
2717 {
2718       assert(net);
2719       switch (net->type_) {
2720 	  case IVL_ST_CASE:
2721 	  case IVL_ST_CASER:
2722 	  case IVL_ST_CASEX:
2723 	  case IVL_ST_CASEZ:
2724 	    assert(idx < net->u_.case_.ncase);
2725 	    return net->u_.case_.case_ex[idx];
2726 
2727 	  default:
2728 	    assert(0);
2729 	    return 0;
2730       }
2731 }
2732 
ivl_stmt_case_quality(ivl_statement_t net)2733 extern "C" ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net)
2734 {
2735       assert(net);
2736       switch (net->type_) {
2737 	  case IVL_ST_CASE:
2738 	  case IVL_ST_CASER:
2739 	  case IVL_ST_CASEX:
2740 	  case IVL_ST_CASEZ:
2741 	    return net->u_.case_.quality;
2742 
2743 	  default:
2744 	    assert(0);
2745 	    return IVL_CASE_QUALITY_BASIC;
2746       }
2747 }
2748 
ivl_stmt_case_stmt(ivl_statement_t net,unsigned idx)2749 extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
2750 {
2751       assert(net);
2752       switch (net->type_) {
2753 	  case IVL_ST_CASE:
2754 	  case IVL_ST_CASER:
2755 	  case IVL_ST_CASEX:
2756 	  case IVL_ST_CASEZ:
2757 	    assert(idx < net->u_.case_.ncase);
2758 	    return net->u_.case_.case_st + idx;
2759 
2760 	  default:
2761 	    assert(0);
2762 	    return 0;
2763       }
2764 }
2765 
ivl_stmt_cond_expr(ivl_statement_t net)2766 extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net)
2767 {
2768       assert(net);
2769       switch (net->type_) {
2770 	  case IVL_ST_ASSIGN_NB:
2771 	    return net->u_.assign_.count;
2772 
2773 	  case IVL_ST_CONDIT:
2774 	    return net->u_.condit_.cond_;
2775 
2776 	  case IVL_ST_CASE:
2777 	  case IVL_ST_CASER:
2778 	  case IVL_ST_CASEX:
2779 	  case IVL_ST_CASEZ:
2780 	    return net->u_.case_.cond;
2781 
2782 	  case IVL_ST_DO_WHILE:
2783 	  case IVL_ST_REPEAT:
2784 	  case IVL_ST_WHILE:
2785 	    return net->u_.while_.cond_;
2786 
2787 	  default:
2788 	    assert(0);
2789 	    return 0;
2790       }
2791 }
2792 
ivl_stmt_cond_false(ivl_statement_t net)2793 extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net)
2794 {
2795       assert(net);
2796       assert(net->type_ == IVL_ST_CONDIT);
2797       if (net->u_.condit_.stmt_[1].type_ == IVL_ST_NONE)
2798 	    return 0;
2799       else
2800 	    return net->u_.condit_.stmt_ + 1;
2801 }
2802 
ivl_stmt_cond_true(ivl_statement_t net)2803 extern "C" ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net)
2804 {
2805       assert(net);
2806       assert(net->type_ == IVL_ST_CONDIT);
2807       if (net->u_.condit_.stmt_[0].type_ == IVL_ST_NONE)
2808 	    return 0;
2809       else
2810 	    return net->u_.condit_.stmt_ + 0;
2811 }
2812 
ivl_stmt_delay_expr(ivl_statement_t net)2813 extern "C" ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net)
2814 {
2815       assert(net);
2816       switch (net->type_) {
2817 	  case IVL_ST_ASSIGN:
2818 	  case IVL_ST_ASSIGN_NB:
2819 	    return net->u_.assign_.delay;
2820 
2821 	  case IVL_ST_DELAYX:
2822 	    return net->u_.delayx_.expr;
2823 
2824 	  default:
2825 	    assert(0);
2826 	    return 0;
2827       }
2828 }
2829 
ivl_stmt_delay_val(ivl_statement_t net)2830 extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net)
2831 {
2832       assert(net);
2833       assert(net->type_ == IVL_ST_DELAY);
2834       return net->u_.delay_.value;
2835 }
2836 
ivl_stmt_needs_t0_trigger(ivl_statement_t net)2837 extern "C" unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net)
2838 {
2839       assert(net);
2840       if (net->type_ == IVL_ST_WAIT) {
2841 	    return net->u_.wait_.needs_t0_trigger;
2842       } else {
2843 	    return 0;
2844       }
2845 }
2846 
ivl_stmt_nevent(ivl_statement_t net)2847 extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
2848 {
2849       assert(net);
2850       switch (net->type_) {
2851 	  case IVL_ST_ASSIGN_NB:
2852 	    return net->u_.assign_.nevent;
2853 
2854 	  case IVL_ST_WAIT:
2855 	    return net->u_.wait_.nevent;
2856 
2857 	  case IVL_ST_TRIGGER:
2858 	    return 1;
2859 
2860 	  default:
2861 	    assert(0);
2862       }
2863       return 0;
2864 }
2865 
ivl_stmt_events(ivl_statement_t net,unsigned idx)2866 extern "C" ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx)
2867 {
2868       assert(net);
2869       switch (net->type_) {
2870 	  case IVL_ST_ASSIGN_NB:
2871 	    assert(idx < net->u_.assign_.nevent);
2872 	    if (net->u_.assign_.nevent == 1)
2873 		  return net->u_.assign_.event;
2874 	    else
2875 		  return net->u_.assign_.events[idx];
2876 
2877 	  case IVL_ST_WAIT:
2878 	    assert(idx < net->u_.wait_.nevent);
2879 	    if (net->u_.wait_.nevent == 1)
2880 		  return net->u_.wait_.event;
2881 	    else
2882 		  return net->u_.wait_.events[idx];
2883 
2884 	  case IVL_ST_TRIGGER:
2885 	    assert(idx == 0);
2886 	    return net->u_.wait_.event;
2887 
2888 	  default:
2889 	    assert(0);
2890       }
2891       return 0;
2892 }
2893 
ivl_stmt_lexp(ivl_statement_t net)2894 extern "C" ivl_expr_t ivl_stmt_lexp(ivl_statement_t net)
2895 {
2896       assert(net);
2897       switch (net->type_) {
2898 	  case IVL_ST_CONTRIB:
2899 	    return net->u_.contrib_.lval;
2900 	  default:
2901 	    assert(0);
2902       }
2903       return 0;
2904 }
2905 
ivl_stmt_lval(ivl_statement_t net,unsigned idx)2906 extern "C" ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx)
2907 {
2908       assert(net);
2909       switch (net->type_) {
2910 	  case IVL_ST_ASSIGN:
2911 	  case IVL_ST_ASSIGN_NB:
2912 	  case IVL_ST_CASSIGN:
2913 	  case IVL_ST_DEASSIGN:
2914 	  case IVL_ST_FORCE:
2915 	  case IVL_ST_RELEASE:
2916 	    assert(idx < net->u_.assign_.lvals_);
2917 	    return net->u_.assign_.lval_ + idx;
2918 
2919 	  default:
2920 	    assert(0);
2921       }
2922       return 0;
2923 }
2924 
ivl_stmt_lvals(ivl_statement_t net)2925 extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net)
2926 {
2927       assert(net);
2928       switch (net->type_) {
2929 	  case IVL_ST_ASSIGN:
2930 	  case IVL_ST_ASSIGN_NB:
2931 	  case IVL_ST_CASSIGN:
2932 	  case IVL_ST_DEASSIGN:
2933 	  case IVL_ST_FORCE:
2934 	  case IVL_ST_RELEASE:
2935 	    return net->u_.assign_.lvals_;
2936 
2937 	  default:
2938 	    assert(0);
2939       }
2940       return 0;
2941 }
2942 
ivl_stmt_lwidth(ivl_statement_t net)2943 extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net)
2944 {
2945       assert(net);
2946       assert((net->type_ == IVL_ST_ASSIGN)
2947 	     || (net->type_ == IVL_ST_ASSIGN_NB)
2948 	     || (net->type_ == IVL_ST_CASSIGN)
2949 	     || (net->type_ == IVL_ST_DEASSIGN)
2950 	     || (net->type_ == IVL_ST_FORCE)
2951 	     || (net->type_ == IVL_ST_RELEASE));
2952 
2953       unsigned sum = 0;
2954 
2955       unsigned nlvals;
2956       struct ivl_lval_s*lvals;
2957       nlvals = net->u_.assign_.lvals_;
2958       lvals  = net->u_.assign_.lval_;
2959 
2960       for (unsigned idx = 0 ;  idx < nlvals ;  idx += 1) {
2961 	    ivl_lval_t cur = lvals + idx;
2962 	    switch(cur->type_) {
2963 		case IVL_LVAL_REG:
2964 		case IVL_LVAL_ARR:
2965 		case IVL_LVAL_LVAL:
2966 		  sum += ivl_lval_width(cur);
2967 		  break;
2968 		default:
2969 		  assert(0);
2970 	    }
2971       }
2972 
2973       return sum;
2974 }
2975 
ivl_stmt_name(ivl_statement_t net)2976 extern "C" const char* ivl_stmt_name(ivl_statement_t net)
2977 {
2978       assert(net);
2979       switch (net->type_) {
2980 	  case IVL_ST_STASK:
2981 	    return net->u_.stask_.name_;
2982 	  default:
2983 	    assert(0);
2984       }
2985 
2986       return 0;
2987 }
2988 
ivl_stmt_opcode(ivl_statement_t net)2989 extern "C" char ivl_stmt_opcode(ivl_statement_t net)
2990 {
2991       assert(net);
2992       switch (net->type_) {
2993 	  case IVL_ST_ASSIGN:
2994 	    return net->u_.assign_.oper;
2995 	  default:
2996 	    assert(0);
2997       }
2998       return 0;
2999 }
3000 
ivl_stmt_parm(ivl_statement_t net,unsigned idx)3001 extern "C" ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx)
3002 {
3003       assert(net);
3004       switch (net->type_) {
3005 	  case IVL_ST_STASK:
3006 	    assert(idx < net->u_.stask_.nparm_);
3007 	    return net->u_.stask_.parms_[idx];
3008 
3009 	  default:
3010 	    assert(0);
3011       }
3012       return 0;
3013 }
3014 
ivl_stmt_parm_count(ivl_statement_t net)3015 extern "C" unsigned ivl_stmt_parm_count(ivl_statement_t net)
3016 {
3017       assert(net);
3018       switch (net->type_) {
3019 	  case IVL_ST_STASK:
3020 	    return net->u_.stask_.nparm_;
3021 	  default:
3022 	    assert(0);
3023       }
3024       return 0;
3025 }
3026 
ivl_stmt_rval(ivl_statement_t net)3027 extern "C" ivl_expr_t ivl_stmt_rval(ivl_statement_t net)
3028 {
3029       assert(net);
3030       switch (net->type_) {
3031 	  case IVL_ST_ASSIGN:
3032 	  case IVL_ST_ASSIGN_NB:
3033 	  case IVL_ST_CASSIGN:
3034 	  case IVL_ST_FORCE:
3035 	    return net->u_.assign_.rval_;
3036 	  case IVL_ST_CONTRIB:
3037 	    return net->u_.contrib_.rval;
3038 	  default:
3039 	    assert(0);
3040       }
3041 
3042       return 0;
3043 }
3044 
ivl_stmt_sfunc_as_task(ivl_statement_t net)3045 extern "C" ivl_sfunc_as_task_t ivl_stmt_sfunc_as_task(ivl_statement_t net)
3046 {
3047       assert(net);
3048       switch (net->type_) {
3049 	  case IVL_ST_STASK:
3050 	    return net->u_.stask_.sfunc_as_task_;
3051 	  default:
3052 	    assert(0);
3053       }
3054 
3055       return IVL_SFUNC_AS_TASK_ERROR;
3056 }
3057 
ivl_stmt_sub_stmt(ivl_statement_t net)3058 extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
3059 {
3060       assert(net);
3061       switch (net->type_) {
3062 	  case IVL_ST_DELAY:
3063 	    return net->u_.delay_.stmt_;
3064 	  case IVL_ST_DELAYX:
3065 	    return net->u_.delayx_.stmt_;
3066 	  case IVL_ST_FOREVER:
3067 	    return net->u_.forever_.stmt_;
3068 	  case IVL_ST_WAIT:
3069 	    return net->u_.wait_.stmt_;
3070 	  case IVL_ST_DO_WHILE:
3071 	  case IVL_ST_REPEAT:
3072 	  case IVL_ST_WHILE:
3073 	    return net->u_.while_.stmt_;
3074 	  default:
3075 	    assert(0);
3076       }
3077 
3078       return 0;
3079 }
3080 
ivl_switch_basename(ivl_switch_t net)3081 extern "C" const char*ivl_switch_basename(ivl_switch_t net)
3082 {
3083       assert(net);
3084       return net->name;
3085 }
3086 
ivl_switch_scope(ivl_switch_t net)3087 extern "C" ivl_scope_t ivl_switch_scope(ivl_switch_t net)
3088 {
3089       assert(net);
3090       return net->scope;
3091 }
3092 
ivl_switch_type(ivl_switch_t net)3093 extern "C" ivl_switch_type_t ivl_switch_type(ivl_switch_t net)
3094 {
3095       assert(net);
3096       return net->type;
3097 }
3098 
ivl_switch_a(ivl_switch_t net)3099 extern "C" ivl_nexus_t ivl_switch_a(ivl_switch_t net)
3100 {
3101       assert(net);
3102       return net->pins[0];
3103 }
3104 
ivl_switch_b(ivl_switch_t net)3105 extern "C" ivl_nexus_t ivl_switch_b(ivl_switch_t net)
3106 {
3107       assert(net);
3108       return net->pins[1];
3109 }
3110 
ivl_switch_enable(ivl_switch_t net)3111 extern "C" ivl_nexus_t ivl_switch_enable(ivl_switch_t net)
3112 {
3113       assert(net);
3114       return net->pins[2];
3115 }
3116 
ivl_switch_width(ivl_switch_t net)3117 extern "C" unsigned ivl_switch_width(ivl_switch_t net)
3118 {
3119       assert(net);
3120       return net->width;
3121 }
3122 
ivl_switch_part(ivl_switch_t net)3123 extern "C" unsigned ivl_switch_part(ivl_switch_t net)
3124 {
3125       assert(net);
3126       return net->part;
3127 }
3128 
ivl_switch_offset(ivl_switch_t net)3129 extern "C" unsigned ivl_switch_offset(ivl_switch_t net)
3130 {
3131       assert(net);
3132       return net->offset;
3133 }
3134 
ivl_switch_delay(ivl_switch_t net,unsigned transition)3135 extern "C" ivl_expr_t ivl_switch_delay(ivl_switch_t net, unsigned transition)
3136 {
3137       assert(net);
3138       assert(transition < 3);
3139       return net->delay[transition];
3140 }
3141 
ivl_switch_file(ivl_switch_t net)3142 extern "C" const char* ivl_switch_file(ivl_switch_t net)
3143 {
3144       assert(net);
3145       return net->file;
3146 }
3147 
ivl_switch_island(ivl_switch_t net)3148 extern "C" ivl_island_t ivl_switch_island(ivl_switch_t net)
3149 {
3150       assert(net);
3151       return net->island;
3152 }
3153 
ivl_switch_lineno(ivl_switch_t net)3154 extern "C" unsigned ivl_switch_lineno(ivl_switch_t net)
3155 {
3156       assert(net);
3157       return net->lineno;
3158 }
3159 
ivl_type_base(ivl_type_t net)3160 extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net)
3161 {
3162       if (net == 0) return IVL_VT_NO_TYPE;
3163       else return net->base_type();
3164 }
3165 
ivl_type_element(ivl_type_t net)3166 extern "C" ivl_type_t ivl_type_element(ivl_type_t net)
3167 {
3168       if (const netarray_t*da = dynamic_cast<const netarray_t*> (net))
3169 	    return da->element_type();
3170 
3171       assert(0);
3172       return 0;
3173 }
3174 
ivl_type_packed_dimensions(ivl_type_t net)3175 extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net)
3176 {
3177       assert(net);
3178       vector<netrange_t> slice = net->slice_dimensions();
3179       return slice.size();
3180 }
3181 
ivl_type_packed_lsb(ivl_type_t net,unsigned dim)3182 extern "C" int ivl_type_packed_lsb(ivl_type_t net, unsigned dim)
3183 {
3184       assert(net);
3185       vector<netrange_t> slice = net->slice_dimensions();
3186       assert(dim < slice.size());
3187       return slice[dim].get_lsb();
3188 }
3189 
ivl_type_packed_msb(ivl_type_t net,unsigned dim)3190 extern "C" int ivl_type_packed_msb(ivl_type_t net, unsigned dim)
3191 {
3192       assert(net);
3193       vector<netrange_t> slice = net->slice_dimensions();
3194       assert(dim < slice.size());
3195       return slice[dim].get_msb();
3196 }
3197 
ivl_type_name(ivl_type_t net)3198 extern "C" const char* ivl_type_name(ivl_type_t net)
3199 {
3200       if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(net))
3201 	    return class_type->get_name();
3202 
3203       return 0;
3204 }
3205 
ivl_type_properties(ivl_type_t net)3206 extern "C" int ivl_type_properties(ivl_type_t net)
3207 {
3208       const netclass_t*class_type = dynamic_cast<const netclass_t*>(net);
3209       assert(class_type);
3210 
3211       return class_type->get_properties();
3212 }
3213 
ivl_type_prop_name(ivl_type_t net,int idx)3214 extern "C" const char* ivl_type_prop_name(ivl_type_t net, int idx)
3215 {
3216       if (idx < 0) return 0;
3217       const netclass_t*class_type = dynamic_cast<const netclass_t*>(net);
3218       assert(class_type);
3219 
3220       return class_type->get_prop_name(idx);
3221 }
3222 
ivl_type_prop_type(ivl_type_t net,int idx)3223 extern "C" ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx)
3224 {
3225       const netclass_t*class_type = dynamic_cast<const netclass_t*>(net);
3226       assert(class_type);
3227 
3228       return class_type->get_prop_type(idx);
3229 }
3230 
ivl_type_signed(ivl_type_t net)3231 extern "C" int ivl_type_signed(ivl_type_t net)
3232 {
3233       assert(net);
3234       return net->get_signed()? 1 : 0;
3235 }
3236