Skip to content

Commit

Permalink
More cost effective and reliable island joining algorithm.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
steveicarus committed Jun 4, 2008
1 parent c2061e8 commit db09f2f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 25 deletions.
3 changes: 0 additions & 3 deletions elab_net.cc
Expand Up @@ -2393,8 +2393,6 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
connect(ps->pin(0), osig->pin(0));
connect(ps->pin(1), nets[idx]->pin(0));

join_island(ps);

ivl_assert(*this, wid <= width);
width -= wid;
}
Expand Down Expand Up @@ -2801,7 +2799,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
des->add_node(sub);
connect(sub->pin(0), sig->pin(0));
connect(sub->pin(1), subsig->pin(0));
join_island(sub);

} else {
NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
Expand Down
9 changes: 0 additions & 9 deletions elaborate.cc
Expand Up @@ -863,14 +863,6 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
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.
Expand Down Expand Up @@ -910,7 +902,6 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,

node->set_line(*this);
des->add_node(node);
join_island(node);

return tmp;
}
Expand Down
5 changes: 5 additions & 0 deletions main.cc
Expand Up @@ -825,6 +825,11 @@ int main(int argc, char*argv[])
func(des);
}

if (verbose_flag) {
cout << "CALCULATING ISLANDS" << endl;
}
des->join_islands();

if (net_path) {
if (verbose_flag)
cerr<<" dumping netlist to " <<net_path<< "..." <<endl;
Expand Down
11 changes: 11 additions & 0 deletions net_design.cc
Expand Up @@ -673,3 +673,14 @@ void Design::delete_process(NetProcTop*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_);
}
63 changes: 50 additions & 13 deletions net_tran.cc
Expand Up @@ -82,42 +82,79 @@ unsigned NetTran::part_offset() const
void join_island(NetObj*obj)
{
IslandBranch*branch = dynamic_cast<IslandBranch*> (obj);

// If this is not even a branch, then stop now.
if (branch == 0)
return;

ivl_assert(*obj, branch->island == 0);
struct ivl_island_s*use_island = 0;
// If this is a branch, but already given to an island, then
// 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) {
Nexus*nex = obj->pin(idx).nexus();
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
unsigned pin;
NetObj*tmp;
cur->cur_link(tmp, pin);

// Skip self.
if (tmp == obj)
continue;

// If tmb is not a branch, then skip it.
IslandBranch*tmp_branch = dynamic_cast<IslandBranch*> (tmp);
if (tmp_branch == 0)
continue;

ivl_assert(*tmp, tmp_branch->island);
ivl_assert(*obj, use_island==0 || use_island==tmp_branch->island);
use_island = tmp_branch->island;
// If that is an uncommitted branch, then save
// it. When I finally choose an island for self,
// 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) {
use_island = new ivl_island_s;
use_island->discipline = 0;
// If after all that we did not find an idland to join, then
// start the island not and join it.
if (branch->island == 0) {
branch->island = new ivl_island_s;
branch->island->discipline = 0;
if (debug_elaborate)
cerr << obj->get_fileline() << ": debug: "
<< "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);
}
}
1 change: 1 addition & 0 deletions netlist.h
Expand Up @@ -3638,6 +3638,7 @@ class Design {
// Iterate over the design...
void dump(ostream&) const;
void functor(struct functor_t*);
void join_islands(void);
int emit(struct target_t*) const;

// This is incremented by elaboration when an error is
Expand Down

0 comments on commit db09f2f

Please sign in to comment.