aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bitpattern.h4
-rw-r--r--kernel/calc.cc20
-rw-r--r--kernel/cellaigs.cc2
-rw-r--r--kernel/celltypes.h6
-rw-r--r--kernel/driver.cc2
-rw-r--r--kernel/hashlib.h140
-rw-r--r--kernel/log.h5
-rw-r--r--kernel/macc.h4
-rw-r--r--kernel/modtools.h23
-rw-r--r--kernel/register.cc51
-rw-r--r--kernel/rtlil.cc74
-rw-r--r--kernel/rtlil.h9
-rw-r--r--kernel/satgen.h2
-rw-r--r--kernel/sigtools.h164
-rw-r--r--kernel/yosys.h10
15 files changed, 315 insertions, 201 deletions
diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h
index 288571d99..894a95ed1 100644
--- a/kernel/bitpattern.h
+++ b/kernel/bitpattern.h
@@ -30,7 +30,7 @@ struct BitPatternPool
int width;
struct bits_t {
std::vector<RTLIL::State> bitdata;
- unsigned int cached_hash;
+ mutable unsigned int cached_hash;
bits_t(int width = 0) : bitdata(width), cached_hash(0) { }
RTLIL::State &operator[](int index) {
return bitdata[index];
@@ -45,7 +45,7 @@ struct BitPatternPool
}
unsigned int hash() const {
if (!cached_hash)
- ((bits_t*)this)->cached_hash = hash_ops<std::vector<RTLIL::State>>::hash(bitdata);
+ cached_hash = hash_ops<std::vector<RTLIL::State>>::hash(bitdata);
return cached_hash;
}
};
diff --git a/kernel/calc.cc b/kernel/calc.cc
index 32c06c189..a24fa2abf 100644
--- a/kernel/calc.cc
+++ b/kernel/calc.cc
@@ -154,7 +154,7 @@ static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL:
RTLIL::Const arg1, RTLIL::Const arg2, bool signed1, bool signed2, int result_len = -1)
{
if (result_len < 0)
- result_len = std::max(arg1.bits.size(), arg2.bits.size());
+ result_len = max(arg1.bits.size(), arg2.bits.size());
extend_u0(arg1, result_len, signed1);
extend_u0(arg2, result_len, signed2);
@@ -310,7 +310,7 @@ RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2
RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
{
RTLIL::Const arg1_ext = arg1;
- extend_u0(arg1_ext, std::max(result_len, GetSize(arg1)), signed1);
+ extend_u0(arg1_ext, max(result_len, GetSize(arg1)), signed1);
return const_shift_worker(arg1_ext, arg2, false, +1, result_len);
}
@@ -389,7 +389,7 @@ RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
RTLIL::Const arg2_ext = arg2;
RTLIL::Const result(RTLIL::State::S0, result_len);
- int width = std::max(arg1_ext.bits.size(), arg2_ext.bits.size());
+ int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
extend_u0(arg1_ext, width, signed1 && signed2);
extend_u0(arg2_ext, width, signed1 && signed2);
@@ -423,7 +423,7 @@ RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2
RTLIL::Const arg2_ext = arg2;
RTLIL::Const result(RTLIL::State::S0, result_len);
- int width = std::max(arg1_ext.bits.size(), arg2_ext.bits.size());
+ int width = max(arg1_ext.bits.size(), arg2_ext.bits.size());
extend_u0(arg1_ext, width, signed1 && signed2);
extend_u0(arg2_ext, width, signed1 && signed2);
@@ -472,21 +472,21 @@ RTLIL::Const RTLIL::const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) + const2big(arg2, signed2, undef_bit_pos);
- return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
+ return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
}
RTLIL::Const RTLIL::const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) - const2big(arg2, signed2, undef_bit_pos);
- return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
+ return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), undef_bit_pos);
}
RTLIL::Const RTLIL::const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{
int undef_bit_pos = -1;
BigInteger y = const2big(arg1, signed1, undef_bit_pos) * const2big(arg2, signed2, undef_bit_pos);
- return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@@ -499,7 +499,7 @@ RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2
bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative);
a = a.getSign() == BigInteger::negative ? -a : a;
b = b.getSign() == BigInteger::negative ? -b : b;
- return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@@ -512,7 +512,7 @@ RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2
bool result_neg = a.getSign() == BigInteger::negative;
a = a.getSign() == BigInteger::negative ? -a : a;
b = b.getSign() == BigInteger::negative ? -b : b;
- return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@@ -563,7 +563,7 @@ RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2
y *= -1;
}
- return big2const(y, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ return big2const(y, result_len >= 0 ? result_len : max(arg1.bits.size(), arg2.bits.size()), min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len)
diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc
index be2e7bbb8..41f81355d 100644
--- a/kernel/cellaigs.cc
+++ b/kernel/cellaigs.cc
@@ -392,7 +392,7 @@ Aig::Aig(Cell *cell)
if (cell->type.in("$eq", "$ne"))
{
- int width = std::max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
+ int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
vector<int> A = mk.inport_vec("\\A", width);
vector<int> B = mk.inport_vec("\\B", width);
int Y = mk.bool_node(false);
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index f36833446..40fdca36e 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -122,7 +122,7 @@ struct CellTypes
void setup_internals_mem()
{
IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
- IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA";
+ IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN";
IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN";
IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA";
IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
@@ -135,10 +135,10 @@ struct CellTypes
setup_type("$dlatch", {EN, D}, {Q});
setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q});
- setup_type("$memrd", {CLK, ADDR}, {DATA});
+ setup_type("$memrd", {CLK, EN, ADDR}, {DATA});
setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>());
- setup_type("$mem", {RD_CLK, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
+ setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT});
}
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 95835951e..02e332f90 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -404,7 +404,7 @@ int main(int argc, char **argv)
log("%s\n", yosys_version_str);
int64_t total_ns = 0;
- std::set<std::tuple<int64_t, int, std::string>> timedat;
+ std::set<tuple<int64_t, int, std::string>> timedat;
for (auto &it : pass_register)
if (it.second->call_counter) {
diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index f94945eca..f015bf4dd 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -63,18 +63,21 @@ struct hash_int_ops {
static inline bool cmp(T a, T b) {
return a == b;
}
+};
+
+template<> struct hash_ops<int32_t> : hash_int_ops
+{
static inline unsigned int hash(int32_t a) {
return a;
}
+};
+template<> struct hash_ops<int64_t> : hash_int_ops
+{
static inline unsigned int hash(int64_t a) {
return mkhash(a, a >> 32);
}
};
-template<> struct hash_ops<int> : hash_int_ops {};
-template<> struct hash_ops<long> : hash_int_ops {};
-template<> struct hash_ops<long long> : hash_int_ops {};
-
template<> struct hash_ops<std::string> {
static inline bool cmp(const std::string &a, const std::string &b) {
return a == b;
@@ -118,10 +121,9 @@ template<typename T> struct hash_ops<std::vector<T>> {
return a == b;
}
static inline unsigned int hash(std::vector<T> a) {
- hash_ops<T> t_ops;
unsigned int h = mkhash_init;
for (auto k : a)
- h = mkhash(h, t_ops.hash(k));
+ h = mkhash(h, hash_ops<T>::hash(k));
return h;
}
};
@@ -160,6 +162,11 @@ struct hash_obj_ops {
}
};
+template<typename T>
+inline unsigned int mkhash(const T &v) {
+ return hash_ops<T>().hash(v);
+}
+
inline int hashtable_size(int min_size)
{
static std::vector<int> zero_and_some_primes = {
@@ -188,6 +195,7 @@ inline int hashtable_size(int min_size)
template<typename K, typename T, typename OPS = hash_ops<K>> class dict;
template<typename K, int offset = 0, typename OPS = hash_ops<K>> class idict;
template<typename K, typename OPS = hash_ops<K>> class pool;
+template<typename K, typename OPS = hash_ops<K>> class mfp;
template<typename K, typename T, typename OPS>
class dict
@@ -498,6 +506,15 @@ public:
return entries[i].udata.second;
}
+ T at(const K &key, const T &defval) const
+ {
+ int hash = do_hash(key);
+ int i = do_lookup(key, hash);
+ if (i < 0)
+ return defval;
+ return entries[i].udata.second;
+ }
+
T& operator[](const K &key)
{
int hash = do_hash(key);
@@ -888,6 +905,15 @@ public:
return i + offset;
}
+ int at(const K &key, int defval) const
+ {
+ int hash = database.do_hash(key);
+ int i = database.do_lookup(key, hash);
+ if (i < 0)
+ return defval;
+ return i + offset;
+ }
+
int count(const K &key) const
{
int hash = database.do_hash(key);
@@ -907,6 +933,108 @@ public:
return database.entries.at(index - offset).udata;
}
+ void swap(idict &other)
+ {
+ database.swap(other.database);
+ }
+
+ size_t size() const { return database.size(); }
+ bool empty() const { return database.empty(); }
+ void clear() { database.clear(); }
+
+ const_iterator begin() const { return database.begin(); }
+ const_iterator end() const { return database.end(); }
+};
+
+template<typename K, typename OPS>
+class mfp
+{
+ mutable idict<K, 0, OPS> database;
+ mutable std::vector<int> parents;
+
+public:
+ typedef typename idict<K, 0, OPS>::const_iterator const_iterator;
+
+ int operator()(const K &key) const
+ {
+ int i = database(key);
+ parents.resize(database.size(), -1);
+ return i;
+ }
+
+ const K &operator[](int index) const
+ {
+ return database[index];
+ }
+
+ int ifind(int i) const
+ {
+ int p = i, k = i;
+
+ while (parents[p] != -1)
+ p = parents[p];
+
+ while (k != p) {
+ int next_k = parents[k];
+ parents[k] = p;
+ k = next_k;
+ }
+
+ return p;
+ }
+
+ void imerge(int i, int j)
+ {
+ i = ifind(i);
+ j = ifind(j);
+
+ if (i != j)
+ parents[i] = j;
+ }
+
+ void ipromote(int i)
+ {
+ int k = i;
+
+ while (k != -1) {
+ int next_k = parents[k];
+ parents[k] = i;
+ k = next_k;
+ }
+
+ parents[i] = -1;
+ }
+
+ int lookup(const K &a) const
+ {
+ return ifind((*this)(a));
+ }
+
+ const K &find(const K &a) const
+ {
+ return (*this)[ifind((*this)(a))];
+ }
+
+ void merge(const K &a, const K &b)
+ {
+ imerge((*this)(a), (*this)(b));
+ }
+
+ void promote(const K &a)
+ {
+ ipromote((*this)(a));
+ }
+
+ void swap(mfp &other)
+ {
+ database.swap(other.database);
+ parents.swap(other.parents);
+ }
+
+ size_t size() const { return database.size(); }
+ bool empty() const { return database.empty(); }
+ void clear() { database.clear(); parents.clear(); }
+
const_iterator begin() const { return database.begin(); }
const_iterator end() const { return database.end(); }
};
diff --git a/kernel/log.h b/kernel/log.h
index 8cf471465..28baf9886 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -29,6 +29,11 @@
# include <sys/resource.h>
#endif
+#if defined(_MSC_VER)
+// At least this is not in MSVC++ 2013.
+# define __PRETTY_FUNCTION__ __FUNCTION__
+#endif
+
// from libs/sha1/sha1.h
class SHA1;
diff --git a/kernel/macc.h b/kernel/macc.h
index 7efd02281..286ce567f 100644
--- a/kernel/macc.h
+++ b/kernel/macc.h
@@ -158,8 +158,8 @@ struct Macc
int max_size = 0, num_bits = 0;
for (auto &port : ports) {
- max_size = std::max(max_size, GetSize(port.in_a));
- max_size = std::max(max_size, GetSize(port.in_b));
+ max_size = max(max_size, GetSize(port.in_a));
+ max_size = max(max_size, GetSize(port.in_b));
}
while (max_size)
diff --git a/kernel/modtools.h b/kernel/modtools.h
index 44c1bde12..1480ec71f 100644
--- a/kernel/modtools.h
+++ b/kernel/modtools.h
@@ -226,7 +226,7 @@ struct ModIndex : public RTLIL::Monitor
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;
@@ -274,6 +274,27 @@ struct ModIndex : public RTLIL::Monitor
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
diff --git a/kernel/register.cc b/kernel/register.cc
index 179d064fd..49a67324d 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -209,7 +209,7 @@ void Pass::call(RTLIL::Design *design, std::string command)
void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
{
- if (args.size() == 0 || args[0][0] == '#')
+ if (args.size() == 0 || args[0][0] == '#' || args[0][0] == ':')
return;
if (echo_mode) {
@@ -534,14 +534,28 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f
design->check();
}
+static struct CellHelpMessages {
+ dict<string, string> cell_help, cell_code;
+ CellHelpMessages() {
+#include "techlibs/common/simlib_help.inc"
+#include "techlibs/common/simcells_help.inc"
+ cell_help.sort();
+ cell_code.sort();
+ }
+} cell_help_messages;
+
struct HelpPass : public Pass {
HelpPass() : Pass("help", "display help messages") { }
virtual void help()
{
log("\n");
- log(" help ............. list all commands\n");
- log(" help <command> ... print help message for given command\n");
- log(" help -all ........ print complete command reference\n");
+ log(" help ................ list all commands\n");
+ log(" help <command> ...... print help message for given command\n");
+ log(" help -all ........... print complete command reference\n");
+ log("\n");
+ log(" help -cells .......... list all cell types\n");
+ log(" help <celltype> ..... print help message for given cell type\n");
+ log(" help <celltype>+ .... print verilog code for given cell type\n");
log("\n");
}
void escape_tex(std::string &tex)
@@ -609,6 +623,7 @@ struct HelpPass : public Pass {
log(" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str());
log("\n");
log("Type 'help <command>' for more information on a command.\n");
+ log("Type 'help -cells' for a list of all cell types.\n");
log("\n");
return;
}
@@ -624,6 +639,18 @@ struct HelpPass : public Pass {
it.second->help();
}
}
+ else if (args[1] == "-cells") {
+ log("\n");
+ for (auto &it : cell_help_messages.cell_help) {
+ string line = split_tokens(it.second, "\n").at(0);
+ string cell_name = next_token(line);
+ log(" %-15s %s\n", cell_name.c_str(), line.c_str());
+ }
+ log("\n");
+ log("Type 'help <cell_type>' for more information on a cell type.\n");
+ log("\n");
+ return;
+ }
// this option is undocumented as it is for internal use only
else if (args[1] == "-write-tex-command-reference-manual") {
FILE *f = fopen("command-reference-manual.tex", "wt");
@@ -649,10 +676,20 @@ struct HelpPass : public Pass {
}
fclose(f);
}
- else if (pass_register.count(args[1]) == 0)
- log("No such command: %s\n", args[1].c_str());
- else
+ else if (pass_register.count(args[1])) {
pass_register.at(args[1])->help();
+ }
+ else if (cell_help_messages.cell_help.count(args[1])) {
+ log("%s", cell_help_messages.cell_help.at(args[1]).c_str());
+ log("Run 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str());
+ log("\n");
+ }
+ else if (cell_help_messages.cell_code.count(args[1])) {
+ log("\n");
+ log("%s", cell_help_messages.cell_code.at(args[1]).c_str());
+ }
+ else
+ log("No such command or cell type: %s\n", args[1].c_str());
return;
}
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 560ef4b64..4403bcfdc 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -947,6 +947,7 @@ namespace {
param_bool("\\CLK_POLARITY");
param_bool("\\TRANSPARENT");
port("\\CLK", 1);
+ port("\\EN", 1);
port("\\ADDR", param("\\ABITS"));
port("\\DATA", param("\\WIDTH"));
check_expected();
@@ -980,12 +981,13 @@ namespace {
param("\\SIZE");
param("\\OFFSET");
param("\\INIT");
- param_bits("\\RD_CLK_ENABLE", std::max(1, param("\\RD_PORTS")));
- param_bits("\\RD_CLK_POLARITY", std::max(1, param("\\RD_PORTS")));
- param_bits("\\RD_TRANSPARENT", std::max(1, param("\\RD_PORTS")));
- param_bits("\\WR_CLK_ENABLE", std::max(1, param("\\WR_PORTS")));
- param_bits("\\WR_CLK_POLARITY", std::max(1, param("\\WR_PORTS")));
+ param_bits("\\RD_CLK_ENABLE", max(1, param("\\RD_PORTS")));
+ param_bits("\\RD_CLK_POLARITY", max(1, param("\\RD_PORTS")));
+ param_bits("\\RD_TRANSPARENT", max(1, param("\\RD_PORTS")));
+ param_bits("\\WR_CLK_ENABLE", max(1, param("\\WR_PORTS")));
+ param_bits("\\WR_CLK_POLARITY", max(1, param("\\WR_PORTS")));
port("\\RD_CLK", param("\\RD_PORTS"));
+ port("\\RD_EN", param("\\RD_PORTS"));
port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
port("\\WR_CLK", param("\\WR_PORTS"));
@@ -1446,6 +1448,19 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
for (auto mon : design->monitors)
mon->notify_connect(this, conn);
+ // ignore all attempts to assign constants to other constants
+ if (conn.first.has_const()) {
+ RTLIL::SigSig new_conn;
+ for (int i = 0; i < GetSize(conn.first); i++)
+ if (conn.first[i].wire) {
+ new_conn.first.append(conn.first[i]);
+ new_conn.second.append(conn.second[i]);
+ }
+ if (GetSize(new_conn.first))
+ connect(new_conn);
+ return;
+ }
+
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);
@@ -1586,10 +1601,10 @@ DEF_METHOD(LogicNot, 1, "$logic_not")
add ## _func(name, sig_a, sig_b, sig_y, is_signed); \
return sig_y; \
}
-DEF_METHOD(And, std::max(sig_a.size(), sig_b.size()), "$and")
-DEF_METHOD(Or, std::max(sig_a.size(), sig_b.size()), "$or")
-DEF_METHOD(Xor, std::max(sig_a.size(), sig_b.size()), "$xor")
-DEF_METHOD(Xnor, std::max(sig_a.size(), sig_b.size()), "$xnor")
+DEF_METHOD(And, max(sig_a.size(), sig_b.size()), "$and")
+DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), "$or")
+DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), "$xor")
+DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), "$xnor")
DEF_METHOD(Shl, sig_a.size(), "$shl")
DEF_METHOD(Shr, sig_a.size(), "$shr")
DEF_METHOD(Sshl, sig_a.size(), "$sshl")
@@ -1604,11 +1619,11 @@ DEF_METHOD(Eqx, 1, "$eqx")
DEF_METHOD(Nex, 1, "$nex")
DEF_METHOD(Ge, 1, "$ge")
DEF_METHOD(Gt, 1, "$gt")
-DEF_METHOD(Add, std::max(sig_a.size(), sig_b.size()), "$add")
-DEF_METHOD(Sub, std::max(sig_a.size(), sig_b.size()), "$sub")
-DEF_METHOD(Mul, std::max(sig_a.size(), sig_b.size()), "$mul")
-DEF_METHOD(Div, std::max(sig_a.size(), sig_b.size()), "$div")
-DEF_METHOD(Mod, std::max(sig_a.size(), sig_b.size()), "$mod")
+DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), "$add")
+DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), "$sub")
+DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), "$mul")
+DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), "$div")
+DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), "$mod")
DEF_METHOD(LogicAnd, 1, "$logic_and")
DEF_METHOD(LogicOr, 1, "$logic_or")
#undef DEF_METHOD
@@ -1740,13 +1755,13 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a
return cell;
}
-RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut)
+RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut)
{
RTLIL::Cell *cell = addCell(name, "$lut");
cell->parameters["\\LUT"] = lut;
- cell->parameters["\\WIDTH"] = sig_i.size();
- cell->setPort("\\A", sig_i);
- cell->setPort("\\Y", sig_o);
+ cell->parameters["\\WIDTH"] = sig_a.size();
+ cell->setPort("\\A", sig_a);
+ cell->setPort("\\Y", sig_y);
return cell;
}
@@ -3182,6 +3197,17 @@ RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const
return chunks_[0];
}
+RTLIL::SigBit RTLIL::SigSpec::as_bit() const
+{
+ cover("kernel.rtlil.sigspec.as_bit");
+
+ log_assert(width_ == 1);
+ if (packed())
+ return RTLIL::SigBit(*chunks_.begin());
+ else
+ return bits_[0];
+}
+
bool RTLIL::SigSpec::match(std::string pattern) const
{
cover("kernel.rtlil.sigspec.match");
@@ -3269,18 +3295,6 @@ dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::S
return new_map;
}
-RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const
-{
- cover("kernel.rtlil.sigspec.to_single_sigbit");
-
- pack();
- log_assert(width_ == 1);
- for (auto &c : chunks_)
- if (c.width)
- return RTLIL::SigBit(c);
- log_abort();
-}
-
static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
{
size_t start = 0, end = 0;
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 21b42cdbe..7b669536e 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -460,7 +460,7 @@ struct RTLIL::Const
Const(std::string str);
Const(int val, int width = 32);
Const(RTLIL::State bit, int width = 1);
- Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; };
+ Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<bool> &bits);
bool operator <(const RTLIL::Const &other) const;
@@ -476,7 +476,7 @@ struct RTLIL::Const
inline int size() const { return bits.size(); }
inline RTLIL::State &operator[](int index) { return bits.at(index); }
- inline const RTLIL::State &operator[](int index) const { return bits.at(index); };
+ inline const RTLIL::State &operator[](int index) const { return bits.at(index); }
inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
RTLIL::Const ret;
@@ -690,6 +690,7 @@ public:
bool is_wire() const;
bool is_chunk() const;
+ inline bool is_bit() const { return width_ == 1; }
bool is_fully_const() const;
bool is_fully_zero() const;
@@ -704,6 +705,7 @@ public:
RTLIL::Const as_const() const;
RTLIL::Wire *as_wire() const;
RTLIL::SigChunk as_chunk() const;
+ RTLIL::SigBit as_bit() const;
bool match(std::string pattern) const;
@@ -712,7 +714,6 @@ public:
std::vector<RTLIL::SigBit> to_sigbit_vector() const;
std::map<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_map(const RTLIL::SigSpec &other) const;
dict<RTLIL::SigBit, RTLIL::SigBit> to_sigbit_dict(const RTLIL::SigSpec &other) const;
- RTLIL::SigBit to_single_sigbit() const;
static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str);
@@ -998,7 +999,7 @@ public:
RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset);
RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y);
- RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut);
+ RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut);
RTLIL::Cell* addTribuf (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y);
RTLIL::Cell* addAssert (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en);
RTLIL::Cell* addEquiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y);
diff --git a/kernel/satgen.h b/kernel/satgen.h
index 7b0994441..d44d61f16 100644
--- a/kernel/satgen.h
+++ b/kernel/satgen.h
@@ -980,7 +980,7 @@ struct SatGen
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
}
} else {
- int copy_a_bits = std::min(cell->getPort("\\A").size(), cell->getPort("\\B").size());
+ int copy_a_bits = min(cell->getPort("\\A").size(), cell->getPort("\\B").size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());
diff --git a/kernel/sigtools.h b/kernel/sigtools.h
index 7082ace4c..83ff470d2 100644
--- a/kernel/sigtools.h
+++ b/kernel/sigtools.h
@@ -222,18 +222,7 @@ struct SigSet
struct SigMap
{
- struct bitDef_t : public std::pair<RTLIL::Wire*, int> {
- bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { }
- bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { }
- unsigned int hash() const { return first->name.hash() + second; }
- };
-
- struct shared_bit_data_t {
- RTLIL::SigBit map_to;
- std::set<bitDef_t> bits;
- };
-
- dict<bitDef_t, shared_bit_data_t*> bits;
+ mfp<SigBit> database;
SigMap(RTLIL::Module *module = NULL)
{
@@ -241,45 +230,14 @@ struct SigMap
set(module);
}
- SigMap(const SigMap &other)
- {
- copy(other);
- }
-
- const SigMap &operator=(const SigMap &other)
- {
- copy(other);
- return *this;
- }
-
- void copy(const SigMap &other)
- {
- clear();
- for (auto &bit : other.bits) {
- bits[bit.first] = new shared_bit_data_t;
- bits[bit.first]->map_to = bit.second->map_to;
- bits[bit.first]->bits = bit.second->bits;
- }
- }
-
void swap(SigMap &other)
{
- bits.swap(other.bits);
- }
-
- ~SigMap()
- {
- clear();
+ database.swap(other.database);
}
void clear()
{
- std::set<shared_bit_data_t*> all_bd_ptr;
- for (auto &it : bits)
- all_bd_ptr.insert(it.second);
- for (auto bd_ptr : all_bd_ptr)
- delete bd_ptr;
- bits.clear();
+ database.clear();
}
void set(RTLIL::Module *module)
@@ -289,118 +247,49 @@ struct SigMap
add(it.first, it.second);
}
- // internal helper function
- void register_bit(const RTLIL::SigBit &bit)
- {
- if (bit.wire && bits.count(bit) == 0) {
- shared_bit_data_t *bd = new shared_bit_data_t;
- bd->map_to = bit;
- bd->bits.insert(bit);
- bits[bit] = bd;
- }
- }
-
- // internal helper function
- void unregister_bit(const RTLIL::SigBit &bit)
- {
- if (bit.wire && bits.count(bit) > 0) {
- shared_bit_data_t *bd = bits[bit];
- bd->bits.erase(bit);
- if (bd->bits.size() == 0)
- delete bd;
- bits.erase(bit);
- }
- }
-
- // internal helper function
- void merge_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2)
- {
- log_assert(bit1.wire != NULL && bit2.wire != NULL);
-
- shared_bit_data_t *bd1 = bits[bit1];
- shared_bit_data_t *bd2 = bits[bit2];
- log_assert(bd1 != NULL && bd2 != NULL);
-
- if (bd1 == bd2)
- return;
-
- if (bd1->bits.size() < bd2->bits.size())
- {
- for (auto &bit : bd1->bits)
- bits[bit] = bd2;
- bd2->bits.insert(bd1->bits.begin(), bd1->bits.end());
- delete bd1;
- }
- else
- {
- bd1->map_to = bd2->map_to;
- for (auto &bit : bd2->bits)
- bits[bit] = bd1;
- bd1->bits.insert(bd2->bits.begin(), bd2->bits.end());
- delete bd2;
- }
- }
-
- // internal helper function
- void set_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2)
- {
- log_assert(bit1.wire != NULL);
- log_assert(bits.count(bit1) > 0);
- bits[bit1]->map_to = bit2;
- }
-
- // internal helper function
- void map_bit(RTLIL::SigBit &bit) const
- {
- if (bit.wire && bits.count(bit) > 0)
- bit = bits.at(bit)->map_to;
- }
-
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
{
log_assert(GetSize(from) == GetSize(to));
for (int i = 0; i < GetSize(from); i++)
{
- RTLIL::SigBit &bf = from[i];
- RTLIL::SigBit &bt = to[i];
+ int bfi = database.lookup(from[i]);
+ int bti = database.lookup(to[i]);
- if (bf.wire == NULL)
- continue;
+ const RTLIL::SigBit &bf = database[bfi];
+ const RTLIL::SigBit &bt = database[bti];
- register_bit(bf);
- register_bit(bt);
+ if (bf.wire || bt.wire)
+ {
+ database.imerge(bfi, bti);
- if (bt.wire != NULL)
- merge_bit(bf, bt);
- else
- set_bit(bf, bt);
+ if (bf.wire == nullptr)
+ database.ipromote(bfi);
+
+ if (bt.wire == nullptr)
+ database.ipromote(bti);
+ }
}
}
void add(RTLIL::SigSpec sig)
{
for (auto &bit : sig) {
- register_bit(bit);
- set_bit(bit, bit);
+ RTLIL::SigBit b = database.find(bit);
+ if (b.wire != nullptr)
+ database.promote(bit);
}
}
- void del(RTLIL::SigSpec sig)
- {
- for (auto &bit : sig)
- unregister_bit(bit);
- }
-
void apply(RTLIL::SigBit &bit) const
{
- map_bit(bit);
+ bit = database.find(bit);
}
void apply(RTLIL::SigSpec &sig) const
{
for (auto &bit : sig)
- map_bit(bit);
+ apply(bit);
}
RTLIL::SigBit operator()(RTLIL::SigBit bit) const
@@ -417,10 +306,19 @@ struct SigMap
RTLIL::SigSpec operator()(RTLIL::Wire *wire) const
{
- RTLIL::SigSpec sig(wire);
+ SigSpec sig(wire);
apply(sig);
return sig;
}
+
+ RTLIL::SigSpec allbits() const
+ {
+ RTLIL::SigSpec sig;
+ for (auto &bit : database)
+ if (bit.wire != nullptr)
+ sig.append(bit);
+ return sig;
+ }
};
YOSYS_NAMESPACE_END
diff --git a/kernel/yosys.h b/kernel/yosys.h
index 6aacd4d54..92fa6ac19 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -41,6 +41,7 @@
#include <map>
#include <set>
+#include <tuple>
#include <vector>
#include <string>
#include <algorithm>
@@ -138,8 +139,14 @@ YOSYS_NAMESPACE_BEGIN
using std::vector;
using std::string;
+using std::tuple;
using std::pair;
+using std::make_tuple;
+using std::make_pair;
+using std::min;
+using std::max;
+
// A primitive shared string implementation that does not
// move its .c_str() when the object is copied or moved.
struct shared_str {
@@ -164,6 +171,7 @@ using hashlib::hash_obj_ops;
using hashlib::dict;
using hashlib::idict;
using hashlib::pool;
+using hashlib::mfp;
namespace RTLIL {
struct IdString;
@@ -242,6 +250,8 @@ YOSYS_NAMESPACE_END
YOSYS_NAMESPACE_BEGIN
using RTLIL::State;
+using RTLIL::SigChunk;
+using RTLIL::SigSig;
namespace hashlib {
template<> struct hash_ops<RTLIL::State> : hash_ops<int> {};