From ca8af1f8c89910b9b3c9112d8e5efd6e031f53ec Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Mon, 21 Jul 2025 14:15:26 +0300 Subject: [PATCH 1/5] opt_dff: implement simplify_patterns --- passes/opt/opt_dff.cc | 60 ++++++++++++++++++++++++++++++-- tests/arch/quicklogic/pp3/fsm.ys | 6 ++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 4ed4b0cb6..b24616928 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -170,9 +170,65 @@ struct OptDffWorker return ret; } - void simplify_patterns(patterns_t&) + void simplify_patterns(patterns_t& patterns) { - // TBD + // remove complimentary patterns + + auto new_patterns = patterns; + bool optimized; + do { + optimized = false; + for (auto i = patterns.begin(); i != patterns.end(); i++) { + for (auto j = std::next(i, 1); j != patterns.end(); j++) { + const auto& smaller = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + const auto& larger = (GetSize(*i) < GetSize(*j)) ? *j : *i; + auto left = std::move(smaller); + auto right = std::move(larger); + + std::optional complimentary_var; + + for (const auto &pt : left) + if (right.count(pt.first) == 0) + goto next; + else if (right[pt.first] == pt.second) + continue; + else + if (complimentary_var) + goto next; + else + complimentary_var = pt.first; + if (complimentary_var) { + new_patterns.erase(right); + right.erase(complimentary_var.value()); + new_patterns.insert(right); + optimized = true; + } + next: + continue; + } + } + patterns = new_patterns; + } while(optimized); + + // remove redundant patterns + + for (auto i = patterns.begin(); i != patterns.end(); ++i) { + for (auto j = std::next(i, 1); j != patterns.end(); ++j) { + const auto& smaller = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + const auto& larger = (GetSize(*i) < GetSize(*j)) ? *j : *i; + auto left = std::move(smaller); + auto right = std::move(larger); + + bool redundant = true; + + for (const auto& pt : left) + if (right.count(pt.first) == 0 || right[pt.first] != pt.second) + redundant = false; + if (redundant) + new_patterns.erase(right); + } + } + patterns = std::move(new_patterns) } ctrl_t make_patterns_logic(const patterns_t &patterns, const ctrls_t &ctrls, bool make_gates) diff --git a/tests/arch/quicklogic/pp3/fsm.ys b/tests/arch/quicklogic/pp3/fsm.ys index 418db8025..9679628e9 100644 --- a/tests/arch/quicklogic/pp3/fsm.ys +++ b/tests/arch/quicklogic/pp3/fsm.ys @@ -11,8 +11,8 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd fsm # Constrain all select calls below inside the top module -select -assert-count 1 t:LUT2 -select -assert-count 9 t:LUT3 +select -assert-count 2 t:LUT2 +select -assert-count 4 t:LUT3 select -assert-count 4 t:dffepc select -assert-count 1 t:logic_0 select -assert-count 1 t:logic_1 @@ -20,4 +20,4 @@ select -assert-count 3 t:inpad select -assert-count 2 t:outpad select -assert-count 1 t:ckpad -select -assert-none t:LUT2 t:LUT3 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D +select -assert-none t:LUT2 t:LUT3 t:LUT4 t:dffepc t:logic_0 t:logic_1 t:inpad t:outpad t:ckpad %% t:* %D From d9fc6dda9ec9354568f372f870af73ccffc6b652 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Mon, 21 Jul 2025 14:42:52 +0300 Subject: [PATCH 2/5] typo --- passes/opt/opt_dff.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index b24616928..def177133 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -228,7 +228,7 @@ struct OptDffWorker new_patterns.erase(right); } } - patterns = std::move(new_patterns) + patterns = std::move(new_patterns); } ctrl_t make_patterns_logic(const patterns_t &patterns, const ctrls_t &ctrls, bool make_gates) From 206d2a455374c1ff25402a6efdcf7e4b47d6d093 Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Wed, 30 Jul 2025 21:31:34 +0300 Subject: [PATCH 3/5] opt_dff: refactor simplify_patterns --- passes/opt/opt_dff.cc | 53 ++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index def177133..036c1b917 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -172,60 +172,57 @@ struct OptDffWorker void simplify_patterns(patterns_t& patterns) { - // remove complimentary patterns - auto new_patterns = patterns; + auto find_comp = [](const auto& left, const auto& right) -> std::optional { + std::optional ret; + for (const auto &pt: left) + if (right.count(pt.first) == 0) + return {}; + else if (right.at(pt.first) == pt.second) + continue; + else + if (ret) + return {}; + else + ret = pt.first; + return ret; + }; + + // remove complimentary patterns bool optimized; do { optimized = false; for (auto i = patterns.begin(); i != patterns.end(); i++) { for (auto j = std::next(i, 1); j != patterns.end(); j++) { - const auto& smaller = (GetSize(*j) <= GetSize(*i)) ? *j : *i; - const auto& larger = (GetSize(*i) < GetSize(*j)) ? *j : *i; - auto left = std::move(smaller); - auto right = std::move(larger); + const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + auto right = (GetSize(*i) < GetSize(*j)) ? *j : *i; - std::optional complimentary_var; + const auto complimentary_var = find_comp(left, right); - for (const auto &pt : left) - if (right.count(pt.first) == 0) - goto next; - else if (right[pt.first] == pt.second) - continue; - else - if (complimentary_var) - goto next; - else - complimentary_var = pt.first; if (complimentary_var) { new_patterns.erase(right); right.erase(complimentary_var.value()); new_patterns.insert(right); optimized = true; } - next: - continue; } } patterns = new_patterns; } while(optimized); // remove redundant patterns - for (auto i = patterns.begin(); i != patterns.end(); ++i) { - for (auto j = std::next(i, 1); j != patterns.end(); ++j) { - const auto& smaller = (GetSize(*j) <= GetSize(*i)) ? *j : *i; - const auto& larger = (GetSize(*i) < GetSize(*j)) ? *j : *i; - auto left = std::move(smaller); - auto right = std::move(larger); + for (auto j = std::next(i, 1); j != patterns.end(); ++j) { + const auto& left = (GetSize(*j) <= GetSize(*i)) ? *j : *i; + const auto& right = (GetSize(*i) < GetSize(*j)) ? *j : *i; bool redundant = true; - for (const auto& pt : left) - if (right.count(pt.first) == 0 || right[pt.first] != pt.second) + for (const auto& pt : smaller) + if (larger.count(pt.first) == 0 || larger[pt.first] != pt.second) redundant = false; if (redundant) - new_patterns.erase(right); + new_patterns.erase(larger); } } patterns = std::move(new_patterns); From bfff7a47f17033e2d61c75a779d0078bc0f8cfcf Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Wed, 30 Jul 2025 21:34:42 +0300 Subject: [PATCH 4/5] typo --- passes/opt/opt_dff.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 036c1b917..2a9d67dd6 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -222,7 +222,7 @@ struct OptDffWorker if (larger.count(pt.first) == 0 || larger[pt.first] != pt.second) redundant = false; if (redundant) - new_patterns.erase(larger); + new_patterns.erase(right); } } patterns = std::move(new_patterns); From 85e0e8ca670333898e9cbbbd4f1bf94dc421ae9c Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Wed, 30 Jul 2025 21:40:20 +0300 Subject: [PATCH 5/5] typo --- passes/opt/opt_dff.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 2a9d67dd6..210c4828f 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -218,8 +218,8 @@ struct OptDffWorker bool redundant = true; - for (const auto& pt : smaller) - if (larger.count(pt.first) == 0 || larger[pt.first] != pt.second) + for (const auto& pt : left) + if (right.count(pt.first) == 0 || right.at(pt.first) != pt.second) redundant = false; if (redundant) new_patterns.erase(right);