aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rtlil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rtlil.cc')
-rw-r--r--kernel/rtlil.cc490
1 files changed, 386 insertions, 104 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 00be796f8..adf89a245 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -19,6 +19,7 @@
#include "kernel/yosys.h"
#include "kernel/macc.h"
+#include "kernel/celltypes.h"
#include "frontends/verilog/verilog_frontend.h"
#include "backends/ilang/ilang_backend.h"
@@ -27,9 +28,10 @@
YOSYS_NAMESPACE_BEGIN
+RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<char*> RTLIL::IdString::global_id_storage_;
-std::map<char*, int, RTLIL::IdString::char_ptr_cmp> RTLIL::IdString::global_id_index_;
+dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_;
std::vector<int> RTLIL::IdString::global_free_idx_list_;
RTLIL::Const::Const()
@@ -127,6 +129,21 @@ std::string RTLIL::Const::as_string() const
return ret;
}
+RTLIL::Const RTLIL::Const::from_string(std::string str)
+{
+ Const c;
+ for (auto it = str.rbegin(); it != str.rend(); it++)
+ switch (*it) {
+ case '0': c.bits.push_back(State::S0); break;
+ case '1': c.bits.push_back(State::S1); break;
+ case 'x': c.bits.push_back(State::Sx); break;
+ case 'z': c.bits.push_back(State::Sz); break;
+ case 'm': c.bits.push_back(State::Sm); break;
+ default: c.bits.push_back(State::Sa);
+ }
+ return c;
+}
+
std::string RTLIL::Const::decode_string() const
{
std::string string;
@@ -235,13 +252,17 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
RTLIL::Design::Design()
{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+
refcount_modules_ = 0;
selection_stack.push_back(RTLIL::Selection());
}
RTLIL::Design::~Design()
{
- for (auto it = modules_.begin(); it != modules_.end(); it++)
+ for (auto it = modules_.begin(); it != modules_.end(); ++it)
delete it->second;
}
@@ -264,6 +285,11 @@ void RTLIL::Design::add(RTLIL::Module *module)
for (auto mon : monitors)
mon->notify_module_add(module);
+
+ if (yosys_xtrace) {
+ log("#X# New Module: %s\n", log_id(module));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
}
RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
@@ -279,6 +305,11 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
for (auto mon : monitors)
mon->notify_module_add(module);
+ if (yosys_xtrace) {
+ log("#X# New Module: %s\n", log_id(module));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
return module;
}
@@ -348,11 +379,24 @@ void RTLIL::Design::remove(RTLIL::Module *module)
for (auto mon : monitors)
mon->notify_module_del(module);
+ if (yosys_xtrace) {
+ log("#X# Remove Module: %s\n", log_id(module));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
log_assert(modules_.at(module->name) == module);
modules_.erase(module->name);
delete module;
}
+void RTLIL::Design::sort()
+{
+ scratchpad.sort();
+ modules_.sort(sort_by_id_str());
+ for (auto &it : modules_)
+ it.second->sort();
+}
+
void RTLIL::Design::check()
{
#ifndef NDEBUG
@@ -417,7 +461,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_module(it.first))
+ if (selected_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
result.push_back(it.second);
return result;
}
@@ -427,7 +471,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_whole_module(it.first))
+ if (selected_whole_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
result.push_back(it.second);
return result;
}
@@ -437,15 +481,21 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_whole_module(it.first))
+ if (it.second->get_bool_attribute("\\blackbox"))
+ continue;
+ else if (selected_whole_module(it.first))
result.push_back(it.second);
else if (selected_module(it.first))
- log("Warning: Ignoring partially selected module %s.\n", log_id(it.first));
+ log_warning("Ignoring partially selected module %s.\n", log_id(it.first));
return result;
}
RTLIL::Module::Module()
{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+
design = nullptr;
refcount_wires_ = 0;
refcount_cells_ = 0;
@@ -453,17 +503,17 @@ RTLIL::Module::Module()
RTLIL::Module::~Module()
{
- for (auto it = wires_.begin(); it != wires_.end(); it++)
+ for (auto it = wires_.begin(); it != wires_.end(); ++it)
delete it->second;
- for (auto it = memories.begin(); it != memories.end(); it++)
+ for (auto it = memories.begin(); it != memories.end(); ++it)
delete it->second;
- for (auto it = cells_.begin(); it != cells_.end(); it++)
+ for (auto it = cells_.begin(); it != cells_.end(); ++it)
delete it->second;
- for (auto it = processes.begin(); it != processes.end(); it++)
+ for (auto it = processes.begin(); it != processes.end(); ++it)
delete it->second;
}
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map<RTLIL::IdString, RTLIL::Const>)
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>)
{
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
}
@@ -479,7 +529,7 @@ namespace {
{
RTLIL::Module *module;
RTLIL::Cell *cell;
- std::set<RTLIL::IdString> expected_params, expected_ports;
+ pool<RTLIL::IdString> expected_params, expected_ports;
InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
@@ -752,6 +802,17 @@ namespace {
return;
}
+ if (cell->type == "$dffe") {
+ param_bool("\\CLK_POLARITY");
+ param_bool("\\EN_POLARITY");
+ port("\\CLK", 1);
+ port("\\EN", 1);
+ port("\\D", param("\\WIDTH"));
+ port("\\Q", param("\\WIDTH"));
+ check_expected();
+ return;
+ }
+
if (cell->type == "$dffsr") {
param_bool("\\CLK_POLARITY");
param_bool("\\SET_POLARITY");
@@ -843,10 +904,20 @@ namespace {
return;
}
+ if (cell->type == "$meminit") {
+ param("\\MEMID");
+ param("\\PRIORITY");
+ port("\\ADDR", param("\\ABITS"));
+ port("\\DATA", param("\\WIDTH"));
+ check_expected();
+ return;
+ }
+
if (cell->type == "$mem") {
param("\\MEMID");
param("\\SIZE");
param("\\OFFSET");
+ param("\\INIT");
param_bits("\\RD_CLK_ENABLE", param("\\RD_PORTS"));
param_bits("\\RD_CLK_POLARITY", param("\\RD_PORTS"));
param_bits("\\RD_TRANSPARENT", param("\\RD_PORTS"));
@@ -870,6 +941,22 @@ namespace {
return;
}
+ if (cell->type == "$assume") {
+ port("\\A", 1);
+ port("\\EN", 1);
+ check_expected();
+ return;
+ }
+
+ if (cell->type == "$equiv") {
+ port("\\A", 1);
+ port("\\B", 1);
+ port("\\Y", 1);
+ check_expected();
+ return;
+ }
+
+ if (cell->type == "$_BUF_") { check_gate("AY"); return; }
if (cell->type == "$_NOT_") { check_gate("AY"); return; }
if (cell->type == "$_AND_") { check_gate("ABY"); return; }
if (cell->type == "$_NAND_") { check_gate("ABY"); return; }
@@ -891,6 +978,11 @@ namespace {
if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; }
if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; }
+ if (cell->type == "$_DFFE_NN_") { check_gate("DQCE"); return; }
+ if (cell->type == "$_DFFE_NP_") { check_gate("DQCE"); return; }
+ if (cell->type == "$_DFFE_PN_") { check_gate("DQCE"); return; }
+ if (cell->type == "$_DFFE_PP_") { check_gate("DQCE"); return; }
+
if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; }
if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; }
if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; }
@@ -927,6 +1019,21 @@ namespace {
}
#endif
+void RTLIL::Module::sort()
+{
+ wires_.sort(sort_by_id_str());
+ cells_.sort(sort_by_id_str());
+ avail_parameters.sort(sort_by_id_str());
+ memories.sort(sort_by_id_str());
+ processes.sort(sort_by_id_str());
+ for (auto &it : cells_)
+ it.second->sort();
+ for (auto &it : wires_)
+ it.second->attributes.sort(sort_by_id_str());
+ for (auto &it : memories)
+ it.second->attributes.sort(sort_by_id_str());
+}
+
void RTLIL::Module::check()
{
#ifndef NDEBUG
@@ -940,10 +1047,10 @@ void RTLIL::Module::check()
for (auto &it2 : it.second->attributes)
log_assert(!it2.first.empty());
if (it.second->port_id) {
- log_assert(SIZE(ports) >= it.second->port_id);
+ log_assert(GetSize(ports) >= it.second->port_id);
log_assert(ports.at(it.second->port_id-1) == it.first);
log_assert(it.second->port_input || it.second->port_output);
- if (SIZE(ports_declared) < it.second->port_id)
+ if (GetSize(ports_declared) < it.second->port_id)
ports_declared.resize(it.second->port_id);
log_assert(ports_declared[it.second->port_id-1] == false);
ports_declared[it.second->port_id-1] = true;
@@ -952,7 +1059,7 @@ void RTLIL::Module::check()
}
for (auto port_declared : ports_declared)
log_assert(port_declared == true);
- log_assert(SIZE(ports) == SIZE(ports_declared));
+ log_assert(GetSize(ports) == GetSize(ports_declared));
for (auto &it : memories) {
log_assert(it.first == it.second->name);
@@ -988,6 +1095,7 @@ void RTLIL::Module::check()
for (auto &it : connections_) {
log_assert(it.first.size() == it.second.size());
+ log_assert(!it.first.has_const());
it.first.check();
it.second.check();
}
@@ -1006,8 +1114,11 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
log_assert(new_mod->refcount_wires_ == 0);
log_assert(new_mod->refcount_cells_ == 0);
- new_mod->connections_ = connections_;
- new_mod->attributes = attributes;
+ for (auto &conn : connections_)
+ new_mod->connect(conn);
+
+ for (auto &attr : attributes)
+ new_mod->attributes[attr.first] = attr.second;
for (auto &it : wires_)
new_mod->addWire(it.first, it.second);
@@ -1061,14 +1172,14 @@ bool RTLIL::Module::has_processes() const
bool RTLIL::Module::has_memories_warn() const
{
if (!memories.empty())
- log("Warning: Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this));
+ log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this));
return !memories.empty();
}
bool RTLIL::Module::has_processes_warn() const
{
if (!processes.empty())
- log("Warning: Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this));
+ log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this));
return !processes.empty();
}
@@ -1114,7 +1225,7 @@ namespace {
struct DeleteWireWorker
{
RTLIL::Module *module;
- const std::set<RTLIL::Wire*> *wires_p;
+ const pool<RTLIL::Wire*> *wires_p;
void operator()(RTLIL::SigSpec &sig) {
std::vector<RTLIL::SigChunk> chunks = sig;
@@ -1128,16 +1239,7 @@ namespace {
};
}
-#if 0
-void RTLIL::Module::remove(RTLIL::Wire *wire)
-{
- std::setPort<RTLIL::Wire*> wires_;
- wires_.insert(wire);
- remove(wires_);
-}
-#endif
-
-void RTLIL::Module::remove(const std::set<RTLIL::Wire*> &wires)
+void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
{
log_assert(refcount_wires_ == 0);
@@ -1266,6 +1368,11 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
for (auto mon : design->monitors)
mon->notify_connect(this, conn);
+ if (yosys_xtrace) {
+ log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
connections_.push_back(conn);
}
@@ -1283,6 +1390,13 @@ void RTLIL::Module::new_connections(const std::vector<RTLIL::SigSig> &new_conn)
for (auto mon : design->monitors)
mon->notify_connect(this, new_conn);
+ if (yosys_xtrace) {
+ log("#X# New connections vector in %s:\n", log_id(this));
+ for (auto &conn: new_conn)
+ log("#X# %s = %s (%d bits)\n", log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
connections_ = new_conn;
}
@@ -1566,6 +1680,15 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a
return cell;
}
+RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y)
+{
+ RTLIL::Cell *cell = addCell(name, "$equiv");
+ cell->setPort("\\A", sig_a);
+ cell->setPort("\\B", sig_b);
+ cell->setPort("\\Y", sig_y);
+ return cell;
+}
+
RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity)
{
RTLIL::Cell *cell = addCell(name, "$sr");
@@ -1578,7 +1701,7 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set,
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
+RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
{
RTLIL::Cell *cell = addCell(name, "$dff");
cell->parameters["\\CLK_POLARITY"] = clk_polarity;
@@ -1589,6 +1712,19 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk,
return cell;
}
+RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity)
+{
+ RTLIL::Cell *cell = addCell(name, "$dffe");
+ cell->parameters["\\CLK_POLARITY"] = clk_polarity;
+ cell->parameters["\\EN_POLARITY"] = en_polarity;
+ cell->parameters["\\WIDTH"] = sig_q.size();
+ cell->setPort("\\CLK", sig_clk);
+ cell->setPort("\\EN", sig_en);
+ cell->setPort("\\D", sig_d);
+ cell->setPort("\\Q", sig_q);
+ return cell;
+}
+
RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity)
{
@@ -1656,6 +1792,16 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_
return cell;
}
+RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity)
+{
+ RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
+ cell->setPort("\\C", sig_clk);
+ cell->setPort("\\E", sig_en);
+ cell->setPort("\\D", sig_d);
+ cell->setPort("\\Q", sig_q);
+ return cell;
+}
+
RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity)
{
@@ -1703,6 +1849,10 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec
RTLIL::Wire::Wire()
{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+
module = nullptr;
width = 1;
start_offset = 0;
@@ -1714,12 +1864,22 @@ RTLIL::Wire::Wire()
RTLIL::Memory::Memory()
{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+
width = 1;
size = 0;
}
RTLIL::Cell::Cell() : module(nullptr)
{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+
+ // log("#memtrace# %p\n", this);
+ memhasher();
}
bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
@@ -1741,6 +1901,11 @@ void RTLIL::Cell::unsetPort(RTLIL::IdString portname)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
+ if (yosys_xtrace) {
+ log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
connections_.erase(conn_it);
}
}
@@ -1753,7 +1918,9 @@ void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
connections_[portname] = RTLIL::SigSpec();
conn_it = connections_.find(portname);
log_assert(conn_it != connections_.end());
- }
+ } else
+ if (conn_it->second == signal)
+ return;
for (auto mon : module->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
@@ -1762,6 +1929,11 @@ void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
+ if (yosys_xtrace) {
+ log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal));
+ log_backtrace("-X- ", yosys_xtrace-1);
+ }
+
conn_it->second = signal;
}
@@ -1770,14 +1942,47 @@ const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const
return connections_.at(portname);
}
-const std::map<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
+const dict<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections() const
{
return connections_;
}
+bool RTLIL::Cell::known() const
+{
+ if (yosys_celltypes.cell_known(type))
+ return true;
+ if (module && module->design && module->design->module(type))
+ return true;
+ return false;
+}
+
+bool RTLIL::Cell::input(RTLIL::IdString portname) const
+{
+ if (yosys_celltypes.cell_known(type))
+ return yosys_celltypes.cell_input(type, portname);
+ if (module && module->design) {
+ RTLIL::Module *m = module->design->module(type);
+ RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
+ return w && w->port_input;
+ }
+ return false;
+}
+
+bool RTLIL::Cell::output(RTLIL::IdString portname) const
+{
+ if (yosys_celltypes.cell_known(type))
+ return yosys_celltypes.cell_output(type, portname);
+ if (module && module->design) {
+ RTLIL::Module *m = module->design->module(type);
+ RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
+ return w && w->port_output;
+ }
+ return false;
+}
+
bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const
{
- return parameters.count(paramname);
+ return parameters.count(paramname) != 0;
}
void RTLIL::Cell::unsetParam(RTLIL::IdString paramname)
@@ -1795,6 +2000,13 @@ const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const
return parameters.at(paramname);
}
+void RTLIL::Cell::sort()
+{
+ connections_.sort(sort_by_id_str());
+ parameters.sort(sort_by_id_str());
+ attributes.sort(sort_by_id_str());
+}
+
void RTLIL::Cell::check()
{
#ifndef NDEBUG
@@ -1810,25 +2022,25 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
return;
if (type == "$mux" || type == "$pmux") {
- parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
+ parameters["\\WIDTH"] = GetSize(connections_["\\Y"]);
if (type == "$pmux")
- parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
+ parameters["\\S_WIDTH"] = GetSize(connections_["\\S"]);
check();
return;
}
if (type == "$lut") {
- parameters["\\WIDTH"] = SIZE(connections_["\\A"]);
+ parameters["\\WIDTH"] = GetSize(connections_["\\A"]);
return;
}
if (type == "$fa") {
- parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
+ parameters["\\WIDTH"] = GetSize(connections_["\\Y"]);
return;
}
if (type == "$lcu") {
- parameters["\\WIDTH"] = SIZE(connections_["\\CO"]);
+ parameters["\\WIDTH"] = GetSize(connections_["\\CO"]);
return;
}
@@ -1841,7 +2053,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
else if (parameters.count("\\A_SIGNED") == 0)
parameters["\\A_SIGNED"] = false;
}
- parameters["\\A_WIDTH"] = SIZE(connections_["\\A"]);
+ parameters["\\A_WIDTH"] = GetSize(connections_["\\A"]);
}
if (connections_.count("\\B")) {
@@ -1851,11 +2063,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
else if (parameters.count("\\B_SIGNED") == 0)
parameters["\\B_SIGNED"] = false;
}
- parameters["\\B_WIDTH"] = SIZE(connections_["\\B"]);
+ parameters["\\B_WIDTH"] = GetSize(connections_["\\B"]);
}
if (connections_.count("\\Y"))
- parameters["\\Y_WIDTH"] = SIZE(connections_["\\Y"]);
+ parameters["\\Y_WIDTH"] = GetSize(connections_["\\Y"]);
check();
}
@@ -1871,7 +2083,7 @@ RTLIL::SigChunk::SigChunk(const RTLIL::Const &value)
{
wire = NULL;
data = value.bits;
- width = SIZE(data);
+ width = GetSize(data);
offset = 0;
}
@@ -1895,7 +2107,7 @@ RTLIL::SigChunk::SigChunk(const std::string &str)
{
wire = NULL;
data = RTLIL::Const(str).bits;
- width = SIZE(data);
+ width = GetSize(data);
offset = 0;
}
@@ -1903,7 +2115,7 @@ RTLIL::SigChunk::SigChunk(int val, int width)
{
wire = NULL;
data = RTLIL::Const(val, width).bits;
- this->width = SIZE(data);
+ this->width = GetSize(data);
offset = 0;
}
@@ -1911,7 +2123,7 @@ RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
{
wire = NULL;
data = RTLIL::Const(bit, width).bits;
- this->width = SIZE(data);
+ this->width = GetSize(data);
offset = 0;
}
@@ -2137,6 +2349,17 @@ RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
check();
}
+RTLIL::SigSpec::SigSpec(pool<RTLIL::SigBit> bits)
+{
+ cover("kernel.rtlil.sigspec.init.pool_bits");
+
+ width_ = 0;
+ hash_ = 0;
+ for (auto &bit : bits)
+ append_bit(bit);
+ check();
+}
+
RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
{
cover("kernel.rtlil.sigspec.init.stdset_bits");
@@ -2148,6 +2371,16 @@ RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
check();
}
+RTLIL::SigSpec::SigSpec(bool bit)
+{
+ cover("kernel.rtlil.sigspec.init.bool");
+
+ width_ = 0;
+ hash_ = 0;
+ append_bit(bit);
+ check();
+}
+
void RTLIL::SigSpec::pack() const
{
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
@@ -2203,9 +2436,7 @@ void RTLIL::SigSpec::unpack() const
that->hash_ = 0;
}
-#define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0)
-
-void RTLIL::SigSpec::hash() const
+void RTLIL::SigSpec::updhash() const
{
RTLIL::SigSpec *that = (RTLIL::SigSpec*)this;
@@ -2215,15 +2446,15 @@ void RTLIL::SigSpec::hash() const
cover("kernel.rtlil.sigspec.hash");
that->pack();
- that->hash_ = 5381;
+ that->hash_ = mkhash_init;
for (auto &c : that->chunks_)
if (c.wire == NULL) {
for (auto &v : c.data)
- DJB2(that->hash_, v);
+ that->hash_ = mkhash(that->hash_, v);
} else {
- DJB2(that->hash_, c.wire->name.index_);
- DJB2(that->hash_, c.offset);
- DJB2(that->hash_, c.width);
+ that->hash_ = mkhash(that->hash_, c.wire->name.index_);
+ that->hash_ = mkhash(that->hash_, c.offset);
+ that->hash_ = mkhash(that->hash_, c.width);
}
if (that->hash_ == 0)
@@ -2255,15 +2486,39 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec
pattern.unpack();
with.unpack();
- std::map<RTLIL::SigBit, RTLIL::SigBit> rules;
+ dict<RTLIL::SigBit, RTLIL::SigBit> rules;
- for (int i = 0; i < SIZE(pattern.bits_); i++)
+ for (int i = 0; i < GetSize(pattern.bits_); i++)
if (pattern.bits_[i].wire != NULL)
rules[pattern.bits_[i]] = with.bits_[i];
replace(rules, other);
}
+void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules)
+{
+ replace(rules, this);
+}
+
+void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
+{
+ cover("kernel.rtlil.sigspec.replace_dict");
+
+ log_assert(other != NULL);
+ log_assert(width_ == other->width_);
+
+ unpack();
+ other->unpack();
+
+ for (int i = 0; i < GetSize(bits_); i++) {
+ auto it = rules.find(bits_[i]);
+ if (it != rules.end())
+ other->bits_[i] = it->second;
+ }
+
+ other->check();
+}
+
void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules)
{
replace(rules, this);
@@ -2271,7 +2526,7 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules, RTLIL::SigSpec *other) const
{
- cover("kernel.rtlil.sigspec.replace");
+ cover("kernel.rtlil.sigspec.replace_map");
log_assert(other != NULL);
log_assert(width_ == other->width_);
@@ -2279,7 +2534,7 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
unpack();
other->unpack();
- for (int i = 0; i < SIZE(bits_); i++) {
+ for (int i = 0; i < GetSize(bits_); i++) {
auto it = rules.find(bits_[i]);
if (it != rules.end())
other->bits_[i] = it->second;
@@ -2301,22 +2556,22 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other
void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
{
- std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
+ pool<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_pool();
remove2(pattern_bits, other);
}
-void RTLIL::SigSpec::remove(const std::set<RTLIL::SigBit> &pattern)
+void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern)
{
remove2(pattern, NULL);
}
-void RTLIL::SigSpec::remove(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const
+void RTLIL::SigSpec::remove(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other) const
{
RTLIL::SigSpec tmp = *this;
tmp.remove2(pattern, other);
}
-void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
+void RTLIL::SigSpec::remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec *other)
{
if (other)
cover("kernel.rtlil.sigspec.remove_other");
@@ -2332,12 +2587,12 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
std::vector<RTLIL::SigBit> new_bits, new_other_bits;
- new_bits.resize(SIZE(bits_));
+ new_bits.resize(GetSize(bits_));
if (other != NULL)
- new_other_bits.resize(SIZE(bits_));
+ new_other_bits.resize(GetSize(bits_));
int k = 0;
- for (int i = 0; i < SIZE(bits_); i++) {
+ for (int i = 0; i < GetSize(bits_); i++) {
if (bits_[i].wire != NULL && pattern.count(bits_[i]))
continue;
if (other != NULL)
@@ -2350,11 +2605,11 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
new_other_bits.resize(k);
bits_.swap(new_bits);
- width_ = SIZE(bits_);
+ width_ = GetSize(bits_);
if (other != NULL) {
other->bits_.swap(new_other_bits);
- other->width_ = SIZE(other->bits_);
+ other->width_ = GetSize(other->bits_);
}
check();
@@ -2362,11 +2617,11 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const
{
- std::set<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_set();
+ pool<RTLIL::SigBit> pattern_bits = pattern.to_sigbit_pool();
return extract(pattern_bits, other);
}
-RTLIL::SigSpec RTLIL::SigSpec::extract(const std::set<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const
+RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other) const
{
if (other)
cover("kernel.rtlil.sigspec.extract_other");
@@ -2417,7 +2672,7 @@ void RTLIL::SigSpec::remove_const()
cover("kernel.rtlil.sigspec.remove_const.packed");
std::vector<RTLIL::SigChunk> new_chunks;
- new_chunks.reserve(SIZE(chunks_));
+ new_chunks.reserve(GetSize(chunks_));
width_ = 0;
for (auto &chunk : chunks_)
@@ -2539,25 +2794,6 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
check();
}
-void RTLIL::SigSpec::extend(int width, bool is_signed)
-{
- cover("kernel.rtlil.sigspec.extend");
-
- pack();
-
- if (width_ > width)
- remove(width, width_ - width);
-
- if (width_ < width) {
- RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
- if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) &&
- padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm))
- padding = RTLIL::SigSpec(RTLIL::State::S0);
- while (width_ < width)
- append(padding);
- }
-}
-
void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
{
cover("kernel.rtlil.sigspec.extend_u0");
@@ -2568,9 +2804,9 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
remove(width, width_ - width);
if (width_ < width) {
- RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0);
+ RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::S0;
if (!is_signed)
- padding = RTLIL::SigSpec(RTLIL::State::S0);
+ padding = RTLIL::State::S0;
while (width_ < width)
append(padding);
}
@@ -2623,7 +2859,7 @@ void RTLIL::SigSpec::check() const
{
cover("kernel.rtlil.sigspec.check.unpacked");
- log_assert(width_ == SIZE(bits_));
+ log_assert(width_ == GetSize(bits_));
log_assert(chunks_.empty());
}
}
@@ -2645,8 +2881,8 @@ bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const
if (chunks_.size() != other.chunks_.size())
return chunks_.size() < other.chunks_.size();
- hash();
- other.hash();
+ updhash();
+ other.updhash();
if (hash_ != other.hash_)
return hash_ < other.hash_;
@@ -2677,8 +2913,8 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
if (chunks_.size() != chunks_.size())
return false;
- hash();
- other.hash();
+ updhash();
+ other.updhash();
if (hash_ != other.hash_)
return false;
@@ -2698,7 +2934,7 @@ bool RTLIL::SigSpec::is_wire() const
cover("kernel.rtlil.sigspec.is_wire");
pack();
- return SIZE(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_;
+ return GetSize(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_;
}
bool RTLIL::SigSpec::is_chunk() const
@@ -2706,7 +2942,7 @@ bool RTLIL::SigSpec::is_chunk() const
cover("kernel.rtlil.sigspec.is_chunk");
pack();
- return SIZE(chunks_) == 1;
+ return GetSize(chunks_) == 1;
}
bool RTLIL::SigSpec::is_fully_const() const
@@ -2750,6 +2986,17 @@ bool RTLIL::SigSpec::is_fully_undef() const
return true;
}
+bool RTLIL::SigSpec::has_const() const
+{
+ cover("kernel.rtlil.sigspec.has_const");
+
+ pack();
+ for (auto it = chunks_.begin(); it != chunks_.end(); it++)
+ if (it->width > 0 && it->wire == NULL)
+ return true;
+ return false;
+}
+
bool RTLIL::SigSpec::has_marked_bits() const
{
cover("kernel.rtlil.sigspec.has_marked_bits");
@@ -2769,7 +3016,7 @@ bool RTLIL::SigSpec::as_bool() const
cover("kernel.rtlil.sigspec.as_bool");
pack();
- log_assert(is_fully_const() && SIZE(chunks_) <= 1);
+ log_assert(is_fully_const() && GetSize(chunks_) <= 1);
if (width_)
return RTLIL::Const(chunks_[0].data).as_bool();
return false;
@@ -2780,7 +3027,7 @@ int RTLIL::SigSpec::as_int(bool is_signed) const
cover("kernel.rtlil.sigspec.as_int");
pack();
- log_assert(is_fully_const() && SIZE(chunks_) <= 1);
+ log_assert(is_fully_const() && GetSize(chunks_) <= 1);
if (width_)
return RTLIL::Const(chunks_[0].data).as_int(is_signed);
return 0;
@@ -2808,7 +3055,7 @@ RTLIL::Const RTLIL::SigSpec::as_const() const
cover("kernel.rtlil.sigspec.as_const");
pack();
- log_assert(is_fully_const() && SIZE(chunks_) <= 1);
+ log_assert(is_fully_const() && GetSize(chunks_) <= 1);
if (width_)
return chunks_[0].data;
return RTLIL::Const();
@@ -2867,6 +3114,18 @@ std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
return sigbits;
}
+pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_pool() const
+{
+ cover("kernel.rtlil.sigspec.to_sigbit_pool");
+
+ pack();
+ pool<RTLIL::SigBit> sigbits;
+ for (auto &c : chunks_)
+ for (int i = 0; i < c.width; i++)
+ sigbits.insert(RTLIL::SigBit(c, i));
+ return sigbits;
+}
+
std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
{
cover("kernel.rtlil.sigspec.to_sigbit_vector");
@@ -2891,6 +3150,22 @@ std::map<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_map(const RTLIL
return new_map;
}
+dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::SigSpec &other) const
+{
+ cover("kernel.rtlil.sigspec.to_sigbit_dict");
+
+ unpack();
+ other.unpack();
+
+ log_assert(width_ == other.width_);
+
+ dict<RTLIL::SigBit, RTLIL::SigBit> new_map;
+ for (int i = 0; i < width_; i++)
+ new_map[bits_[i]] = other.bits_[i];
+
+ return new_map;
+}
+
RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const
{
cover("kernel.rtlil.sigspec.to_single_sigbit");
@@ -2934,7 +3209,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
if (netname.size() == 0)
continue;
- if ('0' <= netname[0] && netname[0] <= '9') {
+ if (('0' <= netname[0] && netname[0] <= '9') || netname[0] == '\'') {
cover("kernel.rtlil.sigspec.parse.const");
AST::get_line_num = sigspec_parse_get_dummy_line_num;
AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname);
@@ -2979,7 +3254,10 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');
if (index_tokens.size() == 1) {
cover("kernel.rtlil.sigspec.parse.bit_sel");
- sig.append(RTLIL::SigSpec(wire, atoi(index_tokens.at(0).c_str())));
+ int a = atoi(index_tokens.at(0).c_str());
+ if (a < 0 || a >= wire->width)
+ return false;
+ sig.append(RTLIL::SigSpec(wire, a));
} else {
cover("kernel.rtlil.sigspec.parse.part_sel");
int a = atoi(index_tokens.at(0).c_str());
@@ -2988,6 +3266,10 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
int tmp = a;
a = b, b = tmp;
}
+ if (a < 0 || a >= wire->width)
+ return false;
+ if (b < 0 || b >= wire->width)
+ return false;
sig.append(RTLIL::SigSpec(wire, a, b-a+1));
}
} else
@@ -3033,7 +3315,7 @@ bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, R
if (lhs.chunks_.size() == 1) {
char *p = (char*)str.c_str(), *endptr;
- long long int val = strtoll(p, &endptr, 10);
+ long int val = strtol(p, &endptr, 10);
if (endptr && endptr != p && *endptr == 0) {
sig = RTLIL::SigSpec(val, lhs.width_);
cover("kernel.rtlil.sigspec.parse.rhs_dec");