1 #ifndef IVL_t_dll_H
2 #define IVL_t_dll_H
3 /*
4  * Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
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  "target.h"
23 # include  "ivl_target.h"
24 # include  "ivl_target_priv.h"
25 # include  "StringHeap.h"
26 # include  "netlist.h"
27 # include  <vector>
28 # include  <map>
29 
30 #if defined(__MINGW32__)
31 #include <windows.h>
32 typedef void *ivl_dll_t;
33 #elif defined(HAVE_DLFCN_H)
34 # include  <dlfcn.h>
35 typedef void* ivl_dll_t;
36 #elif defined(HAVE_DL_H)
37 # include  <dl.h>
38 typedef shl_t ivl_dll_t;
39 #else
40 # error No DLL stub support for this target.
41 #endif
42 
43 /*
44  * The DLL target type loads a named object file to handle the process
45  * of scanning the netlist. When it is time to start the design, I
46  * locate and link in the desired DLL, then start calling methods. The
47  * DLL will call me back to get information out of the netlist in
48  * particular.
49  */
50 struct dll_target  : public target_t, public expr_scan_t {
51 
52 	// This is a special function for loading and testing the
53 	// version of a loadable target code generator.
54       void test_version(const char*target_name);
55 
56       bool start_design(const Design*);
57       int  end_design(const Design*);
58 
59       bool bufz(const NetBUFZ*);
60       bool branch(const NetBranch*);
61       bool class_type(const NetScope*, netclass_t*);
62       bool enumeration(const NetScope*, netenum_t*);
63       void event(const NetEvent*);
64       void logic(const NetLogic*);
65       bool tran(const NetTran*);
66       bool ureduce(const NetUReduce*);
67       void net_case_cmp(const NetCaseCmp*);
68       void udp(const NetUDP*);
69       void lpm_abs(const NetAbs*);
70       void lpm_add_sub(const NetAddSub*);
71       bool lpm_array_dq(const NetArrayDq*);
72       bool lpm_cast_int2(const NetCastInt2*);
73       bool lpm_cast_int4(const NetCastInt4*);
74       bool lpm_cast_real(const NetCastReal*);
75       void lpm_clshift(const NetCLShift*);
76       void lpm_compare(const NetCompare*);
77       void lpm_divide(const NetDivide*);
78       void lpm_ff(const NetFF*);
79       void lpm_latch(const NetLatch*);
80       void lpm_modulo(const NetModulo*);
81       void lpm_mult(const NetMult*);
82       void lpm_mux(const NetMux*);
83       void lpm_pow(const NetPow*);
84       bool concat(const NetConcat*);
85       bool part_select(const NetPartSelect*);
86       bool replicate(const NetReplicate*);
87       void net_assign(const NetAssign_*) const;
88       bool net_sysfunction(const NetSysFunc*);
89       bool net_function(const NetUserFunc*);
90       bool net_const(const NetConst*);
91       bool net_literal(const NetLiteral*);
92       void net_probe(const NetEvProbe*);
93       bool sign_extend(const NetSignExtend*);
94       bool substitute(const NetSubstitute*);
95 
96       bool process(const NetProcTop*);
97       bool process(const NetAnalogTop*);
98       void scope(const NetScope*);
99       void convert_module_ports(const NetScope*);
100       void signal(const NetNet*);
101       bool signal_paths(const NetNet*);
102       ivl_dll_t dll_;
103 
104       ivl_design_s des_;
105 
106       target_design_f target_;
107 
108 
109 	/* These methods and members are used for forming the
110 	   statements of a thread. */
111       struct ivl_statement_s*stmt_cur_;
112       void proc_alloc(const NetAlloc*);
113       bool proc_assign(const NetAssign*);
114       void proc_assign_nb(const NetAssignNB*);
115       bool proc_block(const NetBlock*);
116       void proc_case(const NetCase*);
117       bool proc_cassign(const NetCAssign*);
118       bool proc_condit(const NetCondit*);
119       bool proc_contribution(const NetContribution*);
120       bool proc_deassign(const NetDeassign*);
121       bool proc_delay(const NetPDelay*);
122       bool proc_disable(const NetDisable*);
123       void proc_do_while(const NetDoWhile*);
124       bool proc_force(const NetForce*);
125       void proc_forever(const NetForever*);
126       void proc_free(const NetFree*);
127       bool proc_release(const NetRelease*);
128       void proc_repeat(const NetRepeat*);
129       void proc_stask(const NetSTask*);
130       bool proc_trigger(const NetEvTrig*);
131       void proc_utask(const NetUTask*);
132       bool proc_wait(const NetEvWait*);
133       void proc_while(const NetWhile*);
134 
135       bool func_def(const NetScope*);
136       void task_def(const NetScope*);
137 
138       struct ivl_expr_s*expr_;
139       void expr_access_func(const NetEAccess*);
140       void expr_array_pattern(const NetEArrayPattern*);
141       void expr_binary(const NetEBinary*);
142       void expr_concat(const NetEConcat*);
143       void expr_const(const NetEConst*);
144       void expr_creal(const NetECReal*);
145       void expr_last(const NetELast*);
146       void expr_new(const NetENew*);
147       void expr_null(const NetENull*);
148       void expr_param(const NetEConstParam*);
149       void expr_property(const NetEProperty*);
150       void expr_rparam(const NetECRealParam*);
151       void expr_event(const NetEEvent*);
152       void expr_scope(const NetEScope*);
153       void expr_scopy(const NetEShallowCopy*);
154       void expr_netenum(const NetENetenum*);
155       void expr_select(const NetESelect*);
156       void expr_sfunc(const NetESFunc*);
157       void expr_ternary(const NetETernary*);
158       void expr_ufunc(const NetEUFunc*);
159       void expr_unary(const NetEUnary*);
160       void expr_signal(const NetESignal*);
161 
162       ivl_scope_t lookup_scope_(const NetScope*scope);
163 
164       ivl_attribute_s* fill_in_attributes(const Attrib*net);
165       void switch_attributes(struct ivl_switch_s *obj, const NetNode*net);
166       void logic_attributes(struct ivl_net_logic_s *obj, const NetNode*net);
167 
168     private:
169       StringHeap strings_;
170 
171       static ivl_scope_t find_scope(ivl_design_s &des, const NetScope*cur);
172       static ivl_signal_t find_signal(ivl_design_s &des, const NetNet*net);
173       static ivl_parameter_t scope_find_param(ivl_scope_t scope,
174 					      const char*name);
175 
176       void add_root(const NetScope *s);
177 
178       bool make_assign_lvals_(const NetAssignBase*net);
179       bool make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, const NetAssign_*asn);
180       void sub_off_from_expr_(long);
181       void mul_expr_by_const_(long);
182 
183       void make_delays_(ivl_expr_t*delay, const NetObj*net);
184       void make_logic_delays_(struct ivl_net_logic_s*obj, const NetObj*net);
185       void make_switch_delays_(struct ivl_switch_s*obj, const NetObj*net);
186       void make_lpm_delays_(struct ivl_lpm_s*obj, const NetObj*net);
187       void make_const_delays_(struct ivl_net_const_s*obj, const NetObj*net);
188       void make_scope_parameters(ivl_scope_t scope, const NetScope*net);
189       void make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp);
190 
191       ivl_event_t make_lpm_trigger(const NetEvWait*ev);
192 
193       bool lpm_arith1_(ivl_lpm_type_t lpm_type, unsigned wid, bool signed_flag, const NetNode*net);
194 
195       static ivl_expr_t expr_from_value_(const verinum&that);
196 };
197 
198 extern struct dll_target dll_target_obj;
199 
200 /*
201  * These are various private declarations used by the t-dll target.
202  */
203 
204 struct ivl_delaypath_s {
205       ivl_scope_t scope;
206       ivl_nexus_t src;
207       ivl_nexus_t condit;
208       bool conditional;
209       bool parallel;
210       bool posedge;
211       bool negedge;
212       uint64_t delay[12];
213 };
214 
215 struct ivl_event_s {
216       perm_string name;
217       ivl_scope_t scope;
218       perm_string file;
219       unsigned lineno;
220       unsigned nany, nneg, npos;
221       ivl_nexus_t*pins;
222 };
223 
224 /*
225  * The ivl_expr_t is an opaque reference to one of these
226  * structures. This structure holds all the information we need about
227  * an expression node, including its type, the expression width, and
228  * type specific properties.
229  */
230 struct ivl_expr_s {
231       ivl_expr_type_t type_;
232       ivl_variable_type_t value_;
233       ivl_type_t net_type;
234       perm_string file;
235       unsigned lineno;
236 
237       unsigned width_;
238       unsigned signed_ : 1;
239       unsigned sized_  : 1;
240 
241       union {
242 	    struct {
243 		  char op_;
244 		  ivl_expr_t lef_;
245 		  ivl_expr_t rig_;
246 	    } binary_;
247 
248 	    struct {
249 		  size_t parms;
250 		  ivl_expr_t*parm;
251 	    } array_pattern_;
252 
253 	    struct {
254 		  ivl_select_type_t  sel_type_;
255 		  ivl_expr_t expr_;
256 		  ivl_expr_t base_;
257 	    } select_;
258 
259 	    struct {
260 		  ivl_expr_t dest;
261 		  ivl_expr_t src;
262 	    } shallow_;
263 
264 	    struct {
265 		  ivl_branch_t branch;
266 		  ivl_nature_t nature;
267 	    } branch_;
268 
269 	    struct {
270 		  unsigned   rept;
271 		  unsigned   parms;
272 		  ivl_expr_t*parm;
273 	    } concat_;
274 
275 	    struct {
276 		  char*bits_;
277 		  ivl_parameter_t parameter;
278 	    } number_;
279 
280 	    struct {
281 		  ivl_event_t event;
282 	    } event_;
283 
284 	    struct {
285 		  ivl_scope_t scope;
286 	    } scope_;
287 
288 	    struct {
289 		  ivl_enumtype_t type;
290 	    } enumtype_;
291 
292 	    struct {
293 		  ivl_signal_t sig;
294 		  ivl_expr_t word;
295 	    } signal_;
296 
297 	    struct {
298 		  const char *name_;
299 		  ivl_expr_t *parm;
300 		  unsigned   parms;
301 	    } sfunc_;
302 
303 	    struct {
304 		  char*value_;
305 		  ivl_parameter_t parameter;
306 	    } string_;
307 
308 	    struct {
309 		  ivl_expr_t cond;
310 		  ivl_expr_t true_e;
311 		  ivl_expr_t false_e;
312 	    } ternary_;
313 
314 	    struct {
315 		  ivl_memory_t mem_;
316 		  ivl_expr_t idx_;
317 	    } memory_;
318 
319 	    struct {
320 		  ivl_scope_t def;
321 		  ivl_expr_t  *parm;
322 		  unsigned    parms;
323 	    } ufunc_;
324 
325 	    struct {
326 		  unsigned long value;
327 	    } ulong_;
328 
329 	    struct {
330 		  double value;
331 		  ivl_parameter_t parameter;
332 	    } real_;
333 
334 	    struct {
335 		  char op_;
336 		  ivl_expr_t sub_;
337 	    } unary_;
338 
339 	    struct {
340 		  uint64_t value;
341 	    } delay_;
342 
343 	    struct {
344 		  ivl_expr_t size;
345 		  ivl_expr_t init_val;
346 	    } new_;
347 
348 	    struct {
349 		  ivl_signal_t sig;
350 		  unsigned prop_idx;
351 		  ivl_expr_t index;
352 	    } property_;
353       } u_;
354 };
355 
356 /*
357  * LPM devices are handled by this suite of types. The ivl_lpm_s
358  * structure holds the core, including a type code, the object name
359  * and scope. The other properties of the device are held in the type
360  * specific member of the union.
361  */
362 
363 struct ivl_lpm_s {
364       ivl_lpm_type_t type;
365       ivl_scope_t scope;
366       perm_string name;
367       perm_string file;
368       unsigned lineno;
369 	// Value returned by ivl_lpm_width;
370       unsigned width;
371       ivl_expr_t delay[3];
372 
373       union {
374 	    struct ivl_lpm_ff_s {
375 		  unsigned negedge_flag :1;
376 		  ivl_nexus_t clk;
377 		  ivl_nexus_t we;
378 		  ivl_nexus_t aclr;
379 		  ivl_nexus_t aset;
380 		  ivl_nexus_t sclr;
381 		  ivl_nexus_t sset;
382 		  union {
383 			ivl_nexus_t*pins;
384 			ivl_nexus_t pin;
385 		  } q;
386 		  union {
387 			ivl_nexus_t*pins;
388 			ivl_nexus_t pin;
389 		  } d;
390 		  ivl_expr_t aset_value;
391 		  ivl_expr_t sset_value;
392 	    } ff;
393 	    struct ivl_lpm_latch_s {
394 		  ivl_nexus_t e;
395 		  union {
396 			ivl_nexus_t*pins;
397 			ivl_nexus_t pin;
398 		  } q;
399 		  union {
400 			ivl_nexus_t*pins;
401 			ivl_nexus_t pin;
402 		  } d;
403 	    } latch;
404 
405 	    struct ivl_lpm_mux_s {
406 		  unsigned size;
407 		  unsigned swid;
408 		  ivl_nexus_t*d;
409 		  ivl_nexus_t q, s;
410 	    } mux;
411 
412 	    struct ivl_lpm_shift_s {
413 		  unsigned select;
414 		  unsigned signed_flag :1;
415 		  ivl_nexus_t q, d, s;
416 	    } shift;
417 
418 	    struct ivl_lpm_arith_s {
419 		  unsigned signed_flag :1;
420 		  ivl_nexus_t q,  a,  b;
421 	    } arith;
422 
423 	    struct ivl_lpm_array_s {
424 		  ivl_signal_t sig;
425 		  unsigned swid;
426 		  ivl_nexus_t q,  a;
427 	    } array;
428 
429 	    struct ivl_concat_s {
430 		  unsigned inputs;
431 		  ivl_nexus_t*pins;
432 	    } concat;
433 
434 	    struct ivl_part_s {
435 		  unsigned base;
436 		  unsigned signed_flag :1;
437 		  ivl_nexus_t q, a, s;
438 	    } part;
439 
440 	      // IVL_LPM_RE_* and IVL_LPM_SIGN_EXT use this.
441 	    struct ivl_lpm_reduce_s {
442 		  ivl_nexus_t q,  a;
443 	    } reduce;
444 
445 	    struct ivl_lpm_repeat_s {
446 		  unsigned count;
447 		  ivl_nexus_t q, a;
448 	    } repeat;
449 
450 	    struct ivl_lpm_sfunc_s {
451 		  const char* fun_name;
452 		  unsigned ports;
453 		  ivl_nexus_t*pins;
454 		  ivl_event_t trigger;
455 	    } sfunc;
456 
457 	    struct ivl_lpm_substitute {
458 		  unsigned base;
459 		  ivl_nexus_t q, a, s;
460 	    } substitute;
461 
462 	    struct ivl_lpm_ufunc_s {
463 		  ivl_scope_t def;
464 		  unsigned ports;
465 		  ivl_nexus_t*pins;
466 		  ivl_event_t trigger;
467 	    } ufunc;
468       } u_;
469 };
470 
471 /*
472  * This object represents l-values to assignments. The l-value can be
473  * a register bit or part select, or a memory word select with a part
474  * select.
475  */
476 
477 enum ivl_lval_type_t {
478       IVL_LVAL_REG = 0,
479       IVL_LVAL_ARR = 4,
480       IVL_LVAL_LVAL= 5  // Nested l-value
481 };
482 
483 struct ivl_lval_s {
484       ivl_expr_t loff;
485       ivl_select_type_t sel_type :3;
486       ivl_expr_t idx;
487       unsigned width_;
488       unsigned type_   : 8; /* values from ivl_lval_type_t */
489       int property_idx;
490       union {
491 	    ivl_signal_t sig;
492 	    ivl_lval_t  nest; // type_ == IVL_LVAL_LVAL
493       } n;
494 };
495 
496 /*
497  * This object represents a literal constant, possibly signed, in a
498  * structural context.
499  */
500 struct ivl_net_const_s {
501       ivl_variable_type_t type :  4;
502       unsigned width_          : 24;
503       unsigned signed_         :  1;
504       perm_string file;
505       unsigned lineno;
506       ivl_scope_t scope;
507 
508       union {
509 	    double real_value;
510 	    char bit_[sizeof(char*)];
511 	    const char* bits_;
512       } b;
513 
514       ivl_nexus_t pin_;
515       ivl_expr_t delay[3];
516 
517       void* operator new (size_t s);
518       void  operator delete(void*obj, size_t s); // Not implemented
519 };
520 
521 /*
522  * Logic gates (just about everything that has a single output) are
523  * represented structurally by instances of this object.
524  */
525 struct ivl_net_logic_s {
526       ivl_logic_t type_;
527       unsigned width_;
528       unsigned is_cassign;
529       ivl_udp_t udp;
530 
531       perm_string name_;
532       ivl_scope_t scope_;
533       perm_string file;
534       unsigned lineno;
535 
536       unsigned npins_;
537       ivl_nexus_t*pins_;
538 
539       struct ivl_attribute_s*attr;
540       unsigned nattr;
541 
542       ivl_expr_t delay[3];
543 };
544 
545 struct ivl_switch_s {
546       ivl_switch_type_t type;
547       unsigned width;
548       unsigned part;
549       unsigned offset;
550 
551       perm_string name;
552       ivl_scope_t scope;
553       ivl_island_t island;
554 
555       struct ivl_attribute_s*attr;
556       unsigned nattr;
557 
558       ivl_expr_t delay[3];
559 
560       ivl_nexus_t pins[3];
561       perm_string file;
562       unsigned lineno;
563 };
564 
565 /*
566  * UDP definition.
567  */
568 struct ivl_udp_s {
569       perm_string name;
570       unsigned nin;
571       int sequ; /* boolean */
572       char init;
573       unsigned nrows;
574       typedef const char*ccharp_t;
575       ccharp_t*table; // zero terminated array of pointers
576       perm_string file;
577       unsigned lineno;
578       string*ports;
579 };
580 
581 /*
582  * The ivl_nexus_t is a single-bit link of some number of pins of
583  * devices. the __nexus_ptr structure is a helper that actually does
584  * the pointing.
585  *
586  * The type_ member specifies which of the object pointers in the
587  * union are valid.
588  *
589  * The drive01 members gives the strength of the drive that the device
590  * is applying to the nexus, with 0 HiZ and 3 supply. If the pin is an
591  * input to the device, then the drives are both HiZ.
592  */
593 struct ivl_nexus_ptr_s {
594       unsigned pin_;
595       unsigned type_ : 8;
596       unsigned drive0 : 3;
597       unsigned drive1 : 3;
598       union {
599 	    ivl_signal_t    sig; /* type 0 */
600 	    ivl_net_logic_t log; /* type 1 */
601 	    ivl_net_const_t con; /* type 2 */
602 	    ivl_lpm_t       lpm; /* type 3 */
603 	    ivl_switch_t    swi; /* type 4 */
604 	    ivl_branch_t    bra; /* type 5 */
605       } l;
606 };
607 # define __NEXUS_PTR_SIG 0
608 # define __NEXUS_PTR_LOG 1
609 # define __NEXUS_PTR_CON 2
610 # define __NEXUS_PTR_LPM 3
611 # define __NEXUS_PTR_SWI 4
612 # define __NEXUS_PTR_BRA 5
613 
614 /*
615  * NOTE: ONLY allocate ivl_nexus_s objects with the included "new" operator.
616  */
617 struct ivl_nexus_s {
ivl_nexus_sivl_nexus_s618       ivl_nexus_s() : ptrs_(1), nexus_(0), name_(0), private_data(0) { }
619       vector<ivl_nexus_ptr_s>ptrs_;
620       const Nexus*nexus_;
621       const char*name_;
622       void*private_data;
623 
624       void* operator new (size_t s);
625       void  operator delete(void*obj, size_t s); // Not implemented
626 };
627 
628 /*
629  * This is the implementation of a parameter. Each scope has a list of
630  * these.
631  */
632 struct ivl_parameter_s {
633       perm_string basename;
634       ivl_scope_t scope;
635       ivl_expr_t  value;
636       long          msb;
637       long          lsb;
638       bool  signed_flag;
639       bool        local;
640       perm_string file;
641       unsigned lineno;
642 };
643 /*
644  * All we know about a process is its type (initial or always) and the
645  * single statement that is it. A process also has a scope, although
646  * that generally only matters for VPI calls.
647  */
648 struct ivl_process_s {
649       ivl_process_type_t type_ : 3;
650       unsigned int analog_flag : 1;
651       ivl_scope_t scope_;
652       ivl_statement_t stmt_;
653       perm_string file;
654       unsigned lineno;
655 
656       struct ivl_attribute_s*attr;
657       unsigned nattr;
658 
659       ivl_process_t next_;
660 };
661 
662 /*
663  * Scopes are kept in a tree. Each scope points to its first child,
664  * and also to any siblings. Thus a parent can scan all its children
665  * by following its child pointer, then following sibling pointers from
666  * there.
667  */
668 struct ivl_scope_s {
669       ivl_scope_s();
670 
671       ivl_scope_t parent;
672       std::map<hname_t,ivl_scope_t> children;
673 	// This is just like the children map above, but in vector
674 	// form for convenient access.
675       std::vector<ivl_scope_t> child;
676 
677       perm_string name_;
678       perm_string tname_;
679       perm_string file;
680       perm_string def_file;
681       unsigned lineno;
682       unsigned def_lineno;
683       ivl_scope_type_t type_;
684 
685       std::vector<ivl_type_t> classes;
686       std::vector<ivl_enumtype_t> enumerations_;
687 
688       std::vector<ivl_signal_t> sigs_;
689 
690       unsigned nlog_;
691       ivl_net_logic_t*log_;
692 
693       unsigned nevent_;
694       ivl_event_t* event_;
695 
696       unsigned nlpm_;
697       ivl_lpm_t* lpm_;
698 
699       std::vector<struct ivl_parameter_s> param;
700 
701 	/* Scopes that are tasks/functions have a definition. */
702       ivl_statement_t def;
703       unsigned is_auto;
704       ivl_variable_type_t func_type;
705       bool func_signed;
706       unsigned func_width;
707 
708       unsigned is_cell;
709 
710       // Ports of Module scope (just introspection data for VPI) - actual connections
711       // are nets defined in u_.net (may be > 1 per module port)
712       std::vector<PortInfo>     module_ports_info;
713 
714       unsigned ports;
715       union {
716 	    ivl_signal_t*port;
717 	    ivl_nexus_t*nex;
718 	    NetNet**net;
719       } u_;
720 
721       std::vector<ivl_switch_t>switches;
722 
723       signed int time_precision :8;
724       signed int time_units :8;
725 
726       struct ivl_attribute_s*attr;
727       unsigned nattr;
728 };
729 
730 /*
731  * A signal is a thing like a wire, a reg, or whatever. It has a type,
732  * and if it is a port is also has a direction. Signals are collected
733  * into scopes (which also point back to me) and have pins that
734  * connect to the rest of the netlist.
735  */
736 struct ivl_signal_s {
737       ivl_signal_type_t type_;
738       ivl_signal_port_t port_;
739       int module_port_index_;
740       ivl_discipline_t discipline;
741       perm_string file;
742       unsigned lineno;
743 
744 	// This is the type for the signal
745       ivl_type_t net_type;
746       unsigned local_  : 1;
747 
748       unsigned forced_net_ : 1;
749 
750 	/* For now, support only 0 or 1 array dimensions. */
751       unsigned array_dimensions_ : 8;
752       unsigned array_addr_swapped : 1;
753 
754 	/* These encode the declared packed dimensions for the
755 	   signal, in case they are needed by the run-time */
756       std::vector<netrange_t> packed_dims;
757 
758       perm_string name_;
759       ivl_scope_t scope_;
760 
761       unsigned array_words;
762       int array_base;
763       union {
764 	    ivl_nexus_t pin;
765 	    ivl_nexus_t*pins;
766       };
767 
768       ivl_delaypath_s*path;
769       unsigned npath;
770 
771       struct ivl_attribute_s*attr;
772       unsigned nattr;
773 };
774 
775 
776 /*
777  * The ivl_statement_t represents any statement. The type of statement
778  * is defined by the ivl_statement_type_t enumeration. Given the type,
779  * certain information about the statement may be available.
780  */
781 struct ivl_statement_s {
782       enum ivl_statement_type_e type_;
783       perm_string file;
784       unsigned lineno;
785 
786       union {
787 	    struct { /* IVL_ST_ALLOC */
788 		  ivl_scope_t scope;
789 	    } alloc_;
790 
791 	    struct { /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB
792 			IVL_ST_CASSIGN, IVL_ST_DEASSIGN */
793 		  unsigned lvals_;
794 		  struct ivl_lval_s*lval_;
795 		  char oper; // Operator if this is a compressed assignment.
796 		  ivl_expr_t rval_;
797 		  ivl_expr_t delay;
798 		    // The following are only for NB event control.
799 		  ivl_expr_t count;
800 		  unsigned nevent;
801 		  union {
802 			ivl_event_t event;
803 			ivl_event_t*events;
804 		  };
805 	    } assign_;
806 
807 	    struct { /* IVL_ST_BLOCK, IVL_ST_FORK */
808 		  struct ivl_statement_s*stmt_;
809 		  unsigned nstmt_;
810 		  ivl_scope_t scope;
811 	    } block_;
812 
813 	    struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */
814 		  ivl_case_quality_t quality;
815 		  ivl_expr_t cond;
816 		  unsigned ncase;
817 		  ivl_expr_t*case_ex;
818 		  struct ivl_statement_s*case_st;
819 	    } case_;
820 
821 	    struct { /* IVL_ST_CONDIT */
822 		    /* This is the condition expression */
823 		  ivl_expr_t cond_;
824 		    /* This is two statements, the true and false. */
825 		  struct ivl_statement_s*stmt_;
826 	    } condit_;
827 
828 	    struct { /* IVL_ST_CONTRIB */
829 		  ivl_expr_t lval;
830 		  ivl_expr_t rval;
831 	    } contrib_;
832 
833 	    struct { /* IVL_ST_DELAY */
834 		  uint64_t value;
835 		  ivl_statement_t stmt_;
836 	    } delay_;
837 
838 	    struct { /* IVL_ST_DELAYX */
839 		  ivl_expr_t expr; /* XXXX */
840 		  ivl_statement_t stmt_;
841 	    } delayx_;
842 
843 	    struct { /* IVL_ST_DISABLE */
844 		  ivl_scope_t scope;
845 	    } disable_;
846 
847 	    struct { /* IVL_ST_FOREVER */
848 		  ivl_statement_t stmt_;
849 	    } forever_;
850 
851 	    struct { /* IVL_ST_FREE */
852 		  ivl_scope_t scope;
853 	    } free_;
854 
855 	    struct { /* IVL_ST_STASK */
856 		  const char*name_;
857 		  ivl_sfunc_as_task_t sfunc_as_task_;
858 		  unsigned   nparm_;
859 		  ivl_expr_t*parms_;
860 	    } stask_;
861 
862 	    struct { /* IVL_ST_UTASK */
863 		  ivl_scope_t def;
864 	    } utask_;
865 
866 	    struct { /* IVL_ST_TRIGGER IVL_ST_WAIT */
867 		  unsigned needs_t0_trigger;
868 		  unsigned nevent;
869 		  union {
870 			ivl_event_t event;
871 			ivl_event_t*events;
872 		  };
873 		  ivl_statement_t stmt_;
874 	    } wait_;
875 
876 	    struct { /* IVL_ST_WHILE IVL_ST_REPEAT */
877 		  ivl_expr_t cond_;
878 		  ivl_statement_t stmt_;
879 	    } while_;
880       } u_;
881 };
882 
883 /*
884  * The FILE_NAME function is a shorthand for attaching file/line
885  * information to the statement object.
886  */
FILE_NAME(ivl_expr_t expr,const LineInfo * info)887 static inline void FILE_NAME(ivl_expr_t expr, const LineInfo*info)
888 {
889       expr->file = info->get_file();
890       expr->lineno = info->get_lineno();
891 }
892 
FILE_NAME(ivl_event_t event,const LineInfo * info)893 static inline void FILE_NAME(ivl_event_t event, const LineInfo*info)
894 {
895       event->file = info->get_file();
896       event->lineno = info->get_lineno();
897 }
898 
FILE_NAME(ivl_lpm_t lpm,const LineInfo * info)899 static inline void FILE_NAME(ivl_lpm_t lpm, const LineInfo*info)
900 {
901       lpm->file = info->get_file();
902       lpm->lineno = info->get_lineno();
903 }
904 
FILE_NAME(ivl_net_const_t net,const LineInfo * info)905 static inline void FILE_NAME(ivl_net_const_t net, const LineInfo*info)
906 {
907       net->file = info->get_file();
908       net->lineno = info->get_lineno();
909 }
910 
FILE_NAME(ivl_net_logic_t net,const LineInfo * info)911 static inline void FILE_NAME(ivl_net_logic_t net, const LineInfo*info)
912 {
913       net->file = info->get_file();
914       net->lineno = info->get_lineno();
915 }
916 
FILE_NAME(ivl_parameter_t net,const LineInfo * info)917 static inline void FILE_NAME(ivl_parameter_t net, const LineInfo*info)
918 {
919       net->file = info->get_file();
920       net->lineno = info->get_lineno();
921 }
922 
FILE_NAME(ivl_process_t net,const LineInfo * info)923 static inline void FILE_NAME(ivl_process_t net, const LineInfo*info)
924 {
925       net->file = info->get_file();
926       net->lineno = info->get_lineno();
927 }
928 
FILE_NAME(ivl_scope_t scope,const NetScope * info)929 static inline void FILE_NAME(ivl_scope_t scope, const NetScope*info)
930 {
931       scope->file = info->get_file();
932       scope->def_file = info->get_def_file();
933       scope->lineno = info->get_lineno();
934       scope->def_lineno = info->get_def_lineno();
935 }
936 
FILE_NAME(ivl_statement_t stmt,const LineInfo * info)937 static inline void FILE_NAME(ivl_statement_t stmt, const LineInfo*info)
938 {
939       stmt->file = info->get_file();
940       stmt->lineno = info->get_lineno();
941 }
942 
FILE_NAME(ivl_switch_t net,const LineInfo * info)943 static inline void FILE_NAME(ivl_switch_t net, const LineInfo*info)
944 {
945       net->file = info->get_file();
946       net->lineno = info->get_lineno();
947 }
948 
FILE_NAME(ivl_signal_t net,const LineInfo * info)949 static inline void FILE_NAME(ivl_signal_t net, const LineInfo*info)
950 {
951       net->file = info->get_file();
952       net->lineno = info->get_lineno();
953 }
954 
955 #endif /* IVL_t_dll_H */
956