mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-18 05:05:45 +00:00
patch: instead of cell->cell, use port->sig rewrites
This commit is contained in:
parent
b3a33aeeba
commit
1cd0d37511
4 changed files with 105 additions and 72 deletions
|
|
@ -54,24 +54,50 @@ 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<Cell*> inputs = {};
|
||||
for (auto [port_name, sig] : old_cell->connections()) {
|
||||
auto dir = old_cell->port_dir(port_name);
|
||||
log_assert(dir != PD_UNKNOWN);
|
||||
if (dir == PD_INPUT || dir == PD_INOUT) {
|
||||
if (sig.size() && sig.is_wire()) {
|
||||
Wire* in_wire = sig.as_wire();
|
||||
if (!leaves.count(in_wire))
|
||||
inputs.push_back(in_wire->driverCell());
|
||||
|
||||
|
||||
struct SrcCollector {
|
||||
pool<Cell*> to_do;
|
||||
pool<Cell*> done;
|
||||
pool<string> src;
|
||||
|
||||
void collect_src(Cell* old_cell) {
|
||||
if (done.count(old_cell))
|
||||
return;
|
||||
done.insert(old_cell);
|
||||
|
||||
log("collect %s\n", old_cell->name);
|
||||
src.insert(old_cell->get_src_attribute());
|
||||
|
||||
std::vector<Cell*> input_cells = {};
|
||||
for (auto [port_name, sig] : old_cell->connections()) {
|
||||
auto dir = old_cell->port_dir(port_name);
|
||||
log_assert(dir != PD_UNKNOWN);
|
||||
if (dir == PD_INPUT || dir == PD_INOUT) {
|
||||
if (sig.size() && sig.is_wire()) {
|
||||
Wire* in_wire = sig.as_wire();
|
||||
if (!in_wire->module)
|
||||
input_cells.push_back(in_wire->driverCell());
|
||||
// if (!leaves.count(in_wire))
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto input : input_cells)
|
||||
collect_src(input);
|
||||
}
|
||||
for (auto input : inputs)
|
||||
collect_src(input);
|
||||
}
|
||||
|
||||
void collect_src(SigSpec old_sig) {
|
||||
log("collect %s\n", log_signal(old_sig));
|
||||
for (auto bit : old_sig) {
|
||||
if (bit.is_wire() && bit.wire->module) {
|
||||
log_assert(bit.wire->driverCell_);
|
||||
to_do.insert(bit.wire->driverCell_);
|
||||
}
|
||||
}
|
||||
for (auto cell : to_do)
|
||||
collect_src(cell);
|
||||
}
|
||||
};
|
||||
|
||||
void Patch::gc(Cell* old_cell) {
|
||||
log("gc %s\n", old_cell->name);
|
||||
|
|
@ -89,7 +115,9 @@ void Patch::gc(Cell* old_cell) {
|
|||
}
|
||||
if (dir == PD_INPUT || dir == PD_INOUT) {
|
||||
Wire* in_wire = sig.as_wire();
|
||||
if (!leaves.count(in_wire))
|
||||
log_assert(in_wire);
|
||||
log_debug("%s\n", in_wire->name);
|
||||
if (in_wire->known_driver() && !leaves.count(in_wire))
|
||||
inputs.push_back(in_wire->driverCell());
|
||||
}
|
||||
}
|
||||
|
|
@ -99,42 +127,45 @@ void Patch::gc(Cell* old_cell) {
|
|||
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();
|
||||
mod->wires_[raw->name] = raw;
|
||||
}
|
||||
log("patching:\n");
|
||||
log_cell(old_cell);
|
||||
Wire* Patch::commit_wire(std::unique_ptr<Wire> wire) {
|
||||
Wire* raw = wire.release();
|
||||
mod->wires_[raw->name] = raw;
|
||||
raw->module = mod;
|
||||
return raw;
|
||||
}
|
||||
|
||||
Cell* Patch::commit_cell(std::unique_ptr<Cell> cell) {
|
||||
Cell* raw = cell.release();
|
||||
mod->cells_[raw->name] = raw;
|
||||
raw->module = mod;
|
||||
raw->initIndex();
|
||||
return raw;
|
||||
}
|
||||
|
||||
void Patch::patch(Cell* old_cell, IdString old_port, SigSpec new_sig) {
|
||||
SigSpec old_sig = old_cell->getPort(old_port);
|
||||
log_assert(old_sig.size() == new_sig.size());
|
||||
log_debug("patching %s %s which is %s with %s:\n", old_cell->name, old_port, log_signal(old_sig), log_signal(new_sig));
|
||||
|
||||
SrcCollector collector;
|
||||
collector.collect_src(old_sig);
|
||||
std::string src_str = AttrObject::strpool_attribute_to_str(collector.src);
|
||||
|
||||
old_cell->setPort(old_port, SigSpec());
|
||||
mod->connect(old_sig, new_sig);
|
||||
if (map)
|
||||
map->add(old_sig, new_sig);
|
||||
|
||||
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()) {
|
||||
auto dir = raw->port_dir(port_name);
|
||||
log_assert(dir != PD_UNKNOWN);
|
||||
if (dir == PD_OUTPUT || dir == PD_INOUT) {
|
||||
if (raw == new_cell) {
|
||||
// RAUW
|
||||
auto yoink = old_cell->getPort(port_name);
|
||||
log(">>>> RAUW %s to %s\n", port_name, log_signal(yoink));
|
||||
new_cell->setPort(port_name, yoink);
|
||||
old_cell->setPort(port_name, mod->addWire(NEW_ID, yoink.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
raw->module = mod;
|
||||
raw->initIndex();
|
||||
raw->fixup_parameters();
|
||||
cell->fixup_parameters();
|
||||
commit_cell(std::move(cell));
|
||||
}
|
||||
log_module(mod, "");
|
||||
|
||||
for (auto& wire: wires_)
|
||||
commit_wire(std::move(wire));
|
||||
|
||||
gc(old_cell);
|
||||
}
|
||||
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
Loading…
Add table
Add a link
Reference in a new issue