From ca8af1f8c89910b9b3c9112d8e5efd6e031f53ec Mon Sep 17 00:00:00 2001 From: Anhijkt Date: Mon, 21 Jul 2025 14:15:26 +0300 Subject: [PATCH] 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