diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bitpattern.h | 4 | ||||
-rw-r--r-- | kernel/calc.cc | 20 | ||||
-rw-r--r-- | kernel/cellaigs.cc | 2 | ||||
-rw-r--r-- | kernel/celltypes.h | 6 | ||||
-rw-r--r-- | kernel/driver.cc | 2 | ||||
-rw-r--r-- | kernel/hashlib.h | 140 | ||||
-rw-r--r-- | kernel/log.h | 5 | ||||
-rw-r--r-- | kernel/macc.h | 4 | ||||
-rw-r--r-- | kernel/modtools.h | 23 | ||||
-rw-r--r-- | kernel/register.cc | 51 | ||||
-rw-r--r-- | kernel/rtlil.cc | 74 | ||||
-rw-r--r-- | kernel/rtlil.h | 9 | ||||
-rw-r--r-- | kernel/satgen.h | 2 | ||||
-rw-r--r-- | kernel/sigtools.h | 164 | ||||
-rw-r--r-- | kernel/yosys.h | 10 |
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> {}; |