1 #ifndef IVL_netlist_H
2 #define IVL_netlist_H
3 /*
4  * Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
5  * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
6  *
7  *    This source code is free software; you can redistribute it
8  *    and/or modify it in source code form under the terms of the GNU
9  *    General Public License as published by the Free Software
10  *    Foundation; either version 2 of the License, or (at your option)
11  *    any later version.
12  *
13  *    This program is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    GNU General Public License for more details.
17  *
18  *    You should have received a copy of the GNU General Public License
19  *    along with this program; if not, write to the Free Software
20  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 /*
24  * The netlist types, as described in this header file, are intended
25  * to be the output from elaboration of the source design. The design
26  * can be passed around in this form to the various stages and design
27  * processors.
28  */
29 # include  <string>
30 # include  <map>
31 # include  <list>
32 # include  <memory>
33 # include  <vector>
34 # include  <set>
35 # include  <utility>
36 # include  "ivl_target.h"
37 # include  "ivl_target_priv.h"
38 # include  "pform_types.h"
39 # include  "config.h"
40 # include  "nettypes.h"
41 # include  "verinum.h"
42 # include  "verireal.h"
43 # include  "StringHeap.h"
44 # include  "HName.h"
45 # include  "LineInfo.h"
46 # include  "Attrib.h"
47 # include  "PUdp.h"
48 
49 #ifdef HAVE_IOSFWD
50 # include  <iosfwd>
51 #else
52 class ostream;
53 #endif
54 
55 class Design;
56 class Link;
57 class Nexus;
58 class NetEvent;
59 class NetNet;
60 class NetNode;
61 class NetObj;
62 class NetPins;
63 class NetProc;
64 class NetProcTop;
65 class NetRelease;
66 class NetScope;
67 class NetEvProbe;
68 class NetExpr;
69 class NetEAccess;
70 class NetEConstEnum;
71 class NetESignal;
72 class NetFuncDef;
73 class NetRamDq;
74 class NetTaskDef;
75 class NetEvTrig;
76 class NetEvWait;
77 class PClass;
78 class PExpr;
79 class PFunction;
80 class PPackage;
81 class PTaskFunc;
82 struct enum_type_t;
83 class netclass_t;
84 class netdarray_t;
85 class netparray_t;
86 class netqueue_t;
87 class netenum_t;
88 class netstruct_t;
89 class netvector_t;
90 
91 struct target;
92 struct functor_t;
93 
94 #if defined(__cplusplus) && defined(_MSC_VER)
95 # define ENUM_UNSIGNED_INT : unsigned int
96 #else
97 # define ENUM_UNSIGNED_INT
98 #endif
99 
100 ostream& operator << (ostream&o, ivl_variable_type_t val);
101 
102 extern void join_island(NetPins*obj);
103 
104 class Link {
105 
106       friend void connect(Link&, Link&);
107       friend class NetPins;
108       friend class Nexus;
109       friend class NexusSet;
110 
111     public:
112       enum DIR ENUM_UNSIGNED_INT { PASSIVE, INPUT, OUTPUT };
113     private: // Only NetPins can create/delete Link objects
114       Link();
115       ~Link();
116 
117     public:
118 	// Manipulate the link direction.
119       void set_dir(DIR d);
120       DIR get_dir() const;
121 
122 	// Set the delay for all the drivers to this nexus.
123       void drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay);
124 
125 	// A link has a drive strength for 0 and 1 values. The drive0
126 	// strength is for when the link has the value 0, and drive1
127 	// strength is for when the link has a value 1.
128       void drive0(ivl_drive_t);
129       void drive1(ivl_drive_t);
130 
131 	// This sets the drives for all drivers of this link, and not
132 	// just the current link.
133       void drivers_drive(ivl_drive_t d0, ivl_drive_t d1);
134 
135       ivl_drive_t drive0() const;
136       ivl_drive_t drive1() const;
137 
138       void cur_link(NetPins*&net, unsigned &pin);
139       void cur_link(const NetPins*&net, unsigned &pin) const;
140 
141 	// Get a pointer to the nexus that represents all the links
142 	// connected to me.
143       Nexus* nexus();
144       const Nexus* nexus()const;
145 
146 	// Return a pointer to the next link in the nexus.
147       Link* next_nlink();
148       const Link* next_nlink() const;
149 
150 	// Remove this link from the set of connected pins. The
151 	// destructor will automatically do this if needed.
152       void unlink();
153 
154 	// Return true if this link is connected to anything else.
155       bool is_linked() const;
156 
157 	// Return true if these pins are connected.
158       bool is_linked(const Link&that) const;
159 
160 	// Return true if this is the same pin of the same object of
161 	// that link.
162       bool is_equal(const Link&that) const;
163 
164 	// Return information about the object that this link is
165 	// a part of. Note that the get_obj() method can return NIL if
166 	// this Link is part of a NexusSet. That should be OK, because
167 	// they are collection variables, and not functional parts of
168 	// a design.
169       const NetPins*get_obj() const;
170       NetPins*get_obj();
171       unsigned get_pin() const;
172 
173       void dump_link(ostream&fd, unsigned ind) const;
174 
175     private:
176 	// The NetNode manages these. They point back to the
177 	// NetNode so that following the links can get me here.
178       union {
179 	    NetPins *node_;
180 	    unsigned pin_;
181       };
182 
183       bool pin_zero_     : 1;
184       DIR dir_           : 2;
185       ivl_drive_t drive0_ : 3;
186       ivl_drive_t drive1_ : 3;
187 
188     private:
189       Nexus* find_nexus_() const;
190 
191     private:
192 	// The Nexus uses these to maintain its list of Link
193 	// objects. If this link is not connected to anything,
194 	// then these pointers are both nil.
195       Link *next_;
196       Nexus*nexus_;
197 
198     private: // not implemented
199       Link(const Link&);
200       Link& operator= (const Link&);
201 };
202 
203 
204 class NetPins : public LineInfo {
205 
206     public:
207       explicit NetPins(unsigned npins);
208       virtual ~NetPins();
209 
pin_count()210       unsigned pin_count() const { return npins_; }
211 
212       Link&pin(unsigned idx);
213       const Link&pin(unsigned idx) const;
214 
215       void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const;
216       void set_default_dir(Link::DIR d);
217 
218       bool is_linked();
219       bool pins_are_virtual(void) const;
220       void devirtualize_pins(void);
221 
222 	// This is for showing a brief description of the object to
223 	// the stream. It is used for debug and diagnostics.
224       virtual void show_type(std::ostream&fd) const;
225 
226     private:
227       Link*pins_;
228       const unsigned npins_;
229       Link::DIR default_dir_;
230 };
231 
232 /* =========
233  * A NetObj is anything that has any kind of behavior in the
234  * netlist. Nodes can be gates, registers, etc. and are linked
235  * together to form a design web.
236  *
237  * The web of nodes that makes up a circuit is held together by the
238  * Link class. There is a link for each pin. All mutually connected
239  * pins form a ring of links.
240  *
241  * A link can be INPUT, OUTPUT or PASSIVE. An input never drives the
242  * signal, and PASSIVE never receives the value of the signal. Wires
243  * are PASSIVE, for example.
244  *
245  * A NetObj also has delays specified as rise_time, fall_time and
246  * decay_time. The rise and fall time are the times to transition to 1
247  * or 0 values. The decay_time is the time needed to decay to a 'bz
248  * value, or to decay of the net is a trireg. The exact and precise
249  * interpretation of the rise/fall/decay times is typically left to
250  * the target to properly interpret.
251  */
252 class NetObj  : public NetPins, public Attrib {
253 
254     public:
255 	// The name of the object must be a permallocated string. A
256 	// lex_strings string, for example.
257       explicit NetObj(NetScope*s, perm_string n, unsigned npins);
258       virtual ~NetObj();
259 
260       NetScope* scope();
261       const NetScope* scope() const;
262 
name()263       perm_string name() const { return name_; }
rename(perm_string n)264       void rename(perm_string n) { name_ = n; }
265 
rise_time()266       const NetExpr* rise_time() const { return delay1_; }
fall_time()267       const NetExpr* fall_time() const { return delay2_; }
decay_time()268       const NetExpr* decay_time() const { return delay3_; }
269 
rise_time(const NetExpr * d)270       void rise_time(const NetExpr* d) { delay1_ = d; }
fall_time(const NetExpr * d)271       void fall_time(const NetExpr* d) { delay2_ = d; }
decay_time(const NetExpr * d)272       void decay_time(const NetExpr* d) { delay3_ = d; }
273 
274       void dump_obj_attr(ostream&, unsigned) const;
275 
276       virtual void show_type(std::ostream&fd) const;
277 
278     private:
279       NetScope*scope_;
280       perm_string name_;
281       const NetExpr* delay1_;
282       const NetExpr* delay2_;
283       const NetExpr* delay3_;
284 };
285 
286 /*
287 * Objects that can be island branches are derived from this. (It is
288 * possible for an object to be a NetObj and an IslandBranch.) This is
289 * used to collect island information about the node.
290 */
291 
292 class IslandBranch {
293     public:
294       explicit IslandBranch(ivl_discipline_t dis =0) : island_(0), discipline_(dis) { }
295 
get_island()296       ivl_island_t get_island() const { return island_; }
297 
298       friend void join_island(NetPins*);
299 
300     private:
301       ivl_island_t island_;
302       ivl_discipline_t discipline_;
303 };
304 
305 /*
306  * A NetBranch is a construct of Verilog-A that is a branch between
307  * two nodes. The branch has exactly 2 pins and a discipline.
308  *
309  * pin(0) is the source of flow through a branch and the plus side of
310  * potential. Pin(1) is the sink of flow and the minus (or ground) of
311  * potential.
312  */
313 class NetBranch  : public NetPins, public IslandBranch {
314 
315     public:
316       explicit NetBranch(ivl_discipline_t dis);
317       explicit NetBranch(ivl_discipline_t dis, perm_string name);
318       ~NetBranch();
319 
320 	// If the branch is named, this returns the name.
name()321       perm_string name() const { return name_; }
322 
target_obj()323       ivl_branch_s* target_obj() const { return &target_obj_; }
324 
325       void dump(ostream&, unsigned) const;
326 
327     private:
328       perm_string name_;
329 
330       mutable ivl_branch_s target_obj_;
331 
332 	// The design class uses this member to list the branches.
333       friend class Design;
334       NetBranch*next_;
335 };
336 
337 /*
338  * The Nexus represents a collection of links that are joined
339  * together. Each link has its own properties, this class holds the
340  * properties of the group.
341  *
342  * The links in a nexus are grouped into a circularly linked list,
343  * with the nexus pointing to the last Link. Each link in turn points
344  * to the next link in the nexus, with the last link pointing back to
345  * the first. The last link also has a non-nil nexus_ pointer back to
346  * this nexus.
347  *
348  * The t_cookie() is an ivl_nexus_t that the code generator uses to
349  * store data in the nexus. When a Nexus is created, this cookie is
350  * set to nil. The code generator may set the cookie once. This locks
351  * the nexus, and rewrites the Link list to be optimal for the code
352  * generator. In the process, *all* of the other methods are no longer
353  * functional.
354  */
355 class Nexus {
356 
357       friend void connect(Link&, Link&);
358       friend class Link;
359 
360     private:
361 	// Only Link objects can create (or delete) Nexus objects
362       explicit Nexus(Link&r);
363       ~Nexus();
364 
365     public:
366 
367       void connect(Link&r);
368 
369       const char* name() const;
370 
371       void drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay);
372       void drivers_drive(ivl_drive_t d0, ivl_drive_t d1);
373 
374       Link*first_nlink();
375       const Link* first_nlink()const;
376 
377 	/* Get the width of the Nexus, or 0 if there are no vectors
378 	   (in the form of NetNet objects) linked. */
379       unsigned vector_width() const;
380 
381       NetNet* pick_any_net();
382 
383       NetNode* pick_any_node();
384 
385       /* This method counts the number of input and output links for
386          this nexus, and assigns the results to the output arguments. */
387       void count_io(unsigned&inp, unsigned&out) const;
388 
389 	/* This method returns true if there are any assignments that
390 	   use this nexus as an l-value. This can be true if the nexus
391 	   is a variable, but also if this is a net with a force. */
392       bool assign_lval() const;
393 
394 	/* This method returns true if there are any inputs
395 	   attached to this nexus but no drivers. */
396       bool has_floating_input() const;
397 
398 	/* This method returns true if there are any drivers
399 	   (including variables) attached to this nexus. */
400       bool drivers_present() const;
401 
402 	/* This method returns true if all the possible drivers of
403 	   this nexus are constant. It will also return true if there
404 	   are no drivers at all. */
405       bool drivers_constant() const;
406 
407 	/* Given the nexus has constant drivers, this method returns
408 	   the value that has been driven. */
409       verinum::V driven_value() const;
410       verinum driven_vector() const;
411 
412 	/* Return a mask of the bits of this vector that are
413 	   driven. This is usually all false or all true, but in
414 	   special cases it may be a blend. */
415       std::vector<bool> driven_mask(void)const;
416 
417 	/* The code generator sets an ivl_nexus_t to attach code
418 	   generation details to the nexus. */
t_cookie()419       ivl_nexus_t t_cookie() const { return t_cookie_; }
420       void t_cookie(ivl_nexus_t) const;
421 
422     private:
423       Link*list_;
424       void unlink(Link*);
425 
426       mutable char* name_; /* Cache the calculated name for the Nexus. */
427       mutable ivl_nexus_t t_cookie_;
428 
429       enum VALUE { NO_GUESS, V0, V1, Vx, Vz, VAR };
430       mutable VALUE driven_;
431 
432     private: // not implemented
433       Nexus(const Nexus&);
434       Nexus& operator= (const Nexus&);
435 };
436 
connect(Nexus * l,Link & r)437 inline void connect(Nexus*l, Link&r) { l->connect(r); }
438 
439 class NexusSet {
440 
441     public:
442       struct elem_t {
elem_telem_t443 	    inline elem_t(Nexus*n, unsigned b, unsigned w)
444 	    : base(b), wid(w)
445 	    {
446 		  lnk.set_dir(Link::PASSIVE);
447 		  n->connect(lnk);
448 	    }
elem_telem_t449 	    inline elem_t() : base(0), wid(0)
450 	    {
451 	    }
452 	    inline bool operator == (const struct elem_t&that) const
453 	    { return lnk.is_linked(that.lnk) && base==that.base && wid==that.wid; }
454 
455 	    bool contains(const struct elem_t&that) const;
456 
457 	    Link lnk;
458 	    unsigned base;
459 	    unsigned wid;
460 	  private:
461 	    elem_t(const elem_t&);
462 	    elem_t& operator= (elem_t&);
463       };
464 
465     public:
466       ~NexusSet();
467       NexusSet();
468 
469       size_t size() const;
470 
471 	// Add the nexus/part to the set, if it is not already present.
472       void add(Nexus*that, unsigned base, unsigned wid);
473       void add(NexusSet&that);
474 
475 	// Remove the nexus from the set, if it is present.
476       void rem(const NexusSet&that);
477 
478       unsigned find_nexus(const elem_t&that) const;
479 
480       elem_t& at(unsigned idx);
481       inline elem_t& operator[] (unsigned idx) { return at(idx); }
482 
483 	// Return true if this set contains every nexus/part in that
484 	// set. That means that every bit of that set is accounted for
485 	// this set.
486       bool contains(const NexusSet&that) const;
487 
488 	// Return true if this set contains any nexus in that set.
489       bool intersect(const NexusSet&that) const;
490 
491     private:
492 	// NexSet items are canonical part selects of vectors.
493       std::vector<struct elem_t*> items_;
494 
495       size_t bsearch_(const struct elem_t&that) const;
496       void rem_(const struct elem_t*that);
497       bool contains_(const elem_t&that) const;
498 
499     private: // not implemented
500       NexusSet(const NexusSet&);
501       NexusSet& operator= (const NexusSet&);
502 };
503 
504 /*
505  * A NetBus is a transparent device that is merely a bunch of pins
506  * used to tie some pins to. It is a convenient way to collect a
507  * bundle of pins and pass that bundle around.
508  */
509 class NetBus  : public NetObj {
510 
511     public:
512       NetBus(NetScope*scope, unsigned pin_count);
513       ~NetBus();
514 
515       unsigned find_link(const Link&that) const;
516 
517     private: // not implemented
518       NetBus(const NetBus&);
519       NetBus& operator= (const NetBus&);
520 };
521 
522 /*
523  * A NetNode is a device of some sort, where each pin has a different
524  * meaning. (i.e., pin(0) is the output to an and gate.) NetNode
525  * objects are listed in the nodes_ of the Design object.
526  */
527 class NetNode  : public NetObj {
528 
529     public:
530 	// The name parameter must be a permallocated string.
531       explicit NetNode(NetScope*s, perm_string n, unsigned npins);
532 
533       virtual ~NetNode();
534 
535       virtual bool emit_node(struct target_t*) const;
536       virtual void dump_node(ostream&, unsigned) const;
537 
538 	// This is used to scan a modifiable netlist, one node at a time.
539       virtual void functor_node(Design*, functor_t*);
540 
541     private:
542       friend class Design;
543       NetNode*node_next_, *node_prev_;
544       Design*design_;
545 };
546 
547 /*
548  * A NetDelaySrc is an input-only device that calculates a path delay
549  * based on the time that the inputs change. This class is used by the
550  * NetNet class, and NetDelaySrc objects cannot exist outside of its
551  * association with NetNet objects.
552  */
553 class NetDelaySrc  : public NetObj {
554 
555     public:
556       explicit NetDelaySrc(NetScope*s, perm_string n, unsigned nsrc,
557                            bool condit_src, bool conditional, bool parallel);
558       ~NetDelaySrc();
559 
560 	// These functions set the delays from the values in the
561 	// source. These set_delays functions implement the various
562 	// rules wrt collections of transitions.
563 
564 	// One transition specified.
565       void set_delays(uint64_t del);
566 	// Two transitions: rise and fall
567       void set_delays(uint64_t rise, uint64_t fall);
568 	// Three transitions
569       void set_delays(uint64_t rise, uint64_t fall, uint64_t tz);
570       void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
571 		      uint64_t tz1, uint64_t t1z, uint64_t tz0);
572       void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z,
573 		      uint64_t tz1, uint64_t t1z, uint64_t tz0,
574 		      uint64_t t0x, uint64_t tx1, uint64_t t1x,
575 		      uint64_t tx0, uint64_t txz, uint64_t tzx);
576 
577       uint64_t get_delay(unsigned pe) const;
578 
579       void set_posedge();
580       void set_negedge();
581       bool is_posedge() const;
582       bool is_negedge() const;
583 
584       unsigned src_count() const;
585       Link&src_pin(unsigned);
586       const Link&src_pin(unsigned) const;
587 
588       bool is_condit() const;
589       bool has_condit() const;
590       Link&condit_pin();
591       const Link&condit_pin() const;
592 
593       bool is_parallel() const;
594 
595       void dump(ostream&, unsigned ind) const;
596 
597     private:
598       uint64_t transition_delays_[12];
599       bool condit_flag_;
600       bool conditional_;
601       bool parallel_;
602       bool posedge_;
603       bool negedge_;
604 
605     private: // Not implemented
606       NetDelaySrc(const NetDelaySrc&);
607       NetDelaySrc& operator= (const NetDelaySrc&);
608 };
609 
610 /*
611  * NetNet is a special kind of NetObj that doesn't really do anything,
612  * but carries the properties of the wire/reg/trireg, including its
613  * name. Scalars and vectors are all the same thing here, a NetNet
614  * with a single pin. The difference between a scalar and vector is
615  * the width of the atomic vector datum it carries.
616  *
617  * NetNet objects can also appear as side effects of synthesis or
618  * other abstractions.
619  *
620  * Note that INTEGER types are an alias for a ``reg signed [31:0]''.
621  *
622  * NetNet objects have a name and exist within a scope, so the
623  * constructor takes a pointer to the containing scope. The object
624  * automatically adds itself to the scope.
625  *
626  * NetNet objects are located by searching NetScope objects.
627  *
628  * The pins of a NetNet object are usually PASSIVE: they do not drive
629  * anything and they are not a data sink, per se. The pins follow the
630  * values on the nexus. The exceptions are reg, trireg, tri0, tri1,
631  * supply0, and supply1 objects, whose pins are classed as OUTPUT.
632  */
633 
634 class PortType
635 {
636 public:
637 	enum Enum ENUM_UNSIGNED_INT { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF };
638 
639     /*
640      * Merge Port types (used to construct a sane combined port-type
641      * for module ports with complex defining expressions).
642      *
643      */
644     static Enum merged( Enum lhs, Enum rhs );
645 };
646 
647 extern std::ostream& operator << (std::ostream&, PortType::Enum);
648 
649   /*
650    * Information on actual ports (rather than port-connected signals) of
651    * module.
652    * N.b. must be POD as passed through a "C" interface in the t-dll-api.
653    */
654 struct PortInfo
655 {
656     PortType::Enum  type;
657     unsigned long   width;
658     perm_string     name;
659 };
660 
661 
662 class NetNet  : public NetObj, public PortType {
663 
664     public:
665       enum Type ENUM_UNSIGNED_INT { NONE, IMPLICIT, IMPLICIT_REG, INTEGER, WIRE, TRI, TRI1,
666 		  SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG,
667 		  UNRESOLVED_WIRE };
668 
669       typedef PortType::Enum PortType;
670 
671       static const std::list<netrange_t>not_an_array;
672 
673     public:
674 	// This form is the more generic form of the constructor. For
675 	// now, the unpacked type is not buried into an ivl_type_s object.
676       explicit NetNet(NetScope*s, perm_string n, Type t,
677 		      const std::list<netrange_t>&unpacked,
678 		      ivl_type_t type);
679 
680 	// This form builds a NetNet from its record/enum/darray
681 	// definition. They should probably be replaced with a single
682 	// version that takes an ivl_type_s* base.
683       explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type);
684       explicit NetNet(NetScope*s, perm_string n, Type t, netdarray_t*type);
685       explicit NetNet(NetScope*s, perm_string n, Type t, netvector_t*type);
686 
687       virtual ~NetNet();
688 
689       Type type() const;
690       void type(Type t);
691 
692       PortType port_type() const;
693       void port_type(PortType t);
694 
695       // If this net net is a port (i.e. a *sub*port net of a module port)
696       // its port index is number of the module it connects through
697       int get_module_port_index() const;                // -1 Not connected to port...
698       void set_module_port_index(unsigned idx);
699 
700       ivl_variable_type_t data_type() const;
701 
702 	/* If a NetNet is signed, then its value is to be treated as
703 	   signed. Otherwise, it is unsigned. */
704       bool get_signed() const;
705 
706 	/* Used to maintain original type of net since integers are
707 	   implemented as 'reg signed [31:0]' in Icarus */
708       bool get_isint() const;
709 
710       bool get_scalar() const;
711 
net_type(void)712       inline const ivl_type_s* net_type(void) const { return net_type_; }
713       const netenum_t*enumeration(void) const;
714       const netstruct_t*struct_type(void) const;
715       const netdarray_t*darray_type(void) const;
716       const netqueue_t*queue_type(void) const;
717       const netclass_t*class_type(void) const;
718 
719 	/* Attach a discipline to the net. */
720       ivl_discipline_t get_discipline() const;
721       void set_discipline(ivl_discipline_t dis);
722 
723 	/* This method returns a reference to the packed dimensions
724 	   for the vector. These are arranged as a list where the
725 	   first range in the list (front) is the left-most range in
726 	   the Verilog declaration. These packed dims are compressed
727 	   to represent the dimensions of all the subtypes. */
packed_dims()728       const std::vector<netrange_t>& packed_dims() const { return slice_dims_; }
729 
unpacked_dims()730       const std::vector<netrange_t>& unpacked_dims() const { return unpacked_dims_; }
731 
732 	/* The vector_width returns the bit width of the packed array,
733 	   vector or scalar that is this NetNet object.  */
vector_width()734       inline unsigned long vector_width() const { return slice_width(0); }
735 
736 	/* Given a prefix of indices, figure out how wide the
737 	   resulting slice would be. This is a generalization of the
738 	   vector_width(), where the depth would be 0. */
739       unsigned long slice_width(size_t depth) const;
740 
741 	/* This method converts a signed index (the type that might be
742 	   found in the Verilog source) to canonical. It accounts
743 	   for variation in the definition of the
744 	   reg/wire/whatever. Note that a canonical index of a
745 	   multi-dimensioned packed array is a single dimension. For
746 	   example, "reg [4:1][3:0]..." has the canonical dimension
747 	   [15:0] and the sb_to_idx() method will convert [2][2] to
748 	   the canonical index [6]. */
749       long sb_to_idx(const std::list<long>&prefix, long sb) const;
750 
751 	/* This method converts a partial packed indices list and a
752 	   tail index, and generates a canonical slice offset and
753 	   width. */
754       bool sb_to_slice(const std::list<long>&prefix, long sb, long&off, unsigned long&wid) const;
755 
756 	/* This method checks that the signed index is valid for this
757 	   signal. If it is, the above sb_to_idx can be used to get
758 	   the pin# from the index. */
759       bool sb_is_valid(const std::list<long>&prefix, long sb) const;
760 
761 	/* This method returns 0 for scalars and vectors, and greater
762 	   for arrays. The value is the number of array
763 	   indices. (Currently only one array index is supported.) */
unpacked_dimensions()764       inline unsigned unpacked_dimensions() const { return unpacked_dims_.size(); }
765 
766 	/* This method returns 0 for scalars, but vectors and other
767 	   PACKED arrays have packed dimensions. */
packed_dimensions()768       inline size_t packed_dimensions() const { return slice_dims_.size(); }
769 
770 	// This is the number of array elements.
771       unsigned unpacked_count() const;
772 
local_flag()773       bool local_flag() const { return local_flag_; }
local_flag(bool f)774       void local_flag(bool f) { local_flag_ = f; }
775 
776 	// NetESignal objects may reference this object. Keep a
777 	// reference count so that I keep track of them.
778       void incr_eref();
779       void decr_eref();
780       unsigned peek_eref() const;
781 
782 	// Assignment statements count their lrefs here. And by
783 	// assignment statements, we mean BEHAVIORAL assignments.
784       void incr_lref();
785       void decr_lref();
peek_lref()786       unsigned peek_lref() const { return lref_count_; }
787 
788 	// Treating this node as a uwire, this function tests whether
789 	// any bits in the canonical part are already driven. This is
790 	// only useful for UNRESOLVED_WIRE objects. The msb and lsb
791 	// are the part select of the signal, and the widx is the word
792 	// index if this is an unpacked array.
793       bool test_and_set_part_driver(unsigned msb, unsigned lsb, int widx =0);
794 
795       unsigned get_refs() const;
796 
797 	/* Manage path delays */
798       void add_delay_path(class NetDelaySrc*path);
799       unsigned delay_paths(void) const;
800       const class NetDelaySrc*delay_path(unsigned idx) const;
801 
802       virtual void dump_net(ostream&, unsigned) const;
803 
804     private:
805       void initialize_dir_();
806 
807     private:
808       Type   type_    : 5;
809       PortType port_type_ : 3;
810       bool local_flag_: 1;
811       ivl_type_t net_type_;
812       ivl_discipline_t discipline_;
813 
814       std::vector<netrange_t> unpacked_dims_;
815 
816 	// These are the widths of the various slice depths. There is
817 	// one entry in this vector for each packed dimension. The
818 	// value at N is the slice width if N indices are provided.
819 	//
820 	// For example: slice_wids_[0] is vector_width().
821       void calculate_slice_widths_from_packed_dims_(void);
822       std::vector<netrange_t> slice_dims_;
823       std::vector<unsigned long> slice_wids_;
824 
825       unsigned eref_count_;
826       unsigned lref_count_;
827 
828 	// When the signal is an unresolved wire, we need more detail
829 	// which bits are assigned. This mask is true for each bit
830 	// that is known to be driven.
831       std::vector<bool> lref_mask_;
832 
833       vector<class NetDelaySrc*> delay_paths_;
834       int       port_index_;
835 };
836 
837 /*
838  * This object type is used for holding local variable values when
839  * evaluating constant user functions.
840  */
841 struct LocalVar {
842       int nwords;  // zero for a simple variable, -1 for reference
843       union {
844 	    NetExpr*  value;  // a simple variable
845 	    NetExpr** array;  // an array variable
846 	    LocalVar* ref;    // A reference to a previous scope
847       };
848 };
849 
850 class NetBaseDef {
851     public:
852       NetBaseDef(NetScope*n, const vector<NetNet*>&po,
853 		 const std::vector<NetExpr*>&pd);
854       virtual ~NetBaseDef();
855 
856       const NetScope*scope() const;
857       NetScope*scope();
858 
859       unsigned port_count() const;
860       NetNet*port(unsigned idx) const;
861       NetExpr*port_defe(unsigned idx) const;
862 
863       void set_proc(NetProc*p);
864 
865 	//const string& name() const;
866       const NetProc*proc() const;
867 
868     private:
869       NetScope*scope_;
870       std::vector<NetNet*>ports_;
871       std::vector<NetExpr*>pdefaults_;
872 
873     protected:
874       NetProc*proc_;
875 };
876 
877 /*
878  * Some definitions (and methods to manipulate them) are common to a
879  * couple of types. Keep them here.
880  */
881 class Definitions {
882 
883     public:
884       Definitions();
885       ~Definitions();
886 
887 	// Add the enumeration to the set of enumerations in this
888 	// scope. Include a key that the elaboration can use to look
889 	// up this enumeration based on the pform type.
890       void add_enumeration_set(const enum_type_t*key, netenum_t*enum_set);
891 
892       bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
893 
894 	// Look up the enumeration literal in this scope. if the name
895 	// is present, then return the enumeration type that declares it.
896       const netenum_t* enumeration_for_name(perm_string name);
897 
898 	// Look up the enumeration set that was added with the given
899 	// key. This is used by enum_type_t::elaborate_type to locate
900 	// a previously elaborated enumeration.
901       netenum_t* enumeration_for_key(const enum_type_t*key) const;
902 
903 	// Look up an enumeration literal in this scope. If the
904 	// literal is present, return the expression that defines its
905 	// value.
906       const NetExpr* enumeration_expr(perm_string key);
907 
908 	// Definitions scopes can also hold classes, by name.
909       void add_class(netclass_t*class_type);
910 
911     protected:
912 	// Enumerations. The enum_sets_ is a list of all the
913 	// enumerations present in this scope. The enum_names_ is a
914 	// map of all the enumeration names back to the sets that
915 	// contain them.
916       std::map<const enum_type_t*,netenum_t*> enum_sets_;
917       std::map<perm_string,NetEConstEnum*> enum_names_;
918 
919 	// This is a map of all the classes (by name) in this scope.
920       std::map<perm_string,netclass_t*> classes_;
921 
922 };
923 
924 /*
925  * This object type is used to contain a logical scope within a
926  * design. The scope doesn't represent any executable hardware, but is
927  * just a handle that netlist processors can use to grab at the design.
928  */
929 class NetScope : public Definitions, public Attrib {
930 
931     public:
932       enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE };
933 
934 	/* Create a new scope associated with a given compilation unit,
935 	   and attach it to the given parent. If no compilation unit is
936 	   specified, the parent's compilation unit is used. The name
937 	   is expected to have been permallocated. */
938       NetScope(NetScope*up, const hname_t&name, TYPE t, NetScope*in_unit=0,
939 	       bool nest=false, bool program=false, bool interface=false,
940                bool compilation_unit=false);
941       ~NetScope();
942 
943 	/* Rename the scope using the name generated by inserting as
944 	   many pad characters as required between prefix and suffix
945 	   to make the name unique in the parent scope. Return false
946 	   if a unique name couldn't be generated. */
947       bool auto_name(const char* prefix, char pad, const char* suffix);
948 
949       void add_imports(const map<perm_string,PPackage*>*imports);
950       NetScope*find_import(const Design*des, perm_string name);
951 
952       void add_typedefs(const map<perm_string,data_type_t*>*typedefs);
953 
954         /* Search the scope hierarchy for the scope where 'type' was defined. */
955       NetScope*find_typedef_scope(const Design*des, data_type_t*type);
956 
957 	/* Routine to search for the enumeration given a name. It basically
958 	 * does what enumeration_for_name() does but searched the hierarchy. */
959       const netenum_t*find_enumeration_for_name(const Design*des, perm_string name);
960 
961 	/* Parameters exist within a scope, and these methods allow
962 	   one to manipulate the set. In these cases, the name is the
963 	   *simple* name of the parameter, the hierarchy is implicit in
964 	   the scope. */
965 
966       struct range_t;
967       void set_parameter(perm_string name, bool is_annotatable,
968 			 PExpr*val, ivl_variable_type_t type,
969 			 PExpr*msb, PExpr*lsb, bool signed_flag,
970 			 bool local_flag,
971 			 NetScope::range_t*range_list,
972 			 const LineInfo&file_line);
973       void set_parameter(perm_string name, NetExpr*val,
974 			 const LineInfo&file_line);
975 
976       const NetExpr*get_parameter(Design*des,
977 				  const char* name,
978 				  const NetExpr*&msb,
979 				  const NetExpr*&lsb);
980       const NetExpr*get_parameter(Design*des,
981 				  perm_string name,
982 				  const NetExpr*&msb,
983 				  const NetExpr*&lsb);
984 
985 	/* These are used by defparam elaboration to replace the
986 	   expression with a new expression, without affecting the
987 	   range or signed_flag. Return false if the name does not
988 	   exist. */
989       bool replace_parameter(perm_string name, PExpr*val, NetScope*scope);
990 
991 	/* This is used to ensure the value of a parameter cannot be
992 	   changed at run-time. This is required if a specparam is used
993 	   in an expression that must be evaluated at compile-time.
994 	   Returns true if the named parameter is a specparam and has
995 	   not already been set to be unannotatable. */
996       bool make_parameter_unannotatable(perm_string name);
997 
998 	/* These methods set or access events that live in this
999 	   scope. */
1000 
1001       void add_event(NetEvent*);
1002       void rem_event(NetEvent*);
1003       NetEvent*find_event(perm_string name);
1004 
1005 	/* These methods add or find a genvar that lives in this scope. */
1006       void add_genvar(perm_string name, LineInfo *li);
1007       LineInfo* find_genvar(perm_string name);
1008 
1009 	/* These methods manage signals. The add_ and rem_signal
1010 	   methods are used by the NetNet objects to make themselves
1011 	   available to the scope, and the find_signal method can be
1012 	   used to locate signals within a scope. */
1013 
1014       void add_signal(NetNet*);
1015       void rem_signal(NetNet*);
1016       NetNet* find_signal(perm_string name);
1017 
1018       netclass_t* find_class(perm_string name);
1019 
1020 	/* The unit(), parent(), and child() methods allow users of
1021 	   NetScope objects to locate nearby scopes. */
unit()1022       NetScope* unit() { return unit_; }
parent()1023       NetScope* parent() { return up_; }
1024       NetScope* child(const hname_t&name);
unit()1025       const NetScope* unit() const { return unit_; }
parent()1026       const NetScope* parent() const { return up_; }
1027       const NetScope* child(const hname_t&name) const;
1028 
1029 	/* A helper function to find the enclosing class scope. */
1030       const NetScope* get_class_scope() const;
1031 
1032 	// Look for a child scope by name. This ignores the number
1033 	// part of the child scope name, so there may be multiple
1034 	// matches. Only return one. This function is only really
1035 	// useful for some elaboration error checking.
1036       const NetScope* child_byname(perm_string name) const;
1037 
1038 	// Nested modules have slightly different scope search rules.
nested_module()1039       inline bool nested_module() const { return nested_module_; }
1040 	// Program blocks and interfaces have elaboration constraints.
program_block()1041       inline bool program_block() const { return program_block_; }
is_interface()1042       inline bool is_interface() const { return is_interface_; }
is_unit()1043       inline bool is_unit() const { return is_unit_; }
type()1044       inline TYPE type() const { return type_; }
1045       void print_type(ostream&) const;
1046 
1047 	// This provides a link to the variable initialisation process
1048 	// for use when evaluating a constant function. Note this is
1049 	// only used for static functions - the variable initialization
1050 	// for automatic functions is included in the function definition.
set_var_init(const NetProc * proc)1051       void set_var_init(const NetProc*proc) { var_init_ = proc; }
var_init()1052       const NetProc* var_init() const { return var_init_; }
1053 
1054       void set_task_def(NetTaskDef*);
1055       void set_func_def(NetFuncDef*);
1056       void set_class_def(netclass_t*);
1057       void set_module_name(perm_string);
1058 
1059       NetTaskDef* task_def();
1060       NetFuncDef* func_def();
1061 
1062 	// This is used by the evaluate_function setup to collect
1063 	// local variables from the scope.
1064       void evaluate_function_find_locals(const LineInfo&loc,
1065 					 map<perm_string,LocalVar>&ctx) const;
1066 
1067       void set_line(perm_string file, perm_string def_file,
1068                     unsigned lineno, unsigned def_lineno);
1069       void set_line(perm_string file, unsigned lineno);
1070       void set_line(const LineInfo *info);
get_file()1071       perm_string get_file() const { return file_; };
get_def_file()1072       perm_string get_def_file() const { return def_file_; };
get_lineno()1073       unsigned get_lineno() const { return lineno_; };
get_def_lineno()1074       unsigned get_def_lineno() const { return def_lineno_; };
1075 
1076       bool in_func() const;
1077 
1078 	/* Provide a link back to the pform to allow early elaboration of
1079            constant functions. */
set_func_pform(const PFunction * pfunc)1080       void set_func_pform(const PFunction*pfunc) { func_pform_ = pfunc; };
func_pform()1081       const PFunction*func_pform() const { return func_pform_; };
1082 
1083         /* Allow tracking of elaboration stages. The three stages are:
1084              1 - scope elaboration
1085              2 - signal elaboration
1086              3 - statement elaboration
1087            This is only used for functions, to support early elaboration.
1088         */
set_elab_stage(unsigned stage)1089       void set_elab_stage(unsigned stage) { elab_stage_ = stage; };
elab_stage()1090       unsigned elab_stage() const { return elab_stage_; };
1091 
1092 	/* Is this a function called in a constant expression. */
need_const_func(bool need_const)1093       void need_const_func(bool need_const) { need_const_func_ = need_const; };
need_const_func()1094       bool need_const_func() const { return need_const_func_; };
1095 
1096 	/* Is this a constant function. */
is_const_func(bool is_const)1097       void is_const_func(bool is_const) { is_const_func_ = is_const; };
is_const_func()1098       bool is_const_func() const { return is_const_func_; };
1099 
1100 	/* Is the task or function automatic. */
is_auto(bool is_auto__)1101       void is_auto(bool is_auto__) { is_auto_ = is_auto__; };
is_auto()1102       bool is_auto() const { return is_auto_; };
1103 
1104 	/* Is the module a cell (is in a `celldefine) */
is_cell(bool is_cell__)1105       void is_cell(bool is_cell__) { is_cell_ = is_cell__; };
is_cell()1106       bool is_cell() const { return is_cell_; };
1107 
1108 	/* Is there a call to a system task in this scope. */
calls_sys_task(bool calls_stask__)1109       void calls_sys_task(bool calls_stask__) { calls_stask_ = calls_stask__; };
calls_sys_task()1110       bool calls_sys_task() const { return calls_stask_; };
1111 
1112         /* Is this scope elaborating a final procedure? */
in_final(bool in_final__)1113       void in_final(bool in_final__) { in_final_ = in_final__; };
in_final()1114       bool in_final() const { return in_final_; };
1115 
1116       const NetTaskDef* task_def() const;
1117       const NetFuncDef* func_def() const;
1118       const netclass_t* class_def() const;
1119 
1120 	/* If the scope represents a module instance, the module_name
1121 	   is the name of the module itself. */
1122       perm_string module_name() const;
1123 	/* If the scope is a module then it may have ports that we need
1124 	 * to keep track of. */
1125 
1126       void set_num_ports(unsigned int num_ports);
1127       void add_module_port_net(NetNet*port);
1128       unsigned module_port_nets() const;
1129       NetNet*module_port_net(unsigned idx) const;
1130 
1131       void add_module_port_info( unsigned idx,
1132                             perm_string name,  // May be "" for undeclared port
1133                             PortType::Enum type,
1134                             unsigned long width );
1135 
1136       const std::vector<PortInfo> &module_port_info() const;
1137 
1138 	/* Scopes have their own time units and time precision. The
1139 	   unit and precision are given as power of 10, i.e., -3 is
1140 	   units of milliseconds.
1141 
1142 	   If a NetScope is created with a parent scope, the new scope
1143 	   will initially inherit the unit and precision of the
1144 	   parent scope. */
1145 
1146       void time_unit(int);
1147       void time_precision(int);
1148       void time_from_timescale(bool);
1149 
1150       int time_unit() const;
1151       int time_precision() const;
1152       bool time_from_timescale() const;
1153 
1154 	/* The fullname of the scope is the hierarchical name
1155 	   component (which includes the name and array index) whereas
1156 	   the basename is just my name. */
1157       perm_string basename() const;
fullname()1158       const hname_t& fullname() const { return name_; }
1159 
1160       void run_defparams(class Design*);
1161       void run_defparams_later(class Design*);
1162 
1163       void evaluate_parameters(class Design*);
1164 
1165 	// Look for defparams that never matched, and print warnings.
1166       void residual_defparams(class Design*);
1167 
1168 	/* This method generates a non-hierarchical name that is
1169 	   guaranteed to be unique within this scope. */
1170       perm_string local_symbol();
1171 
1172       void dump(ostream&) const;
1173 	// Check to see if the scope has items that are not allowed
1174 	// in an always_comb/ff/latch process.
1175       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
1176       void emit_scope(struct target_t*tgt) const;
1177       bool emit_defs(struct target_t*tgt) const;
1178 
1179 	/* This method runs the functor on me. Recurse through the
1180 	   children of this node as well. */
1181       void run_functor(Design*des, functor_t*fun);
1182 
1183 	/* These are used in synthesis. They provide shared pullup and
1184 	   pulldown nodes for this scope. */
1185       void add_tie_hi(Design*des);
1186       void add_tie_lo(Design*des);
tie_hi()1187       Link&tie_hi() const { return tie_hi_->pin(0); };
tie_lo()1188       Link&tie_lo() const { return tie_lo_->pin(0); };
1189 
1190 	/* This member is used during elaboration to pass defparam
1191 	   assignments from the scope pass to the parameter evaluation
1192 	   step. After that, it is not used. */
1193 
1194       list<pair<pform_name_t,PExpr*> > defparams;
1195       list<pair<list<hname_t>,PExpr*> > defparams_later;
1196 
1197     public:
1198       struct range_t {
1199 	    bool exclude_flag;
1200 	      // Lower bound
1201 	    bool low_open_flag;
1202 	    NetExpr*low_expr;
1203 	      // Upper bound
1204 	    bool high_open_flag;
1205 	    NetExpr*high_expr;
1206 	      // Link to the next range specification
1207 	    struct range_t*next;
1208       };
1209 
1210 	/* After everything is all set up, the code generators like
1211 	   access to these things to make up the parameter lists. */
1212       struct param_expr_t : public LineInfo {
param_expr_tparam_expr_t1213 	    param_expr_t() : msb_expr(0), lsb_expr(0), val_expr(0), val_scope(0),
1214                              solving(false), is_annotatable(false),
1215                              type(IVL_VT_NO_TYPE), signed_flag(false),
1216                              local_flag(false),
1217                              msb(0), lsb(0), range(0), val(0) { }
1218               // Source expressions
1219 	    PExpr*msb_expr;
1220 	    PExpr*lsb_expr;
1221 	    PExpr*val_expr;
1222               // Scope information
1223             NetScope*val_scope;
1224 	      // Evaluation status
1225 	    bool solving;
1226 	      // specparam status
1227 	    bool is_annotatable;
1228 	      // Type information
1229 	    ivl_variable_type_t type;
1230 	    bool signed_flag;
1231             bool  local_flag;
1232 	    NetExpr*msb;
1233 	    NetExpr*lsb;
1234 	      // range constraints
1235 	    struct range_t*range;
1236 	      // Expression value
1237 	    NetExpr*val;
1238       };
1239       map<perm_string,param_expr_t>parameters;
1240 
1241       typedef map<perm_string,param_expr_t>::iterator param_ref_t;
1242 
1243       param_ref_t find_parameter(perm_string name);
1244 
1245 	/* Module instance arrays are collected here for access during
1246 	   the multiple elaboration passes. */
1247       typedef vector<NetScope*> scope_vec_t;
1248       map<perm_string, scope_vec_t>instance_arrays;
1249 
1250 	/* Loop generate uses this as scratch space during
1251 	   elaboration. Expression evaluation can use this to match
1252 	   names. */
1253       perm_string genvar_tmp;
1254       long genvar_tmp_val;
1255 
1256       std::map<perm_string,LocalVar> loop_index_tmp;
1257 
1258     private:
1259       void evaluate_parameter_logic_(Design*des, param_ref_t cur);
1260       void evaluate_parameter_real_(Design*des, param_ref_t cur);
1261       void evaluate_parameter_(Design*des, param_ref_t cur);
1262 
1263     private:
1264       TYPE type_;
1265       hname_t name_;
1266 
1267 	// True if the scope is a nested module/program block
1268       bool nested_module_;
1269 	// True if the scope is a program block
1270       bool program_block_;
1271 	// True if the scope is an interface
1272       bool is_interface_;
1273 	// True if the scope is a compilation unit
1274       bool is_unit_;
1275 
1276       perm_string file_;
1277       perm_string def_file_;
1278       unsigned lineno_;
1279       unsigned def_lineno_;
1280 
1281       signed char time_unit_, time_prec_;
1282       bool time_from_timescale_;
1283 
1284       const map<perm_string,PPackage*>*imports_;
1285 
1286       const map<perm_string,data_type_t*>*typedefs_;
1287 
1288       NetEvent *events_;
1289 
1290       map<perm_string,LineInfo*> genvars_;
1291 
1292       typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
1293       std::map <perm_string,NetNet*> signals_map_;
1294       perm_string module_name_;
1295       vector<NetNet*> port_nets;
1296 
1297       vector<PortInfo> ports_;
1298 
1299       const NetProc*var_init_;
1300 
1301       union {
1302 	    NetTaskDef*task_;
1303 	    NetFuncDef*func_;
1304 	    netclass_t*class_def_;
1305       };
1306       const PFunction*func_pform_;
1307       unsigned elab_stage_;
1308 
1309       NetScope*unit_;
1310       NetScope*up_;
1311       map<hname_t,NetScope*> children_;
1312 
1313       unsigned lcounter_;
1314       bool need_const_func_, is_const_func_, is_auto_, is_cell_, calls_stask_;
1315 
1316       /* Final procedures sets this to notify statements that
1317 	 they are part of a final procedure. */
1318       bool in_final_;
1319 
1320       NetNode*tie_hi_;
1321       NetNode*tie_lo_;
1322 };
1323 
1324 /*
1325  * This class implements the LPM_ABS component. The node has a single
1326  * input, a signed expression, that it converts to the absolute
1327  * value. The gate is simple: pin(0) is the output and pin(1) is the input.
1328  */
1329 class NetAbs  : public NetNode {
1330 
1331     public:
1332       NetAbs(NetScope*s, perm_string n, unsigned width);
1333       ~NetAbs();
1334 
1335       unsigned width() const;
1336 
1337       virtual void dump_node(ostream&, unsigned ind) const;
1338       virtual bool emit_node(struct target_t*) const;
1339       virtual void functor_node(Design*des, functor_t*fun);
1340 
1341     private:
1342       unsigned width_;
1343 };
1344 
1345 /*
1346  * This class implements the LPM_ADD_SUB component as described in the
1347  * EDIF LPM Version 2 1 0 standard. It is used as a structural
1348  * implementation of the + and - operators.
1349  */
1350 class NetAddSub  : public NetNode {
1351 
1352     public:
1353       NetAddSub(NetScope*s, perm_string n, unsigned width);
1354       ~NetAddSub();
1355 
1356 	// Get the width of the device (that is, the width of the
1357 	// operands and results).
1358       unsigned width() const;
1359 
1360       Link& pin_Cout();
1361       Link& pin_DataA();
1362       Link& pin_DataB();
1363       Link& pin_Result();
1364 
1365       const Link& pin_Cout() const;
1366       const Link& pin_DataA() const;
1367       const Link& pin_DataB() const;
1368       const Link& pin_Result() const;
1369 
1370       virtual void dump_node(ostream&, unsigned ind) const;
1371       virtual bool emit_node(struct target_t*) const;
1372       virtual void functor_node(Design*des, functor_t*fun);
1373 
1374     private:
1375       unsigned width_;
1376 };
1377 
1378 /*
1379  * The NetArrayDq node represents an array dereference. The NetNet
1380  * that this object refers to is an array, and the Address pin selects
1381  * which word of the array to place on the Result.
1382 */
1383 class NetArrayDq  : public NetNode {
1384 
1385     public:
1386       NetArrayDq(NetScope*s, perm_string name, NetNet*mem, unsigned awid);
1387       ~NetArrayDq();
1388 
1389       unsigned width() const;
1390       unsigned awidth() const;
1391       unsigned size() const;
1392       const NetNet*mem() const;
1393 
1394       Link& pin_Address();
1395       Link& pin_Result();
1396 
1397       const Link& pin_Address() const;
1398       const Link& pin_Result() const;
1399 
1400       virtual void dump_node(ostream&, unsigned ind) const;
1401       virtual bool emit_node(struct target_t*) const;
1402 
1403     private:
1404       NetNet*mem_;
1405       unsigned awidth_;
1406 
1407 };
1408 
1409 /*
1410  * Convert an IVL_VT_REAL input to a logical value with the
1411  * given width. The input is pin(1) and the output is pin(0).
1412  */
1413 class NetCastInt4  : public NetNode {
1414 
1415     public:
1416       NetCastInt4(NetScope*s, perm_string n, unsigned width);
1417 
width()1418       unsigned width() const { return width_; }
1419 
1420       virtual void dump_node(ostream&, unsigned ind) const;
1421       virtual bool emit_node(struct target_t*) const;
1422 
1423     private:
1424       unsigned width_;
1425 };
1426 
1427 class NetCastInt2  : public NetNode {
1428 
1429     public:
1430       NetCastInt2(NetScope*s, perm_string n, unsigned width);
1431 
width()1432       unsigned width() const { return width_; }
1433 
1434       virtual void dump_node(ostream&, unsigned ind) const;
1435       virtual bool emit_node(struct target_t*) const;
1436 
1437     private:
1438       unsigned width_;
1439 };
1440 
1441 /*
1442  * Convert an input to IVL_VT_REAL. The input is pin(1), which can be
1443  * any vector type (VT_BOOL or VT_LOGIC) and the output is pin(0),
1444  * which is IVL_VT_REAL. The conversion interprets the input as an
1445  * unsigned value unless the signed_flag is true.
1446  */
1447 class NetCastReal  : public NetNode {
1448 
1449     public:
1450       NetCastReal(NetScope*s, perm_string n, bool signed_flag);
1451 
signed_flag()1452       bool signed_flag() const { return signed_flag_; }
1453 
1454       virtual void dump_node(ostream&, unsigned ind) const;
1455       virtual bool emit_node(struct target_t*) const;
1456 
1457     private:
1458       bool signed_flag_;
1459 };
1460 
1461 /*
1462  * This type represents the LPM_CLSHIFT device.
1463  */
1464 class NetCLShift  : public NetNode {
1465 
1466     public:
1467       NetCLShift(NetScope*s, perm_string n, unsigned width,
1468 		 unsigned width_dist, bool right_flag, bool signed_flag);
1469       ~NetCLShift();
1470 
1471       unsigned width() const;
1472       unsigned width_dist() const;
1473 
1474       bool right_flag() const;
1475       bool signed_flag() const;
1476 
1477       Link& pin_Data();
1478       Link& pin_Result();
1479       Link& pin_Distance();
1480 
1481       const Link& pin_Data() const;
1482       const Link& pin_Result() const;
1483       const Link& pin_Distance() const;
1484 
1485       virtual void dump_node(ostream&, unsigned ind) const;
1486       virtual bool emit_node(struct target_t*) const;
1487 
1488     private:
1489       unsigned width_;
1490       unsigned width_dist_;
1491       bool right_flag_;
1492       bool signed_flag_;
1493 };
1494 
1495 /*
1496  * This class supports the LPM_COMPARE device.
1497  *
1498  * The width of the device is the width of the inputs. If one of the
1499  * inputs is narrower than the other, it is up to the generator to
1500  * make sure all the data pins are properly driven.
1501  *
1502  * The signed() property is true if the comparison is to be done to
1503  * signed arguments. The result is always UNsigned.
1504  *
1505  * NOTE: This is not the same as the device used to support case
1506  * compare. Case comparisons handle Vx and Vz values, whereas this
1507  * device need not.
1508  */
1509 class NetCompare  : public NetNode {
1510 
1511     public:
1512       NetCompare(NetScope*scope, perm_string n, unsigned width);
1513       ~NetCompare();
1514 
1515       unsigned width() const;
1516 
1517       bool get_signed() const;
1518       void set_signed(bool);
1519 
1520       Link& pin_AGB();
1521       Link& pin_AGEB();
1522       Link& pin_AEB();
1523       Link& pin_ANEB();
1524       Link& pin_ALB();
1525       Link& pin_ALEB();
1526 
1527       Link& pin_DataA();
1528       Link& pin_DataB();
1529 
1530       const Link& pin_AGB() const;
1531       const Link& pin_AGEB() const;
1532       const Link& pin_AEB() const;
1533       const Link& pin_ANEB() const;
1534       const Link& pin_ALB() const;
1535       const Link& pin_ALEB() const;
1536 
1537       const Link& pin_DataA() const;
1538       const Link& pin_DataB() const;
1539 
1540       virtual void functor_node(Design*, functor_t*);
1541       virtual void dump_node(ostream&, unsigned ind) const;
1542       virtual bool emit_node(struct target_t*) const;
1543 
1544     private:
1545       unsigned width_;
1546       bool signed_flag_;
1547 };
1548 
1549 
1550 /*
1551  * This node is a means to connect net inputs together to form a wider
1552  * vector. The output (pin 0) is a concatenation of the input vectors,
1553  * with pin-1 at the LSB, pin-2 next, and so on. This node is most
1554  * like the NetLogic node, as it has one output at pin 0 and the
1555  * remaining pins are the input that are combined to make the
1556  * output. It is separated out because it it generally a special case
1557  * for the code generators.
1558  *
1559  * When constructing the node, the width is the vector_width of the
1560  * output, and the cnt is the number of pins. (the number of input
1561  * vectors.)
1562  */
1563 class NetConcat  : public NetNode {
1564 
1565     public:
1566       NetConcat(NetScope*scope, perm_string n, unsigned wid, unsigned cnt,
1567 		bool transparent_flag = false);
1568       ~NetConcat();
1569 
1570       unsigned width() const;
1571 	// This is true if the concatenation is a transparent
1572 	// concatenation, meaning strengths are passed through as
1573 	// is. In this case, the output strengths of this node will be
1574 	// ignored.
transparent()1575       bool transparent() const { return transparent_; }
1576 
1577       void dump_node(ostream&, unsigned ind) const;
1578       bool emit_node(struct target_t*) const;
1579       void functor_node(Design*des, functor_t*fun);
1580 
1581     private:
1582       unsigned width_;
1583       bool transparent_;
1584 };
1585 
1586 
1587 /*
1588  * This class represents a theoretical (though not necessarily
1589  * practical) integer divider gate. This is not to represent any real
1590  * hardware, but to support the / operator in Verilog, when it shows
1591  * up in structural contexts.
1592  *
1593  * The operands of the operation are the DataA<i> and DataB<i> inputs,
1594  * and the Result<i> output reflects the value DataA/DataB.
1595  */
1596 
1597 class NetDivide  : public NetNode {
1598 
1599     public:
1600       NetDivide(NetScope*scope, perm_string n,
1601 		unsigned width, unsigned wa, unsigned wb);
1602       ~NetDivide();
1603 
1604       unsigned width_r() const;
1605       unsigned width_a() const;
1606       unsigned width_b() const;
1607 
1608       void set_signed(bool);
1609       bool get_signed() const;
1610 
1611       Link& pin_DataA();
1612       Link& pin_DataB();
1613       Link& pin_Result();
1614 
1615       const Link& pin_DataA() const;
1616       const Link& pin_DataB() const;
1617       const Link& pin_Result() const;
1618 
1619       virtual void dump_node(ostream&, unsigned ind) const;
1620       virtual bool emit_node(struct target_t*) const;
1621       virtual void functor_node(Design*des, functor_t*fun);
1622 
1623     private:
1624       unsigned width_r_;
1625       unsigned width_a_;
1626       unsigned width_b_;
1627 
1628       bool signed_flag_;
1629 };
1630 
1631 /*
1632  * This class represents a theoretical (though not necessarily
1633  * practical) integer modulo gate. This is not to represent any real
1634  * hardware, but to support the % operator in Verilog, when it shows
1635  * up in structural contexts.
1636  *
1637  * The operands of the operation are the DataA<i> and DataB<i> inputs,
1638  * and the Result<i> output reflects the value DataA%DataB.
1639  */
1640 
1641 class NetModulo  : public NetNode {
1642 
1643     public:
1644       NetModulo(NetScope*s, perm_string n,
1645 		unsigned width, unsigned wa, unsigned wb);
1646       ~NetModulo();
1647 
1648       unsigned width_r() const;
1649       unsigned width_a() const;
1650       unsigned width_b() const;
1651 
1652       void set_signed(bool);
1653       bool get_signed() const;
1654 
1655       Link& pin_DataA();
1656       Link& pin_DataB();
1657       Link& pin_Result();
1658 
1659       const Link& pin_DataA() const;
1660       const Link& pin_DataB() const;
1661       const Link& pin_Result() const;
1662 
1663       virtual void dump_node(ostream&, unsigned ind) const;
1664       virtual bool emit_node(struct target_t*) const;
1665       virtual void functor_node(Design*des, functor_t*fun);
1666 
1667     private:
1668       unsigned width_r_;
1669       unsigned width_a_;
1670       unsigned width_b_;
1671 
1672       bool signed_flag_;
1673 };
1674 
1675 /*
1676  * This class represents an LPM_FF device. There is no literal gate
1677  * type in Verilog that maps, but gates of this type can be inferred.
1678  */
1679 class NetFF  : public NetNode {
1680 
1681     public:
1682       NetFF(NetScope*s, perm_string n, bool negedge, unsigned vector_width);
1683       ~NetFF();
1684 
1685       bool is_negedge() const;
1686       unsigned width() const;
1687 
1688       Link& pin_Clock();
1689       Link& pin_Enable();
1690       Link& pin_Aset();
1691       Link& pin_Aclr();
1692       Link& pin_Sset();
1693       Link& pin_Sclr();
1694       Link& pin_Data();
1695       Link& pin_Q();
1696 
1697       const Link& pin_Clock() const;
1698       const Link& pin_Enable() const;
1699       const Link& pin_Aset() const;
1700       const Link& pin_Aclr() const;
1701       const Link& pin_Sset() const;
1702       const Link& pin_Sclr() const;
1703       const Link& pin_Data() const;
1704       const Link& pin_Q() const;
1705 
1706       void aset_value(const verinum&val);
1707       const verinum& aset_value() const;
1708 
1709       void sset_value(const verinum&val);
1710       const verinum& sset_value() const;
1711 
1712       virtual void dump_node(ostream&, unsigned ind) const;
1713       virtual bool emit_node(struct target_t*) const;
1714       virtual void functor_node(Design*des, functor_t*fun);
1715 
1716     private:
1717       bool negedge_;
1718       unsigned width_;
1719       verinum aset_value_;
1720       verinum sset_value_;
1721 };
1722 
1723 
1724 /*
1725  * This class represents an LPM_LATCH device. There is no literal gate
1726  * type in Verilog that maps, but gates of this type can be inferred.
1727  */
1728 class NetLatch  : public NetNode {
1729 
1730     public:
1731       NetLatch(NetScope*s, perm_string n, unsigned vector_width);
1732       ~NetLatch();
1733 
1734       unsigned width() const;
1735 
1736       Link& pin_Enable();
1737       Link& pin_Data();
1738       Link& pin_Q();
1739 
1740       const Link& pin_Enable() const;
1741       const Link& pin_Data() const;
1742       const Link& pin_Q() const;
1743 
1744       virtual void dump_node(ostream&, unsigned ind) const;
1745       virtual bool emit_node(struct target_t*) const;
1746       virtual void functor_node(Design*des, functor_t*fun);
1747 
1748     private:
1749       unsigned width_;
1750 };
1751 
1752 /*
1753  * This class implements a basic LPM_MULT combinational multiplier. It
1754  * is used as a structural representation of the * operator. The
1755  * device has inputs A and B and output Result all with independent
1756  * widths.
1757  *
1758  * NOTE: Check this width thing. I think that the independence of the
1759  * widths is not necessary or even useful.
1760  */
1761 class NetMult  : public NetNode {
1762 
1763     public:
1764       NetMult(NetScope*sc, perm_string n, unsigned width,
1765 	      unsigned wa, unsigned wb);
1766       ~NetMult();
1767 
1768       bool get_signed() const;
1769       void set_signed(bool);
1770 
1771 	// Get the width of the device bussed inputs. There are these
1772 	// parameterized widths:
1773       unsigned width_r() const; // Result
1774       unsigned width_a() const; // DataA
1775       unsigned width_b() const; // DataB
1776 
1777       Link& pin_DataA();
1778       Link& pin_DataB();
1779       Link& pin_Result();
1780 
1781       const Link& pin_DataA() const;
1782       const Link& pin_DataB() const;
1783       const Link& pin_Result() const;
1784 
1785       virtual void dump_node(ostream&, unsigned ind) const;
1786       virtual bool emit_node(struct target_t*) const;
1787       virtual void functor_node(Design*des, functor_t*fun);
1788 
1789     private:
1790       bool signed_;
1791       unsigned width_r_;
1792       unsigned width_a_;
1793       unsigned width_b_;
1794 };
1795 
1796 
1797 /*
1798  * This class represents an LPM_MUX device. This device has some
1799  * number of Result points (the width of the device) and some number
1800  * of input choices. There is also a selector of some width. The
1801  * parameters are:
1802  *
1803  *      width  -- Width of the result and each possible Data input
1804  *      size   -- Number of Data input (each of width)
1805  *      selw   -- Width in bits of the select input
1806  *
1807  * All the data inputs must have the same type, and are the type of
1808  * the result. The actual type does not matter, as the mux does not
1809  * process data, just selects alternatives.
1810  *
1811  * The select input must be an integral type of some sort. Not real.
1812  */
1813 class NetMux  : public NetNode {
1814 
1815     public:
1816       NetMux(NetScope*scope, perm_string n,
1817 	     unsigned width, unsigned size, unsigned selw);
1818       ~NetMux();
1819 
1820       unsigned width() const;
1821       unsigned size() const;
1822       unsigned sel_width() const;
1823 
1824       Link& pin_Result();
1825       Link& pin_Data(unsigned si);
1826       Link& pin_Sel();
1827 
1828       const Link& pin_Result() const;
1829       const Link& pin_Data(unsigned) const;
1830       const Link& pin_Sel() const;
1831 
1832       virtual void dump_node(ostream&, unsigned ind) const;
1833       virtual bool emit_node(struct target_t*) const;
1834       virtual void functor_node(Design*des, functor_t*fun);
1835 
1836     private:
1837       unsigned width_;
1838       unsigned size_;
1839       unsigned swidth_;
1840 };
1841 
1842 
1843 /*
1844  * This class implements a basic LPM_POW combinational power. It
1845  * is used as a structural representation of the ** operator. The
1846  * device has inputs A and B and output Result all with independent
1847  * widths.
1848  *
1849  * NOTE: Check this width thing. I think that the independence of the
1850  * widths is not necessary or even useful.
1851  */
1852 class NetPow  : public NetNode {
1853 
1854     public:
1855       NetPow(NetScope*sc, perm_string n, unsigned width,
1856 	      unsigned wa, unsigned wb);
1857       ~NetPow();
1858 
1859       bool get_signed() const;
1860       void set_signed(bool);
1861 
1862 	// Get the width of the device bussed inputs. There are these
1863 	// parameterized widths:
1864       unsigned width_r() const; // Result
1865       unsigned width_a() const; // DataA
1866       unsigned width_b() const; // DataB
1867 
1868       Link& pin_DataA();
1869       Link& pin_DataB();
1870       Link& pin_Result();
1871 
1872       const Link& pin_DataA() const;
1873       const Link& pin_DataB() const;
1874       const Link& pin_Result() const;
1875 
1876       virtual void dump_node(ostream&, unsigned ind) const;
1877       virtual bool emit_node(struct target_t*) const;
1878       virtual void functor_node(Design*des, functor_t*fun);
1879 
1880     private:
1881       bool signed_;
1882       unsigned width_r_;
1883       unsigned width_a_;
1884       unsigned width_b_;
1885 };
1886 
1887 
1888 /*
1889  * The NetReplicate node takes a vector input and makes it into a larger
1890  * vector by repeating the input vector some number of times. The
1891  * repeat count is a fixed value. This is just like the repeat
1892  * concatenation of Verilog: {<repeat>{<vector>}}.
1893  *
1894  * When constructing this node, the wid is the vector width of the
1895  * output, and the rpt is the repeat count. The wid must be an even
1896  * multiple of the cnt, and wid/cnt is the expected input width.
1897  *
1898  * The device has exactly 2 pins: pin(0) is the output and pin(1) the
1899  * input.
1900  */
1901 class NetReplicate  : public NetNode {
1902 
1903     public:
1904       NetReplicate(NetScope*scope, perm_string n, unsigned wid, unsigned rpt);
1905       ~NetReplicate();
1906 
1907       unsigned width() const;
1908       unsigned repeat() const;
1909 
1910       void dump_node(ostream&, unsigned ind) const;
1911       bool emit_node(struct target_t*) const;
1912 
1913     private:
1914       unsigned width_;
1915       unsigned repeat_;
1916 };
1917 
1918 /*
1919  * This node represents the call of a user defined function in a
1920  * structural context. The pin count is the same as the port count,
1921  * with pin0 the return value.
1922  */
1923 class NetUserFunc  : public NetNode {
1924 
1925     public:
1926       NetUserFunc(NetScope*s, perm_string n, NetScope*def, NetEvWait*trigger__);
1927       ~NetUserFunc();
1928 
1929       ivl_variable_type_t data_type(unsigned port) const;
1930       unsigned port_width(unsigned port) const;
1931 
1932       const NetScope* def() const;
1933 
trigger()1934       const NetEvWait* trigger() const { return trigger_; }
1935 
1936       virtual void dump_node(ostream&, unsigned ind) const;
1937       virtual bool emit_node(struct target_t*) const;
1938 
1939     private:
1940       NetScope*def_;
1941       NetEvWait*trigger_;
1942 };
1943 
1944 /*
1945  * The number of ports includes the return value, so will always be at
1946  * least 1.
1947  */
1948 class NetSysFunc  : public NetNode {
1949 
1950     public:
1951       NetSysFunc(NetScope*s, perm_string n,
1952 		 const struct sfunc_return_type*def,
1953 		 unsigned ports, NetEvWait*trigger__);
1954       ~NetSysFunc();
1955 
1956       ivl_variable_type_t data_type() const;
1957       unsigned vector_width() const;
1958       const char* func_name() const;
1959 
trigger()1960       const NetEvWait* trigger() const { return trigger_; }
1961 
1962       virtual void dump_node(ostream&, unsigned ind) const;
1963       virtual bool emit_node(struct target_t*) const;
1964 
1965     private:
1966       const struct sfunc_return_type*def_;
1967       NetEvWait*trigger_;
1968 };
1969 
1970 class NetTran  : public NetNode, public IslandBranch {
1971 
1972     public:
1973 	// Tran devices other than TRAN_VP
1974       NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type,
1975               unsigned wid);
1976 	// Create a TRAN_VP
1977       NetTran(NetScope*scope, perm_string n, unsigned wid,
1978 	      unsigned part, unsigned off);
1979       ~NetTran();
1980 
type()1981       ivl_switch_type_t type() const { return type_; }
1982 
1983 	// These are only used for IVL_SW_TRAN_PV
1984       unsigned vector_width() const;
1985       unsigned part_width() const;
1986       unsigned part_offset() const;
1987 
1988       virtual void dump_node(ostream&, unsigned ind) const;
1989       virtual bool emit_node(struct target_t*) const;
1990 
1991     private:
1992       ivl_switch_type_t type_;
1993       unsigned wid_;
1994       unsigned part_;
1995       unsigned off_;
1996 };
1997 
1998 /* =========
1999  * There are cases where expressions need to be represented. The
2000  * NetExpr class is the root of a hierarchy that serves that purpose.
2001  *
2002  * The expr_width() is the width of the expression, which is calculated
2003  * before the expression is elaborated.
2004  */
2005 class NetExpr  : public LineInfo {
2006     public:
2007       explicit NetExpr(unsigned w =0);
2008       explicit NetExpr(ivl_type_t t);
2009       virtual ~NetExpr() =0;
2010 
2011       virtual void expr_scan(struct expr_scan_t*) const =0;
2012       virtual void dump(ostream&) const;
2013 
2014 	// This is the advanced description of the type. I think I
2015 	// want to replace the other type description members with
2016 	// this single method. The default for this method returns
2017 	// nil.
2018       ivl_type_t net_type() const;
2019 
2020 	// Expressions have type.
2021       virtual ivl_variable_type_t expr_type() const;
2022 
2023 	// How wide am I?
expr_width()2024       unsigned expr_width() const { return width_; }
2025 
2026 	// This method returns true if the expression is
2027 	// signed. Unsigned expressions return false.
has_sign()2028       bool has_sign() const { return signed_flag_; }
2029       virtual void cast_signed(bool flag);
2030 
2031 	// This returns true if the expression has a definite
2032 	// width. This is generally true, but in some cases the
2033 	// expression is amorphous and desires a width from its
2034 	// environment. For example, 'd5 has indefinite width, but
2035 	// 5'd5 has a definite width.
2036 
2037 	// This method is only really used within concatenation
2038 	// expressions to check validity.
2039       virtual bool has_width() const;
2040 
2041 	// Return the enumeration set that defines this expressions
2042 	// enumeration type, or return nil if the expression is not
2043 	// part of the enumeration.
2044       virtual const netenum_t*enumeration() const;
2045 
2046 	// This method evaluates the expression and returns an
2047 	// equivalent expression that is reduced as far as compile
2048 	// time knows how. Essentially, this is designed to fold
2049 	// constants.
2050       virtual NetExpr*eval_tree();
2051 
2052 	// Make a duplicate of myself, and subexpressions if I have
2053 	// any. This is a deep copy operation.
2054       virtual NetExpr*dup_expr() const =0;
2055 
2056 	// Evaluate the expression at compile time, a la within a
2057 	// constant function. This is used by the constant function
2058 	// evaluation function code, and the return value is an
2059 	// allocated constant, or nil if the expression cannot be
2060 	// evaluated for any reason.
2061       virtual NetExpr*evaluate_function(const LineInfo&loc,
2062 					map<perm_string,LocalVar>&ctx) const;
2063 
2064 	// Get the Nexus that are the input to this
2065 	// expression. Normally this descends down to the reference to
2066 	// a signal that reads from its input.
2067       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2068                                   bool nested_func = false) const =0;
2069 
2070 	// Return a version of myself that is structural. This is used
2071 	// for converting expressions to gates. The arguments are:
2072 	//
2073 	//  des, scope:  The context where this work is done
2074 	//
2075         //  root: The root expression of which this expression is a part.
2076         //
2077 	//  rise/fall/decay: Attach these delays to the driver for the
2078 	//                   expression output.
2079 	//
2080 	//  drive0/drive1: Attach these strengths to the driver for
2081 	//                 the expression output.
2082       virtual NetNet*synthesize(Design*des, NetScope*scope, NetExpr*root);
2083 
2084     protected:
expr_width(unsigned wid)2085       void expr_width(unsigned wid) { width_ = wid; }
cast_signed_base_(bool flag)2086       void cast_signed_base_(bool flag) { signed_flag_ = flag; }
2087 
2088     private:
2089       ivl_type_t net_type_;
2090       unsigned width_;
2091       bool signed_flag_;
2092 
2093     private: // not implemented
2094       NetExpr(const NetExpr&);
2095       NetExpr& operator=(const NetExpr&);
2096 };
2097 
2098 class NetEArrayPattern  : public NetExpr {
2099 
2100     public:
2101       NetEArrayPattern(ivl_type_t lv_type, std::vector<NetExpr*>&items);
2102       ~NetEArrayPattern();
2103 
item_size()2104       inline size_t item_size() const { return items_.size(); }
item(size_t idx)2105       const NetExpr* item(size_t idx) const { return items_[idx]; }
2106 
2107       void expr_scan(struct expr_scan_t*) const;
2108       void dump(ostream&) const;
2109 
2110       NetEArrayPattern* dup_expr() const;
2111       NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2112                           bool nested_func = false) const;
2113 
2114     private:
2115       std::vector<NetExpr*> items_;
2116 };
2117 
2118 /*
2119  * The expression constant is slightly special, and is sometimes
2120  * returned from other classes that can be evaluated at compile
2121  * time. This class represents constant values in expressions.
2122  */
2123 class NetEConst  : public NetExpr {
2124 
2125     public:
2126       explicit NetEConst(const verinum&val);
2127       ~NetEConst();
2128 
2129       const verinum&value() const;
2130 
2131       virtual void cast_signed(bool flag);
2132       virtual bool has_width() const;
2133       virtual ivl_variable_type_t expr_type() const;
2134 
2135         /* This method allows the constant value to be converted
2136            to an unsized value. This is used after evaluating a
2137            unsized constant expression. */
2138       void trim();
2139 
2140       virtual void expr_scan(struct expr_scan_t*) const;
2141       virtual void dump(ostream&) const;
2142 
2143       virtual NetEConst* dup_expr() const;
2144       virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
2145       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2146                                   bool nested_func = false) const;
2147 
2148       virtual NetExpr*evaluate_function(const LineInfo&loc,
2149 					map<perm_string,LocalVar>&ctx) const;
2150 
2151     private:
2152       verinum value_;
2153 };
2154 
2155 class NetEConstEnum  : public NetEConst {
2156 
2157     public:
2158       explicit NetEConstEnum(Definitions*scope, perm_string name,
2159 			     const netenum_t*enum_set, const verinum&val);
2160       ~NetEConstEnum();
2161 
2162       perm_string name() const;
2163       const netenum_t*enumeration() const;
2164 
2165       virtual void expr_scan(struct expr_scan_t*) const;
2166       virtual void dump(ostream&) const;
2167 
2168       virtual NetEConstEnum* dup_expr() const;
2169 
2170     private:
2171       Definitions*scope_;
2172       const netenum_t*enum_set_;
2173       perm_string name_;
2174 };
2175 
2176 class NetEConstParam  : public NetEConst {
2177 
2178     public:
2179       explicit NetEConstParam(NetScope*scope, perm_string name,
2180 			      const verinum&val);
2181       ~NetEConstParam();
2182 
2183       perm_string name() const;
2184       const NetScope*scope() const;
2185 
2186       virtual void expr_scan(struct expr_scan_t*) const;
2187       virtual void dump(ostream&) const;
2188 
2189       virtual NetEConstParam* dup_expr() const;
2190 
2191     private:
2192       NetScope*scope_;
2193       perm_string name_;
2194 };
2195 
2196 /*
2197  * This class represents a constant real value.
2198  */
2199 class NetECReal  : public NetExpr {
2200 
2201     public:
2202       explicit NetECReal(const verireal&val);
2203       ~NetECReal();
2204 
2205       const verireal&value() const;
2206 
2207 	// This type has no self-determined width. This is false.
2208       virtual bool has_width() const;
2209 
2210 	// The type of this expression is ET_REAL
2211       ivl_variable_type_t expr_type() const;
2212 
2213       virtual void expr_scan(struct expr_scan_t*) const;
2214       virtual void dump(ostream&) const;
2215 
2216       virtual NetECReal* dup_expr() const;
2217       virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*);
2218       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2219                                   bool nested_func = false) const;
2220 
2221       virtual NetExpr*evaluate_function(const LineInfo&loc,
2222 					map<perm_string,LocalVar>&ctx) const;
2223 
2224     private:
2225       verireal value_;
2226 };
2227 
2228 class NetECRealParam  : public NetECReal {
2229 
2230     public:
2231       explicit NetECRealParam(NetScope*scope, perm_string name,
2232 			      const verireal&val);
2233       ~NetECRealParam();
2234 
2235       perm_string name() const;
2236       const NetScope*scope() const;
2237 
2238       virtual void expr_scan(struct expr_scan_t*) const;
2239       virtual void dump(ostream&) const;
2240 
2241       virtual NetECRealParam* dup_expr() const;
2242 
2243     private:
2244       NetScope*scope_;
2245       perm_string name_;
2246 };
2247 
2248 /*
2249  * The NetPartSelect device represents a netlist part select of a
2250  * signal vector. Pin 0 is a vector that is a part select of pin 1,
2251  * which connected to the NetNet of the signal being selected from.
2252  *
2253  * The part to be selected is the canonical (0-based) offset and the
2254  * specified number of bits (wid).
2255  *
2256  * If the offset is non-constant, then pin(2) is the input vector for
2257  * the selector. If this pin is present, then use the non-constant
2258  * selector as the input.
2259  *
2260  * The NetPartSelect can be output from the signal (i.e. reading a
2261  * part) or input into the signal. The DIR method gives the type of
2262  * the node.
2263  *
2264  * VP (Vector-to-Part)
2265  *  Output pin 0 is the part select, and input pin 1 is connected to
2266  *  the NetNet object.
2267  *
2268  * PV (Part-to-Vector)
2269  *  Output pin 1 is connected to the NetNet, and input pin 0 is the
2270  *  part select. In this case, the node is driving the NetNet.
2271  *
2272  * Note that whatever the direction that data is intended to flow,
2273  * pin-0 is the part select and pin-1 is connected to the NetNet.
2274  */
2275 class NetPartSelect  : public NetNode {
2276 
2277     public:
2278 	// enum for the device direction
2279       enum dir_t { VP, PV};
2280 
2281       explicit NetPartSelect(NetNet*sig,
2282 			     unsigned off, unsigned wid, dir_t dir,
2283 			     bool signed_flag__ = false);
2284       explicit NetPartSelect(NetNet*sig, NetNet*sel,
2285 			     unsigned wid, bool signed_flag__ = false);
2286       ~NetPartSelect();
2287 
2288       unsigned base()  const;
2289       unsigned width() const;
dir()2290       inline dir_t dir()   const { return dir_; }
2291 	/* Is the select signal signed? */
signed_flag()2292       inline bool signed_flag() const { return signed_flag_; }
2293 
2294       virtual void dump_node(ostream&, unsigned ind) const;
2295       bool emit_node(struct target_t*tgt) const;
2296       virtual void functor_node(Design*des, functor_t*fun);
2297 
2298     private:
2299       unsigned off_;
2300       unsigned wid_;
2301       dir_t    dir_;
2302       bool signed_flag_;
2303 };
2304 
2305 /*
2306  * This device supports simple substitution of a part within a wider
2307  * vector. For example, this:
2308  *
2309  *      wire [7:0] foo = NetSubstitute(bar, bat, off);
2310  *
2311  * means that bar is a vector the same width as foo, bat is a narrower
2312  * vector. The off is a constant offset into the bar vector. This
2313  * looks something like this:
2314  *
2315  *      foo = bar;
2316  *      foo[off +: <width_of_bat>] = bat;
2317  *
2318  * There is no direct way in Verilog to express this (as a single
2319  * device), it instead turns up in certain synthesis situation,
2320  * i.e. the example above.
2321  */
2322 class NetSubstitute : public NetNode {
2323 
2324     public:
2325       NetSubstitute(NetNet*sig, NetNet*sub, unsigned wid, unsigned off);
2326       ~NetSubstitute();
2327 
width()2328       inline unsigned width() const { return wid_; }
base()2329       inline unsigned base() const  { return off_; }
2330 
2331       virtual void dump_node(ostream&, unsigned ind) const;
2332       virtual bool emit_node(struct target_t*tgt) const;
2333       virtual void functor_node(Design*des, functor_t*fun);
2334 
2335     private:
2336       unsigned wid_;
2337       unsigned off_;
2338 };
2339 
2340 /*
2341  * The NetBUFZ is a magic device that represents the continuous
2342  * assign, with the output being the target register and the input
2343  * the logic that feeds it. The netlist preserves the directional
2344  * nature of that assignment with the BUFZ. The target may elide it if
2345  * that makes sense for the technology.
2346  *
2347  * A NetBUFZ is transparent if strengths are passed through it without
2348  * change. A NetBUFZ is non-transparent if values other than HiZ are
2349  * converted to the strength of the output.
2350  */
2351 class NetBUFZ  : public NetNode {
2352 
2353     public:
2354       explicit NetBUFZ(NetScope*s, perm_string n, unsigned wid, bool transp);
2355       ~NetBUFZ();
2356 
2357       unsigned width() const;
transparent()2358       bool transparent() const { return transparent_; }
2359 
2360       virtual void dump_node(ostream&, unsigned ind) const;
2361       virtual bool emit_node(struct target_t*) const;
2362 
2363     private:
2364       unsigned width_;
2365       bool transparent_;
2366 };
2367 
2368 /*
2369  * This node is used to represent case equality in combinational
2370  * logic. Although this is not normally synthesizable, it makes sense
2371  * to support an abstract gate that can compare x and z. This node
2372  * always generates a single bit result, no matter the width of the
2373  * input. The elaboration, btw, needs to make sure the input widths
2374  * match.
2375  *
2376  * The case compare can be generated to handle ===/!==, or also
2377  * to test guards in the case/casez/casex statements.
2378  *
2379  * This pins are assigned as:
2380  *
2381  *     0   -- Output (always returns 0 or 1)
2382  *     1   -- Input
2383  *     2   -- Input (wildcard input for EQX and EQZ variants)
2384  */
2385 class NetCaseCmp  : public NetNode {
2386 
2387     public:
2388       enum kind_t {
2389 	    EEQ, // ===
2390 	    NEQ, // !==
2391 	    WEQ, // ==?
2392 	    WNE, // !=?
2393 	    XEQ, // casex guard tests
2394 	    ZEQ  // casez guard tests
2395       };
2396 
2397     public:
2398       explicit NetCaseCmp(NetScope*s, perm_string n, unsigned wid, kind_t eeq);
2399       ~NetCaseCmp();
2400 
2401       unsigned width() const;
2402 	// What kind of case compare?
kind()2403       inline kind_t kind() const { return kind_; }
2404 
2405       virtual void dump_node(ostream&, unsigned ind) const;
2406       virtual bool emit_node(struct target_t*) const;
2407 
2408     private:
2409       unsigned width_;
2410       const kind_t kind_;
2411 };
2412 
2413 extern ostream& operator << (ostream&fd, NetCaseCmp::kind_t that);
2414 
2415 /* NOTE: This class should be replaced with the NetLiteral class
2416  * below, that is more general in that it supports different types of
2417  * values.
2418  *
2419  * This class represents instances of the LPM_CONSTANT device. The
2420  * node has only outputs and a constant value. The width is available
2421  * by getting the pin_count(), and the value bits are available one at
2422  * a time. There is no meaning to the aggregation of bits to form a
2423  * wide NetConst object, although some targets may have an easier time
2424  * detecting interesting constructs if they are combined.
2425  */
2426 class NetConst  : public NetNode {
2427 
2428     public:
2429       explicit NetConst(NetScope*s, perm_string n, verinum::V v);
2430       explicit NetConst(NetScope*s, perm_string n, const verinum&val);
2431       ~NetConst();
2432 
value(void)2433       inline const verinum&value(void) const { return value_; }
2434       verinum::V value(unsigned idx) const;
width()2435       inline unsigned width() const { return value_.len(); }
is_string()2436       inline bool is_string() const { return value_.is_string(); }
2437 
2438       virtual bool emit_node(struct target_t*) const;
2439       virtual void functor_node(Design*, functor_t*);
2440       virtual void dump_node(ostream&, unsigned ind) const;
2441 
2442     private:
2443       verinum value_;
2444 };
2445 
2446 /*
2447  * This class represents instances of the LPM_CONSTANT device. The
2448  * node has only outputs and a constant value. The width is available
2449  * by getting the pin_count(), and the value bits are available one at
2450  * a time. There is no meaning to the aggregation of bits to form a
2451  * wide NetConst object, although some targets may have an easier time
2452  * detecting interesting constructs if they are combined.
2453  */
2454 class NetLiteral  : public NetNode {
2455 
2456     public:
2457 	// A read-valued literal.
2458       explicit NetLiteral(NetScope*s, perm_string n, const verireal&val);
2459       ~NetLiteral();
2460 
2461       ivl_variable_type_t data_type() const;
2462 
2463       const verireal& value_real() const;
2464 
2465       virtual bool emit_node(struct target_t*) const;
2466       virtual void functor_node(Design*, functor_t*);
2467       virtual void dump_node(ostream&, unsigned ind) const;
2468 
2469     private:
2470       verireal real_;
2471 };
2472 
2473 /*
2474  * This class represents all manner of logic gates. Pin 0 is OUTPUT and
2475  * all the remaining pins are INPUT. The BUFIF[01] gates have the
2476  * more specific pinout as follows:
2477  *
2478  *     bufif<N>
2479  *       0  -- output
2480  *       1  -- input data
2481  *       2  -- enable
2482  *
2483  * The pullup and pulldown gates have no inputs at all, and pin0 is
2484  * the output 1 or 0, depending on the gate type. It is the strength
2485  * of that value that is important.
2486  *
2487  * All these devices process vectors bitwise, so each bit can be
2488  * logically separated. The exception is the CONCAT gate, which is
2489  * really an abstract gate that takes the inputs and turns it into a
2490  * vector of bits.
2491  */
2492 class NetLogic  : public NetNode {
2493 
2494     public:
2495       enum TYPE { AND, BUF, BUFIF0, BUFIF1, CMOS, EQUIV, IMPL, NAND, NMOS,
2496 		  NOR, NOT, NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RCMOS,
2497 		  RNMOS, RPMOS, PMOS, XNOR, XOR };
2498 
2499       explicit NetLogic(NetScope*s, perm_string n, unsigned pins,
2500 			TYPE t, unsigned wid, bool is_cassign__=false);
2501 
2502       TYPE type() const;
2503       unsigned width() const;
2504       bool is_cassign() const;
2505 
2506       virtual void dump_node(ostream&, unsigned ind) const;
2507       virtual bool emit_node(struct target_t*) const;
2508       virtual void functor_node(Design*, functor_t*);
2509 
2510     private:
2511       TYPE type_;
2512       unsigned width_;
2513       bool is_cassign_;
2514 };
2515 
2516 /*
2517  * This class represents a structural sign extension. The pin-0 is a
2518  * vector of the input pin-1 sign-extended. The input is taken to be
2519  * signed. This generally matches a hardware implementation of
2520  * replicating the top bit enough times to create the desired output
2521  * width.
2522  */
2523 class NetSignExtend  : public NetNode {
2524 
2525     public:
2526       explicit NetSignExtend(NetScope*s, perm_string n, unsigned wid);
2527       ~NetSignExtend();
2528 
2529       unsigned width() const;
2530 
2531       virtual void dump_node(ostream&, unsigned ind) const;
2532       virtual bool emit_node(struct target_t*) const;
2533       virtual void functor_node(Design*, functor_t*);
2534 
2535     private:
2536       unsigned width_;
2537 };
2538 
2539 /*
2540  * This class represents *reduction* logic operators. Certain boolean
2541  * logic operators have reduction forms which take in a vector and
2542  * return a single bit that is calculated by applying the logic
2543  * operation through the width of the input vector. These correspond
2544  * to reduction unary operators in Verilog.
2545  */
2546 class NetUReduce  : public NetNode {
2547 
2548     public:
2549       enum TYPE {NONE, AND, OR, XOR, NAND, NOR, XNOR};
2550 
2551       NetUReduce(NetScope*s, perm_string n, TYPE t, unsigned wid);
2552 
2553       TYPE type() const;
2554       unsigned width() const;
2555 
2556       virtual void dump_node(ostream&, unsigned ind) const;
2557       virtual bool emit_node(struct target_t*) const;
2558       virtual void functor_node(Design*, functor_t*);
2559 
2560     private:
2561       TYPE type_;
2562       unsigned width_;
2563 };
2564 
2565 /*
2566  * The UDP is a User Defined Primitive from the Verilog source. Do not
2567  * expand it out any further than this in the netlist, as this can be
2568  * used to represent target device primitives.
2569  *
2570  * The UDP can be combinational or sequential. The sequential UDP
2571  * includes the current output in the truth table, and supports edges,
2572  * whereas the combinational does not and is entirely level sensitive.
2573  * In any case, pin 0 is an output, and all the remaining pins are
2574  * inputs.
2575  *
2576  * Set_table takes as input a string with one letter per pin. The
2577  * parser translates the written sequences to one of these. The
2578  * valid characters are:
2579  *
2580  *      0, 1, x  -- The levels
2581  *      r   -- (01)
2582  *      R   -- (x1)
2583  *      f   -- (10)
2584  *      F   -- (x0)
2585  *      P   -- (0x)
2586  *      N   -- (1x)
2587  *
2588  * It also takes one of the following glob letters to represent more
2589  * than one item.
2590  *
2591  *      p   -- 01, 0x or x1 // check this with the lexer
2592  *      n   -- 10, 1x or x0 // check this with the lexer
2593  *      ?   -- 0, 1, or x
2594  *      *   -- any edge
2595  *      +   -- 01 or x1
2596  *      _   -- 10 or x0  (Note that this is not the output '-'.)
2597  *      %   -- 0x or 1x
2598  *
2599  * SEQUENTIAL
2600  * These objects have a single bit of memory. The logic table includes
2601  * an entry for the current value, and allows edges on the inputs. In
2602  * canonical form, only the entries that generate 0, 1 or - (no change)
2603  * are listed.
2604  *
2605  * COMBINATIONAL
2606  * The logic table is a map between the input levels and the
2607  * output. Each input pin can have the value 0, 1 or x and the output
2608  * can have the values 0 or 1. If the input matches nothing, the
2609  * output is x. In canonical form, only the entries that generate 0 or
2610  * 1 are listed.
2611  *
2612  */
2613 
2614 class NetUDP  : public NetNode {
2615 
2616     public:
2617       explicit NetUDP(NetScope*s, perm_string n, unsigned pins, PUdp*u);
2618 
2619       virtual bool emit_node(struct target_t*) const;
2620       virtual void dump_node(ostream&, unsigned ind) const;
2621 
2622 	/* Use these methods to scan the truth table of the
2623 	   device. "first" returns the first item in the table, and
2624 	   "next" returns the next item in the table. The method will
2625 	   return false when the scan is done. */
2626       bool first(string&inp, char&out) const;
2627       bool next(string&inp, char&out) const;
rows()2628       unsigned rows() const { return udp->tinput.count(); }
2629 
nin()2630       unsigned nin() const { return pin_count()-1; }
is_sequential()2631       bool is_sequential() const { return udp->sequential; }
udp_name()2632       perm_string udp_name() const { return udp->name_; }
udp_file()2633       perm_string udp_file() const { return udp->get_file(); }
udp_lineno()2634       unsigned udp_lineno() const { return udp->get_lineno(); }
2635       char get_initial() const;
2636 
2637       unsigned port_count() const;
2638       string port_name(unsigned idx) const;
2639 
2640     private:
2641       mutable unsigned table_idx;
2642       PUdp *udp;
2643 };
2644 
2645 enum DelayType { NO_DELAY, ZERO_DELAY, POSSIBLE_DELAY, DEFINITE_DELAY };
2646 
2647 /* =========
2648  * A process is a behavioral-model description. A process is a
2649  * statement that may be compound. The various statement types may
2650  * refer to places in a netlist (by pointing to nodes) but is not
2651  * linked into the netlist. However, elaborating a process may cause
2652  * special nodes to be created to handle things like events.
2653  */
2654 class NetProc : public virtual LineInfo {
2655 
2656     public:
2657       explicit NetProc();
2658       virtual ~NetProc();
2659 
2660 	// Find the nexa that are input by the statement. This is used
2661 	// for example by @* to find the inputs to the process for the
2662 	// sensitivity list.
2663       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2664                                   bool nested_func = false) const;
2665 
2666 	// Find the nexa that are set by the statement. Add the output
2667 	// values to the set passed as a parameter.
2668       virtual void nex_output(NexusSet&);
2669 
2670 	// This method is called to emit the statement to the
2671 	// target. The target returns true if OK, false for errors.
2672       virtual bool emit_proc(struct target_t*) const;
2673 
2674 	// This method is used by the NetFuncDef object to evaluate a
2675 	// constant function at compile time. The loc is the location
2676 	// of the function call, and is used for error messages. The
2677 	// ctx is a map of name to expression. This is for mapping
2678 	// identifiers to values. The function returns true if the
2679 	// processing succeeds, or false otherwise.
2680       virtual bool evaluate_function(const LineInfo&loc,
2681 				     map<perm_string,LocalVar>&ctx) const;
2682 
2683 	// This method is called by functors that want to scan a
2684 	// process in search of matchable patterns.
2685       virtual int match_proc(struct proc_match_t*);
2686 
2687 	// Return true if this represents the root of a combinational
2688 	// process. Most process types are not.
2689       virtual bool is_asynchronous();
2690 
2691 	// Return true if this represents the root of a synchronous
2692 	// process. Most process types are not.
2693       virtual bool is_synchronous();
2694 
2695 	// Synthesize as asynchronous logic, and return true on success.
2696 	//
2697 	// nex_map holds the set of nexuses that are driven by this
2698 	// process, nex_out holds the accumulated outputs from this and
2699 	// preceding sequential processes (i.e statements in the same
2700 	// block), enables holds the accumulated clock/gate enables,
2701 	// and bitmasks holds the accumulated masks that flag which bits
2702 	// are unconditionally driven (i.e. driven by every clause in
2703 	// every statement). On output, the values passed in to nex_out,
2704 	// enables, and bitmasks may either be merged with or replaced
2705 	// by the values originating from this process, depending on the
2706 	// type of statement this process represents.
2707 	//
2708 	// The clock/gate enables generated by synthesis operate at a
2709 	// vector level (i.e. they are asserted if any bit(s) in the
2710 	// vector are driven).
2711       typedef vector<bool> mask_t;
2712       virtual bool synth_async(Design*des, NetScope*scope,
2713 			       NexusSet&nex_map, NetBus&nex_out,
2714 			       NetBus&enables, vector<mask_t>&bitmasks);
2715 
2716 	// Synthesize as synchronous logic, and return true on success.
2717 	// That means binding the outputs to the data port of a FF, and
2718 	// the event inputs to a FF clock. Only some key NetProc sub-types
2719 	// that have specific meaning in synchronous statements. The
2720 	// remainder reduce to a call to synth_async that connects the
2721 	// output to the Data input of the FF.
2722 	//
2723 	// The nex_map, nex_out, ff_ce, and bitmasks arguments serve
2724 	// the same purpose as in the synth_async method (where ff_ce
2725 	// is equivalent to enables). The events argument is filled
2726 	// in by the NetEvWait implementation of this method with the
2727 	// probes that it does not itself pick off as a clock. These
2728 	// events should be picked off by e.g. condit statements as
2729 	// asynchronous set/reset inputs to the flipflop being generated.
2730       virtual bool synth_sync(Design*des, NetScope*scope,
2731 			      bool&ff_negedge,
2732 			      NetNet*ff_clock, NetBus&ff_ce,
2733 			      NetBus&ff_aclr,  NetBus&ff_aset,
2734 			      vector<verinum>&ff_aset_value,
2735 			      NexusSet&nex_map, NetBus&nex_out,
2736 			      vector<mask_t>&bitmasks,
2737 			      const std::vector<NetEvProbe*>&events);
2738 
2739       virtual void dump(ostream&, unsigned ind) const;
2740 
2741 	// Recursively checks to see if there is delay in this element.
2742       virtual DelayType delay_type(bool print_delay=false) const;
2743 	// Check to see if the item is synthesizable.
2744       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
2745 
2746     protected:
2747       bool synth_async_block_substatement_(Design*des, NetScope*scope,
2748 					   NexusSet&nex_map,
2749 					   NetBus&nex_out,
2750 					   NetBus&enables,
2751 					   vector<mask_t>&bitmasks,
2752 					   NetProc*substmt);
2753     private:
2754       friend class NetBlock;
2755       NetProc*next_;
2756 
2757     private: // not implemented
2758       NetProc(const NetProc&);
2759       NetProc& operator= (const NetProc&);
2760 };
2761 
2762 class NetAlloc  : public NetProc {
2763 
2764     public:
2765       explicit NetAlloc(NetScope*);
2766       ~NetAlloc();
2767 
2768       const string name() const;
2769 
2770       const NetScope* scope() const;
2771 
2772       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2773                                   bool nested_func = false) const;
2774       virtual void nex_output(NexusSet&);
2775       virtual bool emit_proc(struct target_t*) const;
2776       virtual void dump(ostream&, unsigned ind) const;
2777 
2778     private:
2779       NetScope*scope_;
2780 };
2781 
2782 /*
2783  * Procedural assignment is broken into a suite of classes. These
2784  * classes represent the various aspects of the assignment statement
2785  * in behavioral code. (The continuous assignment is *not*
2786  * represented here.)
2787  *
2788  * The NetAssignBase carries the common aspects of an assignment,
2789  * including the r-value. This class has no cares of blocking vs
2790  * non-blocking, however it carries nearly all the other properties
2791  * of the assignment statement. It is abstract because it does not
2792  * differentiate the virtual behaviors.
2793  *
2794  * The NetAssign and NetAssignNB classes are the concrete classes that
2795  * give the assignment its final, precise meaning. These classes fill
2796  * in the NetProc behaviors.
2797  *
2798  * The l-value of the assignment is a collection of NetAssign_
2799  * objects that are connected to the structural netlist where the
2800  * assignment has its effect. The NetAssign_ class is not to be
2801  * derived from.
2802  *
2803  * The collection is arranged from lsb up to msb, and represents the
2804  * concatenation of l-values. The elaborator may collapse some
2805  * concatenations into a single NetAssign_. The "more" member of the
2806  * NetAssign_ object points to the next most significant bits of l-value.
2807  *
2808  * NOTE: The elaborator will make an effort to match the width of the
2809  * r-value to the width of the l-value, but targets and functions
2810  * should know that this is not a guarantee.
2811  */
2812 
2813 class NetAssign_ {
2814 
2815     public:
2816       explicit NetAssign_(NetAssign_*nest);
2817       explicit NetAssign_(NetNet*sig);
2818       ~NetAssign_();
2819 
2820 	// This is so NetAssign_ objects can be passed to ivl_assert
2821 	// and other macros that call this method.
2822       string get_fileline() const;
2823 
2824 	// If this expression exists, then it is used to select a word
2825 	// from an array/memory.
2826       NetExpr*word();
2827       const NetExpr*word() const;
2828 
2829       NetScope*scope()const;
2830 
2831 	// Get the base index of the part select, or 0 if there is no
2832 	// part select.
2833       const NetExpr* get_base() const;
2834       ivl_select_type_t select_type() const;
2835 
2836       void set_word(NetExpr*);
2837 	// Set a part select expression for the l-value vector. Note
2838 	// that the expression calculates a CANONICAL bit address.
2839       void set_part(NetExpr* loff, unsigned wid,
2840                     ivl_select_type_t = IVL_SEL_OTHER);
2841 	// Set the member or property name if the signal type is a
2842 	// class.
2843       void set_property(const perm_string&name);
get_property(void)2844       inline perm_string get_property(void) const { return member_; }
2845 
2846 	// Determine if the assigned object is signed or unsigned.
2847 	// This is used when determining the expression type for
2848 	// a compressed assignment statement.
get_signed()2849       bool get_signed() const { return signed_; }
set_signed(bool flag)2850       void set_signed(bool flag) { signed_ = flag; }
2851 
2852 	// Get the width of the r-value that this node expects. This
2853 	// method accounts for the presence of the mux, so it is not
2854 	// necessarily the same as the pin_count().
2855       unsigned lwidth() const;
2856       ivl_variable_type_t expr_type() const;
2857 
2858 	// Get the expression type of the l-value. This may be
2859 	// different from the type of the contained signal if for
2860 	// example a darray is indexed.
2861       const ivl_type_s* net_type() const;
2862 
2863 	// Return the enumeration type of this l-value, or nil if it's
2864 	// not an enumeration.
2865       const netenum_t*enumeration() const;
2866 
2867 	// Get the name of the underlying object.
2868       perm_string name() const;
2869 
2870       NetNet* sig() const;
nest()2871       inline const NetAssign_* nest() const { return nest_; }
2872 
2873 	// Mark that the synthesizer has worked with this l-value, so
2874 	// when it is released, the l-value signal should be turned
2875 	// into a wire.
2876       void turn_sig_to_wire_on_release();
2877 
2878 	// It is possible that l-values can have *inputs*, as well as
2879 	// being outputs. For example foo[idx] = ... is the l-value
2880 	// (NetAssign_ object) with a foo l-value and the input
2881 	// expression idx.
2882       NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2883                           bool nested_func = false) const;
2884 
2885 	// Figuring out nex_output to process ultimately comes down to
2886 	// this method.
2887       void nex_output(NexusSet&);
2888 
2889 	// This pointer is for keeping simple lists.
2890       NetAssign_* more;
2891 
2892       void dump_lval(ostream&o) const;
2893 
2894     private:
2895 	// Nested l-value. If this is set, sig_ must NOT be set!
2896       NetAssign_*nest_;
2897       NetNet *sig_;
2898 	// Memory word index
2899       NetExpr*word_;
2900 	// member/property if signal is a class.
2901       perm_string member_;
2902 
2903       bool signed_;
2904       bool turn_sig_to_wire_on_release_;
2905 	// indexed part select base
2906       NetExpr*base_;
2907       unsigned lwid_;
2908       ivl_select_type_t sel_type_;
2909 };
2910 
2911 class NetAssignBase : public NetProc {
2912 
2913     public:
2914       NetAssignBase(NetAssign_*lv, NetExpr*rv);
2915       virtual ~NetAssignBase() =0;
2916 
2917 	// This is the (procedural) value that is to be assigned when
2918 	// the assignment is executed.
2919       NetExpr*rval();
2920       const NetExpr*rval() const;
2921 
2922       void set_rval(NetExpr*);
2923 
2924       NetAssign_* l_val(unsigned);
2925       const NetAssign_* l_val(unsigned) const;
2926       unsigned l_val_count() const;
2927 
2928       void set_delay(NetExpr*);
2929       const NetExpr* get_delay() const;
2930 
2931       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
2932                                   bool nested_func = false) const;
2933       virtual void nex_output(NexusSet&o);
2934 
2935 
2936 	// This returns the total width of the accumulated l-value. It
2937 	// accounts for any grouping of NetAssign_ objects that might happen.
2938       unsigned lwidth() const;
2939 
2940       bool synth_async(Design*des, NetScope*scope,
2941 		       NexusSet&nex_map, NetBus&nex_out,
2942 		       NetBus&enables, vector<mask_t>&bitmasks);
2943 
2944 	// This dumps all the lval structures.
2945       void dump_lval(ostream&) const;
2946       virtual void dump(ostream&, unsigned ind) const;
2947       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
2948 
2949     private:
2950       NetAssign_*lval_;
2951       NetExpr   *rval_;
2952       NetExpr   *delay_;
2953 };
2954 
2955 class NetAssign : public NetAssignBase {
2956 
2957     public:
2958       explicit NetAssign(NetAssign_*lv, NetExpr*rv);
2959       explicit NetAssign(NetAssign_*lv, char op, NetExpr*rv);
2960       ~NetAssign();
2961 
2962       bool is_asynchronous();
2963 
assign_operator(void)2964       inline char assign_operator(void) const { return op_; }
2965 
2966       virtual bool emit_proc(struct target_t*) const;
2967       virtual int match_proc(struct proc_match_t*);
2968       virtual void dump(ostream&, unsigned ind) const;
2969       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
2970       virtual bool evaluate_function(const LineInfo&loc,
2971 				     map<perm_string,LocalVar>&ctx) const;
2972 
2973     private:
2974       void eval_func_lval_op_real_(const LineInfo&loc, verireal&lv, verireal&rv) const;
2975       void eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const;
2976       bool eval_func_lval_(const LineInfo&loc, map<perm_string,LocalVar>&ctx,
2977 			   const NetAssign_*lval, NetExpr*rval_result) const;
2978 
2979       char op_;
2980 };
2981 
2982 class NetAssignNB  : public NetAssignBase {
2983     public:
2984       explicit NetAssignNB(NetAssign_*lv, NetExpr*rv, NetEvWait*ev,
2985                            NetExpr*cnt);
2986       ~NetAssignNB();
2987 
2988 
2989       virtual bool emit_proc(struct target_t*) const;
2990       virtual int match_proc(struct proc_match_t*);
2991       virtual void dump(ostream&, unsigned ind) const;
2992       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
2993 
2994       unsigned nevents() const;
2995       const NetEvent*event(unsigned) const;
2996       const NetExpr* get_count() const;
2997 
2998     private:
2999       NetEvWait*event_;
3000       NetExpr*count_;
3001 };
3002 
3003 /*
3004  * A block is stuff like begin-end blocks, that contain an ordered
3005  * list of NetProc statements.
3006  *
3007  * NOTE: The emit method calls the target->proc_block function but
3008  * does not recurse. It is up to the target-supplied proc_block
3009  * function to call emit_recurse.
3010  */
3011 class NetBlock  : public NetProc {
3012 
3013     public:
3014       enum Type { SEQU, PARA, PARA_JOIN_ANY, PARA_JOIN_NONE };
3015 
3016       NetBlock(Type t, NetScope*subscope);
3017       ~NetBlock();
3018 
type()3019       Type type() const    { return type_; }
subscope()3020       NetScope* subscope() const { return subscope_; }
3021 
3022       void append(NetProc*);
3023       void prepend(NetProc*);
3024 
3025       const NetProc*proc_first() const;
3026       const NetProc*proc_next(const NetProc*cur) const;
3027 
3028       bool evaluate_function(const LineInfo&loc,
3029 			     map<perm_string,LocalVar>&ctx) const;
3030 
3031 	// synthesize as asynchronous logic, and return true.
3032       bool synth_async(Design*des, NetScope*scope,
3033 		       NexusSet&nex_map, NetBus&nex_out,
3034 		       NetBus&enables, vector<mask_t>&bitmasks);
3035 
3036       bool synth_sync(Design*des, NetScope*scope,
3037 		      bool&ff_negedge,
3038 		      NetNet*ff_clk, NetBus&ff_ce,
3039 		      NetBus&ff_aclr,NetBus&ff_aset,
3040 		      vector<verinum>&ff_aset_value,
3041 		      NexusSet&nex_map, NetBus&nex_out,
3042 		      vector<mask_t>&bitmasks,
3043 		      const std::vector<NetEvProbe*>&events);
3044 
3045 	// This version of emit_recurse scans all the statements of
3046 	// the begin-end block sequentially. It is typically of use
3047 	// for sequential blocks.
3048       void emit_recurse(struct target_t*) const;
3049 
3050       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3051                                   bool nested_func = false) const;
3052       virtual void nex_output(NexusSet&);
3053       virtual bool emit_proc(struct target_t*) const;
3054       virtual int match_proc(struct proc_match_t*);
3055       virtual void dump(ostream&, unsigned ind) const;
3056       virtual DelayType delay_type(bool print_delay=false) const;
3057       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3058 
3059     private:
3060       const Type type_;
3061       NetScope*subscope_;
3062 
3063       NetProc*last_;
3064 };
3065 
3066 /*
3067  * A CASE statement in the Verilog source leads, eventually, to one of
3068  * these. This is different from a simple conditional because of the
3069  * way the comparisons are performed. Also, it is likely that the
3070  * target may be able to optimize differently.
3071  *
3072  * Case statements can have unique, unique0, or priority attached to
3073  * them. If not otherwise adorned, it is QBASIC.
3074  *
3075  * Case can be one of three types:
3076  *    EQ  -- All bits must exactly match
3077  *    EQZ -- z bits are don't care
3078  *    EQX -- x and z bits are don't care.
3079  */
3080 class NetCase  : public NetProc {
3081 
3082     public:
3083       enum TYPE { EQ, EQX, EQZ };
3084 
3085       NetCase(ivl_case_quality_t q, TYPE c, NetExpr*ex, unsigned cnt);
3086       ~NetCase();
3087 
3088       void set_case(unsigned idx, NetExpr*ex, NetProc*st);
3089 
3090       void prune();
3091 
case_quality()3092       inline ivl_case_quality_t case_quality() const { return quality_; }
3093       TYPE type() const;
expr()3094       const NetExpr*expr() const { return expr_; }
nitems()3095       inline unsigned nitems() const { return items_.size(); }
3096 
expr(unsigned idx)3097       inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;}
stat(unsigned idx)3098       inline const NetProc*stat(unsigned idx) const { return items_[idx].statement; }
3099 
3100       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3101                                   bool nested_func = false) const;
3102       virtual void nex_output(NexusSet&out);
3103 
3104       bool synth_async(Design*des, NetScope*scope,
3105 		       NexusSet&nex_map, NetBus&nex_out,
3106 		       NetBus&enables, vector<mask_t>&bitmasks);
3107 
3108       virtual bool emit_proc(struct target_t*) const;
3109       virtual void dump(ostream&, unsigned ind) const;
3110       virtual DelayType delay_type(bool print_delay=false) const;
3111       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3112       virtual bool evaluate_function(const LineInfo&loc,
3113 				     map<perm_string,LocalVar>&ctx) const;
3114 
3115     private:
3116       bool evaluate_function_vect_(const LineInfo&loc,
3117 				   map<perm_string,LocalVar>&ctx) const;
3118       bool evaluate_function_real_(const LineInfo&loc,
3119 				   map<perm_string,LocalVar>&ctx) const;
3120 
3121       bool synth_async_casez_(Design*des, NetScope*scope,
3122 			      NexusSet&nex_map, NetBus&nex_out,
3123 			      NetBus&enables, vector<mask_t>&bitmasks);
3124 
3125       ivl_case_quality_t quality_;
3126       TYPE type_;
3127 
3128       struct Item {
ItemItem3129 	    inline Item() : guard(0), statement(0) { }
3130 	    NetExpr*guard;
3131 	    NetProc*statement;
3132       };
3133 
3134       NetExpr* expr_;
3135       std::vector<Item>items_;
3136 };
3137 
3138 /*
3139  * The cassign statement causes the r-val net to be forced onto the
3140  * l-val reg when it is executed. The code generator is expected to
3141  * know what that means.
3142  */
3143 class NetCAssign  : public NetAssignBase {
3144 
3145     public:
3146       explicit NetCAssign(NetAssign_*lv, NetExpr*rv);
3147       ~NetCAssign();
3148 
3149       virtual void dump(ostream&, unsigned ind) const;
3150       virtual bool emit_proc(struct target_t*) const;
3151       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3152 
3153     private: // not implemented
3154       NetCAssign(const NetCAssign&);
3155       NetCAssign& operator= (const NetCAssign&);
3156 };
3157 
3158 
3159 /*
3160  * A condit represents a conditional. It has an expression to test,
3161  * and a pair of statements to select from. If the original statement
3162  * has empty clauses, then the NetProc for it will be a null pointer.
3163  */
3164 class NetCondit  : public NetProc {
3165 
3166     public:
3167       explicit NetCondit(NetExpr*ex, NetProc*i, NetProc*e);
3168       ~NetCondit();
3169 
3170       const NetExpr*expr() const;
3171       NetExpr*expr();
3172 
3173       NetProc* if_clause();
3174       NetProc* else_clause();
3175 
3176 	// Replace the condition expression.
3177       void set_expr(NetExpr*ex);
3178 
3179       bool emit_recurse_if(struct target_t*) const;
3180       bool emit_recurse_else(struct target_t*) const;
3181 
3182       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3183                                   bool nested_func = false) const;
3184       virtual void nex_output(NexusSet&o);
3185 
3186       bool is_asynchronous();
3187       bool synth_async(Design*des, NetScope*scope,
3188 		       NexusSet&nex_map, NetBus&nex_out,
3189 		       NetBus&enables, vector<mask_t>&bitmasks);
3190 
3191       bool synth_sync(Design*des, NetScope*scope,
3192 		      bool&ff_negedge,
3193 		      NetNet*ff_clk, NetBus&ff_ce,
3194 		      NetBus&ff_aclr,NetBus&ff_aset,
3195 		      vector<verinum>&ff_aset_value,
3196 		      NexusSet&nex_map, NetBus&nex_out,
3197 		      vector<mask_t>&bitmasks,
3198 		      const std::vector<NetEvProbe*>&events);
3199 
3200       virtual bool emit_proc(struct target_t*) const;
3201       virtual int match_proc(struct proc_match_t*);
3202       virtual void dump(ostream&, unsigned ind) const;
3203       virtual DelayType delay_type(bool print_delay=false) const;
3204       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3205       virtual bool evaluate_function(const LineInfo&loc,
3206 				     map<perm_string,LocalVar>&ctx) const;
3207 
3208     private:
3209       NetExpr* expr_;
3210       NetProc*if_;
3211       NetProc*else_;
3212 };
3213 
3214 /*
3215  * This represents the analog contribution statement. The l-val is a
3216  * branch expression, and the r-value is an arbitrary expression that
3217  * may include branches and real values.
3218  */
3219 class NetContribution : public NetProc {
3220 
3221     public:
3222       explicit NetContribution(NetEAccess*lval, NetExpr*rval);
3223       ~NetContribution();
3224 
3225       const NetEAccess* lval() const;
3226       const NetExpr* rval() const;
3227 
3228       virtual bool emit_proc(struct target_t*) const;
3229       virtual void dump(ostream&, unsigned ind) const;
3230 
3231     private:
3232       NetEAccess*lval_;
3233       NetExpr*rval_;
3234 };
3235 
3236 /*
3237  * The procedural deassign statement (the opposite of assign) releases
3238  * any assign expressions attached to the bits of the reg. The
3239  * lval is the expression of the "deassign <expr>;" statement with the
3240  * expr elaborated to a net.
3241  */
3242 class NetDeassign : public NetAssignBase {
3243 
3244     public:
3245       explicit NetDeassign(NetAssign_*l);
3246       ~NetDeassign();
3247 
3248       virtual bool emit_proc(struct target_t*) const;
3249       virtual void dump(ostream&, unsigned ind) const;
3250       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3251 
3252     private: // not implemented
3253       NetDeassign(const NetDeassign&);
3254       NetDeassign& operator= (const NetDeassign&);
3255 };
3256 
3257 /*
3258  * This node represents the behavioral disable statement. The Verilog
3259  * source that produces it looks like:
3260  *
3261  *          disable <scope>;
3262  *
3263  * Where the scope is a named block or a task. It cannot be a module
3264  * instance scope because module instances cannot be disabled.
3265  */
3266 class NetDisable  : public NetProc {
3267 
3268     public:
3269       explicit NetDisable(NetScope*tgt);
3270       ~NetDisable();
3271 
3272       const NetScope*target() const;
3273 
3274       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3275                                   bool nested_func = false) const;
3276       virtual void nex_output(NexusSet&);
3277       virtual bool emit_proc(struct target_t*) const;
3278       virtual void dump(ostream&, unsigned ind) const;
3279       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3280       virtual bool evaluate_function(const LineInfo&loc,
3281 				     map<perm_string,LocalVar>&ctx) const;
3282 
3283     private:
3284       NetScope*target_;
3285 
3286     private: // not implemented
3287       NetDisable(const NetDisable&);
3288       NetDisable& operator= (const NetDisable&);
3289 };
3290 
3291 /*
3292  * The do/while statement is a condition that is tested at the end of
3293  * each iteration, and a statement (a NetProc) that is executed once and
3294  * then again as long as the condition is true.
3295  */
3296 class NetDoWhile  : public NetProc {
3297 
3298     public:
NetDoWhile(NetExpr * c,NetProc * p)3299       NetDoWhile(NetExpr*c, NetProc*p)
3300       : cond_(c), proc_(p) { }
3301 
expr()3302       const NetExpr*expr() const { return cond_; }
3303 
3304       void emit_proc_recurse(struct target_t*) const;
3305 
3306       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3307                                   bool nested_func = false) const;
3308       virtual void nex_output(NexusSet&);
3309       virtual bool emit_proc(struct target_t*) const;
3310       virtual void dump(ostream&, unsigned ind) const;
3311       virtual DelayType delay_type(bool print_delay=false) const;
3312       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3313       virtual bool evaluate_function(const LineInfo&loc,
3314 				     map<perm_string,LocalVar>&ctx) const;
3315 
3316     private:
3317       NetExpr* cond_;
3318       NetProc*proc_;
3319 };
3320 
3321 /*
3322  * A NetEvent is an object that represents an event object, that is
3323  * objects declared like so in Verilog:
3324  *
3325  *        event foo;
3326  *
3327  * Once an object of this type exists, behavioral code can wait on the
3328  * event or trigger the event. Event waits refer to this object, as do
3329  * the event trigger statements. The NetEvent class may have a name and
3330  * a scope. The name is a simple name (no hierarchy) and the scope is
3331  * the NetScope that contains the object. The scope member is written
3332  * by the NetScope object when the NetEvent is stored.
3333  *
3334  * The NetEvWait class represents a thread wait for an event. When
3335  * this statement is executed, it starts waiting on the
3336  * event. Conceptually, it puts itself on the event list for the
3337  * referenced event. When the event is triggered, the wait ends its
3338  * block and starts the associated statement.
3339  *
3340  * The NetEvTrig class represents trigger statements. Executing this
3341  * statement causes the referenced event to be triggered, which in
3342  * turn awakens the waiting threads. Each NetEvTrig object references
3343  * exactly one event object.
3344  *
3345  * The NetEvProbe class is the structural equivalent of the NetEvTrig,
3346  * in that it is a node and watches bit values that it receives. It
3347  * checks for edges then if appropriate triggers the associated
3348  * NetEvent. Each NetEvProbe references exactly one event object, and
3349  * the NetEvent objects have a list of NetEvProbe objects that
3350  * reference it.
3351  */
3352 class NetEvent : public LineInfo {
3353 
3354       friend class NetScope;
3355       friend class NetEvProbe;
3356       friend class NetEvTrig;
3357       friend class NetEvWait;
3358       friend class NetEEvent;
3359 
3360     public:
3361 	// The name of the event is the basename, and should not
3362 	// include the scope. Also, the name passed here should be
3363 	// perm-allocated.
3364       explicit NetEvent (perm_string n);
3365       ~NetEvent();
3366 
3367       perm_string name() const;
3368 
local_flag()3369       bool local_flag() const { return local_flag_; }
local_flag(bool f)3370       void local_flag(bool f) { local_flag_ = f; }
3371 
3372 	// Get information about probes connected to me.
3373       unsigned nprobe() const;
3374       NetEvProbe* probe(unsigned);
3375       const NetEvProbe* probe(unsigned) const;
3376 
3377 	// Return the number of NetEvWait nodes that reference me.
3378       unsigned nwait() const;
3379       unsigned ntrig() const;
3380       unsigned nexpr() const;
3381 
3382       NetScope* scope();
3383       const NetScope* scope() const;
3384 
3385       void nex_output(NexusSet&);
3386 
3387 	// Locate the first event that matches my behavior and
3388 	// monitors the same signals.
3389       void find_similar_event(list<NetEvent*>&);
3390 
3391 	// This method replaces pointers to me with pointers to
3392 	// that. It is typically used to replace similar events
3393 	// located by the find_similar_event method.
3394       void replace_event(NetEvent*that);
3395 
3396     private:
3397 	// This returns a nexus set if it represents possibly
3398 	// asynchronous inputs, otherwise 0.
3399       NexusSet*nex_async_();
3400 
3401     private:
3402       perm_string name_;
3403       bool local_flag_;
3404 
3405 	// The NetScope class uses these to list the events.
3406       NetScope*scope_;
3407       NetEvent*snext_;
3408 
3409 	// Use these methods to list the probes attached to me.
3410       NetEvProbe*probes_;
3411 
3412 	// Use these methods to list the triggers attached to me.
3413       NetEvTrig* trig_;
3414 
3415 	// Use This member to count references by NetEvWait objects.
3416       unsigned waitref_;
3417       struct wcell_ {
3418 	    NetEvWait*obj;
3419 	    struct wcell_*next;
3420       };
3421       struct wcell_ *wlist_;
3422 
3423 	// expression references, ala. task/funcs
3424       unsigned exprref_;
3425 
3426     private: // not implemented
3427       NetEvent(const NetEvent&);
3428       NetEvent& operator= (const NetEvent&);
3429 };
3430 
3431 class NetEvTrig  : public NetProc {
3432 
3433       friend class NetEvent;
3434 
3435     public:
3436       explicit NetEvTrig(NetEvent*tgt);
3437       ~NetEvTrig();
3438 
3439       const NetEvent*event() const;
3440 
3441       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3442                                   bool nested_func = false) const;
3443       virtual void nex_output(NexusSet&);
3444       virtual bool emit_proc(struct target_t*) const;
3445       virtual void dump(ostream&, unsigned ind) const;
3446       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3447 
3448     private:
3449       NetEvent*event_;
3450 	// This is used to place me in the NetEvents lists of triggers.
3451       NetEvTrig*enext_;
3452 };
3453 
3454 class NetEvWait  : public NetProc {
3455 
3456     public:
3457       explicit NetEvWait(NetProc*st);
3458       ~NetEvWait();
3459 
3460       void add_event(NetEvent*tgt);
3461       void replace_event(NetEvent*orig, NetEvent*repl);
set_t0_trigger()3462       inline void set_t0_trigger() { has_t0_trigger_ = true; };
3463 
nevents()3464       inline unsigned nevents() const { return events_.size(); }
event(unsigned idx)3465       inline const NetEvent*event(unsigned idx) const { return events_[idx]; }
event(unsigned idx)3466       inline NetEvent*event(unsigned idx) { return events_[idx]; }
has_t0_trigger()3467       inline bool has_t0_trigger() const { return has_t0_trigger_; };
3468 
3469       NetProc*statement();
3470       const NetProc*statement() const;
3471 
3472       virtual bool emit_proc(struct target_t*) const;
3473       bool emit_recurse(struct target_t*) const;
3474       virtual int match_proc(struct proc_match_t*);
3475 
3476 	// It is possible that this is the root of a combinational
3477 	// process. This method checks.
3478       virtual bool is_asynchronous();
3479 
3480 	// It is possible that this is the root of a synchronous
3481 	// process? This method checks.
3482       virtual bool is_synchronous();
3483 
3484       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3485                                   bool nested_func = false) const;
3486       virtual void nex_output(NexusSet&out);
3487 
3488       virtual bool synth_async(Design*des, NetScope*scope,
3489 			       NexusSet&nex_map, NetBus&nex_out,
3490 			       NetBus&enables, vector<mask_t>&bitmasks);
3491 
3492       virtual bool synth_sync(Design*des, NetScope*scope,
3493 			      bool&ff_negedge,
3494 			      NetNet*ff_clk, NetBus&ff_ce,
3495 			      NetBus&ff_aclr,NetBus&ff_aset,
3496 			      vector<verinum>&ff_aset_value,
3497 			      NexusSet&nex_map, NetBus&nex_out,
3498 			      vector<mask_t>&bitmasks,
3499 			      const std::vector<NetEvProbe*>&events);
3500 
3501       virtual void dump(ostream&, unsigned ind) const;
3502 	// This will ignore any statement.
3503       virtual void dump_inline(ostream&) const;
3504       virtual DelayType delay_type(bool print_delay=false) const;
3505       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3506 
3507     private:
3508       NetProc*statement_;
3509 	// Events that I might wait for.
3510       std::vector<NetEvent*>events_;
3511       bool has_t0_trigger_;
3512 };
3513 
3514 ostream& operator << (ostream&out, const NetEvWait&obj);
3515 
3516 class NetEvProbe  : public NetNode {
3517 
3518       friend class NetEvent;
3519 
3520     public:
3521       enum edge_t { ANYEDGE, POSEDGE, NEGEDGE };
3522 
3523       explicit NetEvProbe(NetScope*s, perm_string n,
3524 			  NetEvent*tgt, edge_t t, unsigned p);
3525       ~NetEvProbe();
3526 
3527       edge_t edge() const;
3528       NetEvent* event();
3529       const NetEvent* event() const;
3530 
3531       void find_similar_probes(list<NetEvProbe*>&);
3532 
3533       virtual bool emit_node(struct target_t*) const;
3534       virtual void dump_node(ostream&, unsigned ind) const;
3535 
3536     private:
3537       NetEvent*event_;
3538       edge_t edge_;
3539 	// The NetEvent class uses this to list me.
3540       NetEvProbe*enext_;
3541 };
3542 
3543 /*
3544  * The force statement causes the r-val net to be forced onto the
3545  * l-val net when it is executed. The code generator is expected to
3546  * know what that means.
3547  */
3548 class NetForce  : public NetAssignBase {
3549 
3550     public:
3551       explicit NetForce(NetAssign_*l, NetExpr*r);
3552       ~NetForce();
3553 
3554       virtual void dump(ostream&, unsigned ind) const;
3555       virtual bool emit_proc(struct target_t*) const;
3556       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3557 };
3558 
3559 /*
3560  * A forever statement is executed over and over again forever. Or
3561  * until its block is disabled.
3562  */
3563 class NetForever : public NetProc {
3564 
3565     public:
3566       explicit NetForever(NetProc*s);
3567       ~NetForever();
3568 
3569       void emit_recurse(struct target_t*) const;
3570 
3571       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3572                                   bool nested_func = false) const;
3573       virtual void nex_output(NexusSet&);
3574       virtual bool emit_proc(struct target_t*) const;
3575       virtual void dump(ostream&, unsigned ind) const;
3576       virtual DelayType delay_type(bool print_delay=false) const;
3577       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3578       virtual bool evaluate_function(const LineInfo&loc,
3579 				     map<perm_string,LocalVar>&ctx) const;
3580 
3581     private:
3582       NetProc*statement_;
3583 };
3584 
3585 class NetForLoop : public NetProc {
3586 
3587     public:
3588       explicit NetForLoop(NetNet*index, NetExpr*initial_expr, NetExpr*cond,
3589 			  NetProc*sub, NetProc*step);
3590       ~NetForLoop();
3591 
3592       void wrap_up();
3593 
3594       void emit_recurse(struct target_t*) const;
3595 
3596       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3597                                   bool nested_func = false) const;
3598       virtual void nex_output(NexusSet&);
3599       virtual bool emit_proc(struct target_t*) const;
3600       virtual void dump(ostream&, unsigned ind) const;
3601       virtual DelayType delay_type(bool print_delay=false) const;
3602       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3603       virtual bool evaluate_function(const LineInfo&loc,
3604 				     map<perm_string,LocalVar>&ctx) const;
3605 
3606 	// synthesize as asynchronous logic, and return true.
3607       bool synth_async(Design*des, NetScope*scope,
3608 		       NexusSet&nex_map, NetBus&nex_out,
3609 		       NetBus&enables, vector<mask_t>&bitmasks);
3610 
3611     private:
3612       NetNet*index_;
3613       NetExpr*init_expr_;
3614       NetExpr*condition_;
3615       NetProc*statement_;
3616       NetProc*step_statement_;
3617 
3618 	// The code generator needs to see this rewritten as a while
3619 	// loop with synthetic statements. This is a hack that I
3620 	// should probably take out later as the ivl_target learns
3621 	// about for loops.
3622       NetBlock*as_block_;
3623 };
3624 
3625 class NetFree   : public NetProc {
3626 
3627     public:
3628       explicit NetFree(NetScope*);
3629       ~NetFree();
3630 
3631       const string name() const;
3632 
3633       const NetScope* scope() const;
3634 
3635       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3636                                   bool nested_func = false) const;
3637       virtual void nex_output(NexusSet&);
3638       virtual bool emit_proc(struct target_t*) const;
3639       virtual void dump(ostream&, unsigned ind) const;
3640 
3641     private:
3642       NetScope*scope_;
3643 };
3644 
3645 /*
3646  * A function definition is elaborated just like a task, though by now
3647  * it is certain that the first parameter (a phantom parameter) is the
3648  * output and all the remaining parameters are the inputs. This makes
3649  * for easy code generation in targets that support behavioral
3650  * descriptions.
3651  *
3652  * The NetNet array that is passed in as a parameter is the set of
3653  * signals that make up its parameter list. These are all internal to
3654  * the scope of the function.
3655  */
3656 class NetFuncDef : public NetBaseDef {
3657 
3658     public:
3659       NetFuncDef(NetScope*, NetNet*result, const std::vector<NetNet*>&po,
3660 		 const std::vector<NetExpr*>&pd);
3661       ~NetFuncDef();
3662 
3663 	// Return true if the function returns "void". We still treat
3664 	// it as a function since we need to check that the contents
3665 	// meet the requirements of a function, but we need to know
3666 	// that it is void because it can be evaluated differently.
is_void()3667       inline bool is_void() const { return result_sig_ == 0; }
3668 
3669 	// Non-void functions have a return value as a signal.
3670       const NetNet*return_sig() const;
3671 
3672 	// When we want to evaluate the function during compile time,
3673 	// use this method to pass in the argument and get out a
3674 	// result. The result should be a constant. If the function
3675 	// cannot evaluate to a constant, this returns nil.
3676       NetExpr* evaluate_function(const LineInfo&loc, const std::vector<NetExpr*>&args) const;
3677 
3678       void dump(ostream&, unsigned ind) const;
3679 
3680     private:
3681       NetNet*result_sig_;
3682 };
3683 
3684 /*
3685  * This class represents delay statements of the form:
3686  *
3687  *     #<expr> <statement>
3688  *
3689  * Where the statement may be null. The delay is evaluated at
3690  * elaboration time to make a constant unsigned long that is the delay
3691  * in simulation ticks.
3692  *
3693  * If the delay expression is non-constant, construct the NetPDelay
3694  * object with a NetExpr* instead of the d value, and use the expr()
3695  * method to get the expression. If expr() returns 0, use the delay()
3696  * method to get the constant delay.
3697  */
3698 class NetPDelay  : public NetProc {
3699 
3700     public:
3701       NetPDelay(uint64_t d, NetProc*st);
3702       NetPDelay(NetExpr* d, NetProc*st);
3703       ~NetPDelay();
3704 
3705       uint64_t delay() const;
3706       const NetExpr*expr() const;
3707 
3708       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3709                                   bool nested_func = false) const;
3710       virtual void nex_output(NexusSet&);
3711 
3712       virtual bool emit_proc(struct target_t*) const;
3713       virtual void dump(ostream&, unsigned ind) const;
3714       virtual DelayType delay_type(bool print_delay=false) const;
3715       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3716 
3717       bool emit_proc_recurse(struct target_t*) const;
3718 
3719     private:
3720       uint64_t delay_;
3721       NetExpr*expr_;
3722       NetProc*statement_;
3723 };
3724 
3725 /*
3726  * A repeat statement is executed some fixed number of times.
3727  */
3728 class NetRepeat : public NetProc {
3729 
3730     public:
3731       explicit NetRepeat(NetExpr*e, NetProc*s);
3732       ~NetRepeat();
3733 
3734       const NetExpr*expr() const;
3735       void emit_recurse(struct target_t*) const;
3736 
3737       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3738                                   bool nested_func = false) const;
3739       virtual void nex_output(NexusSet&);
3740       virtual bool emit_proc(struct target_t*) const;
3741       virtual void dump(ostream&, unsigned ind) const;
3742       virtual DelayType delay_type(bool print_delay=false) const;
3743       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3744       virtual bool evaluate_function(const LineInfo&loc,
3745 				     map<perm_string,LocalVar>&ctx) const;
3746 
3747     private:
3748       NetExpr*expr_;
3749       NetProc*statement_;
3750 };
3751 
3752 /*
3753  * The procedural release statement (the opposite of force) releases
3754  * any force expressions attached to the bits of the wire or reg. The
3755  * lval is the expression of the "release <expr>;" statement with the
3756  * expr elaborated to a net.
3757  */
3758 class NetRelease : public NetAssignBase {
3759 
3760     public:
3761       explicit NetRelease(NetAssign_*l);
3762       ~NetRelease();
3763 
3764       virtual bool emit_proc(struct target_t*) const;
3765       virtual void dump(ostream&, unsigned ind) const;
3766       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3767 
3768     private:
3769 };
3770 
3771 
3772 /*
3773  * The NetSTask class is a call to a system task. These kinds of tasks
3774  * are generally handled very simply in the target. They certainly are
3775  * handled differently from user defined tasks because ivl knows all
3776  * about the user defined tasks.
3777  */
3778 class NetSTask  : public NetProc {
3779 
3780     public:
3781       NetSTask(const char*na, ivl_sfunc_as_task_t sfat,
3782                const std::vector<NetExpr*>&);
3783       ~NetSTask();
3784 
3785       const char* name() const;
3786       ivl_sfunc_as_task_t sfunc_as_task() const;
3787 
3788       unsigned nparms() const;
3789 
3790       const NetExpr* parm(unsigned idx) const;
3791 
3792       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3793                                   bool nested_func = false) const;
3794       virtual void nex_output(NexusSet&);
3795       virtual bool emit_proc(struct target_t*) const;
3796       virtual void dump(ostream&, unsigned ind) const;
3797       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3798       virtual bool evaluate_function(const LineInfo&loc,
3799 				     map<perm_string,LocalVar>&ctx) const;
3800 
3801     private:
3802       const char* name_;
3803       ivl_sfunc_as_task_t sfunc_as_task_;
3804       std::vector<NetExpr*>parms_;
3805 };
3806 
3807 /*
3808  * This class represents an elaborated class definition. NetUTask
3809  * classes may refer to objects of this type to get the meaning of the
3810  * defined task.
3811  *
3812  * The task also introduces a scope, and the parameters are actually
3813  * reg objects in the new scope. The task is called by the calling
3814  * thread assigning (blocking assignment) to the in and inout
3815  * parameters, then invoking the thread, and finally assigning out the
3816  * output and inout variables. The variables accessible as ports are
3817  * also elaborated and accessible as ordinary reg objects.
3818  */
3819 class NetTaskDef : public NetBaseDef {
3820 
3821     public:
3822       NetTaskDef(NetScope*n, const vector<NetNet*>&po,
3823 		 const std::vector<NetExpr*>&pd);
3824       ~NetTaskDef();
3825 
3826       void dump(ostream&, unsigned) const;
3827       DelayType delay_type(bool print_delay=false) const;
3828       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3829 
3830     private: // not implemented
3831       NetTaskDef(const NetTaskDef&);
3832       NetTaskDef& operator= (const NetTaskDef&);
3833 };
3834 
3835 /*
3836  * The NetELast expression node takes as an argument a net, that is
3837  * intended to be a queue or dynamic array object. The return value is
3838  * the index of the last item in the node. This is intended to
3839  * implement the '$' is the expression "foo[$]".
3840  */
3841 class NetELast : public NetExpr {
3842 
3843     public:
3844       explicit NetELast(NetNet*sig);
3845       ~NetELast();
3846 
sig()3847       inline const NetNet*sig() const { return sig_; }
3848 
3849       virtual ivl_variable_type_t expr_type() const;
3850       virtual void dump(std::ostream&) const;
3851 
3852       virtual void expr_scan(struct expr_scan_t*) const;
3853       virtual NetELast*dup_expr() const;
3854       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3855                                   bool nested_func = false) const;
3856 
3857     private:
3858       NetNet*sig_;
3859 };
3860 
3861 /*
3862  * This node represents a function call in an expression. The object
3863  * contains a pointer to the function definition, which is used to
3864  * locate the value register and input expressions.
3865  */
3866 class NetEUFunc  : public NetExpr {
3867 
3868     public:
3869       NetEUFunc(NetScope*, NetScope*, NetESignal*, std::vector<NetExpr*>&, bool);
3870       ~NetEUFunc();
3871 
3872       const NetESignal*result_sig() const;
3873 
3874       unsigned parm_count() const;
3875       const NetExpr* parm(unsigned idx) const;
3876 
3877       const NetScope* func() const;
3878 
3879       virtual ivl_variable_type_t expr_type() const;
3880       virtual const netenum_t* enumeration() const;
3881       virtual void dump(ostream&) const;
3882 
3883       virtual void expr_scan(struct expr_scan_t*) const;
3884       virtual NetEUFunc*dup_expr() const;
3885       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3886                                   bool nested_func = false) const;
3887       virtual NetExpr* eval_tree();
3888       virtual NetExpr*evaluate_function(const LineInfo&loc,
3889 					map<perm_string,LocalVar>&ctx) const;
3890 
3891       virtual NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
3892 
3893     private:
3894       NetScope*scope_;
3895       NetScope*func_;
3896       NetESignal*result_sig_;
3897       std::vector<NetExpr*> parms_;
3898       bool need_const_;
3899 
3900     private: // not implemented
3901       NetEUFunc(const NetEUFunc&);
3902       NetEUFunc& operator= (const NetEUFunc&);
3903 };
3904 
3905 /*
3906  * A call to a nature access function for a branch.
3907  */
3908 class NetEAccess : public NetExpr {
3909 
3910     public:
3911       explicit NetEAccess(NetBranch*br, ivl_nature_t nat);
3912       ~NetEAccess();
3913 
get_nature()3914       ivl_nature_t get_nature() const { return nature_; }
get_branch()3915       NetBranch*   get_branch() const { return branch_; }
3916 
3917       virtual ivl_variable_type_t expr_type() const;
3918       virtual void dump(ostream&) const;
3919 
3920       virtual void expr_scan(struct expr_scan_t*) const;
3921       virtual NetEAccess*dup_expr() const;
3922       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3923                                   bool nested_func = false) const;
3924 
3925     private:
3926       NetBranch*branch_;
3927       ivl_nature_t nature_;
3928 };
3929 
3930 /*
3931  * A call to a user defined task is elaborated into this object. This
3932  * contains a pointer to the elaborated task definition, but is a
3933  * NetProc object so that it can be linked into statements.
3934  */
3935 class NetUTask  : public NetProc {
3936 
3937     public:
3938       explicit NetUTask(NetScope*);
3939       ~NetUTask();
3940 
3941       const string name() const;
3942 
3943       const NetScope* task() const;
3944 
3945       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3946                                   bool nested_func = false) const;
3947       virtual void nex_output(NexusSet&);
3948       virtual bool emit_proc(struct target_t*) const;
3949       virtual void dump(ostream&, unsigned ind) const;
3950       virtual DelayType delay_type(bool print_delay=false) const;
3951       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3952 
3953     private:
3954       NetScope*task_;
3955 };
3956 
3957 /*
3958  * The while statement is a condition that is tested in the front of
3959  * each iteration, and a statement (a NetProc) that is executed as
3960  * long as the condition is true.
3961  */
3962 class NetWhile  : public NetProc {
3963 
3964     public:
NetWhile(NetExpr * c,NetProc * p)3965       NetWhile(NetExpr*c, NetProc*p)
3966       : cond_(c), proc_(p) { }
3967 
expr()3968       const NetExpr*expr() const { return cond_; }
3969 
3970       void emit_proc_recurse(struct target_t*) const;
3971 
3972       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
3973                                   bool nested_func = false) const;
3974       virtual void nex_output(NexusSet&);
3975       virtual bool emit_proc(struct target_t*) const;
3976       virtual void dump(ostream&, unsigned ind) const;
3977       virtual DelayType delay_type(bool print_delay=false) const;
3978       virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const;
3979       virtual bool evaluate_function(const LineInfo&loc,
3980 				     map<perm_string,LocalVar>&ctx) const;
3981 
3982     private:
3983       NetExpr*cond_;
3984       NetProc*proc_;
3985 };
3986 
3987 
3988 /*
3989  * The is the top of any process. It carries the type (initial or
3990  * always) and a pointer to the statement, probably a block, that
3991  * makes up the process.
3992  */
3993 class NetProcTop  : public LineInfo, public Attrib {
3994 
3995     public:
3996       NetProcTop(NetScope*s, ivl_process_type_t t, class NetProc*st);
3997       ~NetProcTop();
3998 
type()3999       ivl_process_type_t type() const { return type_; }
4000       NetProc*statement();
4001       const NetProc*statement() const;
4002 
4003       NetScope*scope();
4004       const NetScope*scope() const;
4005 
4006 	/* Return true if this process represents combinational logic. */
4007       bool is_asynchronous() const;
4008 
4009 	/* Create asynchronous logic from this thread and return true,
4010 	   or return false if that cannot be done. */
4011       bool synth_async(Design*des);
4012 
4013 	/* Return true if this process represents synchronous logic. */
4014       bool is_synchronous();
4015 
4016 	/* Create synchronous logic from this thread and return true,
4017 	   or return false if that cannot be done. */
4018       bool synth_sync(Design*des);
4019 
4020       void dump(ostream&, unsigned ind) const;
4021       bool emit(struct target_t*tgt) const;
4022 
4023     private:
4024       bool tie_off_floating_inputs_(Design*des,
4025 				    NexusSet&nex_map, NetBus&nex_in,
4026 				    vector<NetProc::mask_t>&bitmasks,
4027 				    bool is_ff_input);
4028 
4029       const ivl_process_type_t type_;
4030       NetProc*const statement_;
4031       Design*synthesized_design_;
4032 
4033       NetScope*scope_;
4034       friend class Design;
4035       NetProcTop*next_;
4036 };
4037 
4038 class NetAnalogTop  : public LineInfo, public Attrib {
4039 
4040     public:
4041       NetAnalogTop(NetScope*scope, ivl_process_type_t t, NetProc*st);
4042       ~NetAnalogTop();
4043 
type()4044       ivl_process_type_t type() const { return type_; }
4045 
4046       NetProc*statement();
4047       const NetProc*statement() const;
4048 
4049       NetScope*scope();
4050       const NetScope*scope() const;
4051 
4052       void dump(ostream&, unsigned ind) const;
4053       bool emit(struct target_t*tgt) const;
4054 
4055     private:
4056       const ivl_process_type_t type_;
4057       NetProc* statement_;
4058 
4059       NetScope*scope_;
4060       friend class Design;
4061       NetAnalogTop*next_;
4062 };
4063 
4064 /*
4065  * This class represents a binary operator, with the left and right
4066  * operands and a single character for the operator. The operator
4067  * values are:
4068  *
4069  *   ^  -- Bit-wise exclusive OR
4070  *   +  -- Arithmetic add
4071  *   -  -- Arithmetic minus
4072  *   *  -- Arithmetic multiply
4073  *   /  -- Arithmetic divide
4074  *   %  -- Arithmetic modulus
4075  *   p  -- Arithmetic power (**)
4076  *   &  -- Bit-wise AND
4077  *   |  -- Bit-wise OR
4078  *   <  -- Less than
4079  *   >  -- Greater than
4080  *   e  -- Logical equality (==)
4081  *   E  -- Case equality (===)
4082  *   L  -- Less or equal
4083  *   G  -- Greater or equal
4084  *   n  -- Logical inequality (!=)
4085  *   N  -- Case inequality (!==)
4086  *   a  -- Logical AND (&&)
4087  *   A  -- Bitwise NAND (~&)
4088  *   o  -- Logical OR (||)
4089  *   O  -- Bit-wise NOR (~|)
4090  *   l  -- Left shift (<<)
4091  *   r  -- Right shift (>>)
4092  *   R  -- signed right shift (>>>)
4093  *   X  -- Bitwise exclusive NOR (~^)
4094  *   m  -- min(a,b)
4095  *   M  -- max(a,b)
4096  */
4097 class NetEBinary  : public NetExpr {
4098 
4099     public:
4100       NetEBinary(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4101       ~NetEBinary();
4102 
left()4103       const NetExpr*left() const { return left_; }
right()4104       const NetExpr*right() const { return right_; }
4105 
op()4106       char op() const { return op_; }
4107 
4108 	// A binary expression node only has a definite
4109 	// self-determinable width if the operands both have definite
4110 	// widths.
4111       virtual bool has_width() const;
4112 
4113       virtual NetEBinary* dup_expr() const;
4114       virtual NetExpr* eval_tree();
4115       virtual NetExpr* evaluate_function(const LineInfo&loc,
4116 					 map<perm_string,LocalVar>&ctx) const;
4117       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4118                                   bool nested_func = false) const;
4119 
4120       virtual void expr_scan(struct expr_scan_t*) const;
4121       virtual void dump(ostream&) const;
4122 
4123     protected:
4124       char op_;
4125       NetExpr* left_;
4126       NetExpr* right_;
4127 
4128       virtual NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4129 };
4130 
4131 /*
4132  * The addition operators have slightly more complex width
4133  * calculations because there is the optional carry bit that can be
4134  * used. The operators covered by this class are:
4135  *   +  -- Arithmetic add
4136  *   -  -- Arithmetic minus
4137  */
4138 class NetEBAdd : public NetEBinary {
4139 
4140     public:
4141       NetEBAdd(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4142       ~NetEBAdd();
4143 
4144       virtual ivl_variable_type_t expr_type() const;
4145 
4146       virtual NetEBAdd* dup_expr() const;
4147       virtual NetExpr* eval_tree();
4148       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4149 
4150     private:
4151       NetExpr  * eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4152       NetECReal* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
4153 };
4154 
4155 /*
4156  * This class represents the integer division operators.
4157  *   /  -- Divide
4158  *   %  -- Modulus
4159  */
4160 class NetEBDiv : public NetEBinary {
4161 
4162     public:
4163       NetEBDiv(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4164       ~NetEBDiv();
4165 
4166       virtual ivl_variable_type_t expr_type() const;
4167 
4168       virtual NetEBDiv* dup_expr() const;
4169       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4170 
4171     private:
4172       NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4173       NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
4174 };
4175 
4176 /*
4177  * The bitwise binary operators are represented by this class. This is
4178  * a specialization of the binary operator, so is derived from
4179  * NetEBinary. The particular constraints on these operators are that
4180  * operand and result widths match exactly, and each bit slice of the
4181  * operation can be represented by a simple gate. The operators
4182  * covered by this class are:
4183  *
4184  *   ^  -- Bit-wise exclusive OR
4185  *   &  -- Bit-wise AND
4186  *   |  -- Bit-wise OR
4187  *   O  -- Bit-wise NOR
4188  *   X  -- Bit-wise XNOR (~^)
4189  */
4190 class NetEBBits : public NetEBinary {
4191 
4192     public:
4193       NetEBBits(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4194       ~NetEBBits();
4195 
4196       virtual NetEBBits* dup_expr() const;
4197       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4198 
4199     private:
4200       NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4201 };
4202 
4203 /*
4204  * The binary comparison operators are handled by this class. This
4205  * this case the bit width of the expression is 1 bit, and the
4206  * operands take their natural widths. The supported operators are:
4207  *
4208  *   <  -- Less than
4209  *   >  -- Greater than
4210  *   e  -- Logical equality (==)
4211  *   E  -- Case equality (===)
4212  *   L  -- Less or equal (<=)
4213  *   G  -- Greater or equal (>=)
4214  *   n  -- Logical inequality (!=)
4215  *   N  -- Case inequality (!==)
4216  */
4217 class NetEBComp : public NetEBinary {
4218 
4219     public:
4220       NetEBComp(char op, NetExpr*l, NetExpr*r);
4221       ~NetEBComp();
4222 
4223 	/* A compare expression has a definite width. */
4224       virtual bool has_width() const;
4225       virtual ivl_variable_type_t expr_type() const;
4226       virtual NetEBComp* dup_expr() const;
4227       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4228 
4229     private:
4230       NetEConst* must_be_leeq_(const NetExpr*le, const verinum&rv, bool eq_flag) const;
4231 
4232       NetEConst*eval_arguments_(const NetExpr*le, const NetExpr*re) const;
4233       NetEConst*eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
4234       NetEConst*eval_eqeq_real_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
4235       NetEConst*eval_less_(const NetExpr*le, const NetExpr*re) const;
4236       NetEConst*eval_leeq_(const NetExpr*le, const NetExpr*re) const;
4237       NetEConst*eval_leeq_real_(const NetExpr*le, const NetExpr*ri, bool eq_flag) const;
4238       NetEConst*eval_gt_(const NetExpr*le, const NetExpr*re) const;
4239       NetEConst*eval_gteq_(const NetExpr*le, const NetExpr*re) const;
4240       NetEConst*eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
4241       NetEConst*eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const;
4242 };
4243 
4244 /*
4245  * The binary logical operators are those that return boolean
4246  * results. The supported operators are:
4247  *
4248  *   a  -- Logical AND (&&)
4249  *   o  -- Logical OR (||)
4250  */
4251 class NetEBLogic : public NetEBinary {
4252 
4253     public:
4254       NetEBLogic(char op, NetExpr*l, NetExpr*r);
4255       ~NetEBLogic();
4256 
4257       virtual NetEBLogic* dup_expr() const;
4258       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4259 
4260     private:
4261       NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4262 };
4263 
4264 /*
4265  * Support the binary min(l,r) and max(l,r) operators. The opcodes
4266  * supported are:
4267  *
4268  *   m -- min
4269  *   M -- max
4270  */
4271 class NetEBMinMax : public NetEBinary {
4272 
4273     public:
4274       NetEBMinMax(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4275       ~NetEBMinMax();
4276 
4277       virtual ivl_variable_type_t expr_type() const;
4278 
4279     private:
4280       NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4281       NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
4282 };
4283 
4284 /*
4285  * Support the binary multiplication (*) operator.
4286  */
4287 class NetEBMult : public NetEBinary {
4288 
4289     public:
4290       NetEBMult(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4291       ~NetEBMult();
4292 
4293       virtual ivl_variable_type_t expr_type() const;
4294 
4295       virtual NetEBMult* dup_expr() const;
4296       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4297 
4298     private:
4299       NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4300       NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
4301 };
4302 
4303 /*
4304  * Support the binary power (**) operator.
4305  */
4306 class NetEBPow : public NetEBinary {
4307 
4308     public:
4309       NetEBPow(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4310       ~NetEBPow();
4311 
4312       virtual ivl_variable_type_t expr_type() const;
4313 
4314       virtual NetEBPow* dup_expr() const;
4315       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4316 
4317     private:
4318       NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4319       NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
4320 };
4321 
4322 
4323 /*
4324  * Support the binary shift operators. The supported operators are:
4325  *
4326  *   l  -- left shift (<<)
4327  *   r  -- right shift (>>)
4328  *   R  -- right shift arithmetic (>>>)
4329  */
4330 class NetEBShift : public NetEBinary {
4331 
4332     public:
4333       NetEBShift(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag);
4334       ~NetEBShift();
4335 
4336 	// A shift expression only needs the left expression to have a
4337 	// definite width to give the expression a definite width.
4338       virtual bool has_width() const;
4339 
4340       virtual NetEBShift* dup_expr() const;
4341       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4342 
4343     private:
4344       NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
4345 };
4346 
4347 
4348 /*
4349  * This expression node supports the concat expression. This is an
4350  * operator that just glues the results of many expressions into a
4351  * single value.
4352  *
4353  * Note that the class stores the parameter expressions in source code
4354  * order. That is, the parm(0) is placed in the most significant
4355  * position of the result.
4356  */
4357 class NetEConcat  : public NetExpr {
4358 
4359     public:
4360       NetEConcat(unsigned cnt, unsigned repeat, ivl_variable_type_t vt);
4361       ~NetEConcat();
4362 
4363 	// Manipulate the parameters.
4364       void set(unsigned idx, NetExpr*e);
4365 
repeat()4366       unsigned repeat() const { return repeat_; }
nparms()4367       unsigned nparms() const { return parms_.size() ; }
parm(unsigned idx)4368       NetExpr* parm(unsigned idx) const { return parms_[idx]; }
4369 
4370       virtual ivl_variable_type_t expr_type() const;
4371       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4372                                   bool nested_func = false) const;
4373       virtual bool has_width() const;
4374       virtual NetEConcat* dup_expr() const;
4375       virtual NetEConst*  eval_tree();
4376       virtual NetExpr* evaluate_function(const LineInfo&loc,
4377 					 map<perm_string,LocalVar>&ctx) const;
4378       virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
4379       virtual void expr_scan(struct expr_scan_t*) const;
4380       virtual void dump(ostream&) const;
4381 
4382     private:
4383       std::vector<NetExpr*>parms_;
4384       unsigned repeat_;
4385       ivl_variable_type_t expr_type_;
4386 
4387       NetEConst* eval_arguments_(const vector<NetExpr*>&vals, unsigned gap) const;
4388 };
4389 
4390 
4391 /*
4392  * This expression node supports bit/part selects from general
4393  * expressions. The sub-expression is self-sized, and has bits
4394  * selected from it. The base is the expression that identifies the
4395  * lsb of the expression, and the wid is the width of the part select,
4396  * or 1 for a bit select. No matter what the subexpression is, the
4397  * base is translated in canonical bits. It is up to the elaborator
4398  * to figure this out and adjust the expression if the subexpression
4399  * has a non-canonical base or direction.
4400  *
4401  * If the base expression is null, then this expression node can be
4402  * used to express width expansion, signed or unsigned depending on
4403  * the has_sign() flag.
4404  */
4405 class NetESelect  : public NetExpr {
4406 
4407     public:
4408       NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
4409                  ivl_select_type_t sel_type = IVL_SEL_OTHER);
4410       ~NetESelect();
4411 
4412       const NetExpr*sub_expr() const;
4413       const NetExpr*select() const;
4414       ivl_select_type_t select_type() const;
4415 
4416 	// The type of a NetESelect is the base type of the
4417 	// sub-expression.
4418       virtual ivl_variable_type_t expr_type() const;
4419 
4420       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4421                                   bool nested_func = false) const;
4422       virtual bool has_width() const;
4423       virtual void expr_scan(struct expr_scan_t*) const;
4424       virtual NetEConst* eval_tree();
4425       virtual NetExpr*evaluate_function(const LineInfo&loc,
4426 					map<perm_string,LocalVar>&ctx) const;
4427       virtual NetESelect* dup_expr() const;
4428       virtual NetNet*synthesize(Design*des, NetScope*scope, NetExpr*root);
4429       virtual void dump(ostream&) const;
4430 
4431     private:
4432       NetExpr*expr_;
4433       NetExpr*base_;
4434       ivl_select_type_t sel_type_;
4435 };
4436 
4437 /*
4438  * This node is for representation of named events.
4439  */
4440 class NetEEvent : public NetExpr {
4441 
4442     public:
4443       explicit NetEEvent(NetEvent*);
4444       ~NetEEvent();
4445 
4446       const NetEvent* event() const;
4447 
4448       virtual void expr_scan(struct expr_scan_t*) const;
4449       virtual NetEEvent* dup_expr() const;
4450       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4451                                   bool nested_func = false) const;
4452 
4453       virtual void dump(ostream&os) const;
4454 
4455     private:
4456       NetEvent*event_;
4457 };
4458 
4459 /*
4460  * This class is a special (and magical) expression node type that
4461  * represents enumeration types. These can only be found as parameters
4462  * to NetSTask objects.
4463  */
4464 class NetENetenum  : public NetExpr {
4465 
4466     public:
4467       explicit NetENetenum(const netenum_t*);
4468       ~NetENetenum();
4469 
4470       const netenum_t* netenum() const;
4471 
4472       virtual void expr_scan(struct expr_scan_t*) const;
4473       virtual NetENetenum* dup_expr() const;
4474       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4475                                   bool nested_func = false) const;
4476 
4477       virtual void dump(ostream&os) const;
4478 
4479     private:
4480       const netenum_t*netenum_;
4481 };
4482 
4483 class NetENew : public NetExpr {
4484     public:
4485 	// Make class object
4486       explicit NetENew(ivl_type_t);
4487 	// dynamic array of objects.
4488       explicit NetENew(ivl_type_t, NetExpr*size, NetExpr* init_val=0);
4489       ~NetENew();
4490 
get_type()4491       inline ivl_type_t get_type() const { return obj_type_; }
size_expr()4492       inline const NetExpr*size_expr() const { return size_; }
init_expr()4493       inline const NetExpr*init_expr() const { return init_val_; }
4494 
4495       virtual ivl_variable_type_t expr_type() const;
4496 
4497       virtual void expr_scan(struct expr_scan_t*) const;
4498       virtual NetENew* dup_expr() const;
4499       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4500                                   bool nested_func = false) const;
4501 
4502       virtual void dump(ostream&os) const;
4503 
4504     private:
4505       ivl_type_t obj_type_;
4506       NetExpr*size_;
4507       NetExpr*init_val_;
4508 };
4509 
4510 /*
4511  * The NetENull node represents the SystemVerilog (null)
4512  * expression. This is always a null class handle.
4513  */
4514 class NetENull : public NetExpr {
4515 
4516     public:
4517       NetENull();
4518       ~NetENull();
4519 
4520       virtual void expr_scan(struct expr_scan_t*) const;
4521       virtual NetENull* dup_expr() const;
4522       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4523                                   bool nested_func = false) const;
4524 
4525       virtual void dump(ostream&os) const;
4526 };
4527 
4528 /*
4529  * The NetEProperty represents a SystemVerilog property select of a
4530  * class object. In SV, the expression would look like "a.b", where
4531  * the "a" is the signal (the NetNet) and "b" is the property name.
4532  *
4533  * The canon_index is an optional expression to address an element for
4534  * parameters that are arrays.
4535  */
4536 class NetEProperty : public NetExpr {
4537     public:
4538       NetEProperty(NetNet*n, perm_string pname, NetExpr*canon_index =0);
4539       ~NetEProperty();
4540 
get_sig()4541       inline const NetNet* get_sig() const { return net_; }
property_idx()4542       inline size_t property_idx() const { return pidx_; }
get_index()4543       inline const NetExpr*get_index() const { return index_; }
4544 
4545     public: // Overridden methods
4546       ivl_variable_type_t expr_type() const;
4547       virtual void expr_scan(struct expr_scan_t*) const;
4548       virtual NetEProperty* dup_expr() const;
4549       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4550                                   bool nested_func = false) const;
4551 
4552       virtual void dump(ostream&os) const;
4553 
4554     private:
4555       NetNet*net_;
4556       size_t pidx_;
4557       NetExpr*index_;
4558 };
4559 
4560 /*
4561  * This class is a special (and magical) expression node type that
4562  * represents scope names. These can only be found as parameters to
4563  * NetSTask objects.
4564  */
4565 class NetEScope  : public NetExpr {
4566 
4567     public:
4568       explicit NetEScope(NetScope*);
4569       ~NetEScope();
4570 
4571       const NetScope* scope() const;
4572 
4573       virtual void expr_scan(struct expr_scan_t*) const;
4574       virtual NetEScope* dup_expr() const;
4575       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4576                                   bool nested_func = false) const;
4577 
4578       virtual void dump(ostream&os) const;
4579 
4580     private:
4581       NetScope*scope_;
4582 };
4583 
4584 /*
4585  * This node represents a system function call in an expression. The
4586  * object contains the name of the system function, which the backend
4587  * uses to do VPI matching.
4588  */
4589 class NetESFunc  : public NetExpr {
4590 
4591     public:
4592       NetESFunc(const char*name, ivl_variable_type_t t,
4593 		unsigned width, unsigned nprms, bool is_overridden =false);
4594       NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms);
4595       NetESFunc(const char*name, const netenum_t*enum_type, unsigned nprms);
4596       ~NetESFunc();
4597 
4598       const char* name() const;
4599 
4600       unsigned nparms() const;
4601       void parm(unsigned idx, NetExpr*expr);
4602       NetExpr* parm(unsigned idx);
4603       const NetExpr* parm(unsigned idx) const;
4604 
4605       virtual NetExpr* eval_tree();
4606       virtual NetExpr* evaluate_function(const LineInfo&loc,
4607 					 map<perm_string,LocalVar>&ctx) const;
4608 
4609       virtual ivl_variable_type_t expr_type() const;
4610       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4611                                   bool nested_func = false) const;
4612       virtual const netenum_t* enumeration() const;
4613       virtual void dump(ostream&) const;
4614 
4615       virtual void expr_scan(struct expr_scan_t*) const;
4616       virtual NetESFunc*dup_expr() const;
4617       virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
4618 
4619     private:
4620 	/* Use the 32 bit ID as follows:
4621 	 *   The lower sixteen bits are used to identify the individual
4622 	 *   functions.
4623 	 *
4624 	 *   The top sixteen bits are used to indicate the number of
4625 	 *   arguments the function can take by bit position. If more
4626 	 *   than one bit is set the argument can take a different number
4627 	 *   of arguments. This varies from 0 to 14 with the MSB indicating
4628 	 *   fifteen or more (an unbounded value). For example all bit set
4629 	 *   except for the LSB indicate 1 or more arguments are allowed.
4630 	 */
4631       enum ID { NOT_BUILT_IN = 0x0,
4632                   /* Available in all version of Verilog/SystemVerilog. */
4633                 ITOR   = 0x00020001,  /* $itor takes one argument. */
4634                 RTOI   = 0x00020002,  /* $rtoi takes one argument. */
4635                   /* Available in Verilog 2005 and later. */
4636                 ACOS   = 0x00020003,  /* $acos takes one argument. */
4637                 ACOSH  = 0x00020004,  /* $acosh takes one argument. */
4638                 ASIN   = 0x00020005,  /* $asin takes one argument. */
4639                 ASINH  = 0x00020006,  /* $asinh takes one argument. */
4640                 ATAN   = 0x00020007,  /* $atan takes one argument. */
4641                 ATANH  = 0x00020008,  /* $atanh takes one argument. */
4642                 ATAN2  = 0x00040009,  /* $atan2 takes two argument. */
4643                 CEIL   = 0x0002000a,  /* $ceil takes one argument. */
4644                 CLOG2  = 0x0002000b,  /* $clog2 takes one argument. */
4645                 COS    = 0x0002000c,  /* $cos takes one argument. */
4646                 COSH   = 0x0002000d,  /* $cosh takes one argument. */
4647                 EXP    = 0x0002000e,  /* $exp takes one argument. */
4648                 FLOOR  = 0x0002000f,  /* $floor takes one argument. */
4649                 HYPOT  = 0x00040010,  /* $hypot takes two argument. */
4650                 LN     = 0x00020011,  /* $ln takes one argument. */
4651                 LOG10  = 0x00020012,  /* $log10 takes one argument. */
4652                 POW    = 0x00040013,  /* $pow takes two argument. */
4653                 SIN    = 0x00020014,  /* $sin takes one argument. */
4654                 SINH   = 0x00020015,  /* $sinh takes one argument. */
4655                 SQRT   = 0x00020016,  /* $sqrt takes one argument. */
4656                 TAN    = 0x00020017,  /* $tan takes one argument. */
4657                 TANH   = 0x00020018,  /* $tanh takes one argument. */
4658                   /* Added in SystemVerilog 2005 and later. */
4659                 DIMS   = 0x00020019,  /* $dimensions takes one argument. */
4660                 HIGH   = 0x0006001a,  /* $high takes one or two arguments. */
4661                 INCR   = 0x0006001b,  /* $increment takes one or two arguments. */
4662                 LEFT   = 0x0006001c,  /* $left takes one or two arguments. */
4663                 LOW    = 0x0006001d,  /* $low takes one or two arguments. */
4664                 RIGHT  = 0x0006001e,  /* $right takes one or two arguments. */
4665                 SIZE   = 0x0006001f,  /* $size takes one or two arguments. */
4666                 UPDIMS = 0x00020020,  /* $unpacked_dimensions takes one argument. */
4667                 ISUNKN = 0x00020021,  /* $isunknown takes one argument. */
4668                 ONEHT  = 0x00020022,  /* $onehot takes one argument. */
4669                 ONEHT0 = 0x00020023,  /* $onehot0 takes one argument. */
4670                   /* Added in SystemVerilog 2009 and later. */
4671                 CTONES = 0x00020024,  /* $countones takes one argument. */
4672                   /* Added in SystemVerilog 2012 and later. */
4673                 CTBITS = 0xfffc0025,  /* $countbits takes two or more arguments. */
4674                   /* Added as Icarus extensions to Verilog-A. */
4675                 ABS    = 0x00020026,  /* $abs takes one argument. */
4676                 MAX    = 0x00040027,  /* $max takes two argument. */
4677                 MIN    = 0x00040028,  /* $min takes two argument. */
4678                   /* A dummy value to properly close the enum. */
4679 		DUMMY  = 0xffffffff };
4680 
takes_nargs_(ID func,unsigned nargs)4681       bool takes_nargs_(ID func, unsigned nargs) {
4682 	    if (nargs > 15) nargs = 15;
4683 	    return func & (1U << (nargs + 16));
4684       }
4685 
4686       const char* name_;
4687       ivl_variable_type_t type_;
4688       const netenum_t*enum_type_;
4689       std::vector<NetExpr*>parms_;
4690       bool is_overridden_;
4691 
4692       ID built_in_id_() const;
4693 
4694       NetExpr* evaluate_one_arg_(ID id, const NetExpr*arg) const;
4695       NetExpr* evaluate_two_arg_(ID id, const NetExpr*arg0,
4696 					const NetExpr*arg1) const;
4697 
4698       NetEConst* evaluate_rtoi_(const NetExpr*arg) const;
4699       NetECReal* evaluate_itor_(const NetExpr*arg) const;
4700 
4701       NetEConst* evaluate_clog2_(const NetExpr*arg) const;
4702 
4703       NetECReal* evaluate_math_one_arg_(ID id, const NetExpr*arg) const;
4704       NetECReal* evaluate_math_two_arg_(ID id, const NetExpr*arg0,
4705 					       const NetExpr*arg1) const;
4706 
4707       NetExpr* evaluate_abs_(const NetExpr*arg) const;
4708       NetExpr* evaluate_min_max_(ID id, const NetExpr*arg0,
4709 					const NetExpr*arg1) const;
4710 
4711 	/* Constant SystemVerilog functions. */
4712       NetEConst* evaluate_countones_(const NetExpr*arg) const;
4713       NetEConst* evaluate_dimensions_(const NetExpr*arg) const;
4714       NetEConst* evaluate_isunknown_(const NetExpr*arg) const;
4715       NetEConst* evaluate_onehot_(const NetExpr*arg) const;
4716       NetEConst* evaluate_onehot0_(const NetExpr*arg) const;
4717       NetEConst* evaluate_unpacked_dimensions_(const NetExpr*arg) const;
4718 
4719 	/* This value is used as a default when the array functions are
4720 	 * called with a single argument. */
4721       static const NetEConst*const_one_;
4722 
4723       NetEConst* evaluate_array_funcs_(ID id,
4724                                        const NetExpr*arg0,
4725                                        const NetExpr*arg1) const;
4726       NetEConst* evaluate_countbits_(void) const;
4727 
4728     public:
is_built_in()4729       bool is_built_in() const { return built_in_id_() != NOT_BUILT_IN; };
4730 
4731     private: // not implemented
4732       NetESFunc(const NetESFunc&);
4733       NetESFunc& operator= (const NetESFunc&);
4734 };
4735 
4736 class NetEShallowCopy : public NetExpr {
4737     public:
4738 	// Make a shallow copy from arg2 into arg1.
4739       explicit NetEShallowCopy(NetExpr*arg1, NetExpr*arg2);
4740       ~NetEShallowCopy();
4741 
4742       virtual ivl_variable_type_t expr_type() const;
4743 
4744       virtual void expr_scan(struct expr_scan_t*) const;
4745       virtual NetEShallowCopy* dup_expr() const;
4746       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4747                                   bool nested_func = false) const;
4748 
4749       virtual void dump(ostream&os) const;
4750 
4751       void expr_scan_oper1(struct expr_scan_t*) const;
4752       void expr_scan_oper2(struct expr_scan_t*) const;
4753 
4754     private:
4755       NetExpr*arg1_;
4756       NetExpr*arg2_;
4757 };
4758 
4759 /*
4760  * This class represents the ternary (?:) operator. It has 3
4761  * expressions, one of which is a condition used to select which of
4762  * the other two expressions is the result.
4763  */
4764 class NetETernary  : public NetExpr {
4765 
4766     public:
4767       NetETernary(NetExpr*c, NetExpr*t, NetExpr*f, unsigned wid, bool signed_flag);
4768       ~NetETernary();
4769 
4770       const netenum_t* enumeration() const;
4771 
4772       const NetExpr*cond_expr() const;
4773       const NetExpr*true_expr() const;
4774       const NetExpr*false_expr() const;
4775 
4776       virtual NetETernary* dup_expr() const;
4777       virtual NetExpr* eval_tree();
4778       virtual NetExpr*evaluate_function(const LineInfo&loc,
4779 					map<perm_string,LocalVar>&ctx) const;
4780       virtual ivl_variable_type_t expr_type() const;
4781       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4782                                   bool nested_func = false) const;
4783       virtual void expr_scan(struct expr_scan_t*) const;
4784       virtual void dump(ostream&) const;
4785       virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root);
4786 
4787     public:
4788       static bool test_operand_compat(ivl_variable_type_t tru, ivl_variable_type_t fal);
4789 
4790     private:
4791       NetExpr* blended_arguments_(const NetExpr*t, const NetExpr*f) const;
4792 
4793       NetExpr*cond_;
4794       NetExpr*true_val_;
4795       NetExpr*false_val_;
4796 };
4797 
4798 /*
4799  * This class represents a unary operator, with the single operand
4800  * and a single character for the operator. The operator values are:
4801  *
4802  *   ~  -- Bit-wise negation
4803  *   !  -- Logical negation
4804  *   &  -- Reduction AND
4805  *   |  -- Reduction OR
4806  *   ^  -- Reduction XOR
4807  *   +  --
4808  *   -  --
4809  *   A  -- Reduction NAND (~&)
4810  *   N  -- Reduction NOR (~|)
4811  *   X  -- Reduction NXOR (~^ or ^~)
4812  *   m  -- abs(x)  (i.e. "magnitude")
4813  *   v  -- Cast from real to integer (vector)
4814  *   2  -- Cast from real or logic (vector) to bool (vector)
4815  *   r  -- Cast from integer (vector) to real
4816  *   i  -- post-increment
4817  *   I  -- pre-increment
4818  *   d  -- post-decrement
4819  *   D  -- pre-decrement
4820  */
4821 class NetEUnary  : public NetExpr {
4822 
4823     public:
4824       NetEUnary(char op, NetExpr*ex, unsigned wid, bool signed_flag);
4825       ~NetEUnary();
4826 
op()4827       char op() const { return op_; }
expr()4828       const NetExpr* expr() const { return expr_; }
4829 
4830       virtual NetEUnary* dup_expr() const;
4831       virtual NetExpr* eval_tree();
4832       virtual NetExpr* evaluate_function(const LineInfo&loc,
4833 					 map<perm_string,LocalVar>&ctx) const;
4834       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4835 
4836       virtual ivl_variable_type_t expr_type() const;
4837       virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4838                                   bool nested_func = false) const;
4839       virtual void expr_scan(struct expr_scan_t*) const;
4840       virtual void dump(ostream&) const;
4841 
4842     protected:
4843       char op_;
4844       NetExpr* expr_;
4845 
4846     private:
4847       virtual NetExpr* eval_arguments_(const NetExpr*ex) const;
4848       virtual NetExpr* eval_tree_real_(const NetExpr*ex) const;
4849 };
4850 
4851 class NetEUBits : public NetEUnary {
4852 
4853     public:
4854       NetEUBits(char op, NetExpr*ex, unsigned wid, bool signed_flag);
4855       ~NetEUBits();
4856 
4857       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4858 
4859       virtual NetEUBits* dup_expr() const;
4860       virtual ivl_variable_type_t expr_type() const;
4861 };
4862 
4863 class NetEUReduce : public NetEUnary {
4864 
4865     public:
4866       NetEUReduce(char op, NetExpr*ex);
4867       ~NetEUReduce();
4868 
4869       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4870       virtual NetEUReduce* dup_expr() const;
4871       virtual ivl_variable_type_t expr_type() const;
4872 
4873     private:
4874       virtual NetEConst* eval_arguments_(const NetExpr*ex) const;
4875       virtual NetEConst* eval_tree_real_(const NetExpr*ex) const;
4876 };
4877 
4878 class NetECast : public NetEUnary {
4879 
4880     public:
4881       NetECast(char op, NetExpr*ex, unsigned wid, bool signed_flag);
4882       ~NetECast();
4883 
4884       virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
4885       virtual NetECast* dup_expr() const;
4886       virtual ivl_variable_type_t expr_type() const;
4887       virtual void dump(ostream&) const;
4888 
4889     private:
4890       virtual NetExpr* eval_arguments_(const NetExpr*ex) const;
4891 };
4892 
4893 /*
4894  * When a signal shows up in an expression, this type represents
4895  * it. From this the expression can get any kind of access to the
4896  * structural signal, including arrays.
4897  *
4898  * The NetESignal may refer to an array, if the word_index is
4899  * included. This expression calculates the index of the word in the
4900  * array. It may only be nil if the expression refers to the whole
4901  * array, and that is legal only in limited situation.
4902  */
4903 class NetESignal  : public NetExpr {
4904 
4905     public:
4906       explicit NetESignal(NetNet*n);
4907       NetESignal(NetNet*n, NetExpr*word_index);
4908       ~NetESignal();
4909 
4910       perm_string name() const;
4911 
4912       virtual NetESignal* dup_expr() const;
4913       NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root);
4914       NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
4915                           bool nested_func = false) const;
4916       NexusSet* nex_input_base(bool rem_out, bool always_sens, bool nested_func,
4917                                unsigned base, unsigned width) const;
4918       const netenum_t*enumeration() const;
4919 
4920       virtual NetExpr*evaluate_function(const LineInfo&loc,
4921 					map<perm_string,LocalVar>&ctx) const;
4922 
4923 	// This is the expression for selecting an array word, if this
4924 	// signal refers to an array.
4925       const NetExpr* word_index() const;
4926 
4927 	// This is the width of the vector that this signal refers to.
4928       unsigned vector_width() const;
4929 	// Point back to the signal that this expression node references.
4930       const NetNet* sig() const;
4931       NetNet* sig();
4932 	// Declared vector dimensions for the signal.
4933       long msi() const;
4934       long lsi() const;
4935 
4936       virtual ivl_variable_type_t expr_type() const;
4937 
4938       virtual void expr_scan(struct expr_scan_t*) const;
4939       virtual void dump(ostream&) const;
4940 
4941     private:
4942       NetNet*net_;
4943       const netenum_t*enum_type_;
4944 	// Expression to select a word from the net.
4945       NetExpr*word_;
4946 };
4947 
4948 /*
4949  * The Design object keeps a list of work items for processing
4950  * elaboration. This is the type of those work items.
4951  */
4952 struct elaborator_work_item_t {
elaborator_work_item_telaborator_work_item_t4953       explicit elaborator_work_item_t(Design*d)
4954       : des(d) { }
~elaborator_work_item_telaborator_work_item_t4955       virtual ~elaborator_work_item_t() { }
4956       virtual void elaborate_runrun() =0;
4957     protected:
4958       Design*des;
4959 };
4960 
4961 /*
4962  * This class contains an entire design. It includes processes and a
4963  * netlist, and can be passed around from function to function.
4964  */
4965 class Design {
4966 
4967     public:
4968       Design();
4969       ~Design();
4970 
4971 	/* We need to pass the tool delay selection for $sdf_annotate. */
4972       enum delay_sel_t { MIN, TYP, MAX };
4973       void set_delay_sel(delay_sel_t sel);
4974       const char* get_delay_sel() const;
4975 
4976 	/* The flags are a generic way of accepting command line
4977 	   parameters/flags and passing them to the processing steps
4978 	   that deal with the design. The compilation driver sets the
4979 	   entire flags map after elaboration is done. Subsequent
4980 	   steps can then use the get_flag() function to get the value
4981 	   of an interesting key. */
4982 
set_flags(const map<string,const char * > & f)4983       void set_flags(const map<string,const char*>&f) { flags_ = f; }
4984 
4985       const char* get_flag(const string&key) const;
4986 
4987       NetScope* make_root_scope(perm_string name, NetScope*unit_scope,
4988 				bool program_block, bool is_interface);
4989       NetScope* find_root_scope();
4990       std::list<NetScope*> find_root_scopes() const;
4991 
4992       NetScope* make_package_scope(perm_string name, NetScope*unit_scope,
4993 				   bool is_unit);
4994       std::list<NetScope*> find_package_scopes() const;
4995 
4996 	/* Attempt to set the precision to the specified value. If the
4997 	   precision is already more precise, the keep the precise
4998 	   setting. This is intended to hold the simulation precision
4999 	   for use throughout the entire design. */
5000 
5001       void set_precision(int val);
5002       int  get_precision() const;
5003 
5004 	/* This function takes a delay value and a scope, and returns
5005 	   the delay value scaled to the precision of the design. */
5006       uint64_t scale_to_precision(uint64_t, const NetScope*)const;
5007 
5008 	/* Look up a scope. If no starting scope is passed, then the
5009 	   path is taken as an absolute scope name. Otherwise, the
5010 	   scope is located starting at the passed scope and working
5011 	   up if needed. */
5012       NetScope* find_scope(const hname_t&path) const;
5013       NetScope* find_scope(NetScope*, const hname_t&name,
5014                            NetScope::TYPE type = NetScope::MODULE) const;
5015 
5016       NetScope* find_package(perm_string name) const;
5017 
5018 	// Note: Try to remove these versions of find_scope. Avoid
5019 	// using these in new code, use the above forms (or
5020 	// symbol_search) instead.
5021       NetScope* find_scope(const std::list<hname_t>&path) const;
5022       NetScope* find_scope(NetScope*, const std::list<hname_t>&path,
5023                            NetScope::TYPE type = NetScope::MODULE) const;
5024 
5025 	/* These members help manage elaboration of scopes. When we
5026 	   get to a point in scope elaboration where we want to put
5027 	   off a scope elaboration, an object of scope_elaboration_t
5028 	   is pushed onto the scope_elaborations list. The scope
5029 	   elaborator will go through this list elaborating scopes
5030 	   until the list is empty. */
5031       list<elaborator_work_item_t*>elaboration_work_list;
5032       void run_elaboration_work(void);
5033 
5034       set<NetScope*> defparams_later;
5035 
5036 	// PARAMETERS
5037 
5038       void run_defparams();
5039       void evaluate_parameters();
5040 	// Look for defparams that never matched, and print warnings.
5041       void residual_defparams();
5042 
5043 	/* This method locates a signal, starting at a given
5044 	   scope. The name parameter may be partially hierarchical, so
5045 	   this method, unlike the NetScope::find_signal method,
5046 	   handles global name binding. */
5047 
5048       NetNet*find_signal(NetScope*scope, pform_name_t path);
5049 
5050 	// Functions
5051       NetFuncDef* find_function(NetScope*scope, const pform_name_t&key);
5052 
5053 	// Tasks
5054       NetScope* find_task(NetScope*scope, const pform_name_t&name);
5055 
5056 	// NODES
5057       void add_node(NetNode*);
5058       void del_node(NetNode*);
5059 
5060 	// BRANCHES
5061       void add_branch(NetBranch*);
5062 
5063 	// PROCESSES
5064       void add_process(NetProcTop*);
5065       void add_process(NetAnalogTop*);
5066       void delete_process(NetProcTop*);
5067       bool check_proc_delay() const;
5068       bool check_proc_synth() const;
5069 
5070       NetNet* find_discipline_reference(ivl_discipline_t dis, NetScope*scope);
5071 
5072 	// Iterate over the design...
5073       void dump(ostream&) const;
5074       void functor(struct functor_t*);
5075       void join_islands(void);
5076       int emit(struct target_t*) const;
5077 
5078 	// This is incremented by elaboration when an error is
5079 	// detected. It prevents code being emitted.
5080       unsigned errors;
5081 
5082     private:
5083       NetScope* find_scope_(NetScope*, const hname_t&name,
5084                             NetScope::TYPE type = NetScope::MODULE) const;
5085 
5086       NetScope* find_scope_(NetScope*, const std::list<hname_t>&path,
5087                             NetScope::TYPE type = NetScope::MODULE) const;
5088 
5089 	// Keep a tree of scopes. The NetScope class handles the wide
5090 	// tree and per-hop searches for me.
5091       list<NetScope*>root_scopes_;
5092 
5093 	// Keep a map of all the elaborated packages. Note that
5094 	// packages do not nest.
5095       std::map<perm_string,NetScope*>packages_;
5096 
5097 	// List the nodes in the design.
5098       NetNode*nodes_;
5099 	// These are in support of the node functor iterator.
5100       NetNode*nodes_functor_cur_;
5101       NetNode*nodes_functor_nxt_;
5102 
5103 	// List the branches in the design.
5104       NetBranch*branches_;
5105 
5106 	// List the processes in the design.
5107       NetProcTop*procs_;
5108       NetProcTop*procs_idx_;
5109 
5110 	// List the ANALOG processes in the design.
5111       NetAnalogTop*aprocs_;
5112 
5113 	// Map of discipline take to NetNet for the reference node.
5114       map<perm_string,NetNet*>discipline_references_;
5115 
5116 	// Map the design arguments to values.
5117       map<string,const char*> flags_;
5118 
5119       int des_precision_;
5120       delay_sel_t des_delay_sel_;
5121 
5122     private: // not implemented
5123       Design(const Design&);
5124       Design& operator= (const Design&);
5125 };
5126 
5127 
5128 /* =======
5129  */
5130 
5131 inline bool operator == (const Link&l, const Link&r)
5132 { return l.is_equal(r); }
5133 
5134 inline bool operator != (const Link&l, const Link&r)
5135 { return ! l.is_equal(r); }
5136 
5137 /* Connect the pins of two nodes together. Either may already be
5138    connected to other things, connect is transitive. */
5139 extern void connect(Link&, Link&);
5140 
5141 /* Return true if l and r are connected. */
connected(const Link & l,const Link & r)5142 inline bool connected(const Link&l, const Link&r)
5143 { return l.is_linked(r); }
5144 
5145 /* Return the number of signals in the nexus. */
5146 extern unsigned count_signals(const Link&pin);
5147 
5148 /* Find the next link that is an output into the nexus. */
5149 extern Link* find_next_output(Link*lnk);
5150 
5151 /* Find the signal connected to the given node pin. There should
5152    always be exactly one signal. The bidx parameter gets filled with
5153    the signal index of the Net, in case it is a vector. */
5154 const NetNet* find_link_signal(const NetObj*net, unsigned pin,
5155 			       unsigned&bidx);
5156 
5157 inline ostream& operator << (ostream&o, const NetExpr&exp)
5158 { exp.dump(o); return o; }
5159 
5160 extern ostream& operator << (ostream&, NetNet::Type);
5161 
5162 /*
5163  * Manipulator to dump a scope complete path to the output. The
5164  * manipulator is "scope_path" and works like this:
5165  *
5166  *   out << .... << scope_path(sc) << ... ;
5167  */
5168 struct __ScopePathManip { const NetScope*scope; };
scope_path(const NetScope * scope)5169 inline __ScopePathManip scope_path(const NetScope*scope)
5170 { __ScopePathManip tmp; tmp.scope = scope; return tmp; }
5171 
5172 extern ostream& operator << (ostream&o, __ScopePathManip);
5173 
5174 struct __ObjectPathManip { const NetObj*obj; };
scope_path(const NetObj * obj)5175 inline __ObjectPathManip scope_path(const NetObj*obj)
5176 { __ObjectPathManip tmp; tmp.obj = obj; return tmp; }
5177 
5178 extern ostream& operator << (ostream&o, __ObjectPathManip);
5179 
5180 /*
5181  * If this link has a nexus_ pointer, then it is the last Link in the
5182  * list. next_nlink() returns 0 for the last Link.
5183  */
next_nlink()5184 inline Link* Link::next_nlink()
5185 {
5186       if (nexus_) return 0;
5187       else return next_;
5188 }
5189 
next_nlink()5190 inline const Link* Link::next_nlink() const
5191 {
5192       if (nexus_) return 0;
5193       else return next_;
5194 }
5195 
get_obj()5196 inline NetPins*Link::get_obj()
5197 {
5198       if (pin_zero_)
5199 	    return node_;
5200       Link*tmp = this - pin_;
5201       assert(tmp->pin_zero_);
5202       return tmp->node_;
5203 }
5204 
get_obj()5205 inline const NetPins*Link::get_obj() const
5206 {
5207       if (pin_zero_)
5208 	    return node_;
5209       const Link*tmp = this - pin_;
5210       assert(tmp->pin_zero_);
5211       return tmp->node_;
5212 }
5213 
get_pin()5214 inline unsigned Link::get_pin() const
5215 {
5216       if (pin_zero_)
5217 	    return 0;
5218       else
5219 	    return pin_;
5220 }
5221 
5222 #undef ENUM_UNSIGNED_INT
5223 #endif /* IVL_netlist_H */
5224