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