More cost effective and reliable island joining algorithm.

Rather then join islands while branches are initially created, save the
island creating for the end. This way, the process is actually recursive
and greedy, reliably collecting branches into islands without conflict.
This commit is contained in:
Stephen Williams 2008-06-03 20:21:39 -07:00
parent c2061e8199
commit db09f2fa7e
6 changed files with 67 additions and 25 deletions

View File

@ -2393,8 +2393,6 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
connect(ps->pin(0), osig->pin(0)); connect(ps->pin(0), osig->pin(0));
connect(ps->pin(1), nets[idx]->pin(0)); connect(ps->pin(1), nets[idx]->pin(0));
join_island(ps);
ivl_assert(*this, wid <= width); ivl_assert(*this, wid <= width);
width -= wid; width -= wid;
} }
@ -2801,7 +2799,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
des->add_node(sub); des->add_node(sub);
connect(sub->pin(0), sig->pin(0)); connect(sub->pin(0), sig->pin(0));
connect(sub->pin(1), subsig->pin(0)); connect(sub->pin(1), subsig->pin(0));
join_island(sub);
} else { } else {
NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid, NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,

View File

@ -863,14 +863,6 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1; des->errors += 1;
} }
}
// If these new nodes can belong to an island, then run tests
// to joind islands now.
if (dynamic_cast<IslandBranch*> (cur[0])) {
for (unsigned idx = 0 ; idx < count ; idx += 1) {
join_island(cur[idx]);
}
} }
// "cur" is an array of pointers, and we don't need it any more. // "cur" is an array of pointers, and we don't need it any more.
@ -910,7 +902,6 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
node->set_line(*this); node->set_line(*this);
des->add_node(node); des->add_node(node);
join_island(node);
return tmp; return tmp;
} }

View File

@ -825,6 +825,11 @@ int main(int argc, char*argv[])
func(des); func(des);
} }
if (verbose_flag) {
cout << "CALCULATING ISLANDS" << endl;
}
des->join_islands();
if (net_path) { if (net_path) {
if (verbose_flag) if (verbose_flag)
cerr<<" dumping netlist to " <<net_path<< "..." <<endl; cerr<<" dumping netlist to " <<net_path<< "..." <<endl;

View File

@ -673,3 +673,14 @@ void Design::delete_process(NetProcTop*top)
delete top; delete top;
} }
void Design::join_islands(void)
{
if (nodes_ == 0)
return;
NetNode*cur = nodes_->node_next_;
do {
join_island(cur);
cur = cur->node_next_;
} while (cur != nodes_->node_next_);
}

View File

@ -82,42 +82,79 @@ unsigned NetTran::part_offset() const
void join_island(NetObj*obj) void join_island(NetObj*obj)
{ {
IslandBranch*branch = dynamic_cast<IslandBranch*> (obj); IslandBranch*branch = dynamic_cast<IslandBranch*> (obj);
// If this is not even a branch, then stop now.
if (branch == 0) if (branch == 0)
return; return;
ivl_assert(*obj, branch->island == 0); // If this is a branch, but already given to an island, then
struct ivl_island_s*use_island = 0; // stop.
if (branch->island)
return;
list<NetObj*> uncommitted_neighbors;
// Look for neighboring objects that might already be in
// islands. If we find something, then join that island.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
Nexus*nex = obj->pin(idx).nexus(); Nexus*nex = obj->pin(idx).nexus();
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
unsigned pin; unsigned pin;
NetObj*tmp; NetObj*tmp;
cur->cur_link(tmp, pin); cur->cur_link(tmp, pin);
// Skip self.
if (tmp == obj) if (tmp == obj)
continue; continue;
// If tmb is not a branch, then skip it.
IslandBranch*tmp_branch = dynamic_cast<IslandBranch*> (tmp); IslandBranch*tmp_branch = dynamic_cast<IslandBranch*> (tmp);
if (tmp_branch == 0) if (tmp_branch == 0)
continue; continue;
ivl_assert(*tmp, tmp_branch->island); // If that is an uncommitted branch, then save
ivl_assert(*obj, use_island==0 || use_island==tmp_branch->island); // it. When I finally choose an island for self,
use_island = tmp_branch->island; // these branches will be scanned so tha they join
// this island as well.
if (tmp_branch->island == 0) {
uncommitted_neighbors.push_back(tmp);
continue;
}
ivl_assert(*obj, branch->island==0 || branch->island==tmp_branch->island);
// We found an existing island to join. Join it
// now. Keep scanning in order to find more neighbors.
if (branch->island == 0) {
if (debug_elaborate)
cerr << obj->get_fileline() << ": debug: "
<< "Join brach to existing island." << endl;
branch->island = tmp_branch->island;
} else if (branch->island != tmp_branch->island) {
cerr << obj->get_fileline() << ": internal error: "
<< "Oops, Found 2 neighboring islands." << endl;
ivl_assert(*obj, 0);
}
} }
} }
if (use_island == 0) { // If after all that we did not find an idland to join, then
use_island = new ivl_island_s; // start the island not and join it.
use_island->discipline = 0; if (branch->island == 0) {
branch->island = new ivl_island_s;
branch->island->discipline = 0;
if (debug_elaborate) if (debug_elaborate)
cerr << obj->get_fileline() << ": debug: " cerr << obj->get_fileline() << ": debug: "
<< "Create new island for this branch" << endl; << "Create new island for this branch" << endl;
} else {
if (debug_elaborate)
cerr << obj->get_fileline() << ": debug: "
<< "Join this brach to existing island." << endl;
} }
branch->island = use_island; // Now scan all the uncommitted neighbors I found. Calling
// join_island() on them will cause them to notice me in the
// process, and thus they will join my island. This process
// will recurse until all the connected branches join this island.
for (list<NetObj*>::iterator cur = uncommitted_neighbors.begin()
; cur != uncommitted_neighbors.end() ; cur ++ ) {
join_island(*cur);
}
} }

View File

@ -3638,6 +3638,7 @@ class Design {
// Iterate over the design... // Iterate over the design...
void dump(ostream&) const; void dump(ostream&) const;
void functor(struct functor_t*); void functor(struct functor_t*);
void join_islands(void);
int emit(struct target_t*) const; int emit(struct target_t*) const;
// This is incremented by elaboration when an error is // This is incremented by elaboration when an error is