mirror of
https://github.com/YosysHQ/yosys
synced 2026-05-25 03:16:22 +00:00
patch: signorm, move
This commit is contained in:
parent
b7ea32dbee
commit
d2ae9b48e4
3 changed files with 51 additions and 22 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
#include "kernel/unstable/patch.h"
|
#include "kernel/unstable/patch.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
#include "kernel/rtlil.h"
|
#include "kernel/rtlil.h"
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
@ -17,10 +18,10 @@ using namespace RTLIL;
|
||||||
template class CellAdderMixin<Patch>;
|
template class CellAdderMixin<Patch>;
|
||||||
|
|
||||||
Cell* Patch::addCell(IdString name, IdString type) {
|
Cell* Patch::addCell(IdString name, IdString type) {
|
||||||
cells_.emplace(cells_.end(), std::make_unique<Cell>(Cell::ConstructToken{}));
|
cells_.push_back(std::make_unique<Cell>(Cell::ConstructToken{}));
|
||||||
|
|
||||||
Cell* cell = cells_.back().get();
|
Cell* cell = cells_.back().get();
|
||||||
cell->name = std::move(name);
|
cell->name = name;
|
||||||
cell->type = type;
|
cell->type = type;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
@ -32,25 +33,52 @@ Wire* Patch::addWire(IdString name, int width) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Patch::patch() {
|
void Patch::patch(Cell* old_cell, Cell* new_cell) {
|
||||||
|
pool<Cell*> patch_cells;
|
||||||
for (auto& cell: cells_) {
|
for (auto& cell: cells_) {
|
||||||
Cell* new_cell = mod->addCell(cell->name, cell->type);
|
patch_cells.insert(cell.get());
|
||||||
for (auto [port_name, sig] : new_cell->connections()) {
|
}
|
||||||
log_assert(yosys_celltypes.cell_known(cell->type));
|
log("patching:\n");
|
||||||
auto dir = cell->port_dir(port_name);
|
log_cell(old_cell);
|
||||||
if (dir == PD_OUTPUT || dir == PD_INOUT) {
|
for (auto& cell: cells_) {
|
||||||
for (auto chunk : sig.chunks()) {
|
log("with:\n");
|
||||||
log_assert(chunk.is_wire());
|
log_cell(cell.get());
|
||||||
auto* wire = chunk.wire;
|
log("ptr %p\n", cell.get());
|
||||||
// Unwire old driver
|
Cell* raw = cell.release();
|
||||||
wire->driverCell_->setPort(wire->driverPort_, SigSpec());
|
log("ptr2 %p\n", raw);
|
||||||
// Maintain bufnorm
|
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->driverCell_ = new_cell;
|
||||||
wire->driverPort_ = port_name;
|
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, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public:
|
||||||
void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs);
|
void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs);
|
||||||
const std::vector<RTLIL::SigSig> &connections() const;
|
const std::vector<RTLIL::SigSig> &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, int width = 1);
|
||||||
RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other);
|
RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ struct TestPatchPass : public Pass {
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
(void) args;
|
(void) args;
|
||||||
design->bufNormalize();
|
design->sigNormalize();
|
||||||
for (auto module : design->selected_modules()) {
|
for (auto module : design->selected_modules()) {
|
||||||
for (auto cell : module->selected_cells()) {
|
for (auto cell : module->selected_cells()) {
|
||||||
if (cell->type == ID($add)) {
|
if (cell->type == ID($add)) {
|
||||||
|
|
@ -21,12 +21,13 @@ struct TestPatchPass : public Pass {
|
||||||
patcher.mod = module;
|
patcher.mod = module;
|
||||||
patcher.map = SigMap(module);
|
patcher.map = SigMap(module);
|
||||||
RTLIL::Cell* sub = patcher.addCell(NEW_ID, ID($sub));
|
RTLIL::Cell* sub = patcher.addCell(NEW_ID, ID($sub));
|
||||||
sub->connections_ = cell->connections();
|
// sub->connections_ = cell->connections();
|
||||||
sub->parameters = cell->parameters;
|
sub->parameters = cell->parameters;
|
||||||
sub->setPort(ID::A, cell->getPort(ID::A));
|
sub->connections_[ID::A] = cell->getPort(ID::A);
|
||||||
sub->setPort(ID::B, cell->getPort(ID::B));
|
sub->connections_[ID::B] = cell->getPort(ID::B);
|
||||||
sub->setPort(ID::Y, cell->getPort(ID::Y));
|
sub->connections_[ID::Y] = cell->getPort(ID::Y);
|
||||||
patcher.patch();
|
log_cell(sub);
|
||||||
|
patcher.patch(cell, sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue