From d13eb7e0999def2da03eb6ddef805145f7fd9c9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 16:53:15 +0200 Subject: Added ModIndex helper class, some changes to RTLIL::Monitor --- kernel/log.h | 5 --- kernel/modtools.h | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.cc | 36 +++++++++++------- kernel/rtlil.h | 10 ++--- kernel/sigtools.h | 13 +++++++ kernel/yosys.cc | 5 +++ kernel/yosys.h | 9 ++++- 7 files changed, 165 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 0109faf62..9fc83800c 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -57,11 +57,6 @@ void log_pop(); void log_reset_stack(); void log_flush(); -namespace RTLIL { - struct SigSpec; - struct Cell; -} - const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); const char *log_id(std::string id); diff --git a/kernel/modtools.h b/kernel/modtools.h index 06e96246f..09f2ae65e 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -20,9 +20,118 @@ #ifndef MODTOOLS_H #define MODTOOLS_H +#include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +YOSYS_NAMESPACE_BEGIN + +struct ModIndex : public RTLIL::Monitor +{ + struct PortInfo { + const RTLIL::Cell* cell; + const RTLIL::IdString &port; + const int offset; + + PortInfo(RTLIL::Cell* _c, const RTLIL::IdString &_p, int _o) : cell(_c), port(_p), offset(_o) { } + + bool operator<(const PortInfo &other) const { + if (cell != other.cell) + return cell < other.cell; + if (offset != other.offset) + return offset < other.offset; + return port < other.port; + } + }; + + struct SigBitInfo + { + bool is_input, is_output; + std::set ports; + + SigBitInfo() : is_input(false), is_output(false) { } + }; + + SigMap sigmap; + RTLIL::Module *module; + std::map database; + bool auto_reload_module; + + void port_add(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + { + for (int i = 0; i < SIZE(sig); i++) + database[sigmap(sig[i])].ports.insert(PortInfo(cell, port, i)); + } + + void port_del(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + { + for (int i = 0; i < SIZE(sig); i++) + database[sigmap(sig[i])].ports.erase(PortInfo(cell, port, i)); + } + + const SigBitInfo &info(RTLIL::SigBit bit) + { + return database[sigmap(bit)]; + } + + void reload_module() + { + sigmap.clear(); + sigmap.set(module); + + database.clear(); + for (auto wire : module->wires()) + if (wire->port_input || wire->port_output) + for (int i = 0; i < SIZE(wire); i++) { + if (wire->port_input) + database[sigmap(RTLIL::SigBit(wire, i))].is_input = true; + if (wire->port_output) + database[sigmap(RTLIL::SigBit(wire, i))].is_output = true; + } + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + port_add(cell, conn.first, conn.second); + + auto_reload_module = false; + } + + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override + { + if (auto_reload_module) + reload_module(); + + port_del(cell, port, old_sig); + port_add(cell, port, sig); + } + + virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig&) + { + log_assert(module == mod); + auto_reload_module = true; + } + + virtual void notify_connect(RTLIL::Module *mod, const std::vector&) + { + log_assert(module == mod); + auto_reload_module = true; + } + + virtual void notify_blackout(RTLIL::Module *mod) + { + log_assert(module == mod); + auto_reload_module = true; + } + + ModIndex(RTLIL::Module *_m) : module(_m) { + auto_reload_module = true; + module->monitors.insert(this); + } + + ~ModIndex() { + module->monitors.erase(this); + } +}; + struct ModWalker { struct PortBit @@ -295,4 +404,6 @@ struct ModWalker } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 79ddd2e02..137058522 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1092,11 +1092,11 @@ void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs void RTLIL::Module::new_connections(const std::vector &new_conn) { for (auto mon : monitors) - mon->notify_new_connections(this, new_conn); + mon->notify_connect(this, new_conn); if (design) for (auto mon : design->monitors) - mon->notify_new_connections(this, new_conn); + mon->notify_connect(this, new_conn); connections_ = new_conn; } @@ -1516,30 +1516,40 @@ bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const void RTLIL::Cell::unsetPort(RTLIL::IdString portname) { - std::pair new_conn(portname, RTLIL::SigSpec()); + RTLIL::SigSpec signal; + auto conn_it = connections_.find(portname); - for (auto mon : module->monitors) - mon->notify_cell_connect(this, new_conn); + if (conn_it != connections_.end()) + { + for (auto mon : module->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - if (module->design) - for (auto mon : module->design->monitors) - mon->notify_cell_connect(this, new_conn); + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - connections_.erase(portname); + connections_.erase(conn_it); + } } void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) { - std::pair new_conn(portname, signal); + auto conn_it = connections_.find(portname); + + if (conn_it == connections_.end()) { + connections_[portname] = RTLIL::SigSpec(); + conn_it = connections_.find(portname); + log_assert(conn_it != connections_.end()); + } for (auto mon : module->monitors) - mon->notify_cell_connect(this, new_conn); + mon->notify_connect(this, conn_it->first, conn_it->second, signal); if (module->design) for (auto mon : module->design->monitors) - mon->notify_cell_connect(this, new_conn); + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - connections_[portname] = signal; + conn_it->second = signal; } const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 43c7e1050..0685f1ea2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -334,9 +334,9 @@ struct RTLIL::Monitor virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } - virtual void notify_cell_connect(RTLIL::Cell*, const std::pair&) { } + virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, RTLIL::SigSpec&) { } virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { } - virtual void notify_new_connections(RTLIL::Module*, const std::vector&) { } + virtual void notify_connect(RTLIL::Module*, const std::vector&) { } virtual void notify_blackout(RTLIL::Module*) { } }; @@ -708,15 +708,15 @@ struct RTLIL::SigBit { RTLIL::Wire *wire; union { - RTLIL::State data; - int offset; + RTLIL::State data; // used if wire == NULL + int offset; // used if wire != NULL }; SigBit() : wire(NULL), data(RTLIL::State::S0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0) { log_assert(wire && wire->width == 1); } SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; log_assert(chunk.width == 1); } + SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data.bits[index]; } SigBit(const RTLIL::SigSpec &sig); diff --git a/kernel/sigtools.h b/kernel/sigtools.h index b691749a8..32ef444aa 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -391,11 +391,24 @@ struct SigMap map_bit(bit); } + RTLIL::SigBit operator()(RTLIL::SigBit bit) const + { + apply(bit); + return bit; + } + RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const { apply(sig); return sig; } + + RTLIL::SigSpec operator()(RTLIL::Wire *wire) const + { + RTLIL::SigSpec sig(wire); + apply(sig); + return sig; + } }; YOSYS_NAMESPACE_END diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 34800ce8e..671945631 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -53,6 +53,11 @@ std::string stringf(const char *fmt, ...) return string; } +int SIZE(RTLIL::Wire *wire) +{ + return wire->width; +} + void yosys_setup() { Pass::init_register(); diff --git a/kernel/yosys.h b/kernel/yosys.h index 119e7e8a6..d9db57c51 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -61,8 +61,15 @@ YOSYS_NAMESPACE_BEGIN +namespace RTLIL { + struct SigSpec; + struct Wire; + struct Cell; +} + std::string stringf(const char *fmt, ...); -#define SIZE(__obj) int(__obj.size()) +template int SIZE(const T &obj) { return obj.size(); } +int SIZE(RTLIL::Wire *wire); YOSYS_NAMESPACE_END -- cgit v1.2.3