aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt/opt_ffinv.cc
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2022-05-17 01:52:55 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2022-05-17 02:52:21 +0200
commit98c7804b89f5d384c920fe2280ed33432207f0cb (patch)
treee373b824c393a74b6c1a57ad0efbbad640f9a5c4 /passes/opt/opt_ffinv.cc
parent2864f2826a41574b5c01e6674efa6bd6acc2f2e2 (diff)
downloadyosys-98c7804b89f5d384c920fe2280ed33432207f0cb.tar.gz
yosys-98c7804b89f5d384c920fe2280ed33432207f0cb.tar.bz2
yosys-98c7804b89f5d384c920fe2280ed33432207f0cb.zip
opt_ffinv: Use ModIndex instead of ModWalker.
This avoids using out-of-data index information.
Diffstat (limited to 'passes/opt/opt_ffinv.cc')
-rw-r--r--passes/opt/opt_ffinv.cc103
1 files 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<SigBit> 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<ModWalker::PortBit> 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<ModWalker::PortBit> 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<Cell *> q_luts;
- pool<ModWalker::PortBit> 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<SigBit> 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<ModWalker::PortBit> 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<ModWalker::PortBit> 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<ModWalker::PortBit> 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");