2 * Copyright (c) 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
20 #ident "$Id: net_link.cc,v 1.21 2007/06/02 03:42:13 steve Exp $"
35 void connect(Nexus
*l
, Link
&r
)
45 while (Link
*cur
= tmp
->list_
) {
46 tmp
->list_
= cur
->next_
;
52 l
->driven_
= Nexus::NO_GUESS
;
54 assert(tmp
->list_
== 0);
58 void connect(Link
&l
, Link
&r
)
61 if (r
.is_linked() && !l
.is_linked())
68 : dir_(PASSIVE
), drive0_(STRONG
), drive1_(STRONG
), init_(verinum::Vx
),
69 inst_(0), next_(0), nexus_(0)
71 (new Nexus()) -> relink(this);
88 const Nexus
* Link::nexus() const
93 void Link::set_dir(DIR d
)
98 Link::DIR Link::get_dir() const
103 void Link::drive0(Link::strength_t str
)
108 void Link::drive1(Link::strength_t str
)
113 Link::strength_t
Link::drive0() const
118 Link::strength_t
Link::drive1() const
123 void Link::set_init(verinum::V val
)
128 verinum::V
Link::get_init() const
134 void Link::cur_link(NetObj
*&net
, unsigned &pin
)
140 void Link::cur_link(const NetObj
*&net
, unsigned &pin
) const
152 nexus_
->unlink(this);
153 (new Nexus()) -> relink(this);
156 bool Link::is_equal(const Link
&that
) const
158 return (node_
== that
.node_
) && (pin_
== that
.pin_
);
161 bool Link::is_linked() const
165 if (nexus_
->first_nlink() != this)
171 bool Link::is_linked(const Link
&that
) const
173 return nexus_
== that
.nexus_
;
176 Link
* Link::next_nlink()
181 const Link
* Link::next_nlink() const
186 const NetObj
*Link::get_obj() const
191 NetObj
*Link::get_obj()
196 unsigned Link::get_pin() const
201 void Link::set_name(perm_string n
, unsigned i
)
207 perm_string
Link::get_name() const
212 unsigned Link::get_inst() const
232 verinum::V
Nexus::get_init() const
235 for (Link
*cur
= list_
; cur
; cur
= cur
->next_
) {
236 if (cur
->get_dir() == Link::OUTPUT
)
239 if ((cur
->get_dir() == Link::PASSIVE
)
240 && (cur
->get_init() != verinum::Vz
))
241 return cur
->get_init();
247 void Nexus::unlink(Link
*that
)
254 /* If the link I'm removing was a driver for this nexus, then
255 cancel my guess of the driven value. */
256 if (that
->get_dir() != Link::INPUT
)
268 while (cur
->next_
!= that
) {
273 cur
->next_
= that
->next_
;
278 void Nexus::relink(Link
*that
)
285 /* If the link I'm adding is a driver for this nexus, then
286 cancel my guess of the driven value. */
287 if (that
->get_dir() != Link::INPUT
)
290 assert(that
->nexus_
== 0);
291 assert(that
->next_
== 0);
297 Link
* Nexus::first_nlink()
302 const Link
* Nexus::first_nlink() const
307 ivl_nexus_t
Nexus::t_cookie() const
312 ivl_nexus_t
Nexus::t_cookie(ivl_nexus_t val
)const
314 ivl_nexus_t tmp
= t_cookie_
;
319 unsigned Nexus::vector_width() const
321 for (const Link
*cur
= first_nlink() ; cur
; cur
= cur
->next_nlink()) {
322 const NetNet
*sig
= dynamic_cast<const NetNet
*>(cur
->get_obj());
326 return sig
->vector_width();
332 NetNet
* Nexus::pick_any_net()
334 for (Link
*cur
= first_nlink() ; cur
; cur
= cur
->next_nlink()) {
335 NetNet
*sig
= dynamic_cast<NetNet
*>(cur
->get_obj());
343 const char* Nexus::name() const
348 const NetNet
*sig
= 0;
350 for (const Link
*cur
= first_nlink()
351 ; cur
; cur
= cur
->next_nlink()) {
353 const NetNet
*cursig
= dynamic_cast<const NetNet
*>(cur
->get_obj());
359 pin
= cur
->get_pin();
363 if ((cursig
->pin_count() == 1) && (sig
->pin_count() > 1))
366 if ((cursig
->pin_count() > 1) && (sig
->pin_count() == 1)) {
368 pin
= cur
->get_pin();
372 if (cursig
->local_flag() && !sig
->local_flag())
375 if (cursig
->name() < sig
->name())
379 pin
= cur
->get_pin();
383 const Link
*lnk
= first_nlink();
384 const NetObj
*obj
= lnk
->get_obj();
385 pin
= lnk
->get_pin();
386 cerr
<< "internal error: No signal for nexus of " <<
387 obj
->name() << " pin " << pin
<< "(" <<
388 lnk
->get_name() << "<" << lnk
->get_inst() << ">)"
389 " type=" << typeid(*obj
).name() << "?" << endl
;
394 tmp
<< scope_path(sig
->scope()) << "." << sig
->name();
395 if (sig
->pin_count() > 1)
396 tmp
<< "<" << pin
<< ">";
398 const string tmps
= tmp
.str();
399 name_
= new char[strlen(tmps
.c_str()) + 1];
400 strcpy(name_
, tmps
.c_str());
411 NexusSet::~NexusSet()
421 unsigned NexusSet::count() const
426 void NexusSet::add(Nexus
*that
)
430 items_
= (Nexus
**)malloc(sizeof(Nexus
*));
436 unsigned ptr
= bsearch_(that
);
438 assert(items_
[ptr
] == that
);
442 assert(ptr
== nitems_
);
444 items_
= (Nexus
**)realloc(items_
, (nitems_
+1) * sizeof(Nexus
*));
449 void NexusSet::add(const NexusSet
&that
)
451 for (unsigned idx
= 0 ; idx
< that
.nitems_
; idx
+= 1)
452 add(that
.items_
[idx
]);
455 void NexusSet::rem(Nexus
*that
)
460 unsigned ptr
= bsearch_(that
);
471 for (unsigned idx
= ptr
; idx
< (nitems_
-1) ; idx
+= 1)
472 items_
[idx
] = items_
[idx
+1];
474 items_
= (Nexus
**)realloc(items_
, (nitems_
-1) * sizeof(Nexus
*));
478 void NexusSet::rem(const NexusSet
&that
)
480 for (unsigned idx
= 0 ; idx
< that
.nitems_
; idx
+= 1)
481 rem(that
.items_
[idx
]);
484 Nexus
* NexusSet::operator[] (unsigned idx
) const
486 assert(idx
< nitems_
);
490 unsigned NexusSet::bsearch_(Nexus
*that
) const
492 for (unsigned idx
= 0 ; idx
< nitems_
; idx
+= 1) {
493 if (items_
[idx
] == that
)
500 bool NexusSet::contains(const NexusSet
&that
) const
502 for (unsigned idx
= 0 ; idx
< that
.nitems_
; idx
+= 1) {
503 unsigned where
= bsearch_(that
[idx
]);
504 if (where
== nitems_
)
506 if (items_
[where
] != that
[idx
])
513 bool NexusSet::intersect(const NexusSet
&that
) const
515 for (unsigned idx
= 0 ; idx
< that
.nitems_
; idx
+= 1) {
516 unsigned where
= bsearch_(that
[idx
]);
517 if (where
== nitems_
)
519 if (items_
[where
] == that
[idx
])
527 * $Log: net_link.cc,v $
528 * Revision 1.21 2007/06/02 03:42:13 steve
529 * Properly evaluate scope path expressions.
531 * Revision 1.20 2007/03/26 18:17:50 steve
532 * Remove pretense of general use for t_cookie.
534 * Revision 1.19 2006/02/02 02:43:58 steve
535 * Allow part selects of memory words in l-values.
537 * Revision 1.18 2005/09/25 23:40:11 steve
538 * Simplify NexusSet set handling.
540 * Revision 1.17 2005/06/13 23:22:37 steve
541 * Fix compile errors.
543 * Revision 1.16 2005/04/24 23:44:02 steve
544 * Update DFF support to new data flow.
546 * Revision 1.15 2005/01/09 20:16:01 steve
547 * Use PartSelect/PV and VP to handle part selects through ports.
549 * Revision 1.14 2004/02/18 17:11:56 steve
550 * Use perm_strings for named langiage items.
552 * Revision 1.13 2003/01/14 21:16:18 steve
553 * Move strstream to ostringstream for compatibility.
555 * Revision 1.12 2002/10/21 01:42:08 steve
556 * Synthesizer support for synchronous begin-end blocks.
558 * Revision 1.11 2002/08/18 22:07:16 steve
559 * Detect temporaries in sequential block synthesis.
561 * Revision 1.10 2002/08/12 01:34:59 steve
562 * conditional ident string using autoconfig.
564 * Revision 1.9 2002/07/03 03:08:47 steve
565 * Clear drive cache on link or unlink.
567 * Revision 1.8 2002/06/30 02:21:31 steve
568 * Add structure for asynchronous logic synthesis.
570 * Revision 1.7 2002/06/24 01:49:39 steve
571 * Make link_drive_constant cache its results in
572 * the Nexus, to improve cprop performance.
574 * Revision 1.6 2002/04/21 04:59:08 steve
575 * Add support for conbinational events by finding
576 * the inputs to expressions and some statements.
577 * Get case and assignment statements working.
579 * Revision 1.5 2001/07/25 03:10:49 steve
580 * Create a config.h.in file to hold all the config
581 * junk, and support gcc 3.0. (Stephan Boettcher)
583 * Revision 1.4 2000/10/06 23:46:50 steve
584 * ivl_target updates, including more complete
585 * handling of ivl_nexus_t objects. Much reduced
586 * dependencies on pointers to netlist objects.
588 * Revision 1.3 2000/08/26 00:54:03 steve
589 * Get at gate information for ivl_target interface.
591 * Revision 1.2 2000/07/14 06:12:57 steve
592 * Move inital value handling from NetNet to Nexus
593 * objects. This allows better propogation of inital
596 * Clean up constant propagation a bit to account
597 * for regs that are not really values.
599 * Revision 1.1 2000/06/25 19:59:42 steve
600 * Redesign Links to include the Nexus class that
601 * carries properties of the connected set of links.