Added ModIndex helper class, some changes to RTLIL::Monitor
authorClifford Wolf <clifford@clifford.at>
Fri, 1 Aug 2014 14:53:15 +0000 (16:53 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 1 Aug 2014 15:14:32 +0000 (17:14 +0200)
kernel/log.h
kernel/modtools.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/sigtools.h
kernel/yosys.cc
kernel/yosys.h
passes/cmds/trace.cc
passes/memory/memory_share.cc

index 0109faf626eed04921344ac10a796eef087e92ff..9fc83800c7fb7b8f8247245723882ec245a69da6 100644 (file)
@@ -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);
 
index 06e96246fd56ff7c199f37607f6714ef3129a618..09f2ae65ea4a1ef9b398375b9a0a3c8f25a6d58f 100644 (file)
 #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<PortInfo> ports;
+
+               SigBitInfo() : is_input(false), is_output(false) { }
+       };
+
+       SigMap sigmap;
+       RTLIL::Module *module;
+       std::map<RTLIL::SigBit, SigBitInfo> 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<RTLIL::SigSig>&)
+       {
+               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
index 79ddd2e02594ed2744b8783497a03cb5656ed2da..1370585226547741cee7ebf16cdbcb9fbd40858b 100644 (file)
@@ -1092,11 +1092,11 @@ void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs
 void RTLIL::Module::new_connections(const std::vector<RTLIL::SigSig> &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<RTLIL::IdString, RTLIL::SigSpec> 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<RTLIL::IdString, RTLIL::SigSpec> 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
index 43c7e1050ed75d2844089b76598711c98950dd54..0685f1ea24eea3b64cb72c550c5111ce54837748 100644 (file)
@@ -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<RTLIL::IdString, RTLIL::SigSpec>&) { }
+       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<RTLIL::SigSig>&) { }
+       virtual void notify_connect(RTLIL::Module*, const std::vector<RTLIL::SigSig>&) { }
        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);
 
index b691749a857a25f16e8beab5da26d6cc47ed562e..32ef444aa4f882e9bb2d511e3004982b94bdc595 100644 (file)
@@ -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
index 34800ce8e59af0f5772b6fc076cb0dca9346dc8f..6719456312259b1a3d046e2371f909bb5f94fa96 100644 (file)
@@ -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();
index 119e7e8a6ae7e2167335e35f2420056c46c897d1..d9db57c5162384549838a9900a8bf53ca6d8e3de 100644 (file)
 
 YOSYS_NAMESPACE_BEGIN
 
+namespace RTLIL {
+       struct SigSpec;
+       struct Wire;
+       struct Cell;
+}
+
 std::string stringf(const char *fmt, ...);
-#define SIZE(__obj) int(__obj.size())
+template<typename T> int SIZE(const T &obj) { return obj.size(); }
+int SIZE(RTLIL::Wire *wire);
 
 YOSYS_NAMESPACE_END
 
index b4bc45c20bd0334820c608185dc29c4c02d25825..6a5ea346e40d5426049f13f1adb3107ecab013c0 100644 (file)
@@ -34,9 +34,9 @@ struct TraceMonitor : public RTLIL::Monitor
                log("#TRACE# Module delete: %s\n", log_id(module));
        }
 
-       virtual void notify_cell_connect(RTLIL::Cell *cell, const std::pair<RTLIL::IdString, RTLIL::SigSpec> &conn) override
+       virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override
        {
-               log("#TRACE# Cell connect: %s.%s.%s = %s\n", log_id(cell->module), log_id(cell), log_id(conn.first), log_signal(conn.second));
+               log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig));
        }
 
        virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override
@@ -44,7 +44,7 @@ struct TraceMonitor : public RTLIL::Monitor
                log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second));
        }
 
-       virtual void notify_new_connections(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) override
+       virtual void notify_connect(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) override
        {
                log("#TRACE# New connections in module %s:\n", log_id(module));
                for (auto &sigsig : sigsig_vec)
index fde6ea007b83cc08e44ae441faf8ff7071cfc845..ace6eeaf149084bf7f748c94ebf7a2156d471985 100644 (file)
@@ -735,9 +735,8 @@ struct MemorySharePass : public Pass {
        virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
                log_header("Executing MEMORY_SHARE pass (consolidating $memrc/$memwr cells).\n");
                extra_args(args, 1, design);
-               for (auto &mod_it : design->modules_)
-                       if (design->selected(mod_it.second))
-                               MemoryShareWorker(design, mod_it.second);
+               for (auto module : design->selected_modules())
+                       MemoryShareWorker(design, module);
        }
 } MemorySharePass;