From 88af5b6a162ebc4fcc753794b38491e7897b702a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 29 Mar 2013 11:19:21 +0100 Subject: [PATCH] Improved opt_share for reduce cells --- kernel/rtlil.cc | 13 ++++++++++--- kernel/rtlil.h | 2 ++ passes/opt/opt_share.cc | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 95114469e..b0dcfe428 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -566,7 +566,7 @@ void RTLIL::SigSpec::optimize() check(); } -static bool compare_sigchunks(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b) +bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b) { if (a.wire != b.wire) { if (a.wire == NULL || b.wire == NULL) @@ -583,14 +583,21 @@ static bool compare_sigchunks(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b return a.data.bits < b.data.bits; } +void RTLIL::SigSpec::sort() +{ + expand(); + std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare); + optimize(); +} + void RTLIL::SigSpec::sort_and_unify() { expand(); - std::sort(chunks.begin(), chunks.end(), compare_sigchunks); + std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare); for (size_t i = 1; i < chunks.size(); i++) { RTLIL::SigChunk &ch1 = chunks[i-1]; RTLIL::SigChunk &ch2 = chunks[i]; - if (!compare_sigchunks(ch1, ch2) && !compare_sigchunks(ch2, ch1)) { + if (!RTLIL::SigChunk::compare(ch1, ch2) && !RTLIL::SigChunk::compare(ch2, ch1)) { chunks.erase(chunks.begin()+i); width -= chunks[i].width; i--; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a0d7a1a37..fe88182fa 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -277,6 +277,7 @@ struct RTLIL::SigChunk { bool operator <(const RTLIL::SigChunk &other) const; bool operator ==(const RTLIL::SigChunk &other) const; bool operator !=(const RTLIL::SigChunk &other) const; + static bool compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b); }; struct RTLIL::SigSpec { @@ -291,6 +292,7 @@ struct RTLIL::SigSpec { SigSpec(RTLIL::State bit, int width = 1); void expand(); void optimize(); + void sort(); void sort_and_unify(); void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 6dd4daa0b..43d1a57e1 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -76,6 +76,18 @@ struct OptShareWorker alt_conn["\\B"] = conn->at("\\A"); } conn = &alt_conn; + } else + if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") { + alt_conn = *conn; + assign_map.apply(alt_conn.at("\\A")); + alt_conn.at("\\A").sort(); + conn = &alt_conn; + } else + if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { + alt_conn = *conn; + assign_map.apply(alt_conn.at("\\A")); + alt_conn.at("\\A").sort_and_unify(); + conn = &alt_conn; } for (auto &it : *conn) { @@ -151,6 +163,14 @@ struct OptShareWorker conn2["\\A"] = conn2["\\B"]; conn2["\\B"] = tmp; } + } else + if (cell1->type == "$reduce_xor" || cell1->type == "$reduce_xnor") { + conn1["\\A"].sort(); + conn2["\\A"].sort(); + } else + if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") { + conn1["\\A"].sort_and_unify(); + conn2["\\A"].sort_and_unify(); } if (conn1 != conn2) { -- 2.30.2