Improved opt_share for reduce cells
authorClifford Wolf <clifford@clifford.at>
Fri, 29 Mar 2013 10:19:21 +0000 (11:19 +0100)
committerClifford Wolf <clifford@clifford.at>
Fri, 29 Mar 2013 10:19:21 +0000 (11:19 +0100)
kernel/rtlil.cc
kernel/rtlil.h
passes/opt/opt_share.cc

index 95114469e875c265d3c3ea5f2742bf19723abe47..b0dcfe42892058360f4df57bc9f1d3aa22a40ce9 100644 (file)
@@ -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--;
index a0d7a1a37cd9b91a80437666cbbbcb08a5cab1ee..fe88182fa86d3af31c6b5dad8a2926bd282f54fe 100644 (file)
@@ -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;
index 6dd4daa0b389b3900e6ea06dcb27ef881ab52aa9..43d1a57e1635dd544bce681d8662bde21e1a9854 100644 (file)
@@ -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) {