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