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:
parent
c2061e8199
commit
db09f2fa7e
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
5
main.cc
5
main.cc
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
net_tran.cc
63
net_tran.cc
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue