Added ModIndex helper class, some changes to RTLIL::Monitor

This commit is contained in:
Clifford Wolf 2014-08-01 16:53:15 +02:00
parent 97a17d39e2
commit d13eb7e099
9 changed files with 170 additions and 30 deletions

View 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);

View File

@ -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<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

View 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

View 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);

View 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

View 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();

View File

@ -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<typename T> int SIZE(const T &obj) { return obj.size(); }
int SIZE(RTLIL::Wire *wire);
YOSYS_NAMESPACE_END

View 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)

View 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;