From 4e70c3077562e511d6f840c91dd30ade87d66517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 6 Oct 2021 22:16:55 +0200 Subject: FfData: some refactoring. - FfData now keeps track of the module and underlying cell, if any (so calling emit on FfData created from a cell will replace the existing cell) - FfData implementation is split off to its own .cc file for faster compilation - the "flip FF data sense by inserting inverters in front and after" functionality that zinit uses is moved onto FfData class and beefed up to have dffsr support, to support more use cases --- passes/memory/memory_dff.cc | 2 +- passes/opt/opt_dff.cc | 20 ++++++++--------- passes/sat/async2sync.cc | 11 ++++------ passes/sat/clk2fflogic.cc | 37 ++++++++++++++++---------------- passes/techmap/dffunmap.cc | 9 ++++---- passes/techmap/simplemap.cc | 4 ++-- passes/techmap/zinit.cc | 52 ++++++++------------------------------------- 7 files changed, 48 insertions(+), 87 deletions(-) (limited to 'passes') diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index b87ecdd99..91209d428 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -581,7 +581,7 @@ struct MemoryDffWorker // Now we're commited to merge it. merger.mark_input_ff(bits); // If the address FF has enable and/or sync reset, unmap it. - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); port.clk = ff.sig_clk; port.en = State::S1; port.addr = ff.sig_d; diff --git a/passes/opt/opt_dff.cc b/passes/opt/opt_dff.cc index 0e25484b8..38faba15a 100644 --- a/passes/opt/opt_dff.cc +++ b/passes/opt/opt_dff.cc @@ -275,7 +275,7 @@ struct OptDffWorker bool changed = false; if (!ff.width) { - module->remove(cell); + ff.remove(); did_something = true; continue; } @@ -316,6 +316,7 @@ struct OptDffWorker continue; } ff = ff.slice(keep_bits); + ff.cell = cell; changed = true; } @@ -393,8 +394,7 @@ struct OptDffWorker // Always-active enable. Make a comb circuit, nuke the FF/latch. log("Handling always-active async load on %s (%s) from module %s (changing to combinatorial circuit).\n", log_id(cell), log_id(cell->type), log_id(module)); - initvals.remove_init(ff.sig_q); - module->remove(cell); + ff.remove(); if (ff.has_sr) { SigSpec tmp; if (ff.is_fine) { @@ -456,8 +456,7 @@ struct OptDffWorker // Always-active async reset — change to const driver. log("Handling always-active ARST on %s (%s) from module %s (changing to const driver).\n", log_id(cell), log_id(cell->type), log_id(module)); - initvals.remove_init(ff.sig_q); - module->remove(cell); + ff.remove(); module->connect(ff.sig_q, ff.val_arst); did_something = true; continue; @@ -660,6 +659,7 @@ struct OptDffWorker continue; } ff = ff.slice(keep_bits); + ff.cell = cell; changed = true; } @@ -728,7 +728,7 @@ struct OptDffWorker new_ff.pol_srst = srst.second; if (new_ff.has_ce) new_ff.ce_over_srst = true; - Cell *new_cell = new_ff.emit(module, NEW_ID); + Cell *new_cell = new_ff.emit(); if (new_cell) dff_cells.push_back(new_cell); log("Adding SRST signal on %s (%s) from module %s (D = %s, Q = %s, rval = %s).\n", @@ -741,6 +741,7 @@ struct OptDffWorker continue; } else if (GetSize(remaining_indices) != ff.width) { ff = ff.slice(remaining_indices); + ff.cell = cell; changed = true; } } @@ -790,7 +791,7 @@ struct OptDffWorker new_ff.sig_ce = en.first; new_ff.pol_ce = en.second; new_ff.ce_over_srst = false; - Cell *new_cell = new_ff.emit(module, NEW_ID); + Cell *new_cell = new_ff.emit(); if (new_cell) dff_cells.push_back(new_cell); log("Adding EN signal on %s (%s) from module %s (D = %s, Q = %s).\n", @@ -803,6 +804,7 @@ struct OptDffWorker continue; } else if (GetSize(remaining_indices) != ff.width) { ff = ff.slice(remaining_indices); + ff.cell = cell; changed = true; } } @@ -810,9 +812,7 @@ struct OptDffWorker if (changed) { // Rebuild the FF. - IdString name = cell->name; - module->remove(cell); - ff.emit(module, name); + ff.emit(); did_something = true; } } diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index f1b93d084..46c76eba9 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -78,7 +78,7 @@ struct Async2syncPass : public Pass { if (ff.has_clk) { if (ff.has_sr) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -124,7 +124,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_sr = false; } else if (ff.has_aload) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); log("Replacing %s.%s (%s): ALOAD=%s, AD=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -157,7 +157,7 @@ struct Async2syncPass : public Pass { ff.sig_q = new_q; ff.has_aload = false; } else if (ff.has_arst) { - ff.unmap_srst(module); + ff.unmap_srst(); log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n", log_id(module), log_id(cell), log_id(cell->type), @@ -267,10 +267,7 @@ struct Async2syncPass : public Pass { ff.has_sr = false; ff.has_gclk = true; } - - IdString name = cell->name; - module->remove(cell); - ff.emit(module, name); + ff.emit(); } } } diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index d90206b46..a292941c8 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -153,6 +153,23 @@ struct Clk2fflogicPass : public Pass { continue; } + if (ff.has_clk) { + log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); + } else if (ff.has_aload) { + log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); + } else { + // $sr. + log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", + log_id(module), log_id(cell), log_id(cell->type), + log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); + } + + ff.remove(); + Wire *past_q = module->addWire(NEW_ID, ff.width); if (!ff.is_fine) { module->addFf(NEW_ID, ff.sig_q, past_q); @@ -163,7 +180,7 @@ struct Clk2fflogicPass : public Pass { initvals.set_init(past_q, ff.val_init); if (ff.has_clk) { - ff.unmap_ce_srst(module); + ff.unmap_ce_srst(); Wire *past_clk = module->addWire(NEW_ID); initvals.set_init(past_clk, ff.pol_clk ? State::S1 : State::S0); @@ -173,10 +190,6 @@ struct Clk2fflogicPass : public Pass { else module->addFfGate(NEW_ID, ff.sig_clk, past_clk); - log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_clk), log_signal(ff.sig_d), log_signal(ff.sig_q)); - SigSpec clock_edge_pattern; if (ff.pol_clk) { @@ -203,16 +216,6 @@ struct Clk2fflogicPass : public Pass { else qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge); } else { - if (ff.has_aload) { - log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_aload), log_signal(ff.sig_ad), log_signal(ff.sig_q)); - } else { - // $sr. - log("Replacing %s.%s (%s): SET=%s, CLR=%s, Q=%s\n", - log_id(module), log_id(cell), log_id(cell->type), - log_signal(ff.sig_set), log_signal(ff.sig_clr), log_signal(ff.sig_q)); - } qval = past_q; } @@ -246,10 +249,6 @@ struct Clk2fflogicPass : public Pass { } else { module->connect(ff.sig_q, qval); } - - initvals.remove_init(ff.sig_q); - module->remove(cell); - continue; } } } diff --git a/passes/techmap/dffunmap.cc b/passes/techmap/dffunmap.cc index 583185e75..7312015f1 100644 --- a/passes/techmap/dffunmap.cc +++ b/passes/techmap/dffunmap.cc @@ -86,19 +86,18 @@ struct DffunmapPass : public Pass { if (ce_only) { if (!ff.has_ce) continue; - ff.unmap_ce(mod); + ff.unmap_ce(); } else if (srst_only) { if (!ff.has_srst) continue; - ff.unmap_srst(mod); + ff.unmap_srst(); } else { if (!ff.has_ce && !ff.has_srst) continue; - ff.unmap_ce_srst(mod); + ff.unmap_ce_srst(); } - mod->remove(cell); - ff.emit(mod, name); + ff.emit(); } } } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 04d7ec874..68f44cf6d 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -368,13 +368,13 @@ void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) module->connect(RTLIL::SigSig(sig_y, sig_ab)); } -void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell) +void simplemap_ff(RTLIL::Module *, RTLIL::Cell *cell) { FfData ff(nullptr, cell); for (int i = 0; i < ff.width; i++) { FfData fff = ff.slice({i}); fff.is_fine = true; - fff.emit(module, NEW_ID); + fff.emit(); } } diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc index 8fcc47570..cc208c516 100644 --- a/passes/techmap/zinit.cc +++ b/passes/techmap/zinit.cc @@ -25,14 +25,6 @@ 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 @@ -75,45 +67,19 @@ struct ZinitPass : public Pass { continue; FfData ff(&initvals, cell); - if (!ff.width) - continue; - - // Supporting those would require a new cell type where S has priority over R. - if (ff.has_sr) - continue; - - Wire *new_q = module->addWire(NEW_ID, ff.width); 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)); - 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) - { - 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(ff.sig_q[i], SigSpec(new_q, i)); - if (all_mode) - ff.val_init[i] = State::S0; - } - - ff.sig_q = new_q; - ff.emit(module, name); + pool bits; + for (int i = 0; i < ff.width; i++) { + if (ff.val_init.bits[i] == State::S1) + bits.insert(i); + else if (ff.val_init.bits[i] != State::S0 && all_mode) + ff.val_init.bits[i] = State::S0; + } + ff.flip_bits(bits); + ff.emit(); } } } -- cgit v1.2.3