From 9f22b9d2a02068d5b39764517df68e44d24acb35 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 19 May 2026 19:31:16 +0200 Subject: [PATCH] patch: source transfer --- kernel/rtlil.cc | 9 +++++-- kernel/rtlil.h | 1 + kernel/unstable/patch.cc | 49 +++++++++++++++++++++++++++++++++++++++ kernel/unstable/patch.h | 10 ++++++-- passes/cmds/test_patch.cc | 5 ++-- 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index aa8852586..e3a1e84b1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -952,7 +952,7 @@ string RTLIL::AttrObject::get_string_attribute(RTLIL::IdString id) const return value; } -void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool &data) +std::string RTLIL::AttrObject::strpool_attribute_to_str(const pool &data) { string attrval; for (const auto &s : data) { @@ -960,7 +960,12 @@ void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool &data) +{ + set_string_attribute(id, strpool_attribute_to_str(data)); } void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool &data) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 413a8477c..2951122d4 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1279,6 +1279,7 @@ struct RTLIL::AttrObject void set_string_attribute(RTLIL::IdString id, string value); string get_string_attribute(RTLIL::IdString id) const; + static std::string strpool_attribute_to_str(const pool &data); void set_strpool_attribute(RTLIL::IdString id, const pool &data); void add_strpool_attribute(RTLIL::IdString id, const pool &data); pool get_strpool_attribute(RTLIL::IdString id) const; diff --git a/kernel/unstable/patch.cc b/kernel/unstable/patch.cc index ab0549e0d..0ee521fd0 100644 --- a/kernel/unstable/patch.cc +++ b/kernel/unstable/patch.cc @@ -54,7 +54,54 @@ RTLIL::Wire *RTLIL::Patch::addWire(RTLIL::IdString name, const RTLIL::Wire *othe return wire; } +void Patch::collect_src(Cell* old_cell) { + src.insert(old_cell->get_src_attribute()); + log("collect %s\n", old_cell->name); + std::vector inputs = {}; + for (auto [port_name, sig] : old_cell->connections()) { + auto dir = old_cell->port_dir(port_name); + log_assert(dir != PD_UNKNOWN); + log_assert(!sig.size() || sig.is_wire()); + if (dir == PD_INPUT || dir == PD_INOUT) { + Wire* in_wire = sig.as_wire(); + if (!leaves.count(in_wire)) + inputs.push_back(in_wire->driverCell()); + } + } + for (auto input : inputs) + collect_src(input); +} + +void Patch::gc(Cell* old_cell) { + log("gc %s\n", old_cell->name); + std::vector inputs = {}; + for (auto [port_name, sig] : old_cell->connections()) { + auto dir = old_cell->port_dir(port_name); + log_assert(dir != PD_UNKNOWN); + log_assert(!sig.size() || sig.is_wire()); + if (dir == PD_OUTPUT || dir == PD_INOUT) { + if (sig.size()) { + for (auto bit : sig) { + // Reject GC if used + if (!mod->fanout(bit).empty()) + return; + } + } + } + if (dir == PD_INPUT || dir == PD_INOUT) { + Wire* in_wire = sig.as_wire(); + if (!leaves.count(in_wire)) + inputs.push_back(in_wire->driverCell()); + } + } + for (auto input : inputs) + gc(input); +} + void Patch::patch(Cell* old_cell, Cell* new_cell) { + log_assert(!leaves.empty()); + collect_src(old_cell); + std::string src_str = AttrObject::strpool_attribute_to_str(src); for (auto& wire: wires_) { wire->module = mod; Wire* raw = wire.release(); @@ -64,6 +111,7 @@ void Patch::patch(Cell* old_cell, Cell* new_cell) { log_cell(old_cell); for (auto& cell: cells_) { log_cell(cell.get()); + cell->set_src_attribute(src_str); Cell* raw = cell.release(); mod->cells_[raw->name] = raw; for (auto [port_name, sig] : raw->connections()) { @@ -91,6 +139,7 @@ void Patch::patch(Cell* old_cell, Cell* new_cell) { raw->fixup_parameters(); } log_module(mod, ""); + gc(old_cell); } diff --git a/kernel/unstable/patch.h b/kernel/unstable/patch.h index 10f096403..badf82cda 100644 --- a/kernel/unstable/patch.h +++ b/kernel/unstable/patch.h @@ -11,6 +11,10 @@ struct RTLIL::Patch final : public CellAdderMixin Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } +private: + void collect_src(Cell* old_cell); + void gc(Cell* old_cell); + protected: void add(RTLIL::Wire *wire); void add(RTLIL::Cell *cell); @@ -18,12 +22,14 @@ protected: public: Module *mod; - SigMap map; + // SigMap map; vector> wires_; vector> cells_; Cell* root; + pool leaves; - vector connections_; + // vector connections_; + pool src; void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); diff --git a/passes/cmds/test_patch.cc b/passes/cmds/test_patch.cc index b03dcfe14..5effac2cc 100644 --- a/passes/cmds/test_patch.cc +++ b/passes/cmds/test_patch.cc @@ -24,13 +24,14 @@ struct TestPatchPass : public Pass { log_assert(neg->type == ID($not)); RTLIL::Patch patcher; patcher.mod = module; - patcher.map = SigMap(module); auto sub = patcher.addSub(NEW_ID, neg->getPort(ID::A), - cell->getPort(ID::A), + add->getPort(ID::A), patcher.addWire(NEW_ID, cell->getPort(ID::A).size())); auto new_cell = patcher.addNeg(NEW_ID, sub->getPort(ID::Y), SigSpec()); log_cell(new_cell); + patcher.leaves.insert(neg->getPort(ID::A).as_wire()); + patcher.leaves.insert(add->getPort(ID::A).as_wire()); patcher.patch(add, new_cell); } }