diff --git a/kernel/unstable/patch.cc b/kernel/unstable/patch.cc index 8ef567db7..c7a0bdbac 100644 --- a/kernel/unstable/patch.cc +++ b/kernel/unstable/patch.cc @@ -1,5 +1,6 @@ #include "kernel/unstable/patch.h" #include "kernel/celltypes.h" +#include "kernel/log.h" #include "kernel/rtlil.h" YOSYS_NAMESPACE_BEGIN @@ -17,10 +18,10 @@ using namespace RTLIL; template class CellAdderMixin; Cell* Patch::addCell(IdString name, IdString type) { - cells_.emplace(cells_.end(), std::make_unique(Cell::ConstructToken{})); + cells_.push_back(std::make_unique(Cell::ConstructToken{})); Cell* cell = cells_.back().get(); - cell->name = std::move(name); + cell->name = name; cell->type = type; return cell; } @@ -32,25 +33,52 @@ Wire* Patch::addWire(IdString name, int width) { return nullptr; } -void Patch::patch() { +void Patch::patch(Cell* old_cell, Cell* new_cell) { + pool patch_cells; for (auto& cell: cells_) { - Cell* new_cell = mod->addCell(cell->name, cell->type); - for (auto [port_name, sig] : new_cell->connections()) { - log_assert(yosys_celltypes.cell_known(cell->type)); - auto dir = cell->port_dir(port_name); - if (dir == PD_OUTPUT || dir == PD_INOUT) { - for (auto chunk : sig.chunks()) { - log_assert(chunk.is_wire()); - auto* wire = chunk.wire; - // Unwire old driver - wire->driverCell_->setPort(wire->driverPort_, SigSpec()); - // Maintain bufnorm + patch_cells.insert(cell.get()); + } + log("patching:\n"); + log_cell(old_cell); + for (auto& cell: cells_) { + log("with:\n"); + log_cell(cell.get()); + log("ptr %p\n", cell.get()); + Cell* raw = cell.release(); + log("ptr2 %p\n", raw); + mod->cells_[raw->name] = raw; + raw->module = mod; + for (auto [port_name, sig] : raw->connections()) { + auto dir = raw->port_dir(port_name); + log_assert(dir != PD_UNKNOWN); + if (raw == new_cell) + if (dir == PD_OUTPUT || dir == PD_INOUT) { + // RAUW + old_cell->setPort(port_name, mod->addWire(NEW_ID, sig.size())); + new_cell->setPort(port_name, sig); + auto* wire = sig.as_wire(); wire->driverCell_ = new_cell; wire->driverPort_ = port_name; } - } + // } else { + // new_cell->setPort(port_name, sig); // map? + // for (auto chunk : map(sig).chunks()) { + // if (chunk.size() == 0) + // continue; + // log_assert(chunk.is_wire()); + // auto* wire = chunk.wire; + // // TODO Use roots instead? + // if (patch_cells.count(wire->driverCell_)) { + // // How do we handle this? + // log_assert(false); + // } else { + // // mod->sig_norm_index + + // } + // } } } + log_module(mod, ""); } diff --git a/kernel/unstable/patch.h b/kernel/unstable/patch.h index bc902c2ee..10f096403 100644 --- a/kernel/unstable/patch.h +++ b/kernel/unstable/patch.h @@ -29,7 +29,7 @@ public: void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); const std::vector &connections() const; - void patch(); + void patch(Cell* old_cell, Cell* new_cell); RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); diff --git a/passes/cmds/test_patch.cc b/passes/cmds/test_patch.cc index dc5270b3e..3081034fc 100644 --- a/passes/cmds/test_patch.cc +++ b/passes/cmds/test_patch.cc @@ -13,7 +13,7 @@ struct TestPatchPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { (void) args; - design->bufNormalize(); + design->sigNormalize(); for (auto module : design->selected_modules()) { for (auto cell : module->selected_cells()) { if (cell->type == ID($add)) { @@ -21,12 +21,13 @@ struct TestPatchPass : public Pass { patcher.mod = module; patcher.map = SigMap(module); RTLIL::Cell* sub = patcher.addCell(NEW_ID, ID($sub)); - sub->connections_ = cell->connections(); + // sub->connections_ = cell->connections(); sub->parameters = cell->parameters; - sub->setPort(ID::A, cell->getPort(ID::A)); - sub->setPort(ID::B, cell->getPort(ID::B)); - sub->setPort(ID::Y, cell->getPort(ID::Y)); - patcher.patch(); + sub->connections_[ID::A] = cell->getPort(ID::A); + sub->connections_[ID::B] = cell->getPort(ID::B); + sub->connections_[ID::Y] = cell->getPort(ID::Y); + log_cell(sub); + patcher.patch(cell, sub); } } }