From ba0723cad77a327653c080da84dda9f6ef12fad1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Sat, 2 Oct 2021 00:05:22 +0200 Subject: [PATCH] zinit: Refactor to use FfData. --- passes/techmap/zinit.cc | 139 +++++++++++----------------------------- 1 file changed, 38 insertions(+), 101 deletions(-) diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 7c5b73c90..8fcc47570 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -20,10 +20,19 @@ #include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/ffinit.h" +#include "kernel/ff.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +State invert(State s) { + switch (s) { + case State::S0: return State::S1; + case State::S1: return State::S0; + default: return s; + } +} + struct ZinitPass : public Pass { ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } void help() override @@ -60,123 +69,51 @@ struct ZinitPass : public Pass { SigMap sigmap(module); FfInitVals initvals(&sigmap, module); - pool dff_types = { - // FIXME: It would appear that supporting - // $dffsr/$_DFFSR_* would require a new - // cell type where S has priority over R - ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), ID($adffe), - ID($sdff), ID($sdffe), ID($sdffce), - ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), - /*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_), - ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/ - ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), - // Async set/reset - ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), - ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), - ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), - ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_), - // Sync set/reset - ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), - ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_), - ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), - ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), - ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), - ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_), - ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), - ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), - ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), - ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_) - }; - for (auto cell : module->selected_cells()) { - if (!dff_types.count(cell->type)) + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; - SigSpec sig_d = sigmap(cell->getPort(ID::D)); - SigSpec sig_q = sigmap(cell->getPort(ID::Q)); + FfData ff(&initvals, cell); + if (!ff.width) + continue; - if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) + // Supporting those would require a new cell type where S has priority over R. + if (ff.has_sr) continue; - Const initval = initvals(sig_q); - Const newval = initval; - initvals.remove_init(sig_q); + Wire *new_q = module->addWire(NEW_ID, ff.width); - Wire *initwire = module->addWire(NEW_ID, GetSize(sig_q)); + log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), + log_signal(ff.sig_q), log_signal(ff.val_init)); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) + IdString name = cell->name; + module->remove(cell); + initvals.remove_init(ff.sig_q); + + for (int i = 0; i < ff.width; i++) + if (ff.val_init[i] == State::S1) { - sig_d[i] = module->NotGate(NEW_ID, sig_d[i]); - module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]); - newval[i] = State::S0; + if (ff.has_clk || ff.has_gclk) + ff.sig_d[i] = module->NotGate(NEW_ID, ff.sig_d[i]); + if (ff.has_aload) + ff.sig_ad[i] = module->NotGate(NEW_ID, ff.sig_ad[i]); + if (ff.has_arst) + ff.val_arst[i] = invert(ff.val_arst[i]); + if (ff.has_srst) + ff.val_srst[i] = invert(ff.val_srst[i]); + module->addNotGate(NEW_ID, SigSpec(new_q, i), ff.sig_q[i]); + ff.val_init[i] = State::S0; } else { - module->connect(sig_q[i], SigSpec(initwire, i)); + module->connect(ff.sig_q[i], SigSpec(new_q, i)); if (all_mode) - newval[i] = State::S0; + ff.val_init[i] = State::S0; } - initvals.set_init(initwire, newval); - - log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), - log_signal(sig_q), log_signal(initval)); - - cell->setPort(ID::D, sig_d); - cell->setPort(ID::Q, initwire); - - if (cell->type.in(ID($adff), ID($adffe))) { - auto val = cell->getParam(ID::ARST_VALUE); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) - val[i] = (val[i] == State::S1 ? State::S0 : State::S1); - cell->setParam(ID::ARST_VALUE, std::move(val)); - } - else if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { - auto val = cell->getParam(ID::SRST_VALUE); - for (int i = 0; i < GetSize(initwire); i++) - if (initval[i] == State::S1) - val[i] = (val[i] == State::S1 ? State::S0 : State::S1); - cell->setParam(ID::SRST_VALUE, std::move(val)); - } - else if (initval == State::S1) { - std::string t = cell->type.str(); - if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), - ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) - { - t[8] = (t[8] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), - ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) - { - t[9] = (t[9] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), - ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), - ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), - ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_))) - { - t[9] = (t[9] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), - ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), - ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), - ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_))) - { - t[10] = (t[10] == '0' ? '1' : '0'); - } - else if (cell->type.in(ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), - ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), - ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), - ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_))) - { - t[11] = (t[11] == '0' ? '1' : '0'); - } - cell->type = t; - } + ff.sig_q = new_q; + ff.emit(module, name); } } } -- 2.30.2