Fixed performance bug in proc_dlatch

This commit is contained in:
Clifford Wolf 2016-04-24 19:29:56 +02:00
parent 9aa4b3309c
commit b1d6f05fa2
1 changed files with 61 additions and 2 deletions

View File

@ -33,6 +33,7 @@ struct proc_dlatch_db_t
Module *module;
SigMap sigmap;
dict<Cell*, vector<SigBit>> mux_srcbits;
dict<SigBit, pair<Cell*, int>> mux_drivers;
dict<SigBit, int> sigusers;
@ -40,10 +41,24 @@ struct proc_dlatch_db_t
{
for (auto cell : module->cells())
{
if (cell->type.in("$mux", "$pmux")) {
if (cell->type.in("$mux", "$pmux"))
{
auto sig_y = sigmap(cell->getPort("\\Y"));
for (int i = 0; i < GetSize(sig_y); i++)
mux_drivers[sig_y[i]] = pair<Cell*, int>(cell, i);
pool<SigBit> mux_srcbits_pool;
for (auto bit : sigmap(cell->getPort("\\A")))
mux_srcbits_pool.insert(bit);
for (auto bit : sigmap(cell->getPort("\\B")))
mux_srcbits_pool.insert(bit);
vector<SigBit> mux_srcbits_vec;
for (auto bit : mux_srcbits_pool)
if (bit.wire != nullptr)
mux_srcbits_vec.push_back(bit);
mux_srcbits[cell].swap(mux_srcbits_vec);
}
for (auto &conn : cell->connections())
@ -58,6 +73,42 @@ struct proc_dlatch_db_t
sigusers[bit]++;
}
bool quickcheck(const SigSpec &haystack, const SigSpec &needle)
{
pool<SigBit> haystack_bits = sigmap(haystack).to_sigbit_pool();
pool<SigBit> needle_bits = sigmap(needle).to_sigbit_pool();
pool<Cell*> cells_queue, cells_visited;
pool<SigBit> bits_queue, bits_visited;
bits_queue = haystack_bits;
while (!bits_queue.empty())
{
for (auto &bit : bits_queue) {
auto it = mux_drivers.find(bit);
if (it != mux_drivers.end())
if (!cells_visited.count(it->second.first))
cells_queue.insert(it->second.first);
bits_visited.insert(bit);
}
bits_queue.clear();
for (auto c : cells_queue) {
for (auto bit : mux_srcbits[c]) {
if (needle_bits.count(bit))
return true;
if (!bits_visited.count(bit))
bits_queue.insert(bit);
}
}
cells_queue.clear();
}
return false;
}
struct rule_node_t
{
// a node is true if "signal" equals "match" and [any
@ -218,9 +269,17 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
continue;
}
for (auto ss : sr->actions) {
for (auto ss : sr->actions)
{
db.sigmap.apply(ss.first);
db.sigmap.apply(ss.second);
if (!db.quickcheck(ss.second, ss.first)) {
nolatches_bits.first.append(ss.first);
nolatches_bits.second.append(ss.second);
continue;
}
for (int i = 0; i < GetSize(ss.first); i++)
latches_out_in[ss.first[i]] = ss.second[i];
}