2 * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #if !defined(WINNT) && !defined(macintosh)
20 #ident "$Id: netlist.cc,v 1.127 2000/05/27 19:33:23 steve Exp $"
28 ostream
& operator<< (ostream
&o
, NetNet::Type t
)
31 case NetNet::IMPLICIT
:
32 o
<< "wire /*implicit*/";
34 case NetNet::IMPLICIT_REG
:
35 o
<< "reg /*implicit*/";
78 void connect(Link
&l
, Link
&r
)
81 assert(l
.next_
->prev_
== &l
);
82 assert(l
.prev_
->next_
== &l
);
83 assert(r
.next_
->prev_
== &r
);
84 assert(r
.prev_
->next_
== &r
);
88 Link
*tmp
= cur
->next_
;
90 // If I stumble on r in the nexus, then stop now because
91 // we are already connected.
94 // Pull cur out of left list...
95 cur
->prev_
->next_
= cur
->next_
;
96 cur
->next_
->prev_
= cur
->prev_
;
98 // Put cur in right list
101 cur
->next_
->prev_
= cur
;
102 cur
->prev_
->next_
= cur
;
104 // Go to the next item in the left list.
108 assert(l
.next_
->prev_
== &l
);
109 assert(l
.prev_
->next_
== &l
);
110 assert(r
.next_
->prev_
== &r
);
111 assert(r
.prev_
->next_
== &r
);
115 : dir_(PASSIVE
), drive0_(STRONG
), drive1_(STRONG
),
116 inst_(0), next_(this), prev_(this)
125 void Link::set_dir(DIR d
)
130 Link::DIR Link::get_dir() const
135 void Link::drive0(Link::strength_t str
)
140 void Link::drive1(Link::strength_t str
)
145 Link::strength_t
Link::drive0() const
150 Link::strength_t
Link::drive1() const
155 void Link::cur_link(NetObj
*&net
, unsigned &pin
)
163 next_
->prev_
= prev_
;
164 prev_
->next_
= next_
;
165 next_
= prev_
= this;
168 bool Link::is_equal(const Link
&that
) const
170 return (node_
== that
.node_
) && (pin_
== that
.pin_
);
173 bool Link::is_linked() const
175 return next_
!= this;
178 bool Link::is_linked(const NetObj
&that
) const
180 for (const Link
*idx
= next_
; this != idx
; idx
= idx
->next_
)
181 if (idx
->node_
== &that
)
187 bool Link::is_linked(const Link
&that
) const
189 for (const Link
*idx
= next_
; this != idx
; idx
= idx
->next_
)
190 if (idx
->is_equal(that
))
196 void Link::next_link(NetObj
*&net
, unsigned&pin
)
198 assert(next_
->prev_
== this);
199 assert(prev_
->next_
== this);
204 void Link::next_link(const NetObj
*&net
, unsigned&pin
) const
206 assert(next_
->prev_
== this);
207 assert(prev_
->next_
== this);
212 Link
* Link::next_link()
214 assert(next_
->prev_
== this);
215 assert(prev_
->next_
== this);
219 const Link
* Link::next_link() const
221 assert(next_
->prev_
== this);
222 assert(prev_
->next_
== this);
226 const NetObj
*Link::get_obj() const
231 NetObj
*Link::get_obj()
236 unsigned Link::get_pin() const
241 void Link::set_name(const string
&n
, unsigned i
)
247 const string
& Link::get_name() const
252 unsigned Link::get_inst() const
257 bool connected(const NetObj
&l
, const NetObj
&r
)
259 for (unsigned idx
= 0 ; idx
< l
.pin_count() ; idx
+= 1)
260 if (! l
.pin(idx
).is_linked(r
))
266 unsigned count_inputs(const Link
&pin
)
268 unsigned count
= (pin
.get_dir() == Link::INPUT
)? 1 : 0;
271 pin
.next_link(cur
, cpin
);
272 while (cur
->pin(cpin
) != pin
) {
273 if (cur
->pin(cpin
).get_dir() == Link::INPUT
)
275 cur
->pin(cpin
).next_link(cur
, cpin
);
281 unsigned count_outputs(const Link
&pin
)
283 unsigned count
= (pin
.get_dir() == Link::OUTPUT
)? 1 : 0;
286 pin
.next_link(cur
, cpin
);
287 while (cur
->pin(cpin
) != pin
) {
288 if (cur
->pin(cpin
).get_dir() == Link::OUTPUT
)
290 cur
->pin(cpin
).next_link(cur
, cpin
);
296 unsigned count_signals(const Link
&pin
)
299 if (dynamic_cast<const NetNet
*>(pin
.get_obj()))
304 pin
.next_link(cur
, cpin
);
305 while (cur
->pin(cpin
) != pin
) {
306 if (dynamic_cast<const NetNet
*>(cur
))
309 cur
->pin(cpin
).next_link(cur
, cpin
);
315 const NetNet
* find_link_signal(const NetObj
*net
, unsigned pin
, unsigned&bidx
)
319 net
->pin(pin
).next_link(cur
, cpin
);
322 const NetNet
*sig
= dynamic_cast<const NetNet
*>(cur
);
327 cur
->pin(cpin
).next_link(cur
, cpin
);
333 Link
* find_next_output(Link
*lnk
)
335 for (Link
*cur
= lnk
->next_link()
336 ; cur
!= lnk
; cur
= cur
->next_link())
337 if (cur
->get_dir() == Link::OUTPUT
)
343 NetObj::NetObj(const string
&n
, unsigned np
)
344 : name_(n
), npins_(np
), delay1_(0), delay2_(0), delay3_(0), mark_(false)
346 pins_
= new Link
[npins_
];
347 for (unsigned idx
= 0 ; idx
< npins_
; idx
+= 1) {
348 pins_
[idx
].node_
= this;
349 pins_
[idx
].pin_
= idx
;
358 void NetObj::set_attributes(const map
<string
,string
>&attr
)
360 assert(attributes_
.size() == 0);
364 string
NetObj::attribute(const string
&key
) const
366 map
<string
,string
>::const_iterator idx
= attributes_
.find(key
);
367 if (idx
== attributes_
.end())
370 return (*idx
).second
;
373 void NetObj::attribute(const string
&key
, const string
&value
)
375 attributes_
[key
] = value
;
378 bool NetObj::has_compat_attributes(const NetObj
&that
) const
380 map
<string
,string
>::const_iterator idx
;
381 for (idx
= that
.attributes_
.begin()
382 ; idx
!= that
.attributes_
.end() ; idx
++) {
383 map
<string
,string
>::const_iterator cur
;
384 cur
= attributes_
.find((*idx
).first
);
386 if (cur
== attributes_
.end())
388 if ((*cur
).second
!= (*idx
).second
)
395 Link
& NetObj::pin(unsigned idx
)
397 assert(idx
< npins_
);
401 const Link
& NetObj::pin(unsigned idx
) const
403 assert(idx
< npins_
);
407 NetNode::NetNode(const string
&n
, unsigned npins
)
408 : NetObj(n
, npins
), node_next_(0), node_prev_(0), design_(0)
415 design_
->del_node(this);
418 NetNode
* NetNode::next_node()
420 for (Link
*pin0
= pin(0).next_link()
421 ; *pin0
!= pin(0) ; pin0
= pin0
->next_link()) {
422 NetNode
*cur
= dynamic_cast<NetNode
*>(pin0
->get_obj());
425 if (cur
->pin_count() != pin_count())
430 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1)
431 flag
= flag
&& pin(idx
).is_linked(cur
->pin(idx
));
440 NetNet::NetNet(NetScope
*s
, const string
&n
, Type t
, unsigned npins
)
441 : NetObj(n
, npins
), sig_next_(0), sig_prev_(0), scope_(s
),
442 type_(t
), port_type_(NOT_A_PORT
), msb_(npins
-1), lsb_(0),
443 local_flag_(false), eref_count_(0)
447 ivalue_
= new verinum::V
[npins
];
448 for (unsigned idx
= 0 ; idx
< npins
; idx
+= 1) {
449 pin(idx
).set_name("P", idx
);
450 ivalue_
[idx
] = verinum::Vz
;
453 scope_
->add_signal(this);
456 NetNet::NetNet(NetScope
*s
, const string
&n
, Type t
, long ms
, long ls
)
457 : NetObj(n
, ((ms
>ls
)?ms
-ls
:ls
-ms
) + 1), sig_next_(0),
458 sig_prev_(0), scope_(s
), type_(t
),
459 port_type_(NOT_A_PORT
), msb_(ms
), lsb_(ls
), local_flag_(false),
464 ivalue_
= new verinum::V
[pin_count()];
465 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
466 pin(idx
).set_name("P", idx
);
467 ivalue_
[idx
] = verinum::Vz
;
470 scope_
->add_signal(this);
475 assert(eref_count_
== 0);
477 scope_
->rem_signal(this);
480 NetScope
* NetNet::scope()
485 const NetScope
* NetNet::scope() const
490 unsigned NetNet::sb_to_idx(long sb
) const
498 void NetNet::incr_eref()
503 void NetNet::decr_eref()
505 assert(eref_count_
> 0);
509 unsigned NetNet::get_eref() const
514 NetTmp::NetTmp(NetScope
*s
, const string
&name
, unsigned npins
)
515 : NetNet(s
, name
, IMPLICIT
, npins
)
529 NetProcTop::NetProcTop(Type t
, NetProc
*st
)
530 : type_(t
), statement_(st
)
534 NetProcTop::~NetProcTop()
539 NetProc
* NetProcTop::statement()
544 const NetProc
* NetProcTop::statement() const
550 * The NetFF class represents an LPM_FF device. The pinout is assigned
566 NetFF::NetFF(const string
&n
, unsigned wid
)
567 : NetNode(n
, 8 + 2*wid
)
569 pin_Clock().set_dir(Link::INPUT
);
570 pin_Clock().set_name("Clock", 0);
571 pin_Enable().set_dir(Link::INPUT
);
572 pin_Enable().set_name("Enable", 0);
573 pin_Aload().set_dir(Link::INPUT
);
574 pin_Aload().set_name("Aload", 0);
575 pin_Aset().set_dir(Link::INPUT
);
576 pin_Aset().set_name("Aset", 0);
577 pin_Aclr().set_dir(Link::INPUT
);
578 pin_Aclr().set_name("Aclr", 0);
579 pin_Sload().set_dir(Link::INPUT
);
580 pin_Sload().set_name("Sload", 0);
581 pin_Sset().set_dir(Link::INPUT
);
582 pin_Sset().set_name("Sset", 0);
583 pin_Sclr().set_dir(Link::INPUT
);
584 pin_Sclr().set_name("Sclr", 0);
585 for (unsigned idx
= 0 ; idx
< wid
; idx
+= 1) {
586 pin_Data(idx
).set_dir(Link::INPUT
);
587 pin_Data(idx
).set_name("Data", idx
);
588 pin_Q(idx
).set_dir(Link::OUTPUT
);
589 pin_Q(idx
).set_name("Q", idx
);
597 unsigned NetFF::width() const
599 return (pin_count() - 8) / 2;
602 Link
& NetFF::pin_Clock()
607 const Link
& NetFF::pin_Clock() const
612 Link
& NetFF::pin_Enable()
617 const Link
& NetFF::pin_Enable() const
622 Link
& NetFF::pin_Aload()
627 Link
& NetFF::pin_Aset()
632 Link
& NetFF::pin_Aclr()
637 Link
& NetFF::pin_Sload()
642 Link
& NetFF::pin_Sset()
647 Link
& NetFF::pin_Sclr()
652 Link
& NetFF::pin_Data(unsigned w
)
654 unsigned pn
= 8 + 2*w
;
655 assert(pn
< pin_count());
659 const Link
& NetFF::pin_Data(unsigned w
) const
661 unsigned pn
= 8 + 2*w
;
662 assert(pn
< pin_count());
666 Link
& NetFF::pin_Q(unsigned w
)
668 unsigned pn
= 9 + w
*2;
669 assert(pn
< pin_count());
673 const Link
& NetFF::pin_Q(unsigned w
) const
675 unsigned pn
= 9 + w
*2;
676 assert(pn
< pin_count());
682 * The NetAddSub class represents an LPM_ADD_SUB device. The pinout is
694 NetAddSub::NetAddSub(const string
&n
, unsigned w
)
697 pin(0).set_dir(Link::INPUT
); pin(0).set_name("Add_Sub", 0);
698 pin(1).set_dir(Link::INPUT
); pin(1).set_name("Aclr", 0);
699 pin(2).set_dir(Link::INPUT
); pin(2).set_name("Clock", 0);
700 pin(3).set_dir(Link::INPUT
); pin(3).set_name("Cin", 0);
701 pin(4).set_dir(Link::OUTPUT
); pin(4).set_name("Cout", 0);
702 pin(5).set_dir(Link::OUTPUT
); pin(5).set_name("Overflow", 0);
703 for (unsigned idx
= 0 ; idx
< w
; idx
+= 1) {
704 pin_DataA(idx
).set_dir(Link::INPUT
);
705 pin_DataB(idx
).set_dir(Link::INPUT
);
706 pin_Result(idx
).set_dir(Link::OUTPUT
);
707 pin_DataA(idx
).set_name("DataA", idx
);
708 pin_DataB(idx
).set_name("DataB", idx
);
709 pin_Result(idx
).set_name("Result", idx
);
713 NetAddSub::~NetAddSub()
717 unsigned NetAddSub::width()const
719 return (pin_count() - 6) / 3;
722 Link
& NetAddSub::pin_Cout()
727 const Link
& NetAddSub::pin_Cout() const
732 Link
& NetAddSub::pin_DataA(unsigned idx
)
735 assert(idx
< pin_count());
739 const Link
& NetAddSub::pin_DataA(unsigned idx
) const
742 assert(idx
< pin_count());
746 Link
& NetAddSub::pin_DataB(unsigned idx
)
749 assert(idx
< pin_count());
753 const Link
& NetAddSub::pin_DataB(unsigned idx
) const
756 assert(idx
< pin_count());
760 Link
& NetAddSub::pin_Result(unsigned idx
)
763 assert(idx
< pin_count());
767 const Link
& NetAddSub::pin_Result(unsigned idx
) const
770 assert(idx
< pin_count());
775 * The pinout for the NetCLShift is:
781 * 3+2W -- Distance(0)
783 NetCLShift::NetCLShift(const string
&n
, unsigned width
, unsigned width_dist
)
784 : NetNode(n
, 3+2*width
+width_dist
), width_(width
), width_dist_(width_dist
)
786 pin(0).set_dir(Link::INPUT
); pin(0).set_name("Direction", 0);
787 pin(1).set_dir(Link::OUTPUT
); pin(1).set_name("Underflow", 0);
788 pin(2).set_dir(Link::OUTPUT
); pin(2).set_name("Overflow", 0);
790 for (unsigned idx
= 0 ; idx
< width_
; idx
+= 1) {
791 pin(3+idx
).set_dir(Link::INPUT
);
792 pin(3+idx
).set_name("Data", idx
);
794 pin(3+width_
+idx
).set_dir(Link::OUTPUT
);
795 pin(3+width_
+idx
).set_name("Result", idx
);
798 for (unsigned idx
= 0 ; idx
< width_dist_
; idx
+= 1) {
799 pin(3+2*width_
+idx
).set_dir(Link::INPUT
);
800 pin(3+2*width_
+idx
).set_name("Distance", idx
);
804 NetCLShift::~NetCLShift()
808 unsigned NetCLShift::width() const
813 unsigned NetCLShift::width_dist() const
818 Link
& NetCLShift::pin_Direction()
823 const Link
& NetCLShift::pin_Direction() const
828 Link
& NetCLShift::pin_Underflow()
833 const Link
& NetCLShift::pin_Underflow() const
838 Link
& NetCLShift::pin_Overflow()
843 const Link
& NetCLShift::pin_Overflow() const
848 Link
& NetCLShift::pin_Data(unsigned idx
)
850 assert(idx
< width_
);
854 const Link
& NetCLShift::pin_Data(unsigned idx
) const
856 assert(idx
< width_
);
860 Link
& NetCLShift::pin_Result(unsigned idx
)
862 assert(idx
< width_
);
863 return pin(3+width_
+idx
);
866 const Link
& NetCLShift::pin_Result(unsigned idx
) const
868 assert(idx
< width_
);
869 return pin(3+width_
+idx
);
872 Link
& NetCLShift::pin_Distance(unsigned idx
)
874 assert(idx
< width_dist_
);
875 return pin(3+2*width_
+idx
);
878 const Link
& NetCLShift::pin_Distance(unsigned idx
) const
880 assert(idx
< width_dist_
);
881 return pin(3+2*width_
+idx
);
884 NetCompare::NetCompare(const string
&n
, unsigned wi
)
885 : NetNode(n
, 8+2*wi
), width_(wi
)
887 pin(0).set_dir(Link::INPUT
); pin(0).set_name("Aclr");
888 pin(1).set_dir(Link::INPUT
); pin(1).set_name("Clock");
889 pin(2).set_dir(Link::OUTPUT
); pin(2).set_name("AGB");
890 pin(3).set_dir(Link::OUTPUT
); pin(3).set_name("AGEB");
891 pin(4).set_dir(Link::OUTPUT
); pin(4).set_name("AEB");
892 pin(5).set_dir(Link::OUTPUT
); pin(5).set_name("ANEB");
893 pin(6).set_dir(Link::OUTPUT
); pin(6).set_name("ALB");
894 pin(7).set_dir(Link::OUTPUT
); pin(7).set_name("ALEB");
895 for (unsigned idx
= 0 ; idx
< width_
; idx
+= 1) {
896 pin(8+idx
).set_dir(Link::INPUT
);
897 pin(8+idx
).set_name("DataA", idx
);
898 pin(8+width_
+idx
).set_dir(Link::INPUT
);
899 pin(8+width_
+idx
).set_name("DataB", idx
);
903 NetCompare::~NetCompare()
907 unsigned NetCompare::width() const
912 Link
& NetCompare::pin_Aclr()
917 const Link
& NetCompare::pin_Aclr() const
922 Link
& NetCompare::pin_Clock()
927 const Link
& NetCompare::pin_Clock() const
932 Link
& NetCompare::pin_AGB()
937 const Link
& NetCompare::pin_AGB() const
942 Link
& NetCompare::pin_AGEB()
947 const Link
& NetCompare::pin_AGEB() const
952 Link
& NetCompare::pin_AEB()
957 const Link
& NetCompare::pin_AEB() const
962 Link
& NetCompare::pin_ANEB()
967 const Link
& NetCompare::pin_ANEB() const
972 Link
& NetCompare::pin_ALB()
977 const Link
& NetCompare::pin_ALB() const
982 Link
& NetCompare::pin_ALEB()
987 const Link
& NetCompare::pin_ALEB() const
992 Link
& NetCompare::pin_DataA(unsigned idx
)
997 const Link
& NetCompare::pin_DataA(unsigned idx
) const
1002 Link
& NetCompare::pin_DataB(unsigned idx
)
1004 return pin(8+width_
+idx
);
1007 const Link
& NetCompare::pin_DataB(unsigned idx
) const
1009 return pin(8+width_
+idx
);
1012 NetDivide::NetDivide(const string
&n
, unsigned wr
,
1013 unsigned wa
, unsigned wb
)
1014 : NetNode(n
, wr
+wa
+wb
), width_r_(wr
), width_a_(wa
), width_b_(wb
)
1017 for (unsigned idx
= 0 ; idx
< width_r_
; idx
+= 1, p
+= 1) {
1018 pin(p
).set_dir(Link::OUTPUT
);
1019 pin(p
).set_name("Result", idx
);
1021 for (unsigned idx
= 0 ; idx
< width_a_
; idx
+= 1, p
+= 1) {
1022 pin(p
).set_dir(Link::INPUT
);
1023 pin(p
).set_name("DataA", idx
);
1025 for (unsigned idx
= 0 ; idx
< width_b_
; idx
+= 1, p
+= 1) {
1026 pin(p
).set_dir(Link::INPUT
);
1027 pin(p
).set_name("DataB", idx
);
1031 NetDivide::~NetDivide()
1035 unsigned NetDivide::width_r() const
1040 unsigned NetDivide::width_a() const
1045 unsigned NetDivide::width_b() const
1050 Link
& NetDivide::pin_Result(unsigned idx
)
1052 assert(idx
< width_r_
);
1056 const Link
& NetDivide::pin_Result(unsigned idx
) const
1058 assert(idx
< width_r_
);
1062 Link
& NetDivide::pin_DataA(unsigned idx
)
1064 assert(idx
< width_a_
);
1065 return pin(idx
+width_r_
);
1068 const Link
& NetDivide::pin_DataA(unsigned idx
) const
1070 assert(idx
< width_a_
);
1071 return pin(idx
+width_r_
);
1074 Link
& NetDivide::pin_DataB(unsigned idx
)
1076 assert(idx
< width_b_
);
1077 return pin(idx
+width_r_
+width_a_
);
1080 const Link
& NetDivide::pin_DataB(unsigned idx
) const
1082 assert(idx
< width_b_
);
1083 return pin(idx
+width_r_
+width_a_
);
1086 NetMult::NetMult(const string
&n
, unsigned wr
, unsigned wa
, unsigned wb
,
1088 : NetNode(n
, 2+wr
+wa
+wb
+ws
), width_r_(wr
), width_a_(wa
), width_b_(wb
),
1091 pin(0).set_dir(Link::INPUT
); pin(0).set_name("Aclr", 0);
1092 pin(1).set_dir(Link::INPUT
); pin(1).set_name("Clock", 0);
1096 for (unsigned idx
= 0 ; idx
< width_r_
; idx
+= 1, p
+= 1) {
1097 pin(p
).set_dir(Link::OUTPUT
);
1098 pin(p
).set_name("Result", idx
);
1100 for (unsigned idx
= 0 ; idx
< width_a_
; idx
+= 1, p
+= 1) {
1101 pin(p
).set_dir(Link::INPUT
);
1102 pin(p
).set_name("DataA", idx
);
1104 for (unsigned idx
= 0 ; idx
< width_b_
; idx
+= 1, p
+= 1) {
1105 pin(p
).set_dir(Link::INPUT
);
1106 pin(p
).set_name("DataB", idx
);
1108 for (unsigned idx
= 0 ; idx
< width_s_
; idx
+= 1, p
+= 1) {
1109 pin(p
).set_dir(Link::INPUT
);
1110 pin(p
).set_name("Sum", idx
);
1118 unsigned NetMult::width_r() const
1123 unsigned NetMult::width_a() const
1128 unsigned NetMult::width_b() const
1133 unsigned NetMult::width_s() const
1138 Link
& NetMult::pin_Aclr()
1143 const Link
& NetMult::pin_Aclr() const
1148 Link
& NetMult::pin_Clock()
1153 const Link
& NetMult::pin_Clock() const
1158 Link
& NetMult::pin_Result(unsigned idx
)
1160 assert(idx
< width_r_
);
1164 const Link
& NetMult::pin_Result(unsigned idx
) const
1166 assert(idx
< width_r_
);
1170 Link
& NetMult::pin_DataA(unsigned idx
)
1172 assert(idx
< width_a_
);
1173 return pin(idx
+2+width_r_
);
1176 const Link
& NetMult::pin_DataA(unsigned idx
) const
1178 assert(idx
< width_a_
);
1179 return pin(idx
+2+width_r_
);
1182 Link
& NetMult::pin_DataB(unsigned idx
)
1184 assert(idx
< width_b_
);
1185 return pin(idx
+2+width_r_
+width_a_
);
1188 const Link
& NetMult::pin_DataB(unsigned idx
) const
1190 assert(idx
< width_b_
);
1191 return pin(idx
+2+width_r_
+width_a_
);
1194 Link
& NetMult::pin_Sum(unsigned idx
)
1196 assert(idx
< width_s_
);
1197 return pin(idx
+2+width_r_
+width_a_
+width_b_
);
1200 const Link
& NetMult::pin_Sum(unsigned idx
) const
1202 assert(idx
< width_s_
);
1203 return pin(idx
+2+width_r_
+width_a_
+width_b_
);
1207 * The NetMux class represents an LPM_MUX device. The pinout is assigned
1209 * 0 -- Aclr (optional)
1210 * 1 -- Clock (optional)
1215 NetMux::NetMux(const string
&n
, unsigned wi
, unsigned si
, unsigned sw
)
1216 : NetNode(n
, 2+wi
+sw
+wi
*si
), width_(wi
), size_(si
), swidth_(sw
)
1218 pin(0).set_dir(Link::INPUT
); pin(0).set_name("Aclr", 0);
1219 pin(1).set_dir(Link::INPUT
); pin(1).set_name("Clock", 0);
1221 for (unsigned idx
= 0 ; idx
< width_
; idx
+= 1) {
1222 pin_Result(idx
).set_dir(Link::OUTPUT
);
1223 pin_Result(idx
).set_name("Result", idx
);
1225 for (unsigned jdx
= 0 ; jdx
< size_
; jdx
+= 1) {
1226 pin_Data(idx
,jdx
).set_dir(Link::INPUT
);
1227 pin_Data(idx
,jdx
).set_name("Data", jdx
*width_
+idx
);
1231 for (unsigned idx
= 0 ; idx
< swidth_
; idx
+= 1) {
1232 pin_Sel(idx
).set_dir(Link::INPUT
);
1233 pin_Sel(idx
).set_name("Sel", idx
);
1241 unsigned NetMux::width()const
1246 unsigned NetMux::size() const
1251 unsigned NetMux::sel_width() const
1256 Link
& NetMux::pin_Aclr()
1261 const Link
& NetMux::pin_Aclr() const
1266 Link
& NetMux::pin_Clock()
1271 const Link
& NetMux::pin_Clock() const
1276 Link
& NetMux::pin_Result(unsigned w
)
1282 const Link
& NetMux::pin_Result(unsigned w
) const
1288 Link
& NetMux::pin_Sel(unsigned w
)
1290 assert(w
< swidth_
);
1291 return pin(2+width_
+w
);
1294 const Link
& NetMux::pin_Sel(unsigned w
) const
1296 assert(w
< swidth_
);
1297 return pin(2+width_
+w
);
1300 Link
& NetMux::pin_Data(unsigned w
, unsigned s
)
1304 return pin(2+width_
+swidth_
+s
*width_
+w
);
1307 const Link
& NetMux::pin_Data(unsigned w
, unsigned s
) const
1311 return pin(2+width_
+swidth_
+s
*width_
+w
);
1315 NetRamDq::NetRamDq(const string
&n
, NetMemory
*mem
, unsigned awid
)
1316 : NetNode(n
, 3+2*mem
->width()+awid
), mem_(mem
), awidth_(awid
)
1318 pin(0).set_dir(Link::INPUT
); pin(0).set_name("InClock", 0);
1319 pin(1).set_dir(Link::INPUT
); pin(1).set_name("OutClock", 0);
1320 pin(2).set_dir(Link::INPUT
); pin(2).set_name("WE", 0);
1322 for (unsigned idx
= 0 ; idx
< awidth_
; idx
+= 1) {
1323 pin(3+idx
).set_dir(Link::INPUT
);
1324 pin(3+idx
).set_name("Address", idx
);
1327 for (unsigned idx
= 0 ; idx
< width() ; idx
+= 1) {
1328 pin(3+awidth_
+idx
).set_dir(Link::INPUT
);
1329 pin(3+awidth_
+idx
).set_name("Data", idx
);
1332 for (unsigned idx
= 0 ; idx
< width() ; idx
+= 1) {
1333 pin(3+awidth_
+width()+idx
).set_dir(Link::OUTPUT
);
1334 pin(3+awidth_
+width()+idx
).set_name("Q", idx
);
1337 next_
= mem_
->ram_list_
;
1338 mem_
->ram_list_
= this;
1341 NetRamDq::~NetRamDq()
1343 if (mem_
->ram_list_
== this) {
1344 mem_
->ram_list_
= next_
;
1347 NetRamDq
*cur
= mem_
->ram_list_
;
1348 while (cur
->next_
!= this) {
1352 assert(cur
->next_
== this);
1357 unsigned NetRamDq::width() const
1359 return mem_
->width();
1362 unsigned NetRamDq::awidth() const
1367 unsigned NetRamDq::size() const
1369 return mem_
->count();
1372 const NetMemory
* NetRamDq::mem() const
1377 unsigned NetRamDq::count_partners() const
1380 for (NetRamDq
*cur
= mem_
->ram_list_
; cur
; cur
= cur
->next_
)
1386 void NetRamDq::absorb_partners()
1389 for (cur
= mem_
->ram_list_
, tmp
= 0
1390 ; cur
||tmp
; cur
= cur
? cur
->next_
: tmp
) {
1392 if (cur
== this) continue;
1394 bool ok_flag
= true;
1395 for (unsigned idx
= 0 ; idx
< awidth() ; idx
+= 1)
1396 ok_flag
&= pin_Address(idx
).is_linked(cur
->pin_Address(idx
));
1398 if (!ok_flag
) continue;
1400 if (pin_InClock().is_linked()
1401 && cur
->pin_InClock().is_linked()
1402 && ! pin_InClock().is_linked(cur
->pin_InClock()))
1405 if (pin_OutClock().is_linked()
1406 && cur
->pin_OutClock().is_linked()
1407 && ! pin_OutClock().is_linked(cur
->pin_OutClock()))
1410 if (pin_WE().is_linked()
1411 && cur
->pin_WE().is_linked()
1412 && ! pin_WE().is_linked(cur
->pin_WE()))
1415 for (unsigned idx
= 0 ; idx
< width() ; idx
+= 1) {
1416 if (!pin_Data(idx
).is_linked()) continue;
1417 if (! cur
->pin_Data(idx
).is_linked()) continue;
1419 ok_flag
&= pin_Data(idx
).is_linked(cur
->pin_Data(idx
));
1422 if (! ok_flag
) continue;
1424 for (unsigned idx
= 0 ; idx
< width() ; idx
+= 1) {
1425 if (!pin_Q(idx
).is_linked()) continue;
1426 if (! cur
->pin_Q(idx
).is_linked()) continue;
1428 ok_flag
&= pin_Q(idx
).is_linked(cur
->pin_Q(idx
));
1431 if (! ok_flag
) continue;
1433 // I see no other reason to reject cur, so link up all
1434 // my pins and delete it.
1435 connect(pin_InClock(), cur
->pin_InClock());
1436 connect(pin_OutClock(), cur
->pin_OutClock());
1437 connect(pin_WE(), cur
->pin_WE());
1439 for (unsigned idx
= 0 ; idx
< awidth() ; idx
+= 1)
1440 connect(pin_Address(idx
), cur
->pin_Address(idx
));
1442 for (unsigned idx
= 0 ; idx
< width() ; idx
+= 1) {
1443 connect(pin_Data(idx
), cur
->pin_Data(idx
));
1444 connect(pin_Q(idx
), cur
->pin_Q(idx
));
1453 Link
& NetRamDq::pin_InClock()
1458 const Link
& NetRamDq::pin_InClock() const
1463 Link
& NetRamDq::pin_OutClock()
1468 const Link
& NetRamDq::pin_OutClock() const
1473 Link
& NetRamDq::pin_WE()
1478 const Link
& NetRamDq::pin_WE() const
1483 Link
& NetRamDq::pin_Address(unsigned idx
)
1485 assert(idx
< awidth_
);
1489 const Link
& NetRamDq::pin_Address(unsigned idx
) const
1491 assert(idx
< awidth_
);
1495 Link
& NetRamDq::pin_Data(unsigned idx
)
1497 assert(idx
< width());
1498 return pin(3+awidth_
+idx
);
1501 const Link
& NetRamDq::pin_Data(unsigned idx
) const
1503 assert(idx
< width());
1504 return pin(3+awidth_
+idx
);
1507 Link
& NetRamDq::pin_Q(unsigned idx
)
1509 assert(idx
< width());
1510 return pin(3+awidth_
+width()+idx
);
1513 const Link
& NetRamDq::pin_Q(unsigned idx
) const
1515 assert(idx
< width());
1516 return pin(3+awidth_
+width()+idx
);
1523 NetAssign_::NetAssign_(const string
&n
, unsigned w
)
1524 : NetNode(n
, w
), rval_(0), bmux_(0)
1526 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
1527 pin(idx
).set_dir(Link::OUTPUT
);
1528 pin(idx
).set_name("P", idx
);
1533 NetAssign_::~NetAssign_()
1535 if (rval_
) delete rval_
;
1536 if (bmux_
) delete bmux_
;
1539 void NetAssign_::set_rval(NetExpr
*r
)
1541 if (rval_
) delete rval_
;
1545 void NetAssign_::set_bmux(NetExpr
*r
)
1551 NetExpr
* NetAssign_::rval()
1556 const NetExpr
* NetAssign_::rval() const
1561 const NetExpr
* NetAssign_::bmux() const
1566 NetAssign::NetAssign(const string
&n
, Design
*des
, unsigned w
, NetExpr
*rv
)
1572 NetAssign::NetAssign(const string
&n
, Design
*des
, unsigned w
,
1573 NetExpr
*mu
, NetExpr
*rv
)
1576 bool flag
= rv
->set_width(1);
1577 if (flag
== false) {
1578 cerr
<< rv
->get_line() << ": Expression bit width" <<
1579 " conflicts with l-value bit width." << endl
;
1587 NetAssign::~NetAssign()
1591 NetAssignNB::NetAssignNB(const string
&n
, Design
*des
, unsigned w
, NetExpr
*rv
)
1594 if (rv
->expr_width() < w
) {
1595 cerr
<< rv
->get_line() << ": Expression bit width (" <<
1596 rv
->expr_width() << ") conflicts with l-value "
1597 "bit width (" << w
<< ")." << endl
;
1604 NetAssignNB::NetAssignNB(const string
&n
, Design
*des
, unsigned w
,
1605 NetExpr
*mu
, NetExpr
*rv
)
1608 bool flag
= rv
->set_width(1);
1609 if (flag
== false) {
1610 cerr
<< rv
->get_line() << ": Expression bit width" <<
1611 " conflicts with l-value bit width." << endl
;
1619 NetAssignNB::~NetAssignNB()
1624 NetAssignMem_::NetAssignMem_(NetMemory
*m
, NetNet
*i
, NetExpr
*r
)
1625 : mem_(m
), index_(i
), rval_(r
)
1627 index_
->incr_eref();
1630 NetAssignMem_::~NetAssignMem_()
1632 index_
->decr_eref();
1635 NetAssignMem::NetAssignMem(NetMemory
*m
, NetNet
*i
, NetExpr
*r
)
1636 : NetAssignMem_(m
, i
, r
)
1640 NetAssignMem::~NetAssignMem()
1644 NetAssignMemNB::NetAssignMemNB(NetMemory
*m
, NetNet
*i
, NetExpr
*r
)
1645 : NetAssignMem_(m
, i
, r
)
1649 NetAssignMemNB::~NetAssignMemNB()
1654 NetBlock::~NetBlock()
1658 void NetBlock::append(NetProc
*cur
)
1664 cur
->next_
= last_
->next_
;
1670 const NetProc
* NetBlock::proc_first() const
1675 return last_
->next_
;
1678 const NetProc
* NetBlock::proc_next(const NetProc
*cur
) const
1686 NetBUFZ::NetBUFZ(const string
&n
)
1689 pin(0).set_dir(Link::OUTPUT
);
1690 pin(1).set_dir(Link::INPUT
);
1691 pin(0).set_name("O", 0);
1692 pin(1).set_name("I", 0);
1700 NetCase::NetCase(NetCase::TYPE c
, NetExpr
*ex
, unsigned cnt
)
1701 : type_(c
), expr_(ex
), nitems_(cnt
)
1704 items_
= new Item
[nitems_
];
1705 for (unsigned idx
= 0 ; idx
< nitems_
; idx
+= 1) {
1706 items_
[idx
].statement
= 0;
1713 for (unsigned idx
= 0 ; idx
< nitems_
; idx
+= 1) {
1714 delete items_
[idx
].guard
;
1715 if (items_
[idx
].statement
) delete items_
[idx
].statement
;
1720 NetCase::TYPE
NetCase::type() const
1725 void NetCase::set_case(unsigned idx
, NetExpr
*e
, NetProc
*p
)
1727 assert(idx
< nitems_
);
1728 items_
[idx
].guard
= e
;
1729 items_
[idx
].statement
= p
;
1730 if (items_
[idx
].guard
)
1731 items_
[idx
].guard
->set_width(expr_
->expr_width());
1734 NetCaseCmp::NetCaseCmp(const string
&n
)
1737 pin(0).set_dir(Link::OUTPUT
); pin(0).set_name("O",0);
1738 pin(1).set_dir(Link::INPUT
); pin(1).set_name("I",0);
1739 pin(2).set_dir(Link::INPUT
); pin(2).set_name("I",1);
1742 NetCaseCmp::~NetCaseCmp()
1746 NetCondit::NetCondit(NetExpr
*ex
, NetProc
*i
, NetProc
*e
)
1747 : expr_(ex
), if_(i
), else_(e
)
1751 NetCondit::~NetCondit()
1754 if (if_
) delete if_
;
1755 if (else_
) delete else_
;
1758 const NetExpr
* NetCondit::expr() const
1763 NetExpr
* NetCondit::expr()
1768 void NetCondit::set_expr(NetExpr
*ex
)
1774 NetProc
* NetCondit::if_clause()
1779 NetProc
* NetCondit::else_clause()
1784 NetConst::NetConst(const string
&n
, verinum::V v
)
1787 pin(0).set_dir(Link::OUTPUT
);
1788 pin(0).set_name("O", 0);
1789 value_
= new verinum::V
[1];
1793 NetConst::NetConst(const string
&n
, const verinum
&val
)
1794 : NetNode(n
, val
.len())
1796 value_
= new verinum::V
[pin_count()];
1797 for (unsigned idx
= 0 ; idx
< pin_count() ; idx
+= 1) {
1798 pin(idx
).set_dir(Link::OUTPUT
);
1799 pin(idx
).set_name("O", idx
);
1800 value_
[idx
] = val
.get(idx
);
1804 NetConst::~NetConst()
1809 verinum::V
NetConst::value(unsigned idx
) const
1811 assert(idx
< pin_count());
1815 NetFuncDef::NetFuncDef(NetScope
*s
, const svector
<NetNet
*>&po
)
1816 : scope_(s
), statement_(0), ports_(po
)
1820 NetFuncDef::~NetFuncDef()
1824 const string
NetFuncDef::name() const
1826 return scope_
->name();
1829 void NetFuncDef::set_proc(NetProc
*st
)
1831 assert(statement_
== 0);
1836 const NetProc
* NetFuncDef::proc() const
1841 NetScope
*NetFuncDef::scope()
1846 unsigned NetFuncDef::port_count() const
1848 return ports_
.count();
1851 const NetNet
* NetFuncDef::port(unsigned idx
) const
1853 assert(idx
< ports_
.count());
1857 NetSTask::NetSTask(const string
&na
, const svector
<NetExpr
*>&pa
)
1858 : name_(na
), parms_(pa
)
1860 assert(name_
[0] == '$');
1863 NetSTask::~NetSTask()
1865 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1)
1870 const NetExpr
* NetSTask::parm(unsigned idx
) const
1875 NetEUFunc::NetEUFunc(NetFuncDef
*def
, NetESignal
*res
, svector
<NetExpr
*>&p
)
1876 : func_(def
), result_(res
), parms_(p
)
1878 expr_width(result_
->expr_width());
1881 NetEUFunc::~NetEUFunc()
1883 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1)
1887 const string
NetEUFunc::name() const
1889 return func_
->name();
1892 const NetESignal
*NetEUFunc::result() const
1897 unsigned NetEUFunc::parm_count() const
1899 return parms_
.count();
1902 const NetExpr
* NetEUFunc::parm(unsigned idx
) const
1904 assert(idx
< parms_
.count());
1908 const NetFuncDef
* NetEUFunc::definition() const
1913 NetEUFunc
* NetEUFunc::dup_expr() const
1919 NetUTask::NetUTask(NetTaskDef
*def
)
1924 NetUTask::~NetUTask()
1928 NetExpr::NetExpr(unsigned w
)
1937 NetEBAdd::NetEBAdd(char op
, NetExpr
*l
, NetExpr
*r
)
1938 : NetEBinary(op
, l
, r
)
1940 if (l
->expr_width() > r
->expr_width())
1941 r
->set_width(l
->expr_width());
1943 if (r
->expr_width() > l
->expr_width())
1944 l
->set_width(r
->expr_width());
1946 if (l
->expr_width() < r
->expr_width())
1947 r
->set_width(l
->expr_width());
1949 if (r
->expr_width() < l
->expr_width())
1950 l
->set_width(r
->expr_width());
1952 if (r
->expr_width() > l
->expr_width())
1953 expr_width(r
->expr_width());
1955 expr_width(l
->expr_width());
1958 NetEBAdd::~NetEBAdd()
1962 NetEBAdd
* NetEBAdd::dup_expr() const
1964 NetEBAdd
*result
= new NetEBAdd(op_
, left_
->dup_expr(),
1965 right_
->dup_expr());
1969 NetEBBits::NetEBBits(char op
, NetExpr
*l
, NetExpr
*r
)
1970 : NetEBinary(op
, l
, r
)
1972 /* First try to naturally adjust the size of the
1973 expressions to match. */
1974 if (l
->expr_width() > r
->expr_width())
1975 r
->set_width(l
->expr_width());
1977 if (r
->expr_width() > l
->expr_width())
1978 l
->set_width(r
->expr_width());
1980 if (l
->expr_width() < r
->expr_width())
1981 r
->set_width(l
->expr_width());
1983 if (r
->expr_width() < l
->expr_width())
1984 l
->set_width(r
->expr_width());
1986 /* If the expressions cannot be matched, pad them to fit. */
1987 if (l
->expr_width() > r
->expr_width())
1988 right_
= pad_to_width(r
, l
->expr_width());
1990 if (r
->expr_width() > l
->expr_width())
1991 left_
= pad_to_width(l
, r
->expr_width());
1993 assert(left_
->expr_width() == right_
->expr_width());
1994 expr_width(left_
->expr_width());
1997 NetEBBits::~NetEBBits()
2001 NetEBBits
* NetEBBits::dup_expr() const
2003 NetEBBits
*result
= new NetEBBits(op_
, left_
->dup_expr(),
2004 right_
->dup_expr());
2008 NetEBComp::NetEBComp(char op
, NetExpr
*l
, NetExpr
*r
)
2009 : NetEBinary(op
, l
, r
)
2014 NetEBComp::~NetEBComp()
2018 NetEBComp
* NetEBComp::dup_expr() const
2020 NetEBComp
*result
= new NetEBComp(op_
, left_
->dup_expr(),
2021 right_
->dup_expr());
2025 NetEBDiv::NetEBDiv(char op
, NetExpr
*l
, NetExpr
*r
)
2026 : NetEBinary(op
, l
, r
)
2028 unsigned w
= l
->expr_width();
2029 if (r
->expr_width() > w
)
2030 w
= r
->expr_width();
2035 NetEBDiv::~NetEBDiv()
2039 NetEBDiv
* NetEBDiv::dup_expr() const
2041 NetEBDiv
*result
= new NetEBDiv(op_
, left_
->dup_expr(),
2042 right_
->dup_expr());
2046 NetEBinary::NetEBinary(char op
, NetExpr
*l
, NetExpr
*r
)
2047 : op_(op
), left_(l
), right_(r
)
2051 NetEBinary::~NetEBinary()
2057 NetEBinary
* NetEBinary::dup_expr() const
2062 NetEBLogic::NetEBLogic(char op
, NetExpr
*l
, NetExpr
*r
)
2063 : NetEBinary(op
, l
, r
)
2068 NetEBLogic::~NetEBLogic()
2072 NetEBLogic
* NetEBLogic::dup_expr() const
2074 NetEBLogic
*result
= new NetEBLogic(op_
, left_
->dup_expr(),
2075 right_
->dup_expr());
2079 NetEBMult::NetEBMult(char op
, NetExpr
*l
, NetExpr
*r
)
2080 : NetEBinary(op
, l
, r
)
2082 expr_width(l
->expr_width() + r
->expr_width());
2085 NetEBMult::~NetEBMult()
2089 NetEBMult
* NetEBMult::dup_expr() const
2091 NetEBMult
*result
= new NetEBMult(op_
, left_
->dup_expr(),
2092 right_
->dup_expr());
2096 NetEBShift::NetEBShift(char op
, NetExpr
*l
, NetExpr
*r
)
2097 : NetEBinary(op
, l
, r
)
2099 expr_width(l
->expr_width());
2102 NetEBShift::~NetEBShift()
2106 NetEBShift
* NetEBShift::dup_expr() const
2108 NetEBShift
*result
= new NetEBShift(op_
, left_
->dup_expr(),
2109 right_
->dup_expr());
2113 NetEConcat::NetEConcat(unsigned cnt
, unsigned r
)
2114 : parms_(cnt
), repeat_(r
)
2119 NetEConcat::~NetEConcat()
2121 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1)
2125 void NetEConcat::set(unsigned idx
, NetExpr
*e
)
2127 assert(idx
< parms_
.count());
2128 assert(parms_
[idx
] == 0);
2130 expr_width( expr_width() + repeat_
*e
->expr_width() );
2133 NetEConcat
* NetEConcat::dup_expr() const
2135 NetEConcat
*dup
= new NetEConcat(parms_
.count(), repeat_
);
2136 for (unsigned idx
= 0 ; idx
< parms_
.count() ; idx
+= 1)
2138 assert(parms_
[idx
]->dup_expr());
2139 dup
->parms_
[idx
] = parms_
[idx
]->dup_expr();
2143 dup
->expr_width(expr_width());
2147 NetEConst::NetEConst(const verinum
&val
)
2148 : NetExpr(val
.len()), value_(val
)
2152 NetEConst::~NetEConst()
2156 NetEConst
* NetEConst::dup_expr() const
2158 NetEConst
*tmp
= new NetEConst(value_
);
2159 tmp
->set_line(*this);
2163 NetEIdent
* NetEIdent::dup_expr() const
2168 NetEMemory::NetEMemory(NetMemory
*m
, NetExpr
*i
)
2169 : NetExpr(m
->width()), mem_(m
), idx_(i
)
2173 NetEMemory::~NetEMemory()
2177 NetMemory::NetMemory(NetScope
*sc
, const string
&n
, long w
, long s
, long e
)
2178 : name_(n
), width_(w
), idxh_(s
), idxl_(e
), ram_list_(0), scope_(sc
)
2180 scope_
->add_memory(this);
2183 NetMemory::~NetMemory()
2186 scope_
->rem_memory(this);
2189 unsigned NetMemory::count() const
2192 return idxl_
- idxh_
+ 1;
2194 return idxh_
- idxl_
+ 1;
2197 unsigned NetMemory::index_to_address(long idx
) const
2206 void NetMemory::set_attributes(const map
<string
,string
>&attr
)
2208 assert(attributes_
.size() == 0);
2212 NetEMemory
* NetEMemory::dup_expr() const
2217 NetEParam::NetEParam()
2222 NetEParam::NetEParam(Design
*d
, NetScope
*s
, const string
&n
)
2223 : des_(d
), scope_(s
), name_(n
)
2227 NetEParam::~NetEParam()
2231 NetEParam
* NetEParam::dup_expr() const
2236 NetEScope::NetEScope(NetScope
*s
)
2241 NetEScope::~NetEScope()
2245 const NetScope
* NetEScope::scope() const
2250 NetESFunc::NetESFunc(const string
&n
, unsigned width
, unsigned np
)
2255 parms_
= new NetExpr
*[np
];
2256 for (unsigned idx
= 0 ; idx
< nparms_
; idx
+= 1)
2260 NetESFunc::~NetESFunc()
2262 for (unsigned idx
= 0 ; idx
< nparms_
; idx
+= 1)
2263 if (parms_
[idx
]) delete parms_
[idx
];
2268 const string
& NetESFunc::name() const
2273 unsigned NetESFunc::nparms() const
2278 void NetESFunc::parm(unsigned idx
, NetExpr
*v
)
2280 assert(idx
< nparms_
);
2286 const NetExpr
* NetESFunc::parm(unsigned idx
) const
2288 assert(idx
< nparms_
);
2292 NetExpr
* NetESFunc::parm(unsigned idx
)
2294 assert(idx
< nparms_
);
2298 NetESignal::NetESignal(NetNet
*n
)
2299 : NetExpr(n
->pin_count()), net_(n
)
2305 NetESignal::~NetESignal()
2310 const string
& NetESignal::name() const
2312 return net_
->name();
2315 unsigned NetESignal::pin_count() const
2317 return net_
->pin_count();
2320 Link
& NetESignal::pin(unsigned idx
)
2322 return net_
->pin(idx
);
2325 NetESignal
* NetESignal::dup_expr() const
2330 NetESubSignal::NetESubSignal(NetESignal
*sig
, NetExpr
*ex
)
2331 : sig_(sig
), idx_(ex
)
2333 // This supports mux type indexing of an expression, so the
2334 // with is by definition 1 bit.
2338 NetESubSignal::~NetESubSignal()
2343 NetESubSignal
* NetESubSignal::dup_expr() const
2348 NetETernary::NetETernary(NetExpr
*c
, NetExpr
*t
, NetExpr
*f
)
2349 : cond_(c
), true_val_(t
), false_val_(f
)
2351 expr_width(true_val_
->expr_width());
2354 NetETernary::~NetETernary()
2361 const NetExpr
* NetETernary::cond_expr() const
2366 const NetExpr
* NetETernary::true_expr() const
2371 const NetExpr
* NetETernary::false_expr() const
2376 NetETernary
* NetETernary::dup_expr() const
2381 NetEUnary::NetEUnary(char op
, NetExpr
*ex
)
2382 : NetExpr(ex
->expr_width()), op_(op
), expr_(ex
)
2385 case '!': // Logical not
2386 case '&': // Reduction and
2387 case '|': // Reduction or
2388 case '^': // Reduction XOR
2389 case 'A': // Reduction NAND (~&)
2390 case 'N': // Reduction NOR (~|)
2391 case 'X': // Reduction NXOR (~^)
2397 NetEUnary::~NetEUnary()
2402 NetEUnary
* NetEUnary::dup_expr() const
2407 NetEUBits::NetEUBits(char op
, NetExpr
*ex
)
2412 NetEUBits::~NetEUBits()
2416 NetForever::NetForever(NetProc
*p
)
2421 NetForever::~NetForever()
2426 NetLogic::NetLogic(const string
&n
, unsigned pins
, TYPE t
)
2427 : NetNode(n
, pins
), type_(t
)
2429 pin(0).set_dir(Link::OUTPUT
);
2430 pin(0).set_name("O", 0);
2431 for (unsigned idx
= 1 ; idx
< pins
; idx
+= 1) {
2432 pin(idx
).set_dir(Link::INPUT
);
2433 pin(idx
).set_name("I", idx
-1);
2437 NetRepeat::NetRepeat(NetExpr
*e
, NetProc
*p
)
2438 : expr_(e
), statement_(p
)
2442 NetRepeat::~NetRepeat()
2448 const NetExpr
* NetRepeat::expr() const
2453 NetTaskDef::NetTaskDef(const string
&n
, const svector
<NetNet
*>&po
)
2454 : name_(n
), proc_(0), ports_(po
)
2458 NetTaskDef::~NetTaskDef()
2463 void NetTaskDef::set_proc(NetProc
*p
)
2469 unsigned NetTaskDef::port_count() const
2471 return ports_
.count();
2474 NetNet
* NetTaskDef::port(unsigned idx
)
2476 assert(idx
< ports_
.count());
2480 const string
& NetTaskDef::name() const
2485 const NetProc
*NetTaskDef::proc() const
2491 * This method takes the input string, which contains exactly one
2492 * edge, and connects it to the correct output state. The output state
2493 * will be generated if needed, and the value compared.
2495 bool NetUDP::set_sequ_(const string
&input
, char output
)
2504 unsigned edge
= frm
.find_first_not_of("01x");
2505 assert(frm
.find_last_not_of("01x") == edge
);
2507 switch (input
[edge
]) {
2536 state_t_
*sfrm
= find_state_(frm
);
2537 state_t_
*sto
= find_state_(to
);
2541 // Notice that I might have caught this edge already
2542 if (sfrm
->pins
[edge
].zer
!= sto
) {
2543 assert(sfrm
->pins
[edge
].zer
== 0);
2544 sfrm
->pins
[edge
].zer
= sto
;
2548 // Notice that I might have caught this edge already
2549 if (sfrm
->pins
[edge
].one
!= sto
) {
2550 assert(sfrm
->pins
[edge
].one
== 0);
2551 sfrm
->pins
[edge
].one
= sto
;
2555 // Notice that I might have caught this edge already
2556 if (sfrm
->pins
[edge
].xxx
!= sto
) {
2557 assert(sfrm
->pins
[edge
].xxx
== 0);
2558 sfrm
->pins
[edge
].xxx
= sto
;
2566 bool NetUDP::sequ_glob_(string input
, char output
)
2568 for (unsigned idx
= 0 ; idx
< input
.length() ; idx
+= 1)
2569 switch (input
[idx
]) {
2581 case '?': // Iterate over all the levels
2583 sequ_glob_(input
, output
);
2585 sequ_glob_(input
, output
);
2587 sequ_glob_(input
, output
);
2590 case 'n': // Iterate over (n) edges
2592 sequ_glob_(input
, output
);
2594 sequ_glob_(input
, output
);
2596 sequ_glob_(input
, output
);
2599 case 'p': // Iterate over (p) edges
2601 sequ_glob_(input
, output
);
2603 sequ_glob_(input
, output
);
2605 sequ_glob_(input
, output
);
2608 case '_': // Iterate over (?0) edges
2610 sequ_glob_(input
, output
);
2612 sequ_glob_(input
, output
);
2615 case '*': // Iterate over all the edges
2617 sequ_glob_(input
, output
);
2619 sequ_glob_(input
, output
);
2621 sequ_glob_(input
, output
);
2623 sequ_glob_(input
, output
);
2625 sequ_glob_(input
, output
);
2627 sequ_glob_(input
, output
);
2634 return set_sequ_(input
, output
);
2638 * $Log: netlist.cc,v $
2639 * Revision 1.127 2000/05/27 19:33:23 steve
2640 * Merge similar probes within a module.
2642 * Revision 1.126 2000/05/19 01:43:16 steve
2643 * Accept different widths for add operands.
2645 * Revision 1.125 2000/05/11 23:37:27 steve
2646 * Add support for procedural continuous assignment.
2648 * Revision 1.124 2000/05/07 18:20:07 steve
2649 * Import MCD support from Stephen Tell, and add
2650 * system function parameter support to the IVL core.
2652 * Revision 1.123 2000/05/07 04:37:56 steve
2653 * Carry strength values from Verilog source to the
2654 * pform and netlist for gates.
2656 * Change vvm constants to use the driver_t to drive
2657 * a constant value. This works better if there are
2658 * multiple drivers on a signal.
2660 * Revision 1.122 2000/05/04 03:37:58 steve
2661 * Add infrastructure for system functions, move
2662 * $time to that structure and add $random.
2664 * Revision 1.121 2000/05/02 03:13:31 steve
2665 * Move memories to the NetScope object.
2667 * Revision 1.120 2000/05/02 00:58:12 steve
2668 * Move signal tables to the NetScope class.
2670 * Revision 1.119 2000/04/28 18:43:23 steve
2671 * integer division in expressions properly get width.
2673 * Revision 1.118 2000/04/23 03:45:24 steve
2674 * Add support for the procedural release statement.
2676 * Revision 1.117 2000/04/22 04:20:19 steve
2677 * Add support for force assignment.
2679 * Revision 1.116 2000/04/18 01:02:54 steve
2680 * Minor cleanup of NetTaskDef.
2682 * Revision 1.115 2000/04/16 23:32:19 steve
2683 * Synthesis of comparator in expressions.
2685 * Connect the NetEvent and related classes
2688 * Revision 1.114 2000/04/15 19:51:30 steve
2689 * fork-join support in vvm.
2691 * Revision 1.113 2000/04/12 20:02:53 steve
2692 * Finally remove the NetNEvent and NetPEvent classes,
2693 * Get synthesis working with the NetEvWait class,
2694 * and get started supporting multiple events in a
2697 * Revision 1.112 2000/04/04 03:20:15 steve
2698 * Simulate named event trigger and waits.
2700 * Revision 1.111 2000/04/02 04:26:06 steve
2701 * Remove the useless sref template.
2703 * Revision 1.110 2000/04/01 21:40:22 steve
2704 * Add support for integer division.
2706 * Revision 1.109 2000/03/29 04:37:11 steve
2707 * New and improved combinational primitives.
2709 * Revision 1.108 2000/03/12 17:09:41 steve
2710 * Support localparam.
2712 * Revision 1.107 2000/03/10 06:20:48 steve
2713 * Handle defparam to partial hierarchical names.
2715 * Revision 1.106 2000/03/08 04:36:53 steve
2716 * Redesign the implementation of scopes and parameters.
2717 * I now generate the scopes and notice the parameters
2718 * in a separate pass over the pform. Once the scopes
2719 * are generated, I can process overrides and evalutate
2720 * paremeters before elaboration begins.
2722 * Revision 1.105 2000/02/23 02:56:54 steve
2723 * Macintosh compilers do not support ident.
2725 * Revision 1.104 2000/01/13 03:35:35 steve
2726 * Multiplication all the way to simulation.
2728 * Revision 1.103 2000/01/10 01:35:24 steve
2729 * Elaborate parameters afer binding of overrides.
2731 * Revision 1.102 1999/12/30 04:19:12 steve
2732 * Propogate constant 0 in low bits of adders.