From 98c7804b89f5d384c920fe2280ed33432207f0cb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 17 May 2022 01:52:55 +0200 Subject: [PATCH] opt_ffinv: Use ModIndex instead of ModWalker. This avoids using out-of-data index information. --- passes/opt/opt_ffinv.cc | 103 +++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/passes/opt/opt_ffinv.cc b/passes/opt/opt_ffinv.cc index 279860756..fd76dd2be 100644 --- a/passes/opt/opt_ffinv.cc +++ b/passes/opt/opt_ffinv.cc @@ -30,7 +30,7 @@ struct OptFfInvWorker { int count = 0; RTLIL::Module *module; - ModWalker walker; + ModIndex index; FfInitVals initvals; // Case 1: @@ -38,44 +38,45 @@ struct OptFfInvWorker // - ... which has no other users // - all users of FF are LUTs bool push_d_inv(FfData &ff) { - pool dummy; - - if (walker.get_inputs(dummy, ff.sig_d)) + if (index.query_is_input(ff.sig_d)) return false; - if (walker.get_outputs(dummy, ff.sig_d)) + if (index.query_is_output(ff.sig_d)) return false; - pool d_drivers; - walker.get_drivers(d_drivers, ff.sig_d); - if (d_drivers.size() != 1) + auto d_ports = index.query_ports(ff.sig_d); + if (d_ports.size() != 2) return false; Cell *d_inv = nullptr; - for (auto &driver: d_drivers) { - if (driver.cell->type.in(ID($not), ID($_NOT_))) { + for (auto &port: d_ports) { + if (port.cell == ff.cell && port.port == ID::D) + continue; + if (port.port != ID::Y) + return false; + if (port.cell->type.in(ID($not), ID($_NOT_))) { // OK - } else if (driver.cell->type.in(ID($lut))) { - if (driver.cell->getParam(ID::WIDTH) != 1) + } else if (port.cell->type.in(ID($lut))) { + if (port.cell->getParam(ID::WIDTH) != 1) return false; - if (driver.cell->getParam(ID::LUT).as_int() != 1) + if (port.cell->getParam(ID::LUT).as_int() != 1) return false; } else { return false; } - d_inv = driver.cell; + log_assert(d_inv == nullptr); + d_inv = port.cell; } - pool d_consumers; - walker.get_consumers(d_consumers, ff.sig_d); - if (d_consumers.size() != 1) - return false; - if (walker.get_outputs(dummy, ff.sig_q)) + if (index.query_is_output(ff.sig_q)) return false; + auto q_ports = index.query_ports(ff.sig_q); pool q_luts; - pool q_consumers; - walker.get_consumers(q_consumers, ff.sig_q); - for (auto &consumer: q_consumers) { - if (!consumer.cell->type.in(ID($not), ID($_NOT_), ID($lut))) + for (auto &port: q_ports) { + if (port.cell == ff.cell && port.port == ID::Q) + continue; + if (port.port != ID::A) + return false; + if (!port.cell->type.in(ID($not), ID($_NOT_), ID($lut))) return false; - q_luts.insert(consumer.cell); + q_luts.insert(port.cell); } ff.flip_rst_bits({0}); @@ -86,7 +87,7 @@ struct OptFfInvWorker int flip_mask = 0; SigSpec sig_a = lut->getPort(ID::A); for (int i = 0; i < GetSize(sig_a); i++) { - if (walker.sigmap(sig_a[i]) == walker.sigmap(ff.sig_q)) { + if (index.sigmap(sig_a[i]) == index.sigmap(ff.sig_q)) { flip_mask |= 1 << i; } } @@ -118,47 +119,49 @@ struct OptFfInvWorker // - FF has one user // - ... which is an inverter bool push_q_inv(FfData &ff) { - pool dummy; - - if (walker.get_inputs(dummy, ff.sig_d)) + if (index.query_is_input(ff.sig_d)) return false; - if (walker.get_outputs(dummy, ff.sig_d)) + if (index.query_is_output(ff.sig_d)) return false; Cell *d_lut = nullptr; - pool d_drivers; - walker.get_drivers(d_drivers, ff.sig_d); - if (d_drivers.size() != 1) + auto d_ports = index.query_ports(ff.sig_d); + if (d_ports.size() != 2) return false; - for (auto &driver: d_drivers) { - if (!driver.cell->type.in(ID($not), ID($_NOT_), ID($lut))) + for (auto &port: d_ports) { + if (port.cell == ff.cell && port.port == ID::D) + continue; + if (port.port != ID::Y) + return false; + if (!port.cell->type.in(ID($not), ID($_NOT_), ID($lut))) return false; - d_lut = driver.cell; + log_assert(d_lut == nullptr); + d_lut = port.cell; } - pool d_consumers; - walker.get_consumers(d_consumers, ff.sig_d); - if (d_consumers.size() != 1) - return false; - if (walker.get_outputs(dummy, ff.sig_q)) + if (index.query_is_output(ff.sig_q)) return false; - pool q_consumers; - walker.get_consumers(q_consumers, ff.sig_q); - if (q_consumers.size() != 1) + auto q_ports = index.query_ports(ff.sig_q); + if (q_ports.size() != 2) return false; Cell *q_inv = nullptr; - for (auto &consumer: q_consumers) { - if (consumer.cell->type.in(ID($not), ID($_NOT_))) { + for (auto &port: q_ports) { + if (port.cell == ff.cell && port.port == ID::Q) + continue; + if (port.port != ID::A) + return false; + if (port.cell->type.in(ID($not), ID($_NOT_))) { // OK - } else if (consumer.cell->type.in(ID($lut))) { - if (consumer.cell->getParam(ID::WIDTH) != 1) + } else if (port.cell->type.in(ID($lut))) { + if (port.cell->getParam(ID::WIDTH) != 1) return false; - if (consumer.cell->getParam(ID::LUT).as_int() != 1) + if (port.cell->getParam(ID::LUT).as_int() != 1) return false; } else { return false; } - q_inv = consumer.cell; + log_assert(q_inv == nullptr); + q_inv = port.cell; } ff.flip_rst_bits({0}); @@ -190,7 +193,7 @@ struct OptFfInvWorker } OptFfInvWorker(RTLIL::Module *module) : - module(module), walker(module->design, module), initvals(&walker.sigmap, module) + module(module), index(module), initvals(&index.sigmap, module) { log("Discovering LUTs.\n"); -- 2.30.2