-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- *
+ *
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
SigBitInfo() : is_input(false), is_output(false) { }
+ bool operator==(const SigBitInfo &other) const {
+ return is_input == other.is_input && is_output == other.is_output && ports == other.ports;
+ }
+
void merge(const SigBitInfo &other)
{
is_input = is_input || other.is_input;
SigMap sigmap;
RTLIL::Module *module;
std::map<RTLIL::SigBit, SigBitInfo> database;
+ int auto_reload_counter;
bool auto_reload_module;
void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
return database[sigmap(bit)];
}
- void reload_module()
+ void reload_module(bool reset_sigmap = true)
{
- sigmap.clear();
- sigmap.set(module);
+ if (reset_sigmap) {
+ sigmap.clear();
+ sigmap.set(module);
+ }
database.clear();
for (auto wire : module->wires())
for (auto &conn : cell->connections())
port_add(cell, conn.first, conn.second);
- auto_reload_module = false;
- // log("Auto-reload in ModIndex -- possible performance bug!\n");
+ if (auto_reload_module) {
+ if (++auto_reload_counter > 2)
+ log_warning("Auto-reload in ModIndex -- possible performance bug!\n");
+ auto_reload_module = false;
+ }
}
- virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
+ void check()
+ {
+#ifndef NDEBUG
+ if (auto_reload_module)
+ return;
+
+ for (auto it : database)
+ log_assert(it.first == sigmap(it.first));
+
+ auto database_bak = std::move(database);
+ reload_module(false);
+
+ if (!(database == database_bak))
+ {
+ for (auto &it : database_bak)
+ if (!database.count(it.first))
+ log("ModuleIndex::check(): Only in database_bak, not database: %s\n", log_signal(it.first));
+
+ for (auto &it : database)
+ if (!database_bak.count(it.first))
+ log("ModuleIndex::check(): Only in database, not database_bak: %s\n", log_signal(it.first));
+ else if (!(it.second == database_bak.at(it.first)))
+ log("ModuleIndex::check(): Different content for database[%s].\n", log_signal(it.first));
+
+ log_assert(database == database_bak);
+ }
+#endif
+ }
+
+ void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) override
{
log_assert(module == cell->module);
port_add(cell, port, sig);
}
- virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) YS_OVERRIDE
+ void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) override
{
log_assert(module == mod);
{
RTLIL::SigBit lhs = sigmap(sigsig.first[i]);
RTLIL::SigBit rhs = sigmap(sigsig.second[i]);
- bool has_lhs = database.count(lhs);
- bool has_rhs = database.count(rhs);
+ bool has_lhs = database.count(lhs) != 0;
+ bool has_rhs = database.count(rhs) != 0;
if (!has_lhs && !has_rhs) {
sigmap.add(lhs, rhs);
SigBitInfo new_info = database.at(lhs);
database.erase(lhs);
sigmap.add(lhs, rhs);
- database[sigmap(lhs)] = new_info;
+ lhs = sigmap(lhs);
+ if (lhs.wire)
+ database[lhs] = new_info;
} else
if (!has_lhs) {
SigBitInfo new_info = database.at(rhs);
database.erase(rhs);
sigmap.add(lhs, rhs);
- database[sigmap(rhs)] = new_info;
+ rhs = sigmap(rhs);
+ if (rhs.wire)
+ database[rhs] = new_info;
} else {
- #if 1
- auto_reload_module = true;
- return;
- #else
SigBitInfo new_info = database.at(lhs);
new_info.merge(database.at(rhs));
database.erase(lhs);
database.erase(rhs);
sigmap.add(lhs, rhs);
- database[sigmap(rhs)] = new_info;
- #endif
+ rhs = sigmap(rhs);
+ if (rhs.wire)
+ database[rhs] = new_info;
}
}
}
- virtual void notify_connect(RTLIL::Module *mod, const std::vector<RTLIL::SigSig>&) YS_OVERRIDE
+ void notify_connect(RTLIL::Module *mod, const std::vector<RTLIL::SigSig>&) override
{
log_assert(module == mod);
auto_reload_module = true;
}
- virtual void notify_blackout(RTLIL::Module *mod) YS_OVERRIDE
+ void notify_blackout(RTLIL::Module *mod) override
{
log_assert(module == mod);
auto_reload_module = true;
}
- ModIndex(RTLIL::Module *_m) : module(_m)
+ ModIndex(RTLIL::Module *_m) : sigmap(_m), module(_m)
{
+ auto_reload_counter = 0;
auto_reload_module = true;
module->monitors.insert(this);
}
return empty_result_set;
return info->ports;
}
+
+ void dump_db()
+ {
+ log("--- ModIndex Dump ---\n");
+
+ if (auto_reload_module) {
+ log("AUTO-RELOAD\n");
+ reload_module();
+ }
+
+ for (auto &it : database) {
+ log("BIT %s:\n", log_signal(it.first));
+ if (it.second.is_input)
+ log(" PRIMARY INPUT\n");
+ if (it.second.is_output)
+ log(" PRIMARY OUTPUT\n");
+ for (auto &port : it.second.ports)
+ log(" PORT: %s.%s[%d] (%s)\n", log_id(port.cell),
+ log_id(port.port), port.offset, log_id(port.cell->type));
+ }
+ }
};
struct ModWalker
}
}
- ModWalker() : design(NULL), module(NULL)
- {
- }
-
- ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
+ ModWalker(RTLIL::Design *design) : design(design), module(NULL)
{
- setup(design, module, filter_ct);
+ ct.setup(design);
}
- void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
+ void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL)
{
- this->design = design;
this->module = module;
- ct.clear();
- ct.setup(design);
sigmap.set(module);
signal_drivers.clear();