From f9a307a50b5ce67b67d2b53e8c1334ea23ffd997 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Sep 2014 16:17:53 +0200 Subject: namespace Yosys --- kernel/bitpattern.h | 4 ++++ kernel/consteval.h | 4 ++++ kernel/log.h | 11 +++++++---- kernel/satgen.h | 5 +++++ kernel/utils.h | 4 ++++ kernel/yosys.h | 16 ++++------------ 6 files changed, 28 insertions(+), 16 deletions(-) (limited to 'kernel') diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 91f54593f..4d88c8e34 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -23,6 +23,8 @@ #include "kernel/log.h" #include "kernel/rtlil.h" +YOSYS_NAMESPACE_BEGIN + struct BitPatternPool { int width; @@ -133,4 +135,6 @@ struct BitPatternPool } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/consteval.h b/kernel/consteval.h index 2d29d3f7e..12895ec78 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -25,6 +25,8 @@ #include "kernel/celltypes.h" #include "kernel/macc.h" +YOSYS_NAMESPACE_BEGIN + struct ConstEval { RTLIL::Module *module; @@ -376,4 +378,6 @@ struct ConstEval } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/log.h b/kernel/log.h index e2b4db87b..2177db095 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -26,6 +26,9 @@ #include #include +// from libs/sha1/sha1.h +class SHA1; + YOSYS_NAMESPACE_BEGIN #define S__LINE__sub2(x) #x @@ -37,7 +40,7 @@ struct log_cmd_error_expection { }; extern std::vector log_files; extern std::vector log_streams; extern FILE *log_errfile; -extern class SHA1 *log_hasher; +extern SHA1 *log_hasher; extern bool log_time; extern bool log_cmd_error_throw; @@ -68,9 +71,9 @@ template static inline const char *log_id(T *obj) { void log_cell(RTLIL::Cell *cell, std::string indent = ""); -#define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__) -#define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) -#define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) +#define log_assert(_assert_expr_) do { if (_assert_expr_) break; YOSYS_NAMESPACE_PREFIX log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) +#define log_ping() YOSYS_NAMESPACE_PREFIX log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) // --------------------------------------------------- diff --git a/kernel/satgen.h b/kernel/satgen.h index 692c6e7fb..84a47c43f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -26,6 +26,9 @@ #include "kernel/macc.h" #include "libs/ezsat/ezminisat.h" + +YOSYS_NAMESPACE_BEGIN + typedef ezMiniSAT ezDefaultSAT; struct SatGen @@ -1158,4 +1161,6 @@ struct SatGen } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/utils.h b/kernel/utils.h index a03caf804..264558b83 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -25,6 +25,8 @@ #ifndef UTILS_H #define UTILS_H +YOSYS_NAMESPACE_BEGIN + // ------------------------------------------------ // A map-like container, but you can save and restore the state // ------------------------------------------------ @@ -207,4 +209,6 @@ struct TopoSort } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/yosys.h b/kernel/yosys.h index b571e177f..e796919f2 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -60,18 +60,10 @@ #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } - -#if 0 -# define YOSYS_NAMESPACE_BEGIN namespace Yosys { -# define YOSYS_NAMESPACE_END } -# define YOSYS_NAMESPACE_PREFIX Yosys:: -# define USING_YOSYS_NAMESPACE using namespace Yosys; -#else -# define YOSYS_NAMESPACE_BEGIN -# define YOSYS_NAMESPACE_END -# define YOSYS_NAMESPACE_PREFIX -# define USING_YOSYS_NAMESPACE -#endif +#define YOSYS_NAMESPACE_BEGIN namespace Yosys { +#define YOSYS_NAMESPACE_END } +#define YOSYS_NAMESPACE_PREFIX Yosys:: +#define USING_YOSYS_NAMESPACE using namespace Yosys; #if __cplusplus >= 201103L # define OVERRIDE override -- cgit v1.2.3 From 0b8cfbc6fde8e7500c5df38c74e1da2d74e588bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Sep 2014 12:51:54 +0200 Subject: Added support for "keep" on modules --- kernel/rtlil.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a0ae8f082..8df0bfe19 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -857,6 +857,11 @@ public: void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); + bool has_keep_attr() const { + return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) && + module->design->module(type)->get_bool_attribute("\\keep")); + } + template void rewrite_sigspecs(T functor); }; -- cgit v1.2.3 From c3e779a65f285afa123b990f3a717a7ae8e028f5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 3 Oct 2014 10:12:28 +0200 Subject: Added $_BUF_ cell type --- kernel/celltypes.h | 3 +++ kernel/rtlil.cc | 1 + 2 files changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 85c21ef3c..2774073dc 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -130,6 +130,7 @@ struct CellTypes void setup_stdcells() { + setup_type("$_BUF_", {"\\A"}, {"\\Y"}, true); setup_type("$_NOT_", {"\\A"}, {"\\Y"}, true); setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, true); setup_type("$_NAND_", {"\\A", "\\B"}, {"\\Y"}, true); @@ -261,6 +262,8 @@ struct CellTypes HANDLE_CELL_TYPE(neg) #undef HANDLE_CELL_TYPE + if (type == "$_BUF_") + return arg1; if (type == "$_NOT_") return eval_not(arg1); if (type == "$_AND_") diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 00be796f8..89132ea29 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -870,6 +870,7 @@ namespace { 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; } -- cgit v1.2.3 From 3e4b0cac8dc1f443bbd43030f1ce151b41555d97 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 3 Oct 2014 12:58:40 +0200 Subject: added resource sharing of $macc cells --- kernel/macc.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/macc.h b/kernel/macc.h index 271141112..7d70a2686 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -45,6 +45,9 @@ struct Macc if (SIZE(port.in_a) == 0 && SIZE(port.in_b) == 0) continue; + if (SIZE(port.in_a) < SIZE(port.in_b)) + std::swap(port.in_a, port.in_b); + if (SIZE(port.in_a) == 1 && SIZE(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { bit_ports.append(port.in_a); continue; @@ -224,6 +227,12 @@ struct Macc return true; } + + Macc(RTLIL::Cell *cell = nullptr) + { + if (cell != nullptr) + from_cell(cell); + } }; YOSYS_NAMESPACE_END -- cgit v1.2.3 From 56c1d4340842cd0029778a986cd1eed29c146192 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 3 Oct 2014 18:51:50 +0200 Subject: satgen import sigbit api --- kernel/satgen.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/satgen.h b/kernel/satgen.h index 84a47c43f..d4933050f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -38,6 +38,7 @@ struct SatGen std::string prefix; SigPool initial_state; std::map asserts_a, asserts_en; + std::map> imported_signals; bool ignore_div_by_zero; bool model_undef; @@ -52,7 +53,7 @@ struct SatGen this->prefix = prefix; } - std::vector importSigSpecWorker(RTLIL::SigSpec &sig, std::string &pf, bool undef_mode, bool dup_undef) + std::vector importSigSpecWorker(RTLIL::SigSpec sig, std::string &pf, bool undef_mode, bool dup_undef) { log_assert(!undef_mode || model_undef); sigmap->apply(sig); @@ -69,6 +70,7 @@ struct SatGen } else { std::string name = pf + stringf(bit.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(bit.wire->name), bit.offset); vec.push_back(ez->frozen_literal(name)); + imported_signals[pf][bit] = vec.back(); } return vec; } @@ -94,6 +96,20 @@ struct SatGen return importSigSpecWorker(sig, pf, true, false); } + int importSigBit(RTLIL::SigBit bit, int timestep = -1) + { + log_assert(timestep != 0); + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + return importSigSpecWorker(bit, pf, false, false).front(); + } + + bool importedSigBit(RTLIL::SigBit bit, int timestep = -1) + { + log_assert(timestep != 0); + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + return imported_signals[pf].count(bit); + } + void getAsserts(RTLIL::SigSpec &sig_a, RTLIL::SigSpec &sig_en, int timestep = -1) { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); -- cgit v1.2.3 From d3405c15bf74b9a61968aa93ccbc61155e05585f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Oct 2014 10:51:24 +0200 Subject: No rusage on win32 --- kernel/driver.cc | 6 +++++- kernel/log.h | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index f26d9ef82..4210d7ca4 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -268,12 +268,16 @@ int main(int argc, char **argv) delete log_hasher; log_hasher = nullptr; + log_spacer(); +#ifdef WIN32 + log("End of script. Logfile hash: %s\n", hash.c_str()); +#else struct rusage ru_buffer; getrusage(RUSAGE_SELF, &ru_buffer); - log_spacer(); log("End of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); +#endif log("%s\n", yosys_version_str); int64_t total_ns = 0; diff --git a/kernel/log.h b/kernel/log.h index 2177db095..4514c420b 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -24,7 +24,10 @@ #include #include -#include + +#ifndef WIN32 +# include +#endif // from libs/sha1/sha1.h class SHA1; @@ -154,6 +157,8 @@ struct PerformanceTimer t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; return t; +#elif WIN32 + return 0; #else #error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?). #endif @@ -191,8 +196,10 @@ static inline void log_dump_val_worker(int v) { log("%d", v); } static inline void log_dump_val_worker(unsigned int v) { log("%u", v); } static inline void log_dump_val_worker(long int v) { log("%ld", v); } static inline void log_dump_val_worker(unsigned long int v) { log("%lu", v); } +#ifndef WIN32 static inline void log_dump_val_worker(long long int v) { log("%lld", v); } static inline void log_dump_val_worker(unsigned long long int v) { log("%lld", v); } +#endif static inline void log_dump_val_worker(char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); } static inline void log_dump_val_worker(unsigned char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); } static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false"); } -- cgit v1.2.3 From fea11f0fa493f227af5383cbad196c4b3585ccc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Oct 2014 13:59:26 +0200 Subject: Added API for generic cell cost calculations --- kernel/cost.h | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 kernel/cost.h (limited to 'kernel') diff --git a/kernel/cost.h b/kernel/cost.h new file mode 100644 index 000000000..17aca8376 --- /dev/null +++ b/kernel/cost.h @@ -0,0 +1,84 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef COST_H +#define COST_H + +#include + +YOSYS_NAMESPACE_BEGIN + +int get_cell_cost(RTLIL::Cell *cell, std::map *mod_cost_cache = nullptr); + +int get_cell_cost(RTLIL::IdString type, const std::map ¶meters = std::map(), + RTLIL::Design *design = nullptr, std::map *mod_cost_cache = nullptr) +{ + static std::map gate_cost = { + { "$_BUF_", 1 }, + { "$_NOT_", 2 }, + { "$_AND_", 4 }, + { "$_NAND_", 4 }, + { "$_OR_", 4 }, + { "$_NOR_", 4 }, + { "$_XOR_", 8 }, + { "$_XNOR_", 8 }, + { "$_AOI3_", 6 }, + { "$_OAI3_", 6 }, + { "$_AOI4_", 8 }, + { "$_OAI4_", 8 }, + { "$_MUX_", 4 } + }; + + if (gate_cost.count(type)) + return gate_cost.at(type); + + if (parameters.empty() && design && design->module(type)) + { + RTLIL::Module *mod = design->module(type); + + if (mod->attributes.count("\\cost")) + return mod->attributes.at("\\cost").as_int(); + + std::map local_mod_cost_cache; + if (mod_cost_cache == nullptr) + mod_cost_cache = &local_mod_cost_cache; + + if (mod_cost_cache->count(mod)) + return mod_cost_cache->at(mod); + + int module_cost = 1; + for (auto c : mod->cells()) + module_cost += get_cell_cost(c, mod_cost_cache); + + (*mod_cost_cache)[mod] = module_cost; + return module_cost; + } + + log("Warning: Can't determine cost of %s cell (%d parameters).\n", log_id(type), SIZE(parameters)); + return 1; +} + +int get_cell_cost(RTLIL::Cell *cell, std::map *mod_cost_cache) +{ + return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); +} + +YOSYS_NAMESPACE_END + +#endif -- cgit v1.2.3 From c7f5aab625bb90e766c1852592fdf42c951716c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 9 Oct 2014 17:00:54 +0200 Subject: Replaced "#ifdef WIN32" with "#ifdef _WIN32" --- kernel/driver.cc | 2 +- kernel/log.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 4210d7ca4..8a0939043 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -269,7 +269,7 @@ int main(int argc, char **argv) log_hasher = nullptr; log_spacer(); -#ifdef WIN32 +#ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash.c_str()); #else struct rusage ru_buffer; diff --git a/kernel/log.h b/kernel/log.h index 4514c420b..b4182b5f3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -25,7 +25,7 @@ #include #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif @@ -157,7 +157,7 @@ struct PerformanceTimer t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; return t; -#elif WIN32 +#elif _WIN32 return 0; #else #error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?). @@ -196,7 +196,7 @@ static inline void log_dump_val_worker(int v) { log("%d", v); } static inline void log_dump_val_worker(unsigned int v) { log("%u", v); } static inline void log_dump_val_worker(long int v) { log("%ld", v); } static inline void log_dump_val_worker(unsigned long int v) { log("%lu", v); } -#ifndef WIN32 +#ifndef _WIN32 static inline void log_dump_val_worker(long long int v) { log("%lld", v); } static inline void log_dump_val_worker(unsigned long long int v) { log("%lld", v); } #endif -- cgit v1.2.3 From 4569a747f8af3880e23408eb93323afc8088b78b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 16:59:44 +0200 Subject: Renamed SIZE() to GetSize() because of name collision on Win32 --- kernel/calc.cc | 2 +- kernel/celltypes.h | 12 +++++----- kernel/consteval.h | 20 ++++++++--------- kernel/cost.h | 2 +- kernel/log.cc | 4 ++-- kernel/macc.h | 58 ++++++++++++++++++++++++------------------------- kernel/modtools.h | 6 ++--- kernel/rtlil.cc | 58 ++++++++++++++++++++++++------------------------- kernel/satgen.h | 64 +++++++++++++++++++++++++++--------------------------- kernel/sigtools.h | 8 +++---- kernel/utils.h | 6 ++--- kernel/yosys.cc | 10 ++++----- kernel/yosys.h | 4 ++-- 13 files changed, 127 insertions(+), 127 deletions(-) (limited to 'kernel') diff --git a/kernel/calc.cc b/kernel/calc.cc index 41179d045..aa3e8b919 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -303,7 +303,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, SIZE(arg1)), signed1); + extend_u0(arg1_ext, std::max(result_len, GetSize(arg1)), signed1); return const_shift_worker(arg1_ext, arg2, false, +1, result_len); } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 2774073dc..3d9e4cf93 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -303,7 +303,7 @@ struct CellTypes int width = cell->parameters.at("\\WIDTH").as_int(); std::vector t = cell->parameters.at("\\LUT").bits; - while (SIZE(t) < (1 << width)) + while (GetSize(t) < (1 << width)) t.push_back(RTLIL::S0); t.resize(1 << width); @@ -311,16 +311,16 @@ struct CellTypes RTLIL::State sel = arg1.bits.at(i); std::vector new_t; if (sel == RTLIL::S0) - new_t = std::vector(t.begin(), t.begin() + SIZE(t)/2); + new_t = std::vector(t.begin(), t.begin() + GetSize(t)/2); else if (sel == RTLIL::S1) - new_t = std::vector(t.begin() + SIZE(t)/2, t.end()); + new_t = std::vector(t.begin() + GetSize(t)/2, t.end()); else - for (int j = 0; j < SIZE(t)/2; j++) - new_t.push_back(t[j] == t[j + SIZE(t)/2] ? t[j] : RTLIL::Sx); + for (int j = 0; j < GetSize(t)/2; j++) + new_t.push_back(t[j] == t[j + GetSize(t)/2] ? t[j] : RTLIL::Sx); t.swap(new_t); } - log_assert(SIZE(t) == 1); + log_assert(GetSize(t) == 1); return t; } diff --git a/kernel/consteval.h b/kernel/consteval.h index 12895ec78..c2e9710fb 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -74,7 +74,7 @@ struct ConstEval assign_map.apply(sig); #ifndef NDEBUG RTLIL::SigSpec current_val = values_map(sig); - for (int i = 0; i < SIZE(current_val); i++) + for (int i = 0; i < GetSize(current_val); i++) log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); #endif values_map.add(sig, RTLIL::SigSpec(value)); @@ -109,10 +109,10 @@ struct ConstEval if (sig_p.is_fully_def() && sig_g.is_fully_def() && sig_ci.is_fully_def()) { - RTLIL::Const coval(RTLIL::Sx, SIZE(sig_co)); + RTLIL::Const coval(RTLIL::Sx, GetSize(sig_co)); bool carry = sig_ci.as_bool(); - for (int i = 0; i < SIZE(coval); i++) { + for (int i = 0; i < GetSize(coval); i++) { carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; } @@ -120,7 +120,7 @@ struct ConstEval set(sig_co, coval); } else - set(sig_co, RTLIL::Const(RTLIL::Sx, SIZE(sig_co))); + set(sig_co, RTLIL::Const(RTLIL::Sx, GetSize(sig_co))); return true; } @@ -198,7 +198,7 @@ struct ConstEval { RTLIL::SigSpec sig_c = cell->getPort("\\C"); RTLIL::SigSpec sig_x = cell->getPort("\\X"); - int width = SIZE(sig_c); + int width = GetSize(sig_c); if (!eval(sig_a, undef, cell)) return false; @@ -216,7 +216,7 @@ struct ConstEval RTLIL::Const t3 = const_and(sig_c.as_const(), t1, false, false, width); RTLIL::Const val_x = const_or(t2, t3, false, false, width); - for (int i = 0; i < SIZE(val_y); i++) + for (int i = 0; i < GetSize(val_y); i++) if (val_y.bits[i] == RTLIL::Sx) val_x.bits[i] = RTLIL::Sx; @@ -247,13 +247,13 @@ struct ConstEval RTLIL::SigSpec sig_co = cell->getPort("\\CO"); bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); - sig_a.extend_u0(SIZE(sig_y), signed_a); - sig_b.extend_u0(SIZE(sig_y), signed_b); + sig_a.extend_u0(GetSize(sig_y), signed_a); + sig_b.extend_u0(GetSize(sig_y), signed_b); bool carry = sig_ci[0] == RTLIL::S1; bool b_inv = sig_bi[0] == RTLIL::S1; - for (int i = 0; i < SIZE(sig_y); i++) + for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::SigSpec x_inputs = { sig_a[i], sig_b[i], sig_bi[0] }; @@ -294,7 +294,7 @@ struct ConstEval return false; } - RTLIL::Const result(0, SIZE(cell->getPort("\\Y"))); + RTLIL::Const result(0, GetSize(cell->getPort("\\Y"))); if (!macc.eval(result)) log_abort(); diff --git a/kernel/cost.h b/kernel/cost.h index 17aca8376..5e99df993 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -70,7 +70,7 @@ int get_cell_cost(RTLIL::IdString type, const std::mapupdate(str); diff --git a/kernel/macc.h b/kernel/macc.h index 7d70a2686..ab17f8c41 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -42,20 +42,20 @@ struct Macc for (auto &port : ports) { - if (SIZE(port.in_a) == 0 && SIZE(port.in_b) == 0) + if (GetSize(port.in_a) == 0 && GetSize(port.in_b) == 0) continue; - if (SIZE(port.in_a) < SIZE(port.in_b)) + if (GetSize(port.in_a) < GetSize(port.in_b)) std::swap(port.in_a, port.in_b); - if (SIZE(port.in_a) == 1 && SIZE(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { + if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { bit_ports.append(port.in_a); continue; } if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) { RTLIL::Const v = port.in_a.as_const(); - if (SIZE(port.in_b)) + if (GetSize(port.in_b)) v = const_mul(v, port.in_b.as_const(), port.is_signed, port.is_signed, width); if (port.do_subtract) off = const_sub(off, v, port.is_signed, port.is_signed, width); @@ -65,15 +65,15 @@ struct Macc } if (port.is_signed) { - while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == port.in_a[SIZE(port.in_a)-2]) - port.in_a.remove(SIZE(port.in_a)-1); - while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == port.in_b[SIZE(port.in_b)-2]) - port.in_b.remove(SIZE(port.in_b)-1); + while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == port.in_a[GetSize(port.in_a)-2]) + port.in_a.remove(GetSize(port.in_a)-1); + while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2]) + port.in_b.remove(GetSize(port.in_b)-1); } else { - while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == RTLIL::S0) - port.in_a.remove(SIZE(port.in_a)-1); - while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == RTLIL::S0) - port.in_b.remove(SIZE(port.in_b)-1); + while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == RTLIL::S0) + port.in_a.remove(GetSize(port.in_a)-1); + while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == RTLIL::S0) + port.in_b.remove(GetSize(port.in_b)-1); } new_ports.push_back(port); @@ -108,7 +108,7 @@ struct Macc int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); int config_cursor = 0; - log_assert(SIZE(config_bits) >= config_width); + log_assert(GetSize(config_bits) >= config_width); int num_bits = 0; if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1; @@ -117,7 +117,7 @@ struct Macc if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8; int port_a_cursor = 0; - while (port_a_cursor < SIZE(port_a)) + while (port_a_cursor < GetSize(port_a)) { log_assert(config_cursor + 2 + 2*num_bits <= config_width); @@ -146,7 +146,7 @@ struct Macc } log_assert(config_cursor == config_width); - log_assert(port_a_cursor == SIZE(port_a)); + log_assert(port_a_cursor == GetSize(port_a)); } void to_cell(RTLIL::Cell *cell) const @@ -156,8 +156,8 @@ struct Macc int max_size = 0, num_bits = 0; for (auto &port : ports) { - max_size = std::max(max_size, SIZE(port.in_a)); - max_size = std::max(max_size, SIZE(port.in_b)); + max_size = std::max(max_size, GetSize(port.in_a)); + max_size = std::max(max_size, GetSize(port.in_b)); } while (max_size) @@ -171,17 +171,17 @@ struct Macc for (auto &port : ports) { - if (SIZE(port.in_a) == 0) + if (GetSize(port.in_a) == 0) continue; config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0); config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0); - int size_a = SIZE(port.in_a); + int size_a = GetSize(port.in_a); for (int i = 0; i < num_bits; i++) config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0); - int size_b = SIZE(port.in_b); + int size_b = GetSize(port.in_b); for (int i = 0; i < num_bits; i++) config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0); @@ -192,9 +192,9 @@ struct Macc cell->setPort("\\A", port_a); cell->setPort("\\B", bit_ports); cell->setParam("\\CONFIG", config_bits); - cell->setParam("\\CONFIG_WIDTH", SIZE(config_bits)); - cell->setParam("\\A_WIDTH", SIZE(port_a)); - cell->setParam("\\B_WIDTH", SIZE(bit_ports)); + cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits)); + cell->setParam("\\A_WIDTH", GetSize(port_a)); + cell->setParam("\\B_WIDTH", GetSize(bit_ports)); } bool eval(RTLIL::Const &result) const @@ -208,21 +208,21 @@ struct Macc return false; RTLIL::Const summand; - if (SIZE(port.in_b) == 0) - summand = const_pos(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result)); + if (GetSize(port.in_b) == 0) + summand = const_pos(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, GetSize(result)); else - summand = const_mul(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result)); + summand = const_mul(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, GetSize(result)); if (port.do_subtract) - result = const_sub(result, summand, port.is_signed, port.is_signed, SIZE(result)); + result = const_sub(result, summand, port.is_signed, port.is_signed, GetSize(result)); else - result = const_add(result, summand, port.is_signed, port.is_signed, SIZE(result)); + result = const_add(result, summand, port.is_signed, port.is_signed, GetSize(result)); } for (auto bit : bit_ports) { if (bit.wire) return false; - result = const_add(result, bit.data, false, false, SIZE(result)); + result = const_add(result, bit.data, false, false, GetSize(result)); } return true; diff --git a/kernel/modtools.h b/kernel/modtools.h index 58cdd5b0e..1b6968d74 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -59,7 +59,7 @@ struct ModIndex : public RTLIL::Monitor void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { - for (int i = 0; i < SIZE(sig); i++) { + for (int i = 0; i < GetSize(sig); i++) { RTLIL::SigBit bit = sigmap(sig[i]); if (bit.wire) database[bit].ports.insert(PortInfo(cell, port, i)); @@ -68,7 +68,7 @@ struct ModIndex : public RTLIL::Monitor void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { - for (int i = 0; i < SIZE(sig); i++) { + for (int i = 0; i < GetSize(sig); i++) { RTLIL::SigBit bit = sigmap(sig[i]); if (bit.wire) database[bit].ports.erase(PortInfo(cell, port, i)); @@ -88,7 +88,7 @@ struct ModIndex : public RTLIL::Monitor database.clear(); for (auto wire : module->wires()) if (wire->port_input || wire->port_output) - for (int i = 0; i < SIZE(wire); i++) { + for (int i = 0; i < GetSize(wire); i++) { RTLIL::SigBit bit = sigmap(RTLIL::SigBit(wire, i)); if (bit.wire && wire->port_input) database[bit].is_input = true; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 89132ea29..28f0dfdc5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -941,10 +941,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; @@ -953,7 +953,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); @@ -1811,25 +1811,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; } @@ -1842,7 +1842,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")) { @@ -1852,11 +1852,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(); } @@ -1872,7 +1872,7 @@ RTLIL::SigChunk::SigChunk(const RTLIL::Const &value) { wire = NULL; data = value.bits; - width = SIZE(data); + width = GetSize(data); offset = 0; } @@ -1896,7 +1896,7 @@ RTLIL::SigChunk::SigChunk(const std::string &str) { wire = NULL; data = RTLIL::Const(str).bits; - width = SIZE(data); + width = GetSize(data); offset = 0; } @@ -1904,7 +1904,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; } @@ -1912,7 +1912,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; } @@ -2258,7 +2258,7 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec std::map 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]; @@ -2280,7 +2280,7 @@ void RTLIL::SigSpec::replace(const std::map &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; @@ -2333,12 +2333,12 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS std::vector 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) @@ -2351,11 +2351,11 @@ void RTLIL::SigSpec::remove2(const std::set &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(); @@ -2418,7 +2418,7 @@ void RTLIL::SigSpec::remove_const() cover("kernel.rtlil.sigspec.remove_const.packed"); std::vector new_chunks; - new_chunks.reserve(SIZE(chunks_)); + new_chunks.reserve(GetSize(chunks_)); width_ = 0; for (auto &chunk : chunks_) @@ -2624,7 +2624,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()); } } @@ -2699,7 +2699,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 @@ -2707,7 +2707,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 @@ -2770,7 +2770,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; @@ -2781,7 +2781,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; @@ -2809,7 +2809,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(); diff --git a/kernel/satgen.h b/kernel/satgen.h index d4933050f..2759b3927 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -59,7 +59,7 @@ struct SatGen sigmap->apply(sig); std::vector vec; - vec.reserve(SIZE(sig)); + vec.reserve(GetSize(sig)); for (auto &bit : sig) if (bit.wire == NULL) { @@ -791,24 +791,24 @@ struct SatGen Macc macc; macc.from_cell(cell); - std::vector tmp(SIZE(y), ez->FALSE); + std::vector tmp(GetSize(y), ez->FALSE); for (auto &port : macc.ports) { std::vector in_a = importDefSigSpec(port.in_a, timestep); std::vector in_b = importDefSigSpec(port.in_b, timestep); - while (SIZE(in_a) < SIZE(y)) + while (GetSize(in_a) < GetSize(y)) in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->FALSE); - in_a.resize(SIZE(y)); + in_a.resize(GetSize(y)); - if (SIZE(in_b)) + if (GetSize(in_b)) { - while (SIZE(in_b) < SIZE(y)) + while (GetSize(in_b) < GetSize(y)) in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->FALSE); - in_b.resize(SIZE(y)); + in_b.resize(GetSize(y)); - for (int i = 0; i < SIZE(in_b); i++) { + for (int i = 0; i < GetSize(in_b); i++) { std::vector shifted_a(in_a.size(), ez->FALSE); for (int j = i; j < int(in_a.size()); j++) shifted_a.at(j) = in_a.at(j-i); @@ -827,8 +827,8 @@ struct SatGen } } - for (int i = 0; i < SIZE(b); i++) { - std::vector val(SIZE(y), ez->FALSE); + for (int i = 0; i < GetSize(b); i++) { + std::vector val(GetSize(y), ez->FALSE); val.at(0) = b.at(i); tmp = ez->vec_add(tmp, val); } @@ -842,7 +842,7 @@ struct SatGen int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - ez->assume(ez->vec_eq(undef_y, std::vector(SIZE(y), ez->OR(undef_any_a, undef_any_b)))); + ez->assume(ez->vec_eq(undef_y, std::vector(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); undefGating(y, tmp, undef_y); } @@ -940,43 +940,43 @@ struct SatGen std::vector lut; for (auto bit : cell->getParam("\\LUT").bits) lut.push_back(bit == RTLIL::S1 ? ez->TRUE : ez->FALSE); - while (SIZE(lut) < (1 << SIZE(a))) + while (GetSize(lut) < (1 << GetSize(a))) lut.push_back(ez->FALSE); - lut.resize(1 << SIZE(a)); + lut.resize(1 << GetSize(a)); if (model_undef) { std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector t(lut), u(SIZE(t), ez->FALSE); + std::vector t(lut), u(GetSize(t), ez->FALSE); - for (int i = SIZE(a)-1; i >= 0; i--) + for (int i = GetSize(a)-1; i >= 0; i--) { - std::vector t0(t.begin(), t.begin() + SIZE(t)/2); - std::vector t1(t.begin() + SIZE(t)/2, t.end()); + std::vector t0(t.begin(), t.begin() + GetSize(t)/2); + std::vector t1(t.begin() + GetSize(t)/2, t.end()); - std::vector u0(u.begin(), u.begin() + SIZE(u)/2); - std::vector u1(u.begin() + SIZE(u)/2, u.end()); + std::vector u0(u.begin(), u.begin() + GetSize(u)/2); + std::vector u1(u.begin() + GetSize(u)/2, u.end()); t = ez->vec_ite(a[i], t1, t0); u = ez->vec_ite(undef_a[i], ez->vec_or(ez->vec_xor(t0, t1), ez->vec_or(u0, u1)), ez->vec_ite(a[i], u1, u0)); } - log_assert(SIZE(t) == 1); - log_assert(SIZE(u) == 1); + log_assert(GetSize(t) == 1); + log_assert(GetSize(u) == 1); undefGating(y, t, u); ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u)); } else { std::vector t = lut; - for (int i = SIZE(a)-1; i >= 0; i--) + for (int i = GetSize(a)-1; i >= 0; i--) { - std::vector t0(t.begin(), t.begin() + SIZE(t)/2); - std::vector t1(t.begin() + SIZE(t)/2, t.end()); + std::vector t0(t.begin(), t.begin() + GetSize(t)/2); + std::vector t1(t.begin() + GetSize(t)/2, t.end()); t = ez->vec_ite(a[i], t1, t0); } - log_assert(SIZE(t) == 1); + log_assert(GetSize(t) == 1); ez->assume(ez->vec_eq(y, t)); } return true; @@ -1027,7 +1027,7 @@ struct SatGen std::vector yy = model_undef ? ez->vec_var(co.size()) : co; - for (int i = 0; i < SIZE(co); i++) + for (int i = 0; i < GetSize(co); i++) ez->SET(yy[i], ez->OR(g[i], ez->AND(p[i], i ? yy[i-1] : ci[0]))); if (model_undef) @@ -1068,12 +1068,12 @@ struct SatGen std::vector def_x = model_undef ? ez->vec_var(x.size()) : x; std::vector def_co = model_undef ? ez->vec_var(co.size()) : co; - log_assert(SIZE(y) == SIZE(x)); - log_assert(SIZE(y) == SIZE(co)); - log_assert(SIZE(ci) == 1); - log_assert(SIZE(bi) == 1); + log_assert(GetSize(y) == GetSize(x)); + log_assert(GetSize(y) == GetSize(co)); + log_assert(GetSize(ci) == 1); + log_assert(GetSize(bi) == 1); - for (int i = 0; i < SIZE(y); i++) + for (int i = 0; i < GetSize(y); i++) { int s1 = a.at(i), s2 = ez->XOR(b.at(i), bi.at(0)), s3 = i ? co.at(i-1) : ci.at(0); ez->SET(def_x.at(i), ez->XOR(s1, s2)); @@ -1103,7 +1103,7 @@ struct SatGen all_inputs_undef.insert(all_inputs_undef.end(), undef_bi.begin(), undef_bi.end()); int undef_any = ez->expression(ezSAT::OpOr, all_inputs_undef); - for (int i = 0; i < SIZE(undef_y); i++) { + for (int i = 0; i < GetSize(undef_y); i++) { ez->SET(undef_y.at(i), undef_any); ez->SET(undef_x.at(i), ez->OR(undef_a.at(i), undef_b.at(i), undef_bi.at(0))); ez->SET(undef_co.at(i), undef_any); diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 32ef444aa..c3c6a8db1 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -66,8 +66,8 @@ struct SigPool void expand(RTLIL::SigSpec from, RTLIL::SigSpec to) { - log_assert(SIZE(from) == SIZE(to)); - for (int i = 0; i < SIZE(from); i++) { + log_assert(GetSize(from) == GetSize(to)); + for (int i = 0; i < GetSize(from); i++) { bitDef_t bit_from(from[i]), bit_to(to[i]); if (bit_from.first != NULL && bit_to.first != NULL && bits.count(bit_from) > 0) bits.insert(bit_to); @@ -346,9 +346,9 @@ struct SigMap void add(RTLIL::SigSpec from, RTLIL::SigSpec to) { - log_assert(SIZE(from) == SIZE(to)); + log_assert(GetSize(from) == GetSize(to)); - for (int i = 0; i < SIZE(from); i++) + for (int i = 0; i < GetSize(from); i++) { RTLIL::SigBit &bf = from[i]; RTLIL::SigBit &bt = to[i]; diff --git a/kernel/utils.h b/kernel/utils.h index 264558b83..1779a9afc 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -83,7 +83,7 @@ public: void reset(const Key &k) { - for (int i = SIZE(backup_state)-1; i >= 0; i--) + for (int i = GetSize(backup_state)-1; i >= 0; i--) if (backup_state[i].count(k) != 0) { if (backup_state[i].at(k) == nullptr) current_state.erase(k); @@ -160,7 +160,7 @@ struct TopoSort found_loops = true; if (analyze_loops) { std::set loop; - for (int i = SIZE(active_stack)-1; i >= 0; i--) { + for (int i = GetSize(active_stack)-1; i >= 0; i--) { loop.insert(active_stack[i]); if (active_stack[i] == n) break; @@ -204,7 +204,7 @@ struct TopoSort for (auto &it : database) sort_worker(it.first, marked_cells, active_cells, active_stack); - log_assert(SIZE(sorted) == SIZE(database)); + log_assert(GetSize(sorted) == GetSize(database)); return !found_loops; } }; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 0ecb4cdaf..971da78ab 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -66,7 +66,7 @@ std::string vstringf(const char *fmt, va_list ap) return string; } -int SIZE(RTLIL::Wire *wire) +int GetSize(RTLIL::Wire *wire) { return wire->width; } @@ -275,15 +275,15 @@ static void handle_label(std::string &command, bool &from_to_active, const std:: int pos = 0; std::string label; - while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) + while (pos < GetSize(command) && (command[pos] == ' ' || command[pos] == '\t')) pos++; - while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') + while (pos < GetSize(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') label += command[pos++]; - if (label.back() == ':' && SIZE(label) > 1) + if (label.back() == ':' && GetSize(label) > 1) { - label = label.substr(0, SIZE(label)-1); + label = label.substr(0, GetSize(label)-1); command = command.substr(pos); if (label == run_from) diff --git a/kernel/yosys.h b/kernel/yosys.h index e796919f2..c5da9f046 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -84,8 +84,8 @@ namespace RTLIL { std::string stringf(const char *fmt, ...); std::string vstringf(const char *fmt, va_list ap); -template int SIZE(const T &obj) { return obj.size(); } -int SIZE(RTLIL::Wire *wire); +template int GetSize(const T &obj) { return obj.size(); } +int GetSize(RTLIL::Wire *wire); YOSYS_NAMESPACE_END -- cgit v1.2.3 From 7cb0d3aa1acf37025e82846f809d066356a98843 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 17:06:02 +0200 Subject: Renamed TRUE/FALSE to CONST_TRUE/CONST_FALSE because of name collision on Win32 --- kernel/satgen.h | 104 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) (limited to 'kernel') diff --git a/kernel/satgen.h b/kernel/satgen.h index 2759b3927..779c97506 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -66,7 +66,7 @@ struct SatGen if (model_undef && dup_undef && bit == RTLIL::State::Sx) vec.push_back(ez->frozen_literal()); else - vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->TRUE : ez->FALSE); + vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE); } else { std::string name = pf + stringf(bit.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(bit.wire->name), bit.offset); vec.push_back(ez->frozen_literal(name)); @@ -160,9 +160,9 @@ struct SatGen if (!forced_signed && cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters.count("\\B_SIGNED") > 0) is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); while (vec_a.size() < vec_b.size() || vec_a.size() < y_width) - vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->FALSE); + vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE); while (vec_b.size() < vec_a.size() || vec_b.size() < y_width) - vec_b.push_back(is_signed && vec_b.size() > 0 ? vec_b.back() : ez->FALSE); + vec_b.push_back(is_signed && vec_b.size() > 0 ? vec_b.back() : ez->CONST_FALSE); } void extendSignalWidth(std::vector &vec_a, std::vector &vec_b, std::vector &vec_y, RTLIL::Cell *cell, bool forced_signed = false) @@ -176,7 +176,7 @@ struct SatGen { bool is_signed = forced_signed || (cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool()); while (vec_a.size() < vec_y.size()) - vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->FALSE); + vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE); while (vec_y.size() < vec_a.size()) vec_y.push_back(ez->literal()); } @@ -226,7 +226,7 @@ struct SatGen if (is_arith_compare) { for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->FALSE, undef_y.at(i)); + ez->SET(ez->CONST_FALSE, undef_y.at(i)); ez->SET(undef_y_bit, undef_y.at(0)); } else { std::vector undef_y_bits(undef_y.size(), undef_y_bit); @@ -307,7 +307,7 @@ struct SatGen int a = importDefSigSpec(cell->getPort("\\A"), timestep).at(0); int b = importDefSigSpec(cell->getPort("\\B"), timestep).at(0); int c = importDefSigSpec(cell->getPort("\\C"), timestep).at(0); - int d = three_mode ? (aoi_mode ? ez->TRUE : ez->FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0); + int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0); int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); int yy = model_undef ? ez->literal() : y; @@ -321,7 +321,7 @@ struct SatGen int undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep).at(0); int undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep).at(0); int undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep).at(0); - int undef_d = three_mode ? ez->FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0); + int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0); int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); if (aoi_mode) @@ -433,14 +433,14 @@ struct SatGen std::vector undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - int maybe_one_hot = ez->FALSE; - int maybe_many_hot = ez->FALSE; + int maybe_one_hot = ez->CONST_FALSE; + int maybe_many_hot = ez->CONST_FALSE; - int sure_one_hot = ez->FALSE; - int sure_many_hot = ez->FALSE; + int sure_one_hot = ez->CONST_FALSE; + int sure_many_hot = ez->CONST_FALSE; - std::vector bits_set = std::vector(undef_y.size(), ez->FALSE); - std::vector bits_clr = std::vector(undef_y.size(), ez->FALSE); + std::vector bits_set = std::vector(undef_y.size(), ez->CONST_FALSE); + std::vector bits_clr = std::vector(undef_y.size(), ez->CONST_FALSE); for (size_t i = 0; i < s.size(); i++) { @@ -482,7 +482,7 @@ struct SatGen if (cell->type == "$pos") { ez->assume(ez->vec_eq(a, yy)); } else { - std::vector zero(a.size(), ez->FALSE); + std::vector zero(a.size(), ez->CONST_FALSE); ez->assume(ez->vec_eq(ez->vec_sub(zero, a), yy)); } @@ -524,7 +524,7 @@ struct SatGen if (cell->type == "$logic_not") ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0)); for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->FALSE, yy.at(i)); + ez->SET(ez->CONST_FALSE, yy.at(i)); if (model_undef) { @@ -546,7 +546,7 @@ struct SatGen log_abort(); for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->FALSE, undef_y.at(i)); + ez->SET(ez->CONST_FALSE, undef_y.at(i)); undefGating(y, yy, undef_y); } @@ -569,7 +569,7 @@ struct SatGen else ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0)); for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->FALSE, yy.at(i)); + ez->SET(ez->CONST_FALSE, yy.at(i)); if (model_undef) { @@ -592,7 +592,7 @@ struct SatGen log_abort(); for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->FALSE, undef_y.at(i)); + ez->SET(ez->CONST_FALSE, undef_y.at(i)); undefGating(y, yy, undef_y); } @@ -630,7 +630,7 @@ struct SatGen if (cell->type == "$gt") ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0)); for (size_t i = 1; i < y.size(); i++) - ez->SET(ez->FALSE, yy.at(i)); + ez->SET(ez->CONST_FALSE, yy.at(i)); if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { @@ -645,7 +645,7 @@ struct SatGen yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b)); for (size_t i = 0; i < y.size(); i++) - ez->SET(ez->FALSE, undef_y.at(i)); + ez->SET(ez->CONST_FALSE, undef_y.at(i)); ez->assume(ez->vec_eq(y, yy)); } @@ -667,7 +667,7 @@ struct SatGen int undef_y_bit = ez->AND(undef_any, ez->NOT(masked_ne)); for (size_t i = 1; i < undef_y.size(); i++) - ez->SET(ez->FALSE, undef_y.at(i)); + ez->SET(ez->CONST_FALSE, undef_y.at(i)); ez->SET(undef_y_bit, undef_y.at(0)); undefGating(y, yy, undef_y); @@ -689,7 +689,7 @@ struct SatGen std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); - int extend_bit = ez->FALSE; + int extend_bit = ez->CONST_FALSE; if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) extend_bit = a.back(); @@ -703,16 +703,16 @@ struct SatGen std::vector shifted_a; if (cell->type == "$shl" || cell->type == "$sshl") - shifted_a = ez->vec_shift_left(a, b, false, ez->FALSE, ez->FALSE); + shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$shr") - shifted_a = ez->vec_shift_right(a, b, false, ez->FALSE, ez->FALSE); + shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$sshr") - shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->FALSE, ez->FALSE); + shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$shift" || cell->type == "$shiftx") - shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->FALSE, ez->FALSE); + shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); ez->assume(ez->vec_eq(shifted_a, yy)); @@ -723,7 +723,7 @@ struct SatGen std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); std::vector undef_a_shifted; - extend_bit = cell->type == "$shiftx" ? ez->TRUE : ez->FALSE; + extend_bit = cell->type == "$shiftx" ? ez->CONST_TRUE : ez->CONST_FALSE; if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) extend_bit = undef_a.back(); @@ -733,19 +733,19 @@ struct SatGen undef_a.push_back(extend_bit); if (cell->type == "$shl" || cell->type == "$sshl") - undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->FALSE, ez->FALSE); + undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$shr") - undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->FALSE, ez->FALSE); + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$sshr") - undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->FALSE, ez->FALSE); + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$shift") - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->FALSE, ez->FALSE); + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); if (cell->type == "$shiftx") - undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->TRUE, ez->TRUE); + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); std::vector undef_all_y_bits(undef_y.size(), undef_any_b); @@ -764,10 +764,10 @@ struct SatGen std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - std::vector tmp(a.size(), ez->FALSE); + std::vector tmp(a.size(), ez->CONST_FALSE); for (int i = 0; i < int(a.size()); i++) { - std::vector shifted_a(a.size(), ez->FALSE); + std::vector shifted_a(a.size(), ez->CONST_FALSE); for (int j = i; j < int(a.size()); j++) shifted_a.at(j) = a.at(j-i); tmp = ez->vec_ite(b.at(i), ez->vec_add(tmp, shifted_a), tmp); @@ -791,7 +791,7 @@ struct SatGen Macc macc; macc.from_cell(cell); - std::vector tmp(GetSize(y), ez->FALSE); + std::vector tmp(GetSize(y), ez->CONST_FALSE); for (auto &port : macc.ports) { @@ -799,17 +799,17 @@ struct SatGen std::vector in_b = importDefSigSpec(port.in_b, timestep); while (GetSize(in_a) < GetSize(y)) - in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->FALSE); + in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->CONST_FALSE); in_a.resize(GetSize(y)); if (GetSize(in_b)) { while (GetSize(in_b) < GetSize(y)) - in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->FALSE); + in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->CONST_FALSE); in_b.resize(GetSize(y)); for (int i = 0; i < GetSize(in_b); i++) { - std::vector shifted_a(in_a.size(), ez->FALSE); + std::vector shifted_a(in_a.size(), ez->CONST_FALSE); for (int j = i; j < int(in_a.size()); j++) shifted_a.at(j) = in_a.at(j-i); if (port.do_subtract) @@ -828,7 +828,7 @@ struct SatGen } for (int i = 0; i < GetSize(b); i++) { - std::vector val(GetSize(y), ez->FALSE); + std::vector val(GetSize(y), ez->CONST_FALSE); val.at(0) = b.at(i); tmp = ez->vec_add(tmp, val); } @@ -871,14 +871,14 @@ struct SatGen } std::vector chain_buf = a_u; - std::vector y_u(a_u.size(), ez->FALSE); + std::vector y_u(a_u.size(), ez->CONST_FALSE); for (int i = int(a.size())-1; i >= 0; i--) { - chain_buf.insert(chain_buf.end(), chain_buf.size(), ez->FALSE); + chain_buf.insert(chain_buf.end(), chain_buf.size(), ez->CONST_FALSE); - std::vector b_shl(i, ez->FALSE); + std::vector b_shl(i, ez->CONST_FALSE); b_shl.insert(b_shl.end(), b_u.begin(), b_u.end()); - b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(), ez->FALSE); + b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(), ez->CONST_FALSE); y_u.at(i) = ez->vec_ge_unsigned(chain_buf, b_shl); chain_buf = ez->vec_ite(y_u.at(i), ez->vec_sub(chain_buf, b_shl), chain_buf); @@ -905,13 +905,13 @@ struct SatGen std::vector div_zero_result; if (cell->type == "$div") { if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) { - std::vector all_ones(y.size(), ez->TRUE); - std::vector only_first_one(y.size(), ez->FALSE); - only_first_one.at(0) = ez->TRUE; + std::vector all_ones(y.size(), ez->CONST_TRUE); + std::vector only_first_one(y.size(), ez->CONST_FALSE); + only_first_one.at(0) = ez->CONST_TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->getPort("\\A").size(), ez->TRUE); - div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); + div_zero_result.insert(div_zero_result.end(), cell->getPort("\\A").size(), ez->CONST_TRUE); + 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()); @@ -919,7 +919,7 @@ struct SatGen 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()); else - div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); + div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); } ez->assume(ez->vec_eq(yy, ez->vec_ite(ez->expression(ezSAT::OpOr, b), y_tmp, div_zero_result))); } @@ -939,15 +939,15 @@ struct SatGen std::vector lut; for (auto bit : cell->getParam("\\LUT").bits) - lut.push_back(bit == RTLIL::S1 ? ez->TRUE : ez->FALSE); + lut.push_back(bit == RTLIL::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); while (GetSize(lut) < (1 << GetSize(a))) - lut.push_back(ez->FALSE); + lut.push_back(ez->CONST_FALSE); lut.resize(1 << GetSize(a)); if (model_undef) { std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); - std::vector t(lut), u(GetSize(t), ez->FALSE); + std::vector t(lut), u(GetSize(t), ez->CONST_FALSE); for (int i = GetSize(a)-1; i >= 0; i--) { -- cgit v1.2.3 From bbd808072be859074a023795a15bebab87cbfba8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 17:22:08 +0200 Subject: Added format __attribute__ to stringf() --- kernel/satgen.h | 2 +- kernel/yosys.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/satgen.h b/kernel/satgen.h index 779c97506..d556f4f32 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -68,7 +68,7 @@ struct SatGen else vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->CONST_TRUE : ez->CONST_FALSE); } else { - std::string name = pf + stringf(bit.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(bit.wire->name), bit.offset); + std::string name = pf + (bit.wire->width == 1 ? stringf("%s", log_id(bit.wire)) : stringf("%s [%d]", log_id(bit.wire->name), bit.offset)); vec.push_back(ez->frozen_literal(name)); imported_signals[pf][bit] = vec.back(); } diff --git a/kernel/yosys.h b/kernel/yosys.h index c5da9f046..d3f885644 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -82,7 +82,7 @@ namespace RTLIL { struct Cell; } -std::string stringf(const char *fmt, ...); +std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); std::string vstringf(const char *fmt, va_list ap); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3 From 774933a0d88502585cf8c169280e71d0c3d182fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:02:17 +0200 Subject: Replaced fnmatch() with patmatch() --- kernel/patmatch.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 kernel/patmatch.h (limited to 'kernel') diff --git a/kernel/patmatch.h b/kernel/patmatch.h new file mode 100644 index 000000000..611c8d86e --- /dev/null +++ b/kernel/patmatch.h @@ -0,0 +1,91 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef PATMATCH_H +#define PATMATCH_H + +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +// this is very similar to fnmatch(). the exact rules used by this +// function are: +// +// ? matches any character except +// * matches any sequence of characters +// [...] matches any of the characters in the list +// [!..] matches any of the characters not in the list +// +// a backslash may be used to escape the next characters in the +// pattern. each special character can also simply match itself. +// +static bool patmatch(const char *pattern, const char *string) +{ + if (*pattern == 0) + return *string == 0; + + if (*pattern == '\\') { + if (pattern[1] == string[0] && patmatch(pattern+2, string+1)) + return true; + } + + if (*pattern == '?') { + if (*string == 0) + return false; + return patmatch(pattern+1, string+1); + } + + if (*pattern == '*') { + while (*string) { + if (patmatch(pattern+1, string++)) + return true; + } + return pattern[1] == 0; + } + + if (*pattern == '[') { + bool found_match = false; + bool inverted_list = pattern[1] == '!'; + const char *p = pattern + (inverted_list ? 1 : 0); + + while (*++p) { + if (*p == ']') { + if (found_match != inverted_list && patmatch(p+1, string+1)) + return true; + break; + } + + if (*p == '\\') { + if (*++p == *string) + found_match = true; + } else + if (*p == *string) + found_match = true; + } + } + + if (*pattern == *string) + return patmatch(pattern+1, string+1); + + return false; +} + +YOSYS_NAMESPACE_END + +#endif -- cgit v1.2.3 From ee5165c6e470d0f66e339ff796b074f8ac1a89aa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:19:00 +0200 Subject: Moved patmatch() to yosys.cc --- kernel/patmatch.h | 91 ------------------------------------------------------- kernel/yosys.cc | 62 +++++++++++++++++++++++++++++++++++++ kernel/yosys.h | 3 ++ 3 files changed, 65 insertions(+), 91 deletions(-) delete mode 100644 kernel/patmatch.h (limited to 'kernel') diff --git a/kernel/patmatch.h b/kernel/patmatch.h deleted file mode 100644 index 611c8d86e..000000000 --- a/kernel/patmatch.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef PATMATCH_H -#define PATMATCH_H - -#include "kernel/yosys.h" - -YOSYS_NAMESPACE_BEGIN - -// this is very similar to fnmatch(). the exact rules used by this -// function are: -// -// ? matches any character except -// * matches any sequence of characters -// [...] matches any of the characters in the list -// [!..] matches any of the characters not in the list -// -// a backslash may be used to escape the next characters in the -// pattern. each special character can also simply match itself. -// -static bool patmatch(const char *pattern, const char *string) -{ - if (*pattern == 0) - return *string == 0; - - if (*pattern == '\\') { - if (pattern[1] == string[0] && patmatch(pattern+2, string+1)) - return true; - } - - if (*pattern == '?') { - if (*string == 0) - return false; - return patmatch(pattern+1, string+1); - } - - if (*pattern == '*') { - while (*string) { - if (patmatch(pattern+1, string++)) - return true; - } - return pattern[1] == 0; - } - - if (*pattern == '[') { - bool found_match = false; - bool inverted_list = pattern[1] == '!'; - const char *p = pattern + (inverted_list ? 1 : 0); - - while (*++p) { - if (*p == ']') { - if (found_match != inverted_list && patmatch(p+1, string+1)) - return true; - break; - } - - if (*p == '\\') { - if (*++p == *string) - found_match = true; - } else - if (*p == *string) - found_match = true; - } - } - - if (*pattern == *string) - return patmatch(pattern+1, string+1); - - return false; -} - -YOSYS_NAMESPACE_END - -#endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 971da78ab..d728329e3 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -66,6 +66,68 @@ std::string vstringf(const char *fmt, va_list ap) return string; } +// this is very similar to fnmatch(). the exact rules used by this +// function are: +// +// ? matches any character except +// * matches any sequence of characters +// [...] matches any of the characters in the list +// [!..] matches any of the characters not in the list +// +// a backslash may be used to escape the next characters in the +// pattern. each special character can also simply match itself. +// +static bool patmatch(const char *pattern, const char *string) +{ + if (*pattern == 0) + return *string == 0; + + if (*pattern == '\\') { + if (pattern[1] == string[0] && patmatch(pattern+2, string+1)) + return true; + } + + if (*pattern == '?') { + if (*string == 0) + return false; + return patmatch(pattern+1, string+1); + } + + if (*pattern == '*') { + while (*string) { + if (patmatch(pattern+1, string++)) + return true; + } + return pattern[1] == 0; + } + + if (*pattern == '[') { + bool found_match = false; + bool inverted_list = pattern[1] == '!'; + const char *p = pattern + (inverted_list ? 1 : 0); + + while (*++p) { + if (*p == ']') { + if (found_match != inverted_list && patmatch(p+1, string+1)) + return true; + break; + } + + if (*p == '\\') { + if (*++p == *string) + found_match = true; + } else + if (*p == *string) + found_match = true; + } + } + + if (*pattern == *string) + return patmatch(pattern+1, string+1); + + return false; +} + int GetSize(RTLIL::Wire *wire) { return wire->width; diff --git a/kernel/yosys.h b/kernel/yosys.h index d3f885644..a796dd09f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -84,6 +84,9 @@ namespace RTLIL { std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); std::string vstringf(const char *fmt, va_list ap); + +bool patmatch(const char *pattern, const char *string); + template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3 From 986bcc13cbe6a085aa826e87f9d56bde22c7e521 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:19:18 +0200 Subject: Various win32 build fixes in yosys.cc --- kernel/yosys.cc | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d728329e3..7272c073b 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -24,7 +24,10 @@ # include #endif -#include +#ifndef _WIN32 +# include +#endif + #include #include #include @@ -55,8 +58,22 @@ std::string vstringf(const char *fmt, va_list ap) std::string string; char *str = NULL; +#ifdef _WIN32 + int sz = 64, rc; + while (1) { + va_list apc; + va_copy(apc, ap); + str = (char*)realloc(str, sz); + rc = vsnprintf(str, sz, fmt, apc); + va_end(apc); + if (rc >= 0 && rc < sz) + break; + sz *= 2; + } +#else if (vasprintf(&str, fmt, ap) < 0) str = NULL; +#endif if (str != NULL) { string = str; @@ -163,8 +180,10 @@ void yosys_shutdown() } #endif +#ifndef _WIN32 for (auto &it : loaded_plugins) dlclose(it.second); +#endif loaded_plugins.clear(); loaded_plugin_aliases.clear(); @@ -272,7 +291,7 @@ struct TclPass : public Pass { #endif #if defined(__linux__) -std::string proc_self_dirname () +std::string proc_self_dirname() { char path [PATH_MAX]; ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); @@ -285,7 +304,7 @@ std::string proc_self_dirname () } #elif defined(__APPLE__) #include -std::string proc_self_dirname () +std::string proc_self_dirname() { char * path = NULL; uint32_t buflen = 0; @@ -295,8 +314,14 @@ std::string proc_self_dirname () buflen--; return std::string(path, buflen); } +#elif defined(_WIN32) +std::string proc_self_dirname() +{ + #warning Fixme: Implement proc_self_dirname() for win32. + log_error("proc_self_dirname() is not implemented for win32 yet!\n"); +} #elif defined(EMSCRIPTEN) -std::string proc_self_dirname () +std::string proc_self_dirname() { return "/"; } @@ -304,7 +329,7 @@ std::string proc_self_dirname () #error Dont know how to determine process executable base path! #endif -std::string proc_share_dirname () +std::string proc_share_dirname() { std::string proc_self_path = proc_self_dirname(); std::string proc_share_path = proc_self_path + "share/"; -- cgit v1.2.3 From 2c683102be85b0ee9c03c85ddcf5d7fd0f004ab7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:33:55 +0200 Subject: Added next_token() function (strtok() replacement) --- kernel/yosys.cc | 19 ++++++++++++++++++- kernel/yosys.h | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 7272c073b..96fe5446d 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -83,6 +83,23 @@ std::string vstringf(const char *fmt, va_list ap) return string; } +std::string next_token(std::string &text, const char *sep) +{ + size_t pos_begin = text.find_first_not_of(sep); + + if (pos_begin == string::npos) + pos_begin = text.size(); + + size_t pos_end = text.find_first_of(sep, pos_begin); + + if (pos_end == string::npos) + pos_end = text.size(); + + std::string token = text.substr(pos_begin, pos_end-pos_begin); + text = text.substr(pos_end); + return token; +} + // this is very similar to fnmatch(). the exact rules used by this // function are: // @@ -94,7 +111,7 @@ std::string vstringf(const char *fmt, va_list ap) // a backslash may be used to escape the next characters in the // pattern. each special character can also simply match itself. // -static bool patmatch(const char *pattern, const char *string) +bool patmatch(const char *pattern, const char *string) { if (*pattern == 0) return *string == 0; diff --git a/kernel/yosys.h b/kernel/yosys.h index a796dd09f..919e3bb98 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -84,7 +84,7 @@ namespace RTLIL { std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); std::string vstringf(const char *fmt, va_list ap); - +std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); template int GetSize(const T &obj) { return obj.size(); } -- cgit v1.2.3 From 20d85f20dbb16a1c47f7993da06f5b9abac1d09d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:38:40 +0200 Subject: Fixed next_token() --- kernel/yosys.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 96fe5446d..08f75df7b 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -87,12 +87,12 @@ std::string next_token(std::string &text, const char *sep) { size_t pos_begin = text.find_first_not_of(sep); - if (pos_begin == string::npos) + if (pos_begin == std::string::npos) pos_begin = text.size(); size_t pos_end = text.find_first_of(sep, pos_begin); - if (pos_end == string::npos) + if (pos_end == std::string::npos) pos_end = text.size(); std::string token = text.substr(pos_begin, pos_end-pos_begin); -- cgit v1.2.3 From df537a216ba6a954a7b3e5631d35f58ebe3b2c0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 10 Oct 2014 18:53:03 +0200 Subject: Using next_token() to parse commands --- kernel/register.cc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 2f7b89ffd..9452eb355 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -146,35 +146,34 @@ void Pass::extra_args(std::vector args, size_t argidx, RTLIL::Desig void Pass::call(RTLIL::Design *design, std::string command) { std::vector args; - char *s = strdup(command.c_str()), *sstart = s, *saveptr; - s += strspn(s, " \t\r\n"); - if (*s == 0 || *s == '#') { - free(sstart); + + std::string cmd_buf = command; + std::string tok = next_token(cmd_buf, " \t\r\n"); + + if (tok.empty() || tok[0] == '#') return; - } - if (*s == '!') { - for (s++; *s == ' ' || *s == '\t'; s++) { } - char *p = s + strlen(s) - 1; - while (p >= s && (*p == '\r' || *p == '\n')) - *(p--) = 0; - log_header("Shell command: %s\n", s); - int retCode = system(s); + + if (tok[0] == '!') { + cmd_buf = command.substr(command.find('!') + 1); + while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' || + cmd_buf.back() == '\r' || cmd_buf.back() == '\n')) + cmd_buf.resize(cmd_buf.size()-1); + log_header("Shell command: %s\n", cmd_buf.c_str()); + int retCode = system(cmd_buf.c_str()); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); - free(sstart); return; } - for (char *p = strtok_r(s, " \t\r\n", &saveptr); p; p = strtok_r(NULL, " \t\r\n", &saveptr)) { - std::string str = p; - int strsz = str.size(); - if (str == "#") + + while (!tok.empty()) { + if (tok == "#") break; - if (strsz > 0 && str[strsz-1] == ';') { + if (tok.back() == ';') { int num_semikolon = 0; - while (strsz > 0 && str[strsz-1] == ';') - strsz--, num_semikolon++; - if (strsz > 0) - args.push_back(str.substr(0, strsz)); + while (!tok.empty() && tok.back() == ';') + tok.resize(tok.size()-1), num_semikolon++; + if (!tok.empty()) + args.push_back(tok); call(design, args); args.clear(); if (num_semikolon == 2) @@ -182,9 +181,10 @@ void Pass::call(RTLIL::Design *design, std::string command) if (num_semikolon == 3) call(design, "clean -purge"); } else - args.push_back(str); + args.push_back(tok); + tok = next_token(cmd_buf, " \t\r\n"); } - free(sstart); + call(design, args); } -- cgit v1.2.3 From 53349fb634e79641a7a728f6d030c5eda0702477 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Oct 2014 10:57:46 +0200 Subject: Fixed ifdefs for plugin unloading --- kernel/yosys.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 08f75df7b..f2492555e 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -24,7 +24,7 @@ # include #endif -#ifndef _WIN32 +#ifdef YOSYS_ENABLE_PLUGINS # include #endif @@ -197,7 +197,7 @@ void yosys_shutdown() } #endif -#ifndef _WIN32 +#ifdef YOSYS_ENABLE_PLUGINS for (auto &it : loaded_plugins) dlclose(it.second); #endif -- cgit v1.2.3 From 568fee5e74093838121ea61ec15d98a111306bba Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Oct 2014 11:08:52 +0200 Subject: Added proc_self_dirname() for win32 --- kernel/yosys.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f2492555e..921f2b383 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -28,6 +28,10 @@ # include #endif +#ifdef _WIN32 +# include +#endif + #include #include #include @@ -310,7 +314,7 @@ struct TclPass : public Pass { #if defined(__linux__) std::string proc_self_dirname() { - char path [PATH_MAX]; + char path[PATH_MAX]; ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); if (buflen < 0) { log_error("readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno)); @@ -323,7 +327,7 @@ std::string proc_self_dirname() #include std::string proc_self_dirname() { - char * path = NULL; + char *path = NULL; uint32_t buflen = 0; while (_NSGetExecutablePath(path, &buflen) != 0) path = (char *) realloc((void *) path, buflen); @@ -334,8 +338,12 @@ std::string proc_self_dirname() #elif defined(_WIN32) std::string proc_self_dirname() { - #warning Fixme: Implement proc_self_dirname() for win32. - log_error("proc_self_dirname() is not implemented for win32 yet!\n"); + char path[MAX_PATH+1]; + if (!GetModuleFileName(0, path, MAX_PATH+1)) + log_error("GetModuleFileName() failed.\n"); + for (int i = strlen(path)-1; i >= 0 && path[i] != '/' && path[i] != '\\' ; i--) + path[i] = 0; + return std::string(path); } #elif defined(EMSCRIPTEN) std::string proc_self_dirname() -- cgit v1.2.3 From 8263f6a74a822579f3c1da7d8b128ea8ab7b4d79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Oct 2014 11:36:22 +0200 Subject: Fixed win32 troubles with f.readsome() --- kernel/yosys.cc | 16 ++++++++++++++++ kernel/yosys.h | 1 + 2 files changed, 17 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 921f2b383..a40ad4372 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -166,6 +166,22 @@ bool patmatch(const char *pattern, const char *string) return false; } +int readsome(std::istream &f, char *s, int n) +{ + int rc = f.readsome(s, n); + + // win32 sometimes returns 0 on a non-empty stream.. + if (rc == 0) { + int c = f.get(); + if (c != EOF) { + *s = c; + rc = 1; + } + } + + return rc; +} + int GetSize(RTLIL::Wire *wire) { return wire->width; diff --git a/kernel/yosys.h b/kernel/yosys.h index 919e3bb98..d38e60ceb 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -86,6 +86,7 @@ std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)) std::string vstringf(const char *fmt, va_list ap); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); +int readsome(std::istream &f, char *s, int n); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3 From 0dc249ccd78fa7e3366a89cf46f209ff5ce09e26 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 11 Oct 2014 11:59:35 +0200 Subject: Shrinked the copyright banner by 1 character --- kernel/driver.cc | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 8a0939043..8117a61c5 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -203,25 +203,25 @@ int main(int argc, char **argv) if (print_banner) { log("\n"); - log(" /-----------------------------------------------------------------------------\\\n"); - log(" | |\n"); - log(" | yosys -- Yosys Open SYnthesis Suite |\n"); - log(" | |\n"); - log(" | Copyright (C) 2012 Clifford Wolf |\n"); - log(" | |\n"); - log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); - log(" | purpose with or without fee is hereby granted, provided that the above |\n"); - log(" | copyright notice and this permission notice appear in all copies. |\n"); - log(" | |\n"); - log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); - log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); - log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); - log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); - log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); - log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); - log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); - log(" | |\n"); - log(" \\-----------------------------------------------------------------------------/\n"); + log(" /----------------------------------------------------------------------------\\\n"); + log(" | |\n"); + log(" | yosys -- Yosys Open SYnthesis Suite |\n"); + log(" | |\n"); + log(" | Copyright (C) 2012 Clifford Wolf |\n"); + log(" | |\n"); + log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); + log(" | purpose with or without fee is hereby granted, provided that the above |\n"); + log(" | copyright notice and this permission notice appear in all copies. |\n"); + log(" | |\n"); + log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); + log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); + log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); + log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); + log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); + log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); + log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); + log(" | |\n"); + log(" \\----------------------------------------------------------------------------/\n"); log("\n"); log(" %s\n", yosys_version_str); log("\n"); -- cgit v1.2.3 From b1596bc0e7e5269fd610508f608f65f3aa696bd9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Oct 2014 10:57:15 +0200 Subject: Added run_command() api to replace system() and popen() --- kernel/register.cc | 2 +- kernel/yosys.cc | 25 +++++++++++++++++++++++++ kernel/yosys.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 9452eb355..33c129d83 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -159,7 +159,7 @@ void Pass::call(RTLIL::Design *design, std::string command) cmd_buf.back() == '\r' || cmd_buf.back() == '\n')) cmd_buf.resize(cmd_buf.size()-1); log_header("Shell command: %s\n", cmd_buf.c_str()); - int retCode = system(cmd_buf.c_str()); + int retCode = run_command(cmd_buf); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); return; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index a40ad4372..50da13ae7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -182,6 +182,31 @@ int readsome(std::istream &f, char *s, int n) return rc; } +int run_command(const std::string &command, std::function process_line) +{ + if (!process_line) + return system(command.c_str()); + + FILE *f = popen(command.c_str(), "r"); + if (f == nullptr) + return -1; + + std::string line; + char logbuf[128]; + while (fgets(logbuf, 128, f) != NULL) { + line += logbuf; + if (!line.empty() && line.back() == '\n') + process_line(line), line.clear(); + } + if (!line.empty()) + process_line(line); + + int ret = pclose(f); + if (ret < 0) + return -1; + return WEXITSTATUS(ret); +} + int GetSize(RTLIL::Wire *wire) { return wire->width; diff --git a/kernel/yosys.h b/kernel/yosys.h index d38e60ceb..fcf60f9f1 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -87,6 +87,7 @@ std::string vstringf(const char *fmt, va_list ap); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); int readsome(std::istream &f, char *s, int n); +int run_command(const std::string &command, std::function process_line = std::function()); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3 From 0b9282a779867459fe5babfff300795c343c46ea Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Oct 2014 12:11:57 +0200 Subject: Added make_temp_{file,dir}() and remove_directory() APIs --- kernel/yosys.cc | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/yosys.h | 3 ++ 2 files changed, 93 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 50da13ae7..4af3ff9c0 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -34,6 +34,7 @@ #include #include +#include #include YOSYS_NAMESPACE_BEGIN @@ -204,7 +205,96 @@ int run_command(const std::string &command, std::function> 17, x ^= x << 5; + template_str[pos+i] = y[x % y.size()]; + } + if (access(template_str.c_str(), F_OK) != 0) + break; + } +#else + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); + + int suffixlen = GetSize(template_str) - pos - 6; + + char *p = strdup(template_str.c_str()); + close(mkstemps(p, suffixlen)); + template_str = p; + free(p); +#endif + + return template_str; +} + +std::string make_temp_dir(std::string template_str) +{ +#ifdef _WIN32 + template_str = make_temp_file(template_str); + mkdir(template_str.c_str()); + return template_str; +#else + size_t pos = template_str.rfind("XXXXXX"); + log_assert(pos != std::string::npos); + + int suffixlen = GetSize(template_str) - pos - 6; + log_assert(suffixlen == 0); + + char *p = strdup(template_str.c_str()); + mkdtemp(p, suffixlen); + template_str = p; + free(p); + + return template_str; +#endif +} + +void remove_directory(std::string dirname) +{ +#ifdef _WIN32 + run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str())); +#else + struct stat stbuf; + struct dirent **namelist; + int n = scandir(dirname.c_str(), &namelist, nullptr, alphasort); + log_assert(n >= 0); + for (int i = 0; i < n; i++) { + if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { + buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); + if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { + log("Removing `%s'.\n", buffer.c_str()); + remove(buffer.c_str()); + } else + remove_directory(buffer); + } + free(namelist[i]); + } + free(namelist); + log("Removing `%s'.\n", dirname.c_str()); + rmdir(dirname.c_str()); +#endif } int GetSize(RTLIL::Wire *wire) diff --git a/kernel/yosys.h b/kernel/yosys.h index fcf60f9f1..e579e90d9 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -88,6 +88,9 @@ std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); int readsome(std::istream &f, char *s, int n); int run_command(const std::string &command, std::function process_line = std::function()); +std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); +std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); +void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); -- cgit v1.2.3 From 1a7684be24ba5d776c4f1f4c0889e1200c41d7b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Oct 2014 12:18:38 +0200 Subject: Various small fixes for non-win32 builds --- kernel/yosys.cc | 10 +++++++--- kernel/yosys.h | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 4af3ff9c0..fa14c5d9a 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -30,6 +30,11 @@ #ifdef _WIN32 # include +#elif defined(__APPLE__) +# include +#else +# include +# include #endif #include @@ -263,7 +268,7 @@ std::string make_temp_dir(std::string template_str) log_assert(suffixlen == 0); char *p = strdup(template_str.c_str()); - mkdtemp(p, suffixlen); + mkdtemp(p); template_str = p; free(p); @@ -282,7 +287,7 @@ void remove_directory(std::string dirname) log_assert(n >= 0); for (int i = 0; i < n; i++) { if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { - buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); + std::string buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { log("Removing `%s'.\n", buffer.c_str()); remove(buffer.c_str()); @@ -455,7 +460,6 @@ std::string proc_self_dirname() return std::string(path, buflen); } #elif defined(__APPLE__) -#include std::string proc_self_dirname() { char *path = NULL; diff --git a/kernel/yosys.h b/kernel/yosys.h index e579e90d9..5a37dd3c5 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -58,6 +58,10 @@ #include #include +#ifdef YOSYS_ENABLE_TCL +# include +#endif + #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } #define YOSYS_NAMESPACE_BEGIN namespace Yosys { @@ -107,7 +111,6 @@ void yosys_setup(); void yosys_shutdown(); #ifdef YOSYS_ENABLE_TCL -#include Tcl_Interp *yosys_get_tcl_interp(); #endif -- cgit v1.2.3 From 0913e968f59aed413dcb9bc5e392a554e2711ad7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Oct 2014 14:48:19 +0200 Subject: More win32/abc fixes --- kernel/yosys.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index fa14c5d9a..e50bfcbe6 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -473,12 +473,14 @@ std::string proc_self_dirname() #elif defined(_WIN32) std::string proc_self_dirname() { - char path[MAX_PATH+1]; - if (!GetModuleFileName(0, path, MAX_PATH+1)) + char longpath[MAX_PATH+1], shortpath[MAX_PATH+1]; + if (!GetModuleFileName(0, longpath, MAX_PATH+1)) log_error("GetModuleFileName() failed.\n"); - for (int i = strlen(path)-1; i >= 0 && path[i] != '/' && path[i] != '\\' ; i--) - path[i] = 0; - return std::string(path); + if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) + log_error("GetShortPathName() failed.\n"); + for (int i = strlen(shortpath)-1; i >= 0 && shortpath[i] != '/' && shortpath[i] != '\\' ; i--) + shortpath[i] = 0; + return std::string(shortpath); } #elif defined(EMSCRIPTEN) std::string proc_self_dirname() -- cgit v1.2.3 From 0352dbfd65072f42824852b2f5b925e7d9865a90 Mon Sep 17 00:00:00 2001 From: William Speirs Date: Tue, 14 Oct 2014 17:07:30 -0400 Subject: Fixed log so it will compile under Visual Studio - Included an implementation of gettimeofday --- kernel/log.cc | 25 ++++++++++++++++++++++++- kernel/log.h | 22 +++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 87a75410d..4585e7eff 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -21,7 +21,10 @@ #include "libs/sha1/sha1.h" #include "backends/ilang/ilang_backend.h" -#include +#ifndef _WIN32 + #include +#endif + #include #include #include @@ -48,6 +51,26 @@ static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; static int log_newline_count = 0; +#ifdef _WIN32 +// this will get time information and return it in timeval, simulating gettimeofday() +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + LARGE_INTEGER counter; + LARGE_INTEGER freq; + + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&counter); + + counter.QuadPart *= 1000000; + counter.QuadPart /= freq.QuadPart; + + tv->tv_sec = counter.QuadPart / 1000000; + tv->tv_usec = counter.QuadPart % 1000000; + + return 0; +} +#endif + void logv(const char *format, va_list ap) { while (format[0] == '\n' && format[1] != 0) { diff --git a/kernel/log.h b/kernel/log.h index b4182b5f3..d4b21110c 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -23,10 +23,10 @@ #define LOG_H #include -#include #ifndef _WIN32 -# include + #include + #include #endif // from libs/sha1/sha1.h @@ -51,12 +51,20 @@ extern int log_verbose_level; void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); -void logv_error(const char *format, va_list ap) __attribute__ ((noreturn)); -void log(const char *format, ...) __attribute__ ((format (printf, 1, 2))); -void log_header(const char *format, ...) __attribute__ ((format (printf, 1, 2))); -void log_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))) __attribute__ ((noreturn)); -void log_cmd_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))) __attribute__ ((noreturn)); +#if !defined(__GNUC__) && !defined(__clang__) + void logv_error(const char *format, va_list ap); + void log(const char *format, ...); + void log_header(const char *format, ...); + void log_error(const char *format, ...); + void log_cmd_error(const char *format, ...); +#else + void logv_error(const char *format, va_list ap) __attribute__((noreturn)); + void log(const char *format, ...) __attribute__((format(printf, 1, 2))); + void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); + void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); + void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); +#endif void log_spacer(); void log_push(); -- cgit v1.2.3 From 069521e2d5d5568739c7e8d7db31859bb88965a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 00:56:04 +0200 Subject: Define empty __attribute__ macro for non-gcc, non-clang compilers --- kernel/log.h | 18 +++++------------- kernel/yosys.h | 4 ++++ 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index d4b21110c..e0c8f7ba0 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -52,19 +52,11 @@ extern int log_verbose_level; void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); -#if !defined(__GNUC__) && !defined(__clang__) - void logv_error(const char *format, va_list ap); - void log(const char *format, ...); - void log_header(const char *format, ...); - void log_error(const char *format, ...); - void log_cmd_error(const char *format, ...); -#else - void logv_error(const char *format, va_list ap) __attribute__((noreturn)); - void log(const char *format, ...) __attribute__((format(printf, 1, 2))); - void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); - void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); - void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); -#endif +void logv_error(const char *format, va_list ap) __attribute__((noreturn)); +void log(const char *format, ...) __attribute__((format(printf, 1, 2))); +void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); +void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); +void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); void log_spacer(); void log_push(); diff --git a/kernel/yosys.h b/kernel/yosys.h index 5a37dd3c5..37d3e52f4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -77,6 +77,10 @@ # define FINAL #endif +#if !defined(__GNUC__) && !defined(__clang__) +# define __attribute__(...) +#endif + YOSYS_NAMESPACE_BEGIN namespace RTLIL { -- cgit v1.2.3 From 9cb230379901da89649676d4a2752bde59c09f59 Mon Sep 17 00:00:00 2001 From: William Speirs Date: Tue, 14 Oct 2014 17:10:08 -0400 Subject: Made iterators extend std::iterator and added == operator --- kernel/rtlil.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8df0bfe19..5629c8652 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -920,23 +920,25 @@ struct RTLIL::SigBit } }; -struct RTLIL::SigSpecIterator +struct RTLIL::SigSpecIterator : public std::iterator { RTLIL::SigSpec *sig_p; int index; inline RTLIL::SigBit &operator*() const; inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; } + inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } inline void operator++() { index++; } }; -struct RTLIL::SigSpecConstIterator +struct RTLIL::SigSpecConstIterator : public std::iterator { const RTLIL::SigSpec *sig_p; int index; inline const RTLIL::SigBit &operator*() const; inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; } + inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } inline void operator++() { index++; } }; -- cgit v1.2.3 From cf85aab62f961c905e4691fde59af774053d3d58 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 01:05:08 +0200 Subject: A few indent fixes --- kernel/log.cc | 2 +- kernel/log.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 4585e7eff..2cae6a636 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -22,7 +22,7 @@ #include "backends/ilang/ilang_backend.h" #ifndef _WIN32 - #include +# include #endif #include diff --git a/kernel/log.h b/kernel/log.h index e0c8f7ba0..904ba4759 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -25,8 +25,8 @@ #include #ifndef _WIN32 - #include - #include +# include +# include #endif // from libs/sha1/sha1.h -- cgit v1.2.3 From c3e9922b5d871269bf4ee33da24318d3b5199ac3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 01:12:53 +0200 Subject: Replaced readsome() with read() and gcount() --- kernel/yosys.cc | 16 ---------------- kernel/yosys.h | 1 - 2 files changed, 17 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index e50bfcbe6..ba3049c53 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -172,22 +172,6 @@ bool patmatch(const char *pattern, const char *string) return false; } -int readsome(std::istream &f, char *s, int n) -{ - int rc = f.readsome(s, n); - - // win32 sometimes returns 0 on a non-empty stream.. - if (rc == 0) { - int c = f.get(); - if (c != EOF) { - *s = c; - rc = 1; - } - } - - return rc; -} - int run_command(const std::string &command, std::function process_line) { if (!process_line) diff --git a/kernel/yosys.h b/kernel/yosys.h index 37d3e52f4..83230cbfb 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -94,7 +94,6 @@ std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)) std::string vstringf(const char *fmt, va_list ap); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); -int readsome(std::istream &f, char *s, int n); int run_command(const std::string &command, std::function process_line = std::function()); std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); -- cgit v1.2.3 From 1fc6208ec05af672c7c6b7973b0eba1295bca5f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 01:18:31 +0200 Subject: Check for _YOSYS_ in yosys.h --- kernel/yosys.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.h b/kernel/yosys.h index 83230cbfb..239146d77 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -58,6 +58,12 @@ #include #include +#ifndef _YOSYS_ +# error It looks like you are trying to build Yosys with the config defines set. \ + When building Yosys with a custom make system, make sure you set all the \ + defines the Yosys Makefile would set for your build configuration. +#endif + #ifdef YOSYS_ENABLE_TCL # include #endif -- cgit v1.2.3 From 3445a933a5f2c23b697b96948f44fb1b2012dbdb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 02:43:50 +0200 Subject: Fixed MXE build --- kernel/log.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 2cae6a636..19eb38c73 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -21,7 +21,7 @@ #include "libs/sha1/sha1.h" #include "backends/ilang/ilang_backend.h" -#ifndef _WIN32 +#if !defined(_WIN32) || defined(__MINGW32__) # include #endif @@ -51,7 +51,7 @@ static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; static int log_newline_count = 0; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW32__) // this will get time information and return it in timeval, simulating gettimeofday() int gettimeofday(struct timeval *tv, struct timezone *tz) { -- cgit v1.2.3 From 2355ddf75d094e9272184ddd9ea916be49102b1b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 02:48:51 +0200 Subject: Fixed gcc warning --- kernel/yosys.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ba3049c53..1ce7b5207 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -252,7 +252,8 @@ std::string make_temp_dir(std::string template_str) log_assert(suffixlen == 0); char *p = strdup(template_str.c_str()); - mkdtemp(p); + p = mkdtemp(p); + log_assert(p != NULL); template_str = p; free(p); -- cgit v1.2.3 From 82ed814fa1d0e8e58392210976069daa4faa3f4a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 15 Oct 2014 20:36:32 +0200 Subject: Replaced log_assert() do { ... } while (0) hack with a static inline function --- kernel/log.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 904ba4759..421c50d3f 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -74,8 +74,12 @@ template static inline const char *log_id(T *obj) { void log_cell(RTLIL::Cell *cell, std::string indent = ""); +static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { + if (!cond) log_error("Assert `%s' failed in %s:%d.\n", expr, file, line); +} + #define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) -#define log_assert(_assert_expr_) do { if (_assert_expr_) break; YOSYS_NAMESPACE_PREFIX log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) +#define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) #define log_ping() YOSYS_NAMESPACE_PREFIX log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) -- cgit v1.2.3 From 3be5fa053f61a29039ed99876d3e89406c99cb7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 16 Oct 2014 00:54:14 +0200 Subject: Fixed RTLIL::SigSpec::parse() for out-of-range bit- and part-selects --- kernel/rtlil.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 28f0dfdc5..5a94008d8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2980,7 +2980,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()); @@ -2989,6 +2992,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 -- cgit v1.2.3 From 34caeeb4f3e21d8da3b75682e48ab85c27021b82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 17 Oct 2014 06:02:38 +0200 Subject: Fixed a few VS warnings --- kernel/log.h | 2 +- kernel/rtlil.h | 2 +- kernel/satgen.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 421c50d3f..10250cb9d 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -181,7 +181,7 @@ struct PerformanceTimer } float sec() const { - return total_ns * 1e-9; + return total_ns * 1e-9f; } #else static int64_t query() { return 0; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 5629c8652..8a4d348be 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -898,7 +898,7 @@ struct RTLIL::SigBit SigBit() : wire(NULL), data(RTLIL::State::S0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } - SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } + SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } SigBit(const RTLIL::SigSpec &sig); diff --git a/kernel/satgen.h b/kernel/satgen.h index d556f4f32..2c69663c4 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -107,7 +107,7 @@ struct SatGen { log_assert(timestep != 0); std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - return imported_signals[pf].count(bit); + return imported_signals[pf].count(bit) != 0; } void getAsserts(RTLIL::SigSpec &sig_a, RTLIL::SigSpec &sig_en, int timestep = -1) -- cgit v1.2.3 From 31267a1ae8d670c4b8749fc55b07c01d9285a488 Mon Sep 17 00:00:00 2001 From: William Speirs Date: Thu, 16 Oct 2014 12:06:54 -0400 Subject: Header changes so it will compile on VS --- kernel/driver.cc | 7 +++++-- kernel/yosys.cc | 10 +++++++--- kernel/yosys.h | 29 ++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 8117a61c5..7f2cdb325 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -27,11 +27,14 @@ #include #include -#include -#include #include #include +#ifndef _WIN32 +# include +#endif + + USING_YOSYS_NAMESPACE int main(int argc, char **argv) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 1ce7b5207..9c1cb58f3 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -33,17 +33,21 @@ #elif defined(__APPLE__) # include #else +# include +# include # include # include #endif -#include #include -#include #include YOSYS_NAMESPACE_BEGIN +#ifdef _WIN32 +const char *yosys_version_str = "Windows"; +#endif + int autoidx = 1; RTLIL::Design *yosys_design = NULL; @@ -325,10 +329,10 @@ void yosys_shutdown() #ifdef YOSYS_ENABLE_PLUGINS for (auto &it : loaded_plugins) dlclose(it.second); -#endif loaded_plugins.clear(); loaded_plugin_aliases.clear(); +#endif } RTLIL::IdString new_id(std::string file, int line, std::string func) diff --git a/kernel/yosys.h b/kernel/yosys.h index 239146d77..e4465edf7 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -68,6 +68,30 @@ # include #endif +// a few platform specific things +#ifdef _WIN32 +# define NOMINMAX +# include +# include // takes care of a number of typedefs +# include +# include + +// these are always a bit dangerous :-) +# define strtok_r strtok_s +# define strdup _strdup +# define snprintf _snprintf +# define access _access +# define getcwd _getcwd +# define mkdir _mkdir +# define popen _popen +# define pclose _pclose + +# define PATH_MAX MAX_PATH +# define F_OK 00 +# define X_OK 00 // note this is NOT correct as there is no execute flag in Windows +#endif + + #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } #define YOSYS_NAMESPACE_BEGIN namespace Yosys { @@ -85,6 +109,9 @@ #if !defined(__GNUC__) && !defined(__clang__) # define __attribute__(...) +# define _NORETURN_ __declspec(noreturn) +#else +# define _NORETURN_ #endif YOSYS_NAMESPACE_BEGIN @@ -96,7 +123,7 @@ namespace RTLIL { struct Cell; } -std::string stringf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +std::string stringf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); std::string vstringf(const char *fmt, va_list ap); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); -- cgit v1.2.3 From 4df902637a3b486ab4836ddc2bde7889c6dccfeb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 17 Oct 2014 12:04:40 +0200 Subject: Various MXE build fixes --- kernel/driver.cc | 2 +- kernel/yosys.cc | 21 +++++++++++++++++---- kernel/yosys.h | 11 +++++------ 3 files changed, 23 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 7f2cdb325..7a3cd1a1a 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -30,7 +30,7 @@ #include #include -#ifndef _WIN32 +#if !defined(_WIN32) || defined(__MINGW32__) # include #endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 9c1cb58f3..ed90a6f33 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -30,6 +30,7 @@ #ifdef _WIN32 # include +# include #elif defined(__APPLE__) # include #else @@ -44,7 +45,7 @@ YOSYS_NAMESPACE_BEGIN -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW32__) const char *yosys_version_str = "Windows"; #endif @@ -224,7 +225,7 @@ std::string make_temp_file(std::string template_str) x ^= x << 13, x ^= x >> 17, x ^= x << 5; template_str[pos+i] = y[x % y.size()]; } - if (access(template_str.c_str(), F_OK) != 0) + if (_access(template_str.c_str(), 0) != 0) break; } #else @@ -265,6 +266,18 @@ std::string make_temp_dir(std::string template_str) #endif } +#ifdef _WIN32 +bool check_file_exists(std::string filename, bool) +{ + return _access(filename.c_str(), 0); +} +#else +bool check_file_exists(std::string filename, bool is_exec) +{ + return access(filename.c_str(), is_exec ? X_OK : F_OK); +} +#endif + void remove_directory(std::string dirname) { #ifdef _WIN32 @@ -484,10 +497,10 @@ std::string proc_share_dirname() { std::string proc_self_path = proc_self_dirname(); std::string proc_share_path = proc_self_path + "share/"; - if (access(proc_share_path.c_str(), X_OK) == 0) + if (check_file_exists(proc_share_path, true) == 0) return proc_share_path; proc_share_path = proc_self_path + "../share/yosys/"; - if (access(proc_share_path.c_str(), X_OK) == 0) + if (check_file_exists(proc_share_path, true) == 0) return proc_share_path; log_error("proc_share_dirname: unable to determine share/ directory!\n"); } diff --git a/kernel/yosys.h b/kernel/yosys.h index e4465edf7..562cec121 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -70,8 +70,10 @@ // a few platform specific things #ifdef _WIN32 -# define NOMINMAX -# include +# ifndef NOMINMAX +# define NOMINMAX 1 +# endif +# include # include // takes care of a number of typedefs # include # include @@ -80,15 +82,11 @@ # define strtok_r strtok_s # define strdup _strdup # define snprintf _snprintf -# define access _access # define getcwd _getcwd # define mkdir _mkdir # define popen _popen # define pclose _pclose - # define PATH_MAX MAX_PATH -# define F_OK 00 -# define X_OK 00 // note this is NOT correct as there is no execute flag in Windows #endif @@ -130,6 +128,7 @@ bool patmatch(const char *pattern, const char *string); int run_command(const std::string &command, std::function process_line = std::function()); std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); +bool check_file(std::string filename, bool is_exec = false); void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } -- cgit v1.2.3 From 468ae923748a01b2763bafa3cf5fba883fe06479 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 17 Oct 2014 14:01:47 +0200 Subject: Various win32 / vs build fixes --- kernel/log.h | 4 ++-- kernel/rtlil.cc | 2 +- kernel/yosys.cc | 8 ++++---- kernel/yosys.h | 17 +++++++++-------- 4 files changed, 16 insertions(+), 15 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 10250cb9d..81d01ace7 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -55,8 +55,8 @@ void logv_header(const char *format, va_list ap); void logv_error(const char *format, va_list ap) __attribute__((noreturn)); void log(const char *format, ...) __attribute__((format(printf, 1, 2))); void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); -void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); -void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); +_NORETURN_ void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); +_NORETURN_ void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); void log_spacer(); void log_push(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 5a94008d8..36443c5ac 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2204,7 +2204,7 @@ void RTLIL::SigSpec::unpack() const that->hash_ = 0; } -#define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0) +#define DJB2(_hash, _value) (_hash) = (((_hash) << 5) + (_hash)) + (_value) void RTLIL::SigSpec::hash() const { diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ed90a6f33..26665e5b2 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -269,12 +269,12 @@ std::string make_temp_dir(std::string template_str) #ifdef _WIN32 bool check_file_exists(std::string filename, bool) { - return _access(filename.c_str(), 0); + return _access(filename.c_str(), 0) == 0; } #else bool check_file_exists(std::string filename, bool is_exec) { - return access(filename.c_str(), is_exec ? X_OK : F_OK); + return access(filename.c_str(), is_exec ? X_OK : F_OK) == 0; } #endif @@ -497,10 +497,10 @@ std::string proc_share_dirname() { std::string proc_self_path = proc_self_dirname(); std::string proc_share_path = proc_self_path + "share/"; - if (check_file_exists(proc_share_path, true) == 0) + if (check_file_exists(proc_share_path, true)) return proc_share_path; proc_share_path = proc_self_path + "../share/yosys/"; - if (check_file_exists(proc_share_path, true) == 0) + if (check_file_exists(proc_share_path, true)) return proc_share_path; log_error("proc_share_dirname: unable to determine share/ directory!\n"); } diff --git a/kernel/yosys.h b/kernel/yosys.h index 562cec121..a0a42be9b 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -56,6 +56,7 @@ #include #include #include +#include #include #ifndef _YOSYS_ @@ -68,17 +69,18 @@ # include #endif -// a few platform specific things #ifdef _WIN32 -# ifndef NOMINMAX -# define NOMINMAX 1 -# endif +# undef NOMINMAX +# define NOMINMAX 1 +# undef YY_NO_UNISTD_H +# define YY_NO_UNISTD_H 1 +# undef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS 1 + # include -# include // takes care of a number of typedefs # include # include -// these are always a bit dangerous :-) # define strtok_r strtok_s # define strdup _strdup # define snprintf _snprintf @@ -89,7 +91,6 @@ # define PATH_MAX MAX_PATH #endif - #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } #define YOSYS_NAMESPACE_BEGIN namespace Yosys { @@ -128,7 +129,7 @@ bool patmatch(const char *pattern, const char *string); int run_command(const std::string &command, std::function process_line = std::function()); std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX"); -bool check_file(std::string filename, bool is_exec = false); +bool check_file_exists(std::string filename, bool is_exec = false); void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } -- cgit v1.2.3 From b3a6f8f53019d1984d4e319db459b11da0663aa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 17 Oct 2014 15:51:33 +0200 Subject: More win32 (mxe and vs) build fixes --- kernel/driver.cc | 30 ++++++++++++++++++++++++++++++ kernel/yosys.cc | 36 ++++++++++++++++++++++++++++-------- kernel/yosys.h | 11 +++++++---- 3 files changed, 65 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 7a3cd1a1a..5e69cced3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -32,6 +32,36 @@ #if !defined(_WIN32) || defined(__MINGW32__) # include +#else +char *optarg; +int optind = 1, optcur = 1; +int getopt(int argc, char **argv, const char *optstring) +{ + if (optind >= argc || argv[optind][0] != '-') + return -1; + + bool takes_arg = false; + int opt = argv[optind][optcur]; + for (int i = 0; optstring[i]; i++) + if (opt == optstring[i] && optstring[i + 1] == ':') + takes_arg = true; + + if (!takes_arg) { + if (argv[optind][++optcur] == 0) + optind++, optcur = 1; + return opt; + } + + if (argv[optind][++optcur]) { + optarg = argv[optind++] + optcur; + optcur = 1; + return opt; + } + + optarg = argv[++optind]; + optind++, optcur = 1; + return opt; +} #endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 26665e5b2..7d1d273cb 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -46,7 +46,7 @@ YOSYS_NAMESPACE_BEGIN #if defined(_WIN32) && !defined(__MINGW32__) -const char *yosys_version_str = "Windows"; +const char *yosys_version_str = "Yosys for Windows (Version Information Unavailable)"; #endif int autoidx = 1; @@ -210,9 +210,19 @@ std::string make_temp_file(std::string template_str) { #ifdef _WIN32 if (template_str.rfind("/tmp/", 0) == 0) { - char path[MAX_PATH+1]; - GetTempPath(MAX_PATH+1, path); - template_str = stringf("%s\\%s", path, template_str.c_str() + 5); +# ifdef __MINGW32__ + char longpath[MAX_PATH + 1]; + char shortpath[MAX_PATH + 1]; +# else + WCHAR longpath[MAX_PATH + 1]; + TCHAR shortpath[MAX_PATH + 1]; +# endif + if (!GetTempPath(MAX_PATH+1, longpath)) + log_error("GetTempPath() failed.\n"); + if (!GetShortPathName(longpath, shortpath, MAX_PATH + 1)) + log_error("GetShortPathName() failed.\n"); + log_assert(sizeof(TCHAR) == sizeof(char)); + template_str = stringf("%s\\%s", shortpath, template_str.c_str() + 5); } size_t pos = template_str.rfind("XXXXXX"); @@ -475,14 +485,24 @@ std::string proc_self_dirname() #elif defined(_WIN32) std::string proc_self_dirname() { - char longpath[MAX_PATH+1], shortpath[MAX_PATH+1]; + int i = 0; +# ifdef __MINGW32__ + char longpath[MAX_PATH + 1]; + char shortpath[MAX_PATH + 1]; +# else + WCHAR longpath[MAX_PATH + 1]; + TCHAR shortpath[MAX_PATH + 1]; +# endif if (!GetModuleFileName(0, longpath, MAX_PATH+1)) log_error("GetModuleFileName() failed.\n"); if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) log_error("GetShortPathName() failed.\n"); - for (int i = strlen(shortpath)-1; i >= 0 && shortpath[i] != '/' && shortpath[i] != '\\' ; i--) - shortpath[i] = 0; - return std::string(shortpath); + while (shortpath[i] != 0) + i++; + while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\') + shortpath[--i] = 0; + log_assert(sizeof(TCHAR) == sizeof(char)); + return std::string((char*)shortpath); } #elif defined(EMSCRIPTEN) std::string proc_self_dirname() diff --git a/kernel/yosys.h b/kernel/yosys.h index a0a42be9b..b9182c1df 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -60,9 +60,9 @@ #include #ifndef _YOSYS_ -# error It looks like you are trying to build Yosys with the config defines set. \ +# error It looks like you are trying to build Yosys without the config defines set. \ When building Yosys with a custom make system, make sure you set all the \ - defines the Yosys Makefile would set for your build configuration. + defines the Yosys Makefile would set for your build configuration. #endif #ifdef YOSYS_ENABLE_TCL @@ -74,8 +74,6 @@ # define NOMINMAX 1 # undef YY_NO_UNISTD_H # define YY_NO_UNISTD_H 1 -# undef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS 1 # include # include @@ -89,6 +87,11 @@ # define popen _popen # define pclose _pclose # define PATH_MAX MAX_PATH + +# ifndef __MINGW32__ +# define isatty _isatty +# define fileno _fileno +# endif #endif #define PRIVATE_NAMESPACE_BEGIN namespace { -- cgit v1.2.3 From 84ffe04075bbddfd1b288295c07d036416923c3a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 18 Oct 2014 15:20:38 +0200 Subject: Fixed various VS warnings --- kernel/log.cc | 2 +- kernel/rtlil.cc | 4 ++-- kernel/yosys.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 19eb38c73..807f58bf6 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -64,7 +64,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) counter.QuadPart *= 1000000; counter.QuadPart /= freq.QuadPart; - tv->tv_sec = counter.QuadPart / 1000000; + tv->tv_sec = long(counter.QuadPart / 1000000); tv->tv_usec = counter.QuadPart % 1000000; return 0; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 36443c5ac..1a9eb4d14 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1778,7 +1778,7 @@ const std::map &RTLIL::Cell::connections() cons bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const { - return parameters.count(paramname); + return parameters.count(paramname) != 0; } void RTLIL::Cell::unsetParam(RTLIL::IdString paramname) @@ -3041,7 +3041,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"); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 7d1d273cb..f314f546a 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -231,7 +231,7 @@ std::string make_temp_file(std::string template_str) while (1) { for (int i = 0; i < 6; i++) { static std::string y = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - static uint32_t x = 314159265 ^ time(NULL); + static uint32_t x = 314159265 ^ uint32_t(time(NULL)); x ^= x << 13, x ^= x >> 17, x ^= x << 5; template_str[pos+i] = y[x % y.size()]; } -- cgit v1.2.3 From 6bcb4f1f45d1310718d356b7e439bd87fc7d045a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 18 Oct 2014 16:51:50 +0100 Subject: Fixed shell prompt and proc_self_dirname() for win32 --- kernel/yosys.cc | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f314f546a..2303673c5 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -221,8 +221,10 @@ std::string make_temp_file(std::string template_str) log_error("GetTempPath() failed.\n"); if (!GetShortPathName(longpath, shortpath, MAX_PATH + 1)) log_error("GetShortPathName() failed.\n"); - log_assert(sizeof(TCHAR) == sizeof(char)); - template_str = stringf("%s\\%s", shortpath, template_str.c_str() + 5); + std::string path; + for (int i = 0; shortpath[i]; i++) + path += char(shortpath[i]); + template_str = stringf("%s\\%s", path.c_str(), template_str.c_str() + 5); } size_t pos = template_str.rfind("XXXXXX"); @@ -501,8 +503,10 @@ std::string proc_self_dirname() i++; while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\') shortpath[--i] = 0; - log_assert(sizeof(TCHAR) == sizeof(char)); - return std::string((char*)shortpath); + std::string path; + for (i = 0; shortpath[i]; i++) + path += char(shortpath[i]); + return path; } #elif defined(EMSCRIPTEN) std::string proc_self_dirname() @@ -516,12 +520,21 @@ std::string proc_self_dirname() std::string proc_share_dirname() { std::string proc_self_path = proc_self_dirname(); +#ifdef _WIN32 + std::string proc_share_path = proc_self_path + "share\\"; + if (check_file_exists(proc_share_path, true)) + return proc_share_path; + proc_share_path = proc_self_path + "..\\share\\"; + if (check_file_exists(proc_share_path, true)) + return proc_share_path; +#else std::string proc_share_path = proc_self_path + "share/"; if (check_file_exists(proc_share_path, true)) return proc_share_path; proc_share_path = proc_self_path + "../share/yosys/"; if (check_file_exists(proc_share_path, true)) return proc_share_path; +#endif log_error("proc_share_dirname: unable to determine share/ directory!\n"); } @@ -789,11 +802,16 @@ void shell(RTLIL::Design *design) char *command = NULL; #ifdef YOSYS_ENABLE_READLINE while ((command = readline(create_prompt(design, recursion_counter))) != NULL) + { #else char command_buffer[4096]; - while ((command = fgets(command_buffer, 4096, stdin)) != NULL) -#endif + while (1) { + fputs(create_prompt(design, recursion_counter), stdout); + fflush(stdout); + if ((command = fgets(command_buffer, 4096, stdin)) == NULL) + break; +#endif if (command[strspn(command, " \t\r\n")] == 0) continue; #ifdef YOSYS_ENABLE_READLINE -- cgit v1.2.3 From 0471d158d955804c011338c5c664dfa7a38aed1f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 18 Oct 2014 19:00:52 +0200 Subject: Various improvements to version reporting on win32 --- kernel/yosys.cc | 4 ---- 1 file changed, 4 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 2303673c5..e26eaf4be 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -45,10 +45,6 @@ YOSYS_NAMESPACE_BEGIN -#if defined(_WIN32) && !defined(__MINGW32__) -const char *yosys_version_str = "Yosys for Windows (Version Information Unavailable)"; -#endif - int autoidx = 1; RTLIL::Design *yosys_design = NULL; -- cgit v1.2.3 From 6c1c1e9a07c66b37f65835ed03370ac062616b7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 18 Oct 2014 19:26:03 +0200 Subject: Improved new_id() for win32 --- kernel/yosys.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index e26eaf4be..42cfcb5bb 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -358,11 +358,19 @@ void yosys_shutdown() RTLIL::IdString new_id(std::string file, int line, std::string func) { - std::string str = "$auto$"; +#ifdef _WIN32 + size_t pos = file.find_last_of("/\\"); +#else size_t pos = file.find_last_of('/'); - str += pos != std::string::npos ? file.substr(pos+1) : file; - str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); - return str; +#endif + if (pos != std::string::npos) + file = file.substr(pos+1); + + pos = func.find_last_of(':'); + if (pos != std::string::npos) + func = func.substr(pos+1); + + return stringf("$auto$%s:%d:%s$%d", file.c_str(), line, func.c_str(), autoidx++); } RTLIL::Design *yosys_get_design() -- cgit v1.2.3 From de8adb8ec538913b93662198cf12c0f2a3b72630 Mon Sep 17 00:00:00 2001 From: Parviz Palangpour Date: Sat, 18 Oct 2014 14:26:49 -0500 Subject: Builds on Mac 10.9.2 with LLVM 3.5. --- kernel/yosys.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index f314f546a..e9b113dd2 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -33,6 +33,9 @@ # include #elif defined(__APPLE__) # include +# include +# include +# include #else # include # include -- cgit v1.2.3 From c5eb5e56b8911bb520a987761739bbb9d9328380 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 23 Oct 2014 10:47:21 +0200 Subject: Re-introduced Yosys::readsome() helper function (f.read() + f.gcount() made problems with lines > 16kB) --- kernel/yosys.cc | 16 ++++++++++++++++ kernel/yosys.h | 1 + 2 files changed, 17 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ad0aa5a6d..d4365ee00 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -97,6 +97,22 @@ std::string vstringf(const char *fmt, va_list ap) return string; } +int readsome(std::istream &f, char *s, int n) +{ + int rc = f.readsome(s, n); + + // f.readsome() sometimes returns 0 on a non-empty stream.. + if (rc == 0) { + int c = f.get(); + if (c != EOF) { + *s = c; + rc = 1; + } + } + + return rc; +} + std::string next_token(std::string &text, const char *sep) { size_t pos_begin = text.find_first_not_of(sep); diff --git a/kernel/yosys.h b/kernel/yosys.h index b9182c1df..11f356adc 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -127,6 +127,7 @@ namespace RTLIL { std::string stringf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); std::string vstringf(const char *fmt, va_list ap); +int readsome(std::istream &f, char *s, int n); std::string next_token(std::string &text, const char *sep); bool patmatch(const char *pattern, const char *string); int run_command(const std::string &command, std::function process_line = std::function()); -- cgit v1.2.3 From 70b2efdb05f24eb7a9f3e2f456e5452fff94a15e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 26 Oct 2014 20:33:10 +0100 Subject: Added support for $readmemh/$readmemb --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1a9eb4d14..8cfc0c5f9 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2935,7 +2935,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); -- cgit v1.2.3 From 269e37e969562275f337362b5423e2801f9c5765 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 29 Oct 2014 09:05:17 +0100 Subject: Added support for empty lines to here documents --- kernel/register.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 33c129d83..2927a333e 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -333,8 +333,8 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r')) break; } - int indent = buffer.find_first_not_of(" \t\r\n"); - if (buffer.substr(indent, eot_marker.size()) == eot_marker) + size_t indent = buffer.find_first_not_of(" \t\r\n"); + if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker) break; last_here_document += buffer; } -- cgit v1.2.3 From a346c0bf2b0ed5278e0f86d4ef23a6a9d03eef40 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Nov 2014 09:39:55 +0100 Subject: Made "cover" a compile-time option (disabled by default) --- kernel/driver.cc | 2 +- kernel/log.cc | 2 +- kernel/log.h | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 5e69cced3..8164fef28 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -335,7 +335,7 @@ int main(int argc, char **argv) log("%s\n", out_count ? "" : " no commands executed"); } -#ifdef COVER_ACTIVE +#ifdef YOSYS_ENABLE_COVER if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) { char filename_buffer[4096]; diff --git a/kernel/log.cc b/kernel/log.cc index 807f58bf6..1a21e9fe6 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -274,7 +274,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent) // --------------------------------------------------- // This is the magic behind the code coverage counters // --------------------------------------------------- -#ifdef COVER_ACTIVE +#ifdef YOSYS_ENABLE_COVER std::map> extra_coverage_data; diff --git a/kernel/log.h b/kernel/log.h index 81d01ace7..a6f808922 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -87,8 +87,7 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi // This is the magic behind the code coverage counters // --------------------------------------------------- -#if defined(__linux__) && !defined(NDEBUG) -#define COVER_ACTIVE +#ifdef YOSYS_ENABLE_COVER #define cover(_id) do { \ static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ -- cgit v1.2.3 From 99cdfb31106cc399072f129d912fa8377d919e2e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Nov 2014 12:48:15 +0100 Subject: Fixed typo in "log_cmd_error_exception" --- kernel/log.cc | 2 +- kernel/log.h | 2 +- kernel/yosys.cc | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 1a21e9fe6..99e92e44d 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -194,7 +194,7 @@ void log_cmd_error(const char *format, ...) log("ERROR: "); logv(format, ap); log_flush(); - throw log_cmd_error_expection(); + throw log_cmd_error_exception(); } logv_error(format, ap); diff --git a/kernel/log.h b/kernel/log.h index a6f808922..707497a99 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -38,7 +38,7 @@ YOSYS_NAMESPACE_BEGIN #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) -struct log_cmd_error_expection { }; +struct log_cmd_error_exception { }; extern std::vector log_files; extern std::vector log_streams; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d4365ee00..6cc643152 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -668,9 +668,9 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi Pass::call(design, command); } } - catch (log_cmd_error_expection) { + catch (log_cmd_error_exception) { Frontend::current_script_file = backup_script_file; - throw log_cmd_error_expection(); + throw log_cmd_error_exception(); } Frontend::current_script_file = backup_script_file; @@ -852,7 +852,7 @@ void shell(RTLIL::Design *design) try { log_assert(design->selection_stack.size() == 1); Pass::call(design, command); - } catch (log_cmd_error_expection) { + } catch (log_cmd_error_exception) { while (design->selection_stack.size() > 1) design->selection_stack.pop_back(); log_reset_stack(); -- cgit v1.2.3 From 546e8b5fe7063caf0140d753d8c20614cbeae723 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Nov 2014 15:21:03 +0100 Subject: Improved TopoSort determinism --- kernel/rtlil.h | 2 +- kernel/utils.h | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8a4d348be..0bb1e4e84 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -216,7 +216,7 @@ namespace RTLIL // set has an influence on the algorithm. template struct compare_ptr_by_name { - bool operator()(const T *a, const T *b) { + bool operator()(const T *a, const T *b) const { return (a == nullptr || b == nullptr) ? (a < b) : (a->name < b->name); } }; diff --git a/kernel/utils.h b/kernel/utils.h index 1779a9afc..479effdc9 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -128,12 +128,12 @@ public: // A simple class for topological sorting // ------------------------------------------------ -template +template> struct TopoSort { bool analyze_loops, found_loops; - std::map> database; - std::set> loops; + std::map, C> database; + std::set> loops; std::vector sorted; TopoSort() @@ -145,7 +145,7 @@ struct TopoSort void node(T n) { if (database.count(n) == 0) - database[n] = std::set(); + database[n] = std::set(); } void edge(T left, T right) @@ -154,12 +154,12 @@ struct TopoSort database[right].insert(left); } - void sort_worker(const T &n, std::set &marked_cells, std::set &active_cells, std::vector &active_stack) + void sort_worker(const T &n, std::set &marked_cells, std::set &active_cells, std::vector &active_stack) { if (active_cells.count(n)) { found_loops = true; if (analyze_loops) { - std::set loop; + std::set loop; for (int i = GetSize(active_stack)-1; i >= 0; i--) { loop.insert(active_stack[i]); if (active_stack[i] == n) @@ -197,8 +197,8 @@ struct TopoSort sorted.clear(); found_loops = false; - std::set marked_cells; - std::set active_cells; + std::set marked_cells; + std::set active_cells; std::vector active_stack; for (auto &it : database) -- cgit v1.2.3 From 89be7bf52785c9a3058a0049481388ad44459174 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Nov 2014 20:58:08 +0100 Subject: Added "used" attribute to entries in yosys_cover_list http://www.reddit.com/r/yosys/comments/2kw479/fyi_clang_350_build_error/cltgwyc http://llvm.org/bugs/show_bug.cgi?id=19474 --- kernel/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 707497a99..93e8144a0 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -90,7 +90,7 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi #ifdef YOSYS_ENABLE_COVER #define cover(_id) do { \ - static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1), used)) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ __d.counter++; \ } while (0) -- cgit v1.2.3 From 003336c58dcc9bc96484d6e7a9f3033309a747df Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 8 Nov 2014 12:38:22 +0100 Subject: Use a cache for log_id() memory management --- kernel/log.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 99e92e44d..9f5f03b2f 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -44,6 +44,7 @@ bool log_cmd_error_throw = false; int log_verbose_level; std::vector header_count; +std::set log_id_cache; std::list string_buf; int string_buf_size = 0; @@ -214,6 +215,7 @@ void log_push() void log_pop() { header_count.pop_back(); + log_id_cache.clear(); string_buf.clear(); string_buf_size = 0; log_flush(); @@ -223,6 +225,7 @@ void log_reset_stack() { while (header_count.size() > 1) header_count.pop_back(); + log_id_cache.clear(); string_buf.clear(); string_buf_size = 0; log_flush(); @@ -257,8 +260,8 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) const char *log_id(RTLIL::IdString str) { + log_id_cache.insert(str); const char *p = str.c_str(); - log_assert(RTLIL::IdString::global_refcount_storage_[str.index_] > 1); if (p[0] == '\\' && p[1] != '$' && p[1] != 0) return p+1; return p; -- cgit v1.2.3 From fe829bdbdc436f425e082ab1cc8c3d276f168945 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Nov 2014 10:44:23 +0100 Subject: Added log_warning() API --- kernel/cost.h | 2 +- kernel/log.cc | 25 +++++++++++++++++++++++-- kernel/log.h | 4 +++- kernel/rtlil.cc | 6 +++--- 4 files changed, 30 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/cost.h b/kernel/cost.h index 5e99df993..61a693b9c 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -70,7 +70,7 @@ int get_cell_cost(RTLIL::IdString type, const std::map> get_coverage_data() for (auto &it : extra_coverage_data) { if (coverage_data.count(it.first)) - log("WARNING: found duplicate coverage id \"%s\".\n", it.first.c_str()); + log_warning("found duplicate coverage id \"%s\".\n", it.first.c_str()); coverage_data[it.first].first = it.second.first; coverage_data[it.first].second += it.second.second; } for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { if (coverage_data.count(p->id)) - log("WARNING: found duplicate coverage id \"%s\".\n", p->id); + log_warning("found duplicate coverage id \"%s\".\n", p->id); coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); coverage_data[p->id].second += p->counter; } diff --git a/kernel/log.h b/kernel/log.h index 93e8144a0..b003aba22 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -51,10 +51,12 @@ extern int log_verbose_level; void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); +void logv_warning(const char *format, va_list ap); +_NORETURN_ void logv_error(const char *format, va_list ap) __attribute__((noreturn)); -void logv_error(const char *format, va_list ap) __attribute__((noreturn)); void log(const char *format, ...) __attribute__((format(printf, 1, 2))); void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); +void log_warning(const char *format, ...) __attribute__((format(printf, 1, 2))); _NORETURN_ void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); _NORETURN_ void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8cfc0c5f9..803d783af 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -440,7 +440,7 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const 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; } @@ -1062,14 +1062,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(); } -- cgit v1.2.3 From a112b1093444429a1a55a90b73c58c8b7ffee1bc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Nov 2014 10:55:04 +0100 Subject: Introducing YS_OVERRIDE, YS_FINAL, YS_ATTRIBUTE, YS_NORETURN --- kernel/log.h | 16 ++++++++-------- kernel/modtools.h | 2 +- kernel/register.h | 4 ++-- kernel/yosys.h | 22 +++++++++++++--------- 4 files changed, 24 insertions(+), 20 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index b003aba22..b69e2ee2d 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -52,13 +52,13 @@ extern int log_verbose_level; void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); void logv_warning(const char *format, va_list ap); -_NORETURN_ void logv_error(const char *format, va_list ap) __attribute__((noreturn)); +YS_NORETURN void logv_error(const char *format, va_list ap) YS_ATTRIBUTE(noreturn); -void log(const char *format, ...) __attribute__((format(printf, 1, 2))); -void log_header(const char *format, ...) __attribute__((format(printf, 1, 2))); -void log_warning(const char *format, ...) __attribute__((format(printf, 1, 2))); -_NORETURN_ void log_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); -_NORETURN_ void log_cmd_error(const char *format, ...) __attribute__((format(printf, 1, 2))) __attribute__((noreturn)); +void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +void log_header(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); +YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn); void log_spacer(); void log_push(); @@ -92,14 +92,14 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi #ifdef YOSYS_ENABLE_COVER #define cover(_id) do { \ - static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1), used)) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + static CoverData __d YS_ATTRIBUTE(section("yosys_cover_list"), aligned(1), used) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ __d.counter++; \ } while (0) struct CoverData { const char *file, *func, *id; int line, counter; -} __attribute__ ((packed)); +} YS_ATTRIBUTE(packed); // this two symbols are created by the linker for the "yosys_cover_list" ELF section extern "C" struct CoverData __start_yosys_cover_list[]; diff --git a/kernel/modtools.h b/kernel/modtools.h index 1b6968d74..e3020ae3c 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -102,7 +102,7 @@ struct ModIndex : public RTLIL::Monitor auto_reload_module = false; } - virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) OVERRIDE + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE { if (auto_reload_module) reload_module(); diff --git a/kernel/register.h b/kernel/register.h index a49675ed2..5214dd9a3 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -73,7 +73,7 @@ struct Frontend : Pass Frontend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Frontend(); - virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; + virtual void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; static std::vector next_args; @@ -89,7 +89,7 @@ struct Backend : Pass Backend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Backend(); - virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; + virtual void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; void extra_args(std::ostream *&f, std::string &filename, std::vector args, size_t argidx); diff --git a/kernel/yosys.h b/kernel/yosys.h index 11f356adc..b64739ad4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -102,18 +102,22 @@ #define USING_YOSYS_NAMESPACE using namespace Yosys; #if __cplusplus >= 201103L -# define OVERRIDE override -# define FINAL final +# define YS_OVERRIDE override +# define YS_FINAL final #else -# define OVERRIDE -# define FINAL +# define YS_OVERRIDE +# define YS_FINAL #endif -#if !defined(__GNUC__) && !defined(__clang__) -# define __attribute__(...) -# define _NORETURN_ __declspec(noreturn) +#if defined(__GNUC__) || defined(__clang__) +# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +# define YS_NORETURN +#elif defined(_MSC_VER) +# define YS_ATTRIBUTE(...) +# define YS_NORETURN __declspec(noreturn) #else -# define _NORETURN_ +# define YS_ATTRIBUTE(...) +# define YS_NORETURN #endif YOSYS_NAMESPACE_BEGIN @@ -125,7 +129,7 @@ namespace RTLIL { struct Cell; } -std::string stringf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); std::string next_token(std::string &text, const char *sep); -- cgit v1.2.3 From 1e0f6b5ddbfc3a7bc30f2537decf45654e7f1524 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Nov 2014 11:02:20 +0100 Subject: Added "yosys -qq" to also quiet warning messages --- kernel/driver.cc | 5 ++++- kernel/log.cc | 5 +++-- kernel/log.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 8164fef28..7f466839c 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -141,6 +141,8 @@ int main(int argc, char **argv) } break; case 'q': + if (log_errfile == stderr) + log_quiet_warnings = true; log_errfile = stderr; break; case 'v': @@ -170,7 +172,8 @@ int main(int argc, char **argv) fprintf(stderr, " suppress printing of footer (log hash, version, timing statistics)\n"); fprintf(stderr, "\n"); fprintf(stderr, " -q\n"); - fprintf(stderr, " quiet operation. only write error messages to console\n"); + fprintf(stderr, " quiet operation. only write warnings and error messages to console\n"); + fprintf(stderr, " use this option twice to also quiet warning messages\n"); fprintf(stderr, "\n"); fprintf(stderr, " -v \n"); fprintf(stderr, " print log headers up to level to the console. (implies -q)\n"); diff --git a/kernel/log.cc b/kernel/log.cc index 9f9c4db9f..0773429a6 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -41,6 +41,7 @@ SHA1 *log_hasher = NULL; bool log_time = false; bool log_cmd_error_throw = false; +bool log_quiet_warnings = false; int log_verbose_level; std::vector header_count; @@ -154,14 +155,14 @@ void logv_header(const char *format, va_list ap) void logv_warning(const char *format, va_list ap) { - if (log_errfile != NULL) + if (log_errfile != NULL && !log_quiet_warnings) log_files.push_back(log_errfile); log("Warning: "); logv(format, ap); log_flush(); - if (log_errfile != NULL) + if (log_errfile != NULL && !log_quiet_warnings) log_files.pop_back(); } diff --git a/kernel/log.h b/kernel/log.h index b69e2ee2d..278e35b41 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -47,6 +47,7 @@ extern SHA1 *log_hasher; extern bool log_time; extern bool log_cmd_error_throw; +extern bool log_quiet_warnings; extern int log_verbose_level; void logv(const char *format, va_list ap); -- cgit v1.2.3 From fad9cec47b3aa9fc3d413abee92cc8380d0c0dc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Dec 2014 10:43:38 +0100 Subject: Added $_DFFE_??_ cell types --- kernel/celltypes.h | 4 ++++ kernel/rtlil.cc | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 3d9e4cf93..f58ae14c4 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -156,6 +156,10 @@ struct CellTypes for (auto c1 : list_np) setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"}); + for (auto c1 : list_np) + for (auto c2 : list_np) + setup_type(stringf("$_DFFE_%c%c_", c1, c2), {"\\C", "\\D", "\\E"}, {"\\Q"}); + for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_01) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 803d783af..321c39e10 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -892,6 +892,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; } -- cgit v1.2.3 From f1764b4fe99807c445526774563a98224b642766 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Dec 2014 10:50:19 +0100 Subject: Added $dffe cell type --- kernel/rtlil.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 321c39e10..b1bf43941 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -752,6 +752,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"); -- cgit v1.2.3 From bca2442c671b8ae0b8a8b933f6a27593dd13a168 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Dec 2014 14:59:38 +0100 Subject: Added module->addDffe() and module->addDffeGate() --- kernel/rtlil.cc | 25 ++++++++++++++++++++++++- kernel/rtlil.h | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b1bf43941..2f2f7c704 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1595,7 +1595,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; @@ -1606,6 +1606,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) { @@ -1673,6 +1686,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) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0bb1e4e84..a488d3a6b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -701,6 +701,7 @@ public: RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true); RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); + RTLIL::Cell* addDffe (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true); RTLIL::Cell* 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 = true, bool set_polarity = true, bool clr_polarity = true); RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, @@ -723,6 +724,7 @@ public: RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y); RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); + RTLIL::Cell* addDffeGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true); RTLIL::Cell* 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 = true, bool set_polarity = true, bool clr_polarity = true); RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, -- cgit v1.2.3 From 7d6e586df8128d4265499ef3f61c1a85ff3cc02a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Dec 2014 15:08:02 +0100 Subject: Added bool constructors to SigBit and SigSpec --- kernel/rtlil.cc | 10 ++++++++++ kernel/rtlil.h | 2 ++ 2 files changed, 12 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2f2f7c704..f5dbafe16 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2188,6 +2188,16 @@ RTLIL::SigSpec::SigSpec(std::set 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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a488d3a6b..0157f3b7c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -899,6 +899,7 @@ struct RTLIL::SigBit SigBit() : wire(NULL), data(RTLIL::State::S0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } + SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } @@ -982,6 +983,7 @@ public: SigSpec(std::vector chunks); SigSpec(std::vector bits); SigSpec(std::set bits); + SigSpec(bool bit); SigSpec(RTLIL::SigSpec &&other) { width_ = other.width_; -- cgit v1.2.3 From 032511fac854cd0507dc84242bb55508c4757441 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Dec 2014 15:38:58 +0100 Subject: Added functionality to dff2dffe pass --- kernel/celltypes.h | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index f58ae14c4..5ba4dd88b 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -116,6 +116,7 @@ struct CellTypes { setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"}); setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"}); + setup_type("$dffe", {"\\CLK", "\\EN", "\\D"}, {"\\Q"}); setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"}); setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"}); -- cgit v1.2.3 From 7775d2806fe082626103f5abffd95fe9e1fccc27 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 11 Dec 2014 21:46:36 +0100 Subject: Added IdString::destruct_guard hack --- kernel/rtlil.cc | 1 + kernel/rtlil.h | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f5dbafe16..5c010dabf 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -27,6 +27,7 @@ YOSYS_NAMESPACE_BEGIN +RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_id_storage_; std::map RTLIL::IdString::global_id_index_; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0157f3b7c..29fa90692 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -85,6 +85,12 @@ namespace RTLIL } }; + static struct destruct_guard_t { + bool ok = false; + destruct_guard_t() { ok = true; } + ~destruct_guard_t() { ok = false; } + } destruct_guard; + static std::vector global_refcount_storage_; static std::vector global_id_storage_; static std::map global_id_index_; @@ -98,6 +104,8 @@ namespace RTLIL static inline int get_reference(const char *p) { + log_assert(destruct_guard.ok); + if (p[0]) { log_assert(p[1] != 0); log_assert(p[0] == '$' || p[0] == '\\'); @@ -126,6 +134,11 @@ namespace RTLIL static inline void put_reference(int idx) { + // put_reference() may be called from destructors after the destructor of + // global_refcount_storage_ has been run. in this case we simply do nothing. + if (!destruct_guard.ok) + return; + log_assert(global_refcount_storage_.at(idx) > 0); if (--global_refcount_storage_.at(idx) != 0) -- cgit v1.2.3 From 6cec188c524f83a84e2cda88f0c121998867bc77 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Dec 2014 10:38:25 +0100 Subject: Fixed build with gcc 4.6 --- kernel/rtlil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 29fa90692..19996c8fc 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -86,7 +86,7 @@ namespace RTLIL }; static struct destruct_guard_t { - bool ok = false; + bool ok; // POD, will be initialized to zero destruct_guard_t() { ok = true; } ~destruct_guard_t() { ok = false; } } destruct_guard; -- cgit v1.2.3 From 76fa5274927e8f960060938e10a042d85268a6ac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Dec 2014 16:52:05 +0100 Subject: Added support for multiple clock domains to "abc" pass --- kernel/rtlil.h | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 19996c8fc..efb8e833a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1017,6 +1017,7 @@ public: inline const std::vector &bits() const { inline_unpack(); return bits_; } inline int size() const { return width_; } + inline bool empty() const { return width_ == 0; } inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); } inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); } -- cgit v1.2.3 From edb3c9d0c4f0bc3a108ffebc01f02ff4d7354487 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 24 Dec 2014 09:51:17 +0100 Subject: Renamed extend() to extend_xx(), changed most users to extend_u0() --- kernel/rtlil.cc | 15 +++++++-------- kernel/rtlil.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 5c010dabf..0e8078df6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2590,9 +2590,9 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) check(); } -void RTLIL::SigSpec::extend(int width, bool is_signed) +void RTLIL::SigSpec::extend_xx(int width, bool is_signed) { - cover("kernel.rtlil.sigspec.extend"); + cover("kernel.rtlil.sigspec.extend_xx"); pack(); @@ -2600,10 +2600,9 @@ void RTLIL::SigSpec::extend(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); - 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); + RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::S0; + if (!is_signed && (padding == RTLIL::State::S1 || padding.wire)) + padding = RTLIL::State::S0; while (width_ < width) append(padding); } @@ -2619,9 +2618,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); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index efb8e833a..99831244e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1057,7 +1057,7 @@ public: void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); - void extend(int width, bool is_signed = false); + void extend_xx(int width, bool is_signed = false); void extend_u0(int width, bool is_signed = false); RTLIL::SigSpec repeat(int num) const; -- cgit v1.2.3 From a6c96b986be313368b4fa03eba5cf6987448100c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 10:53:21 +0100 Subject: Added Yosys::{dict,nodict,vector} container types --- kernel/cost.h | 12 +- kernel/rtlil.cc | 100 ++++++--- kernel/rtlil.h | 620 ++++++++++++++++++++++++++++++++------------------------ kernel/yosys.h | 12 ++ 4 files changed, 452 insertions(+), 292 deletions(-) (limited to 'kernel') diff --git a/kernel/cost.h b/kernel/cost.h index 61a693b9c..1b4166e00 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -24,12 +24,12 @@ YOSYS_NAMESPACE_BEGIN -int get_cell_cost(RTLIL::Cell *cell, std::map *mod_cost_cache = nullptr); +int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache = nullptr); -int get_cell_cost(RTLIL::IdString type, const std::map ¶meters = std::map(), - RTLIL::Design *design = nullptr, std::map *mod_cost_cache = nullptr) +int get_cell_cost(RTLIL::IdString type, const dict ¶meters = dict(), + RTLIL::Design *design = nullptr, dict *mod_cost_cache = nullptr) { - static std::map gate_cost = { + static dict gate_cost = { { "$_BUF_", 1 }, { "$_NOT_", 2 }, { "$_AND_", 4 }, @@ -55,7 +55,7 @@ int get_cell_cost(RTLIL::IdString type, const std::mapattributes.count("\\cost")) return mod->attributes.at("\\cost").as_int(); - std::map local_mod_cost_cache; + dict local_mod_cost_cache; if (mod_cost_cache == nullptr) mod_cost_cache = &local_mod_cost_cache; @@ -74,7 +74,7 @@ int get_cell_cost(RTLIL::IdString type, const std::map *mod_cost_cache) +int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache) { return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 0e8078df6..2d3d83f42 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -30,7 +30,7 @@ YOSYS_NAMESPACE_BEGIN RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_id_storage_; -std::map RTLIL::IdString::global_id_index_; +dict RTLIL::IdString::global_id_index_; std::vector RTLIL::IdString::global_free_idx_list_; RTLIL::Const::Const() @@ -464,7 +464,7 @@ RTLIL::Module::~Module() delete it->second; } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::map) +RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict) { log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name)); } @@ -480,7 +480,7 @@ namespace { { RTLIL::Module *module; RTLIL::Cell *cell; - std::set expected_params, expected_ports; + nodict expected_params, expected_ports; InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } @@ -1132,7 +1132,7 @@ namespace { struct DeleteWireWorker { RTLIL::Module *module; - const std::set *wires_p; + const nodict *wires_p; void operator()(RTLIL::SigSpec &sig) { std::vector chunks = sig; @@ -1146,16 +1146,7 @@ namespace { }; } -#if 0 -void RTLIL::Module::remove(RTLIL::Wire *wire) -{ - std::setPort wires_; - wires_.insert(wire); - remove(wires_); -} -#endif - -void RTLIL::Module::remove(const std::set &wires) +void RTLIL::Module::remove(const nodict &wires) { log_assert(refcount_wires_ == 0); @@ -1811,7 +1802,7 @@ const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const return connections_.at(portname); } -const std::map &RTLIL::Cell::connections() const +const dict &RTLIL::Cell::connections() const { return connections_; } @@ -2178,6 +2169,17 @@ RTLIL::SigSpec::SigSpec(std::vector bits) check(); } +RTLIL::SigSpec::SigSpec(nodict bits) +{ + cover("kernel.rtlil.sigspec.init.stdset_bits"); + + width_ = 0; + hash_ = 0; + for (auto &bit : bits) + append_bit(bit); + check(); +} + RTLIL::SigSpec::SigSpec(std::set bits) { cover("kernel.rtlil.sigspec.init.stdset_bits"); @@ -2306,7 +2308,7 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec pattern.unpack(); with.unpack(); - std::map rules; + dict rules; for (int i = 0; i < GetSize(pattern.bits_); i++) if (pattern.bits_[i].wire != NULL) @@ -2315,6 +2317,30 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec replace(rules, other); } +void RTLIL::SigSpec::replace(const dict &rules) +{ + replace(rules, this); +} + +void RTLIL::SigSpec::replace(const dict &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 &rules) { replace(rules, this); @@ -2322,7 +2348,7 @@ void RTLIL::SigSpec::replace(const std::map &rules void RTLIL::SigSpec::replace(const std::map &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_); @@ -2352,22 +2378,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 pattern_bits = pattern.to_sigbit_set(); + nodict pattern_bits = pattern.to_sigbit_nodict(); remove2(pattern_bits, other); } -void RTLIL::SigSpec::remove(const std::set &pattern) +void RTLIL::SigSpec::remove(const nodict &pattern) { remove2(pattern, NULL); } -void RTLIL::SigSpec::remove(const std::set &pattern, RTLIL::SigSpec *other) const +void RTLIL::SigSpec::remove(const nodict &pattern, RTLIL::SigSpec *other) const { RTLIL::SigSpec tmp = *this; tmp.remove2(pattern, other); } -void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigSpec *other) +void RTLIL::SigSpec::remove2(const nodict &pattern, RTLIL::SigSpec *other) { if (other) cover("kernel.rtlil.sigspec.remove_other"); @@ -2413,11 +2439,11 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const { - std::set pattern_bits = pattern.to_sigbit_set(); + nodict pattern_bits = pattern.to_sigbit_nodict(); return extract(pattern_bits, other); } -RTLIL::SigSpec RTLIL::SigSpec::extract(const std::set &pattern, const RTLIL::SigSpec *other) const +RTLIL::SigSpec RTLIL::SigSpec::extract(const nodict &pattern, const RTLIL::SigSpec *other) const { if (other) cover("kernel.rtlil.sigspec.extract_other"); @@ -2917,6 +2943,18 @@ std::set RTLIL::SigSpec::to_sigbit_set() const return sigbits; } +nodict RTLIL::SigSpec::to_sigbit_nodict() const +{ + cover("kernel.rtlil.sigspec.to_sigbit_nodict"); + + pack(); + nodict sigbits; + for (auto &c : chunks_) + for (int i = 0; i < c.width; i++) + sigbits.insert(RTLIL::SigBit(c, i)); + return sigbits; +} + std::vector RTLIL::SigSpec::to_sigbit_vector() const { cover("kernel.rtlil.sigspec.to_sigbit_vector"); @@ -2941,6 +2979,22 @@ std::map RTLIL::SigSpec::to_sigbit_map(const RTLIL return new_map; } +dict 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 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"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 99831244e..e684ba4ae 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -22,6 +22,27 @@ #ifndef RTLIL_H #define RTLIL_H +namespace std { + template<> struct hash { + size_t operator()(const Yosys::RTLIL::IdString &arg) const; + }; + template<> struct equal_to { + bool operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const; + }; + template<> struct hash { + size_t operator()(const Yosys::RTLIL::SigBit &arg) const; + }; + template<> struct equal_to { + bool operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const; + }; + template<> struct hash { + size_t operator()(const Yosys::RTLIL::SigSpec &arg) const; + }; + template<> struct equal_to { + bool operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const; + }; +} + YOSYS_NAMESPACE_BEGIN namespace RTLIL @@ -85,6 +106,24 @@ namespace RTLIL } }; + struct char_ptr_hash { + size_t operator()(const char *a) const { + size_t hash = 5381; + for (int c; (c = *a); a++) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + return hash; + } + }; + + struct char_ptr_eq { + bool operator()(const char *a, const char *b) const { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return false; + return true; + } + }; + static struct destruct_guard_t { bool ok; // POD, will be initialized to zero destruct_guard_t() { ok = true; } @@ -93,7 +132,7 @@ namespace RTLIL static std::vector global_refcount_storage_; static std::vector global_id_storage_; - static std::map global_id_index_; + static dict global_id_index_; static std::vector global_free_idx_list_; static inline int get_reference(int idx) @@ -224,8 +263,8 @@ namespace RTLIL *this = IdString(); } - // The following is a helper key_compare class. Instead of for example std::set - // use std::set> if the order of cells in the + // The following is a helper key_compare class. Instead of for example nodict + // use nodict> if the order of cells in the // set has an influence on the algorithm. template struct compare_ptr_by_name { @@ -245,7 +284,7 @@ namespace RTLIL bool in(IdString rhs) { return *this == rhs; } bool in(const char *rhs) { return *this == rhs; } bool in(const std::string &rhs) { return *this == rhs; } - bool in(const std::set &rhs) { return rhs.count(*this) != 0; } + bool in(const nodict &rhs) { return rhs.count(*this) != 0; } }; static inline std::string escape_id(std::string str) { @@ -336,8 +375,8 @@ namespace RTLIL template struct ObjIterator { - typename std::map::iterator it; - std::map *list_p; + typename dict::iterator it; + dict *list_p; int *refcount_p; ObjIterator() : list_p(nullptr), refcount_p(nullptr) { @@ -401,7 +440,7 @@ namespace RTLIL template struct ObjRange { - std::map *list_p; + dict *list_p; int *refcount_p; ObjRange(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { } @@ -412,8 +451,8 @@ namespace RTLIL return list_p->size(); } - operator std::set() const { - std::set result; + operator nodict() const { + nodict result; for (auto &it : *list_p) result.insert(it.second); return result; @@ -427,7 +466,7 @@ namespace RTLIL return result; } - std::set to_set() const { return *this; } + nodict to_set() const { return *this; } std::vector to_vector() const { return *this; } }; }; @@ -457,11 +496,232 @@ struct RTLIL::Const inline int size() const { return bits.size(); } }; +struct RTLIL::SigChunk +{ + RTLIL::Wire *wire; + std::vector data; // only used if wire == NULL, LSB at index 0 + int width, offset; + + SigChunk(); + SigChunk(const RTLIL::Const &value); + SigChunk(RTLIL::Wire *wire); + SigChunk(RTLIL::Wire *wire, int offset, int width = 1); + SigChunk(const std::string &str); + SigChunk(int val, int width = 32); + SigChunk(RTLIL::State bit, int width = 1); + SigChunk(RTLIL::SigBit bit); + + RTLIL::SigChunk extract(int offset, int length) const; + + bool operator <(const RTLIL::SigChunk &other) const; + bool operator ==(const RTLIL::SigChunk &other) const; + bool operator !=(const RTLIL::SigChunk &other) const; +}; + +struct RTLIL::SigBit +{ + RTLIL::Wire *wire; + union { + RTLIL::State data; // used if wire == NULL + int offset; // used if wire != NULL + }; + + SigBit(); + SigBit(RTLIL::State bit); + SigBit(bool bit); + SigBit(RTLIL::Wire *wire); + SigBit(RTLIL::Wire *wire, int offset); + SigBit(const RTLIL::SigChunk &chunk); + SigBit(const RTLIL::SigChunk &chunk, int index); + SigBit(const RTLIL::SigSpec &sig); + + bool operator <(const RTLIL::SigBit &other) const; + bool operator ==(const RTLIL::SigBit &other) const; + bool operator !=(const RTLIL::SigBit &other) const; +}; + +struct RTLIL::SigSpecIterator : public std::iterator +{ + RTLIL::SigSpec *sig_p; + int index; + + inline RTLIL::SigBit &operator*() const; + inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; } + inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } + inline void operator++() { index++; } +}; + +struct RTLIL::SigSpecConstIterator : public std::iterator +{ + const RTLIL::SigSpec *sig_p; + int index; + + inline const RTLIL::SigBit &operator*() const; + inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; } + inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } + inline void operator++() { index++; } +}; + +struct RTLIL::SigSpec +{ +private: + int width_; + unsigned long hash_; + std::vector chunks_; // LSB at index 0 + std::vector bits_; // LSB at index 0 + + void pack() const; + void unpack() const; + void hash() const; + + inline bool packed() const { + return bits_.empty(); + } + + inline void inline_unpack() const { + if (!chunks_.empty()) + unpack(); + } + +public: + SigSpec(); + SigSpec(const RTLIL::SigSpec &other); + SigSpec(std::initializer_list parts); + const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); + + SigSpec(const RTLIL::Const &value); + SigSpec(const RTLIL::SigChunk &chunk); + SigSpec(RTLIL::Wire *wire); + SigSpec(RTLIL::Wire *wire, int offset, int width = 1); + SigSpec(const std::string &str); + SigSpec(int val, int width = 32); + SigSpec(RTLIL::State bit, int width = 1); + SigSpec(RTLIL::SigBit bit, int width = 1); + SigSpec(std::vector chunks); + SigSpec(std::vector bits); + SigSpec(nodict bits); + SigSpec(std::set bits); + SigSpec(bool bit); + + SigSpec(RTLIL::SigSpec &&other) { + width_ = other.width_; + hash_ = other.hash_; + chunks_ = std::move(other.chunks_); + bits_ = std::move(other.bits_); + } + + const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) { + width_ = other.width_; + hash_ = other.hash_; + chunks_ = std::move(other.chunks_); + bits_ = std::move(other.bits_); + return *this; + } + + size_t get_hash() const { + if (!hash_) hash(); + return hash_; + } + + inline const std::vector &chunks() const { pack(); return chunks_; } + inline const std::vector &bits() const { inline_unpack(); return bits_; } + + inline int size() const { return width_; } + inline bool empty() const { return width_ == 0; } + + inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); } + inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); } + + inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } + inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } + + inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; } + inline RTLIL::SigSpecConstIterator end() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = width_; return it; } + + void sort(); + void sort_and_unify(); + + void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); + void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; + + void replace(const dict &rules); + void replace(const dict &rules, RTLIL::SigSpec *other) const; + + void replace(const std::map &rules); + void replace(const std::map &rules, RTLIL::SigSpec *other) const; + + void replace(int offset, const RTLIL::SigSpec &with); + + void remove(const RTLIL::SigSpec &pattern); + void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; + void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); + + void remove(const nodict &pattern); + void remove(const nodict &pattern, RTLIL::SigSpec *other) const; + void remove2(const nodict &pattern, RTLIL::SigSpec *other); + + void remove(int offset, int length = 1); + void remove_const(); + + RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const nodict &pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(int offset, int length = 1) const; + + void append(const RTLIL::SigSpec &signal); + void append_bit(const RTLIL::SigBit &bit); + + void extend_xx(int width, bool is_signed = false); + void extend_u0(int width, bool is_signed = false); + + RTLIL::SigSpec repeat(int num) const; + + bool operator <(const RTLIL::SigSpec &other) const; + bool operator ==(const RTLIL::SigSpec &other) const; + inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } + + bool is_wire() const; + bool is_chunk() const; + + bool is_fully_const() const; + bool is_fully_def() const; + bool is_fully_undef() const; + bool has_marked_bits() const; + + bool as_bool() const; + int as_int(bool is_signed = false) const; + std::string as_string() const; + RTLIL::Const as_const() const; + RTLIL::Wire *as_wire() const; + RTLIL::SigChunk as_chunk() const; + + bool match(std::string pattern) const; + + std::set to_sigbit_set() const; + nodict to_sigbit_nodict() const; + std::vector to_sigbit_vector() const; + std::map to_sigbit_map(const RTLIL::SigSpec &other) const; + dict 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); + static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); + + operator std::vector() const { return chunks(); } + operator std::vector() const { return bits(); } + +#ifndef NDEBUG + void check() const; +#else + void check() const { } +#endif +}; + struct RTLIL::Selection { bool full_selection; - std::set selected_modules; - std::map> selected_members; + nodict selected_modules; + dict> selected_members; Selection(bool full = true) : full_selection(full) { } @@ -500,14 +760,14 @@ struct RTLIL::Monitor struct RTLIL::Design { - std::set monitors; - std::map scratchpad; + nodict monitors; + dict scratchpad; int refcount_modules_; - std::map modules_; + dict modules_; std::vector selection_stack; - std::map selection_vars; + dict selection_vars; std::string selected_active_module; Design(); @@ -569,7 +829,7 @@ struct RTLIL::Design }; #define RTLIL_ATTRIBUTE_MEMBERS \ - std::map attributes; \ + dict attributes; \ void set_bool_attribute(RTLIL::IdString id) { \ attributes[id] = RTLIL::Const(1); \ } \ @@ -587,24 +847,24 @@ protected: public: RTLIL::Design *design; - std::set monitors; + nodict monitors; int refcount_wires_; int refcount_cells_; - std::map wires_; - std::map cells_; + dict wires_; + dict cells_; std::vector connections_; RTLIL::IdString name; - std::set avail_parameters; - std::map memories; - std::map processes; + nodict avail_parameters; + dict memories; + dict processes; RTLIL_ATTRIBUTE_MEMBERS Module(); virtual ~Module(); - virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); + virtual RTLIL::IdString derive(RTLIL::Design *design, dict parameters); virtual size_t count_id(RTLIL::IdString id); virtual void check(); virtual void optimize(); @@ -641,7 +901,7 @@ public: RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const std::set &wires); + void remove(const nodict &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); @@ -852,8 +1112,8 @@ public: RTLIL::Module *module; RTLIL::IdString name; RTLIL::IdString type; - std::map connections_; - std::map parameters; + dict connections_; + dict parameters; RTLIL_ATTRIBUTE_MEMBERS // access cell ports @@ -861,7 +1121,7 @@ public: void unsetPort(RTLIL::IdString portname); void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal); const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const; - const std::map &connections() const; + const dict &connections() const; // access cell parameters bool hasParam(RTLIL::IdString paramname) const; @@ -880,241 +1140,6 @@ public: template void rewrite_sigspecs(T functor); }; -struct RTLIL::SigChunk -{ - RTLIL::Wire *wire; - std::vector data; // only used if wire == NULL, LSB at index 0 - int width, offset; - - SigChunk(); - SigChunk(const RTLIL::Const &value); - SigChunk(RTLIL::Wire *wire); - SigChunk(RTLIL::Wire *wire, int offset, int width = 1); - SigChunk(const std::string &str); - SigChunk(int val, int width = 32); - SigChunk(RTLIL::State bit, int width = 1); - SigChunk(RTLIL::SigBit bit); - - RTLIL::SigChunk extract(int offset, int length) const; - - bool operator <(const RTLIL::SigChunk &other) const; - bool operator ==(const RTLIL::SigChunk &other) const; - bool operator !=(const RTLIL::SigChunk &other) const; -}; - -struct RTLIL::SigBit -{ - RTLIL::Wire *wire; - union { - RTLIL::State data; // used if wire == NULL - int offset; // used if wire != NULL - }; - - SigBit() : wire(NULL), data(RTLIL::State::S0) { } - SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } - SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } - SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } - SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } - SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } - SigBit(const RTLIL::SigSpec &sig); - - bool operator <(const RTLIL::SigBit &other) const { - if (wire == other.wire) - return wire ? (offset < other.offset) : (data < other.data); - if (wire != nullptr && other.wire != nullptr) - return wire->name < other.wire->name; - return wire < other.wire; - } - - bool operator ==(const RTLIL::SigBit &other) const { - return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data)); - } - - bool operator !=(const RTLIL::SigBit &other) const { - return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); - } -}; - -struct RTLIL::SigSpecIterator : public std::iterator -{ - RTLIL::SigSpec *sig_p; - int index; - - inline RTLIL::SigBit &operator*() const; - inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; } - inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } - inline void operator++() { index++; } -}; - -struct RTLIL::SigSpecConstIterator : public std::iterator -{ - const RTLIL::SigSpec *sig_p; - int index; - - inline const RTLIL::SigBit &operator*() const; - inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; } - inline bool operator==(const RTLIL::SigSpecIterator &other) const { return index == other.index; } - inline void operator++() { index++; } -}; - -struct RTLIL::SigSpec -{ -private: - int width_; - unsigned long hash_; - std::vector chunks_; // LSB at index 0 - std::vector bits_; // LSB at index 0 - - void pack() const; - void unpack() const; - void hash() const; - - inline bool packed() const { - return bits_.empty(); - } - - inline void inline_unpack() const { - if (!chunks_.empty()) - unpack(); - } - -public: - SigSpec(); - SigSpec(const RTLIL::SigSpec &other); - SigSpec(std::initializer_list parts); - const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); - - SigSpec(const RTLIL::Const &value); - SigSpec(const RTLIL::SigChunk &chunk); - SigSpec(RTLIL::Wire *wire); - SigSpec(RTLIL::Wire *wire, int offset, int width = 1); - SigSpec(const std::string &str); - SigSpec(int val, int width = 32); - SigSpec(RTLIL::State bit, int width = 1); - SigSpec(RTLIL::SigBit bit, int width = 1); - SigSpec(std::vector chunks); - SigSpec(std::vector bits); - SigSpec(std::set bits); - SigSpec(bool bit); - - SigSpec(RTLIL::SigSpec &&other) { - width_ = other.width_; - hash_ = other.hash_; - chunks_ = std::move(other.chunks_); - bits_ = std::move(other.bits_); - } - - const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) { - width_ = other.width_; - hash_ = other.hash_; - chunks_ = std::move(other.chunks_); - bits_ = std::move(other.bits_); - return *this; - } - - inline const std::vector &chunks() const { pack(); return chunks_; } - inline const std::vector &bits() const { inline_unpack(); return bits_; } - - inline int size() const { return width_; } - inline bool empty() const { return width_ == 0; } - - inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); } - inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); } - - inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } - inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } - - inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; } - inline RTLIL::SigSpecConstIterator end() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = width_; return it; } - - void sort(); - void sort_and_unify(); - - void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); - void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; - - void replace(const std::map &rules); - void replace(const std::map &rules, RTLIL::SigSpec *other) const; - - void replace(int offset, const RTLIL::SigSpec &with); - - void remove(const RTLIL::SigSpec &pattern); - void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; - void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); - - void remove(const std::set &pattern); - void remove(const std::set &pattern, RTLIL::SigSpec *other) const; - void remove2(const std::set &pattern, RTLIL::SigSpec *other); - - void remove(int offset, int length = 1); - void remove_const(); - - RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; - RTLIL::SigSpec extract(const std::set &pattern, const RTLIL::SigSpec *other = NULL) const; - RTLIL::SigSpec extract(int offset, int length = 1) const; - - void append(const RTLIL::SigSpec &signal); - void append_bit(const RTLIL::SigBit &bit); - - void extend_xx(int width, bool is_signed = false); - void extend_u0(int width, bool is_signed = false); - - RTLIL::SigSpec repeat(int num) const; - - bool operator <(const RTLIL::SigSpec &other) const; - bool operator ==(const RTLIL::SigSpec &other) const; - inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } - - bool is_wire() const; - bool is_chunk() const; - - bool is_fully_const() const; - bool is_fully_def() const; - bool is_fully_undef() const; - bool has_marked_bits() const; - - bool as_bool() const; - int as_int(bool is_signed = false) const; - std::string as_string() const; - RTLIL::Const as_const() const; - RTLIL::Wire *as_wire() const; - RTLIL::SigChunk as_chunk() const; - - bool match(std::string pattern) const; - - std::set to_sigbit_set() const; - std::vector to_sigbit_vector() const; - std::map to_sigbit_map(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); - static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); - - operator std::vector() const { return chunks(); } - operator std::vector() const { return bits(); } - -#ifndef NDEBUG - void check() const; -#else - inline void check() const { } -#endif -}; - -inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { - return (*sig_p)[index]; -} - -inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const { - return (*sig_p)[index]; -} - -inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { - log_assert(sig.size() == 1 && sig.chunks().size() == 1); - *this = SigBit(sig.chunks().front()); -} - struct RTLIL::CaseRule { std::vector compare; @@ -1163,6 +1188,44 @@ struct RTLIL::Process RTLIL::Process *clone() const; }; + +inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { } +inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } +inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } +inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } +inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); } +inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } +inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } + +inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const { + if (wire == other.wire) + return wire ? (offset < other.offset) : (data < other.data); + if (wire != nullptr && other.wire != nullptr) + return wire->name < other.wire->name; + return wire < other.wire; +} + +inline bool RTLIL::SigBit::operator==(const RTLIL::SigBit &other) const { + return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data)); +} + +inline bool RTLIL::SigBit::operator!=(const RTLIL::SigBit &other) const { + return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); +} + +inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { + return (*sig_p)[index]; +} + +inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const { + return (*sig_p)[index]; +} + +inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { + log_assert(sig.size() == 1 && sig.chunks().size() == 1); + *this = SigBit(sig.chunks().front()); +} + template void RTLIL::Module::rewrite_sigspecs(T functor) { @@ -1222,4 +1285,35 @@ void RTLIL::Process::rewrite_sigspecs(T functor) YOSYS_NAMESPACE_END +inline size_t std::hash::operator()(const Yosys::RTLIL::IdString &arg) const { + return arg.index_; +} + +inline bool std::equal_to::operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const { + return lhs.index_ == rhs.index_; +} + +inline size_t std::hash::operator()(const Yosys::RTLIL::SigBit &arg) const { + if (arg.wire) { + size_t hash = arg.wire->name.index_; + hash = ((hash << 5) + hash) + arg.offset; + return hash; + } + return arg.data; +} + +inline bool std::equal_to::operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const { + if (lhs.wire || rhs.wire) + return lhs.wire == rhs.wire && lhs.offset == rhs.offset; + return lhs.data == rhs.data; +} + +inline size_t std::hash::operator()(const Yosys::RTLIL::SigSpec &arg) const { + return arg.get_hash(); +} + +inline bool std::equal_to::operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const { + return lhs == rhs; +} + #endif diff --git a/kernel/yosys.h b/kernel/yosys.h index b64739ad4..5a6945c8f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include @@ -122,8 +124,18 @@ YOSYS_NAMESPACE_BEGIN +template , class KeyEqual = std::equal_to> +using dict = std::unordered_map; + +template , class KeyEqual = std::equal_to> +using nodict = std::unordered_set; + +template +using vector = std::vector; + namespace RTLIL { struct IdString; + struct SigBit; struct SigSpec; struct Wire; struct Cell; -- cgit v1.2.3 From 35f611e2f6b38b18fc50fadbb07df1d1bc462583 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 10:54:23 +0100 Subject: Added "yosys -d" command line option --- kernel/driver.cc | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 7f466839c..6ba0c1134 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -80,6 +80,7 @@ int main(int argc, char **argv) bool print_banner = true; bool print_stats = true; bool call_abort = false; + bool timing_details = false; #ifdef YOSYS_ENABLE_READLINE int history_offset = 0; @@ -92,7 +93,7 @@ int main(int argc, char **argv) #endif int opt; - while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) + while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) { switch (opt) { @@ -152,6 +153,9 @@ int main(int argc, char **argv) case 't': log_time = true; break; + case 'd': + timing_details = true; + break; case 's': scriptfile = optarg; scriptfile_tcl = false; @@ -181,6 +185,9 @@ int main(int argc, char **argv) fprintf(stderr, " -t\n"); fprintf(stderr, " annotate all log messages with a time stamp\n"); fprintf(stderr, "\n"); + fprintf(stderr, " -d\n"); + fprintf(stderr, " print more detailed timing stats at exit\n"); + fprintf(stderr, "\n"); fprintf(stderr, " -l logfile\n"); fprintf(stderr, " write log messages to the specified file\n"); fprintf(stderr, "\n"); @@ -325,17 +332,28 @@ int main(int argc, char **argv) timedat.insert(make_tuple(it.second->runtime_ns + 1, it.second->call_counter, it.first)); } - int out_count = 0; - log("Time spent:"); - for (auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) { - if (out_count >= 2 && (std::get<0>(*it) < 1000000000 || int(100*std::get<0>(*it) / total_ns) < 20)) { - log(", ..."); - break; + if (timing_details) + { + log("Time spent:\n"); + for (auto it = timedat.rbegin(); it != timedat.rend(); it++) { + log("%5d%% %5d calls %8.3f sec %s\n", int(100*std::get<0>(*it) / total_ns), + std::get<1>(*it), std::get<0>(*it) / 1000000000.0, std::get<2>(*it).c_str()); + } + } + else + { + int out_count = 0; + log("Time spent:"); + for (auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) { + if (out_count >= 2 && (std::get<0>(*it) < 1000000000 || int(100*std::get<0>(*it) / total_ns) < 20)) { + log(", ..."); + break; + } + log("%s %d%% %dx %s (%d sec)", out_count ? "," : "", int(100*std::get<0>(*it) / total_ns), + std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000)); } - log("%s %d%% %dx %s (%d sec)", out_count ? "," : "", int(100*std::get<0>(*it) / total_ns), - std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000)); + log("%s\n", out_count ? "" : " no commands executed"); } - log("%s\n", out_count ? "" : " no commands executed"); } #ifdef YOSYS_ENABLE_COVER -- cgit v1.2.3 From e0c0011863c891e0c168eb2fabecf88b2f0a45b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 11:05:23 +0100 Subject: Temporary gcc 4.6 build hotfix for Yosys::dict and Yosys::nodict --- kernel/yosys.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.h b/kernel/yosys.h index 5a6945c8f..e2daabfae 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -124,14 +124,9 @@ YOSYS_NAMESPACE_BEGIN -template , class KeyEqual = std::equal_to> -using dict = std::unordered_map; - -template , class KeyEqual = std::equal_to> -using nodict = std::unordered_set; - -template -using vector = std::vector; +#define dict std::unordered_map +#define nodict std::unordered_set +using std::vector; namespace RTLIL { struct IdString; -- cgit v1.2.3 From e52d1f9b9a7f71634d4e8e8228060f792fa20dec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 19:28:52 +0100 Subject: Added new_dict (hashmap.h) and re-enabled code coverage counters --- kernel/hashmap.h | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/log.cc | 6 +- kernel/log.h | 4 +- kernel/rtlil.cc | 2 +- kernel/yosys.h | 1 + 5 files changed, 245 insertions(+), 6 deletions(-) create mode 100644 kernel/hashmap.h (limited to 'kernel') diff --git a/kernel/hashmap.h b/kernel/hashmap.h new file mode 100644 index 000000000..bd4fc4d22 --- /dev/null +++ b/kernel/hashmap.h @@ -0,0 +1,238 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef YOSYS_HASHMAP_H + +#include +#include + +inline unsigned int mkhash(unsigned int a, unsigned int b) { + return ((a << 5) + a) ^ b; +} + +template struct hash_ops { + bool cmp(const T &a, const T &b) { + return a == b; + } + unsigned int hash(const T &a) { + return a.hash(); + } +}; + +template<> struct hash_ops { + bool cmp(int a, int b) { + return a == b; + } + unsigned int hash(int a) { + return a; + } +}; + +template<> struct hash_ops { + bool cmp(const std::string &a, const std::string &b) { + return a == b; + } + unsigned int hash(const std::string &a) { + unsigned int v = 0; + for (auto c : a) + v = mkhash(v, c); + return v; + } +}; + +template> +class new_dict +{ + struct entry_t + { + int link; + std::pair udata; + entry_t() : link(-1) { } + + bool is_free() const { return link < 0; } + int get_next() const { return (link > 0 ? link : -link) - 2; } + bool get_last() const { return get_next() == -1; } + void set_next_used(int next) { link = next + 2; } + void set_next_free(int next) { link = -(next + 2); } + }; + + std::vector hashtable; + std::vector entries; + int free_list, counter; + OPS ops; + + void init() + { + counter = 0; + entries.resize(61); + rehash(); + } + + int mkhash(const K &key) + { + return ops.hash(key) % int(hashtable.size()); + } + +public: + void rehash() + { + free_list = -1; + + hashtable.resize(entries.size()); + for (auto &h : hashtable) + h = -1; + + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + entries[i].set_next_free(free_list); + free_list = i; + } else { + int hash = mkhash(entries[i].udata.first); + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + } + } + + void do_erase(const K &key, int hash) + { + int last_index = -1; + int index = hashtable[hash]; + while (1) { + if (index < 0) + return; + if (ops.cmp(entries[index].udata.first, key)) { + if (last_index < 0) + hashtable[hash] = entries[index].get_next(); + else + entries[last_index].set_next_used(entries[index].get_next()); + entries[index].udata = std::pair(); + entries[index].set_next_free(free_list); + free_list = index; + counter--; + return; + } + last_index = index; + index = entries[index].get_next(); + } + } + + int lookup_index(const K &key, int hash) + { + int index = hashtable[hash]; + while (1) { + if (index < 0) + return -1; + if (ops.cmp(entries[index].udata.first, key)) + return index; + index = entries[index].get_next(); + } + } + + int insert_at(const std::pair &value, int hash) + { + if (free_list < 0) + { + int i = entries.size(); + entries.resize(2*entries.size()); + entries[i].udata = value; + entries[i].set_next_used(0); + counter++; + rehash(); + return i; + } + + int i = free_list; + free_list = entries[i].get_next(); + entries[i].udata = value; + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + counter++; + return i; + } + +public: + class iterator + { + new_dict *ptr; + int index; + public: + iterator(new_dict *ptr, int index) : ptr(ptr), index(index) { } + iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + std::pair &operator*() { return ptr->entries[index].udata; } + }; + + new_dict() + { + init(); + } + + template + new_dict(InputIterator first, InputIterator last) + { + init(); + insert(first, last); + } + + template + void insert(InputIterator first, InputIterator last) + { + for (; first != last; ++first) + insert(*first); + } + + iterator insert(const std::pair &value) + { + int hash = mkhash(value.first); + int i = lookup_index(value.first, hash); + if (i >= 0) + return iterator(this, i); + i = insert_at(value, hash); + return iterator(this, i); + } + + void erase(const K &key) + { + int hash = mkhash(key); + do_erase(key, hash); + } + + int count(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i < 0 ? 0 : 1; + } + + T& operator[](const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + i = insert_at(std::pair(key, T()), hash); + return entries[i].udata.second; + } + + iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } + iterator end() { return iterator(this, entries.size()); } +}; + +#endif diff --git a/kernel/log.cc b/kernel/log.cc index 0773429a6..677884c97 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -301,7 +301,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent) // --------------------------------------------------- #ifdef YOSYS_ENABLE_COVER -std::map> extra_coverage_data; +new_dict> extra_coverage_data; void cover_extra(std::string parent, std::string id, bool increment) { if (extra_coverage_data.count(id) == 0) { @@ -314,9 +314,9 @@ void cover_extra(std::string parent, std::string id, bool increment) { extra_coverage_data[id].second++; } -std::map> get_coverage_data() +new_dict> get_coverage_data() { - std::map> coverage_data; + new_dict> coverage_data; for (auto &it : pass_register) { std::string key = stringf("passes.%s", it.first.c_str()); diff --git a/kernel/log.h b/kernel/log.h index 278e35b41..eec071991 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -106,10 +106,10 @@ struct CoverData { extern "C" struct CoverData __start_yosys_cover_list[]; extern "C" struct CoverData __stop_yosys_cover_list[]; -extern std::map> extra_coverage_data; +extern new_dict> extra_coverage_data; void cover_extra(std::string parent, std::string id, bool increment = true); -std::map> get_coverage_data(); +new_dict> get_coverage_data(); #define cover_list(_id, ...) do { cover(_id); \ std::string r = cover_list_worker(_id, __VA_ARGS__); \ diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2d3d83f42..28fdeecdd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2171,7 +2171,7 @@ RTLIL::SigSpec::SigSpec(std::vector bits) RTLIL::SigSpec::SigSpec(nodict bits) { - cover("kernel.rtlil.sigspec.init.stdset_bits"); + cover("kernel.rtlil.sigspec.init.nodict_bits"); width_ = 0; hash_ = 0; diff --git a/kernel/yosys.h b/kernel/yosys.h index e2daabfae..b14852eaf 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -126,6 +126,7 @@ YOSYS_NAMESPACE_BEGIN #define dict std::unordered_map #define nodict std::unordered_set +#include "kernel/hashmap.h" using std::vector; namespace RTLIL { -- cgit v1.2.3 From 9e6fb0b02ccf209528ead026de8eef0a8a0d7740 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 21:35:22 +0100 Subject: Replaced std::unordered_map as implementation for Yosys::dict --- kernel/cost.h | 14 ++-- kernel/hashmap.h | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++----- kernel/log.cc | 6 +- kernel/log.h | 4 +- kernel/rtlil.cc | 22 +++--- kernel/rtlil.h | 32 +++++++- kernel/yosys.h | 1 - 7 files changed, 262 insertions(+), 47 deletions(-) (limited to 'kernel') diff --git a/kernel/cost.h b/kernel/cost.h index 1b4166e00..c6c631e0a 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -24,10 +24,10 @@ YOSYS_NAMESPACE_BEGIN -int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache = nullptr); +int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache = nullptr); int get_cell_cost(RTLIL::IdString type, const dict ¶meters = dict(), - RTLIL::Design *design = nullptr, dict *mod_cost_cache = nullptr) + RTLIL::Design *design = nullptr, dict *mod_cost_cache = nullptr) { static dict gate_cost = { { "$_BUF_", 1 }, @@ -55,18 +55,18 @@ int get_cell_cost(RTLIL::IdString type, const dictattributes.count("\\cost")) return mod->attributes.at("\\cost").as_int(); - dict local_mod_cost_cache; + dict local_mod_cost_cache; if (mod_cost_cache == nullptr) mod_cost_cache = &local_mod_cost_cache; - if (mod_cost_cache->count(mod)) - return mod_cost_cache->at(mod); + if (mod_cost_cache->count(mod->name)) + return mod_cost_cache->at(mod->name); int module_cost = 1; for (auto c : mod->cells()) module_cost += get_cell_cost(c, mod_cost_cache); - (*mod_cost_cache)[mod] = module_cost; + (*mod_cost_cache)[mod->name] = module_cost; return module_cost; } @@ -74,7 +74,7 @@ int get_cell_cost(RTLIL::IdString type, const dict *mod_cost_cache) +int get_cell_cost(RTLIL::Cell *cell, dict *mod_cost_cache) { return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); } diff --git a/kernel/hashmap.h b/kernel/hashmap.h index bd4fc4d22..d5f8c4e98 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -19,6 +19,7 @@ #ifndef YOSYS_HASHMAP_H +#include #include #include @@ -27,28 +28,28 @@ inline unsigned int mkhash(unsigned int a, unsigned int b) { } template struct hash_ops { - bool cmp(const T &a, const T &b) { + bool cmp(const T &a, const T &b) const { return a == b; } - unsigned int hash(const T &a) { + unsigned int hash(const T &a) const { return a.hash(); } }; template<> struct hash_ops { - bool cmp(int a, int b) { + bool cmp(int a, int b) const { return a == b; } - unsigned int hash(int a) { + unsigned int hash(int a) const { return a; } }; template<> struct hash_ops { - bool cmp(const std::string &a, const std::string &b) { + bool cmp(const std::string &a, const std::string &b) const { return a == b; } - unsigned int hash(const std::string &a) { + unsigned int hash(const std::string &a) const { unsigned int v = 0; for (auto c : a) v = mkhash(v, c); @@ -56,14 +57,25 @@ template<> struct hash_ops { } }; +struct hash_ptr_ops { + bool cmp(const void *a, const void *b) const { + return a == b; + } + unsigned int hash(const void *a) const { + return (unsigned long)a; + } +}; + template> -class new_dict +class dict { struct entry_t { int link; std::pair udata; + entry_t() : link(-1) { } + entry_t(const std::pair &udata) : link(1), udata(udata) { } bool is_free() const { return link < 0; } int get_next() const { return (link > 0 ? link : -link) - 2; } @@ -79,17 +91,61 @@ class new_dict void init() { + free_list = -1; counter = 0; - entries.resize(61); + } + + void init_from(const dict &other) + { + hashtable.clear(); + entries.clear(); + + counter = other.size(); + int new_size = grow_size(counter); + entries.reserve(new_size); + + for (auto &it : other) + entries.push_back(entry_t(it)); + entries.resize(new_size); rehash(); } - int mkhash(const K &key) + size_t grow_size(size_t old_size) { - return ops.hash(key) % int(hashtable.size()); + if (old_size < 53) return 53; + if (old_size < 113) return 113; + if (old_size < 251) return 251; + if (old_size < 503) return 503; + if (old_size < 1130) return 1130; + if (old_size < 2510) return 2510; + if (old_size < 5030) return 5030; + if (old_size < 11300) return 11300; + if (old_size < 25100) return 25100; + if (old_size < 50300) return 50300; + if (old_size < 113000) return 113000; + if (old_size < 251000) return 251000; + if (old_size < 503000) return 503000; + if (old_size < 1130000) return 1130000; + if (old_size < 2510000) return 2510000; + if (old_size < 5030000) return 5030000; + if (old_size < 11300000) return 11300000; + if (old_size < 25100000) return 25100000; + if (old_size < 50300000) return 50300000; + if (old_size < 113000000) return 113000000; + if (old_size < 251000000) return 251000000; + if (old_size < 503000000) return 503000000; + if (old_size < 1130000000) return 1130000000; + throw std::length_error("maximum size for dict reached"); + } + + int mkhash(const K &key) const + { + unsigned int hash = 0; + if (!hashtable.empty()) + hash = ops.hash(key) % (unsigned int)(hashtable.size()); + return hash; } -public: void rehash() { free_list = -1; @@ -112,7 +168,7 @@ public: void do_erase(const K &key, int hash) { int last_index = -1; - int index = hashtable[hash]; + int index = hashtable.empty() ? -1 : hashtable[hash]; while (1) { if (index < 0) return; @@ -124,7 +180,8 @@ public: entries[index].udata = std::pair(); entries[index].set_next_free(free_list); free_list = index; - counter--; + if (--counter == 0) + init(); return; } last_index = index; @@ -132,9 +189,9 @@ public: } } - int lookup_index(const K &key, int hash) + int lookup_index(const K &key, int hash) const { - int index = hashtable[hash]; + int index = hashtable.empty() ? -1 : hashtable[hash]; while (1) { if (index < 0) return -1; @@ -149,7 +206,7 @@ public: if (free_list < 0) { int i = entries.size(); - entries.resize(2*entries.size()); + entries.resize(grow_size(i)); entries[i].udata = value; entries[i].set_next_used(0); counter++; @@ -169,24 +226,74 @@ public: public: class iterator { - new_dict *ptr; + dict *ptr; int index; public: - iterator(new_dict *ptr, int index) : ptr(ptr), index(index) { } + iterator() { } + iterator(dict *ptr, int index) : ptr(ptr), index(index) { } iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } std::pair &operator*() { return ptr->entries[index].udata; } + std::pair *operator->() { return &ptr->entries[index].udata; } + const std::pair &operator*() const { return ptr->entries[index].udata; } + const std::pair *operator->() const { return &ptr->entries[index].udata; } }; - new_dict() + class const_iterator + { + const dict *ptr; + int index; + public: + const_iterator() { } + const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } + const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } + const std::pair &operator*() const { return ptr->entries[index].udata; } + const std::pair *operator->() const { return &ptr->entries[index].udata; } + }; + + dict() { init(); } + dict(const dict &other) + { + init_from(other); + } + + dict(dict &&other) + { + free_list = -1; + counter = 0; + swap(other); + } + + dict &operator=(const dict &other) { + clear(); + init_from(other); + return *this; + } + + dict &operator=(dict &&other) { + clear(); + swap(other); + return *this; + } + + dict(const std::initializer_list> &list) + { + init(); + for (auto &it : list) + insert(it); + } + template - new_dict(InputIterator first, InputIterator last) + dict(InputIterator first, InputIterator last) { init(); insert(first, last); @@ -215,13 +322,55 @@ public: do_erase(key, hash); } - int count(const K &key) + void erase(const iterator it) + { + int hash = mkhash(it->first); + do_erase(it->first, hash); + } + + int count(const K &key) const { int hash = mkhash(key); int i = lookup_index(key, hash); return i < 0 ? 0 : 1; } + iterator find(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return iterator(this, i); + } + + const_iterator find(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return const_iterator(this, i); + } + + T& at(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + throw std::out_of_range("dict::at()"); + return entries[i].udata.second; + } + + const T& at(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + throw std::out_of_range("dict::at()"); + return entries[i].udata.second; + } + T& operator[](const K &key) { int hash = mkhash(key); @@ -231,8 +380,47 @@ public: return entries[i].udata.second; } + void swap(dict &other) + { + hashtable.swap(other.hashtable); + entries.swap(other.entries); + std::swap(free_list, other.free_list); + std::swap(counter, other.counter); + } + + bool operator==(const dict &other) const { + if (counter != other.counter) + return false; + if (counter == 0) + return true; + if (entries.size() < other.entries.size()) + for (auto &it : *this) { + auto oit = other.find(it.first); + if (oit == other.end() || oit->second != it.second) + return false; + } + else + for (auto &oit : other) { + auto it = find(oit.first); + if (it == end() || it->second != oit.second) + return false; + } + return true; + } + + bool operator!=(const dict &other) const { + return !(*this == other); + } + + size_t size() const { return counter; } + bool empty() const { return counter == 0; } + void clear() { hashtable.clear(); entries.clear(); init(); } + iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } iterator end() { return iterator(this, entries.size()); } + + const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } + const_iterator end() const { return const_iterator(this, entries.size()); } }; #endif diff --git a/kernel/log.cc b/kernel/log.cc index 677884c97..5b18e3d6c 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -301,7 +301,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent) // --------------------------------------------------- #ifdef YOSYS_ENABLE_COVER -new_dict> extra_coverage_data; +dict> extra_coverage_data; void cover_extra(std::string parent, std::string id, bool increment) { if (extra_coverage_data.count(id) == 0) { @@ -314,9 +314,9 @@ void cover_extra(std::string parent, std::string id, bool increment) { extra_coverage_data[id].second++; } -new_dict> get_coverage_data() +dict> get_coverage_data() { - new_dict> coverage_data; + dict> coverage_data; for (auto &it : pass_register) { std::string key = stringf("passes.%s", it.first.c_str()); diff --git a/kernel/log.h b/kernel/log.h index eec071991..9bb2b3621 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -106,10 +106,10 @@ struct CoverData { extern "C" struct CoverData __start_yosys_cover_list[]; extern "C" struct CoverData __stop_yosys_cover_list[]; -extern new_dict> extra_coverage_data; +extern dict> extra_coverage_data; void cover_extra(std::string parent, std::string id, bool increment = true); -new_dict> get_coverage_data(); +dict> get_coverage_data(); #define cover_list(_id, ...) do { cover(_id); \ std::string r = cover_list_worker(_id, __VA_ARGS__); \ diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 28fdeecdd..05160b869 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -30,7 +30,7 @@ YOSYS_NAMESPACE_BEGIN RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_id_storage_; -dict RTLIL::IdString::global_id_index_; +dict RTLIL::IdString::global_id_index_; std::vector RTLIL::IdString::global_free_idx_list_; RTLIL::Const::Const() @@ -242,7 +242,7 @@ RTLIL::Design::Design() RTLIL::Design::~Design() { - for (auto it = modules_.begin(); it != modules_.end(); it++) + for (auto it = modules_.begin(); it != modules_.end(); ++it) delete it->second; } @@ -454,13 +454,13 @@ 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; } @@ -2258,7 +2258,7 @@ void RTLIL::SigSpec::unpack() const #define DJB2(_hash, _value) (_hash) = (((_hash) << 5) + (_hash)) + (_value) -void RTLIL::SigSpec::hash() const +void RTLIL::SigSpec::updhash() const { RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; @@ -2721,8 +2721,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_; @@ -2753,8 +2753,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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e684ba4ae..756cca71c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -124,6 +124,21 @@ namespace RTLIL } }; + struct char_ptr_ops { + bool cmp(const char *a, const char *b) const { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return false; + return true; + } + unsigned int hash(const char *a) const { + size_t hash = 5381; + while (*a) + hash = mkhash(hash, *(a++)); + return hash; + } + }; + static struct destruct_guard_t { bool ok; // POD, will be initialized to zero destruct_guard_t() { ok = true; } @@ -132,7 +147,7 @@ namespace RTLIL static std::vector global_refcount_storage_; static std::vector global_id_storage_; - static dict global_id_index_; + static dict global_id_index_; static std::vector global_free_idx_list_; static inline int get_reference(int idx) @@ -263,6 +278,10 @@ namespace RTLIL *this = IdString(); } + unsigned int hash() const { + return index_; + } + // The following is a helper key_compare class. Instead of for example nodict // use nodict> if the order of cells in the // set has an influence on the algorithm. @@ -538,6 +557,7 @@ struct RTLIL::SigBit bool operator <(const RTLIL::SigBit &other) const; bool operator ==(const RTLIL::SigBit &other) const; bool operator !=(const RTLIL::SigBit &other) const; + unsigned int hash() const; }; struct RTLIL::SigSpecIterator : public std::iterator @@ -572,7 +592,7 @@ private: void pack() const; void unpack() const; - void hash() const; + void updhash() const; inline bool packed() const { return bits_.empty(); @@ -710,6 +730,8 @@ public: operator std::vector() const { return chunks(); } operator std::vector() const { return bits(); } + unsigned int hash() const { if (!hash_) updhash(); return hash_; }; + #ifndef NDEBUG void check() const; #else @@ -1213,6 +1235,12 @@ inline bool RTLIL::SigBit::operator!=(const RTLIL::SigBit &other) const { return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); } +inline unsigned int RTLIL::SigBit::hash() const { + if (wire) + return wire->name.hash() * 33 + offset; + return data; +} + inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { return (*sig_p)[index]; } diff --git a/kernel/yosys.h b/kernel/yosys.h index b14852eaf..9b76d28c6 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -124,7 +124,6 @@ YOSYS_NAMESPACE_BEGIN -#define dict std::unordered_map #define nodict std::unordered_set #include "kernel/hashmap.h" using std::vector; -- cgit v1.2.3 From ec4751e55c11d7287dacd39fb61ad936995fc963 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 21:59:41 +0100 Subject: Replaced std::unordered_set (nodict) with Yosys::pool --- kernel/hashmap.h | 352 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.cc | 30 ++--- kernel/rtlil.h | 132 +++------------------ kernel/yosys.h | 1 - 4 files changed, 386 insertions(+), 129 deletions(-) (limited to 'kernel') diff --git a/kernel/hashmap.h b/kernel/hashmap.h index d5f8c4e98..50098ac35 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -57,6 +57,21 @@ template<> struct hash_ops { } }; +struct hash_cstr_ops { + bool cmp(const char *a, const char *b) const { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return false; + return true; + } + unsigned int hash(const char *a) const { + size_t hash = 5381; + while (*a) + hash = mkhash(hash, *(a++)); + return hash; + } +}; + struct hash_ptr_ops { bool cmp(const void *a, const void *b) const { return a == b; @@ -423,4 +438,341 @@ public: const_iterator end() const { return const_iterator(this, entries.size()); } }; +template> +class pool +{ + struct entry_t + { + int link; + K key; + + entry_t() : link(-1) { } + entry_t(const K &key) : link(1), key(key) { } + + bool is_free() const { return link < 0; } + int get_next() const { return (link > 0 ? link : -link) - 2; } + bool get_last() const { return get_next() == -1; } + void set_next_used(int next) { link = next + 2; } + void set_next_free(int next) { link = -(next + 2); } + }; + + std::vector hashtable; + std::vector entries; + int free_list, counter; + OPS ops; + + void init() + { + free_list = -1; + counter = 0; + } + + void init_from(const pool &other) + { + hashtable.clear(); + entries.clear(); + + counter = other.size(); + int new_size = grow_size(counter); + entries.reserve(new_size); + + for (auto &it : other) + entries.push_back(entry_t(it)); + entries.resize(new_size); + rehash(); + } + + size_t grow_size(size_t old_size) + { + if (old_size < 53) return 53; + if (old_size < 113) return 113; + if (old_size < 251) return 251; + if (old_size < 503) return 503; + if (old_size < 1130) return 1130; + if (old_size < 2510) return 2510; + if (old_size < 5030) return 5030; + if (old_size < 11300) return 11300; + if (old_size < 25100) return 25100; + if (old_size < 50300) return 50300; + if (old_size < 113000) return 113000; + if (old_size < 251000) return 251000; + if (old_size < 503000) return 503000; + if (old_size < 1130000) return 1130000; + if (old_size < 2510000) return 2510000; + if (old_size < 5030000) return 5030000; + if (old_size < 11300000) return 11300000; + if (old_size < 25100000) return 25100000; + if (old_size < 50300000) return 50300000; + if (old_size < 113000000) return 113000000; + if (old_size < 251000000) return 251000000; + if (old_size < 503000000) return 503000000; + if (old_size < 1130000000) return 1130000000; + throw std::length_error("maximum size for pool reached"); + } + + int mkhash(const K &key) const + { + unsigned int hash = 0; + if (!hashtable.empty()) + hash = ops.hash(key) % (unsigned int)(hashtable.size()); + return hash; + } + + void rehash() + { + free_list = -1; + + hashtable.resize(entries.size()); + for (auto &h : hashtable) + h = -1; + + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + entries[i].set_next_free(free_list); + free_list = i; + } else { + int hash = mkhash(entries[i].key); + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + } + } + + void do_erase(const K &key, int hash) + { + int last_index = -1; + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return; + if (ops.cmp(entries[index].key, key)) { + if (last_index < 0) + hashtable[hash] = entries[index].get_next(); + else + entries[last_index].set_next_used(entries[index].get_next()); + entries[index].key = K(); + entries[index].set_next_free(free_list); + free_list = index; + if (--counter == 0) + init(); + return; + } + last_index = index; + index = entries[index].get_next(); + } + } + + int lookup_index(const K &key, int hash) const + { + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return -1; + if (ops.cmp(entries[index].key, key)) + return index; + index = entries[index].get_next(); + } + } + + int insert_at(const K &key, int hash) + { + if (free_list < 0) + { + int i = entries.size(); + entries.resize(grow_size(i)); + entries[i].key = key; + entries[i].set_next_used(0); + counter++; + rehash(); + return i; + } + + int i = free_list; + free_list = entries[i].get_next(); + entries[i].key = key; + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + counter++; + return i; + } + +public: + class iterator + { + pool *ptr; + int index; + public: + iterator() { } + iterator(pool *ptr, int index) : ptr(ptr), index(index) { } + iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + K &operator*() { return ptr->entries[index].key; } + K *operator->() { return &ptr->entries[index].key; } + const K &operator*() const { return ptr->entries[index].key; } + const K *operator->() const { return &ptr->entries[index].key; } + }; + + class const_iterator + { + const pool *ptr; + int index; + public: + const_iterator() { } + const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } + const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } + const K &operator*() const { return ptr->entries[index].key; } + const K *operator->() const { return &ptr->entries[index].key; } + }; + + pool() + { + init(); + } + + pool(const pool &other) + { + init_from(other); + } + + pool(pool &&other) + { + free_list = -1; + counter = 0; + swap(other); + } + + pool &operator=(const pool &other) { + clear(); + init_from(other); + return *this; + } + + pool &operator=(pool &&other) { + clear(); + swap(other); + return *this; + } + + pool(const std::initializer_list &list) + { + init(); + for (auto &it : list) + insert(it); + } + + template + pool(InputIterator first, InputIterator last) + { + init(); + insert(first, last); + } + + template + void insert(InputIterator first, InputIterator last) + { + for (; first != last; ++first) + insert(*first); + } + + iterator insert(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i >= 0) + return iterator(this, i); + i = insert_at(key, hash); + return iterator(this, i); + } + + void erase(const K &key) + { + int hash = mkhash(key); + do_erase(key, hash); + } + + void erase(const iterator it) + { + int hash = mkhash(it->first); + do_erase(it->first, hash); + } + + int count(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i < 0 ? 0 : 1; + } + + iterator find(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return iterator(this, i); + } + + const_iterator find(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return const_iterator(this, i); + } + + bool operator[](const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i >= 0; + } + + void swap(pool &other) + { + hashtable.swap(other.hashtable); + entries.swap(other.entries); + std::swap(free_list, other.free_list); + std::swap(counter, other.counter); + } + + bool operator==(const pool &other) const { + if (counter != other.counter) + return false; + if (counter == 0) + return true; + if (entries.size() < other.entries.size()) + for (auto &it : *this) { + auto oit = other.find(it.first); + if (oit == other.end() || oit->second != it.second) + return false; + } + else + for (auto &oit : other) { + auto it = find(oit.first); + if (it == end() || it->second != oit.second) + return false; + } + return true; + } + + bool operator!=(const pool &other) const { + return !(*this == other); + } + + size_t size() const { return counter; } + bool empty() const { return counter == 0; } + void clear() { hashtable.clear(); entries.clear(); init(); } + + iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } + iterator end() { return iterator(this, entries.size()); } + + const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } + const_iterator end() const { return const_iterator(this, entries.size()); } +}; + #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 05160b869..8f65f5273 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -30,7 +30,7 @@ YOSYS_NAMESPACE_BEGIN RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; std::vector RTLIL::IdString::global_refcount_storage_; std::vector RTLIL::IdString::global_id_storage_; -dict RTLIL::IdString::global_id_index_; +dict RTLIL::IdString::global_id_index_; std::vector RTLIL::IdString::global_free_idx_list_; RTLIL::Const::Const() @@ -480,7 +480,7 @@ namespace { { RTLIL::Module *module; RTLIL::Cell *cell; - nodict expected_params, expected_ports; + pool expected_params, expected_ports; InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } @@ -1132,7 +1132,7 @@ namespace { struct DeleteWireWorker { RTLIL::Module *module; - const nodict *wires_p; + const pool *wires_p; void operator()(RTLIL::SigSpec &sig) { std::vector chunks = sig; @@ -1146,7 +1146,7 @@ namespace { }; } -void RTLIL::Module::remove(const nodict &wires) +void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); @@ -2169,9 +2169,9 @@ RTLIL::SigSpec::SigSpec(std::vector bits) check(); } -RTLIL::SigSpec::SigSpec(nodict bits) +RTLIL::SigSpec::SigSpec(pool bits) { - cover("kernel.rtlil.sigspec.init.nodict_bits"); + cover("kernel.rtlil.sigspec.init.pool_bits"); width_ = 0; hash_ = 0; @@ -2378,22 +2378,22 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { - nodict pattern_bits = pattern.to_sigbit_nodict(); + pool pattern_bits = pattern.to_sigbit_nodict(); remove2(pattern_bits, other); } -void RTLIL::SigSpec::remove(const nodict &pattern) +void RTLIL::SigSpec::remove(const pool &pattern) { remove2(pattern, NULL); } -void RTLIL::SigSpec::remove(const nodict &pattern, RTLIL::SigSpec *other) const +void RTLIL::SigSpec::remove(const pool &pattern, RTLIL::SigSpec *other) const { RTLIL::SigSpec tmp = *this; tmp.remove2(pattern, other); } -void RTLIL::SigSpec::remove2(const nodict &pattern, RTLIL::SigSpec *other) +void RTLIL::SigSpec::remove2(const pool &pattern, RTLIL::SigSpec *other) { if (other) cover("kernel.rtlil.sigspec.remove_other"); @@ -2439,11 +2439,11 @@ void RTLIL::SigSpec::remove2(const nodict &pattern, RTLIL::SigSpe RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const { - nodict pattern_bits = pattern.to_sigbit_nodict(); + pool pattern_bits = pattern.to_sigbit_nodict(); return extract(pattern_bits, other); } -RTLIL::SigSpec RTLIL::SigSpec::extract(const nodict &pattern, const RTLIL::SigSpec *other) const +RTLIL::SigSpec RTLIL::SigSpec::extract(const pool &pattern, const RTLIL::SigSpec *other) const { if (other) cover("kernel.rtlil.sigspec.extract_other"); @@ -2943,12 +2943,12 @@ std::set RTLIL::SigSpec::to_sigbit_set() const return sigbits; } -nodict RTLIL::SigSpec::to_sigbit_nodict() const +pool RTLIL::SigSpec::to_sigbit_nodict() const { - cover("kernel.rtlil.sigspec.to_sigbit_nodict"); + cover("kernel.rtlil.sigspec.to_sigbit_pool"); pack(); - nodict sigbits; + pool sigbits; for (auto &c : chunks_) for (int i = 0; i < c.width; i++) sigbits.insert(RTLIL::SigBit(c, i)); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 756cca71c..ae37c350c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -22,27 +22,6 @@ #ifndef RTLIL_H #define RTLIL_H -namespace std { - template<> struct hash { - size_t operator()(const Yosys::RTLIL::IdString &arg) const; - }; - template<> struct equal_to { - bool operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const; - }; - template<> struct hash { - size_t operator()(const Yosys::RTLIL::SigBit &arg) const; - }; - template<> struct equal_to { - bool operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const; - }; - template<> struct hash { - size_t operator()(const Yosys::RTLIL::SigSpec &arg) const; - }; - template<> struct equal_to { - bool operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const; - }; -} - YOSYS_NAMESPACE_BEGIN namespace RTLIL @@ -97,48 +76,6 @@ namespace RTLIL { // the global id string cache - struct char_ptr_cmp { - bool operator()(const char *a, const char *b) const { - for (int i = 0; a[i] || b[i]; i++) - if (a[i] != b[i]) - return a[i] < b[i]; - return false; - } - }; - - struct char_ptr_hash { - size_t operator()(const char *a) const { - size_t hash = 5381; - for (int c; (c = *a); a++) - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - return hash; - } - }; - - struct char_ptr_eq { - bool operator()(const char *a, const char *b) const { - for (int i = 0; a[i] || b[i]; i++) - if (a[i] != b[i]) - return false; - return true; - } - }; - - struct char_ptr_ops { - bool cmp(const char *a, const char *b) const { - for (int i = 0; a[i] || b[i]; i++) - if (a[i] != b[i]) - return false; - return true; - } - unsigned int hash(const char *a) const { - size_t hash = 5381; - while (*a) - hash = mkhash(hash, *(a++)); - return hash; - } - }; - static struct destruct_guard_t { bool ok; // POD, will be initialized to zero destruct_guard_t() { ok = true; } @@ -147,7 +84,7 @@ namespace RTLIL static std::vector global_refcount_storage_; static std::vector global_id_storage_; - static dict global_id_index_; + static dict global_id_index_; static std::vector global_free_idx_list_; static inline int get_reference(int idx) @@ -282,8 +219,8 @@ namespace RTLIL return index_; } - // The following is a helper key_compare class. Instead of for example nodict - // use nodict> if the order of cells in the + // The following is a helper key_compare class. Instead of for example pool + // use pool> if the order of cells in the // set has an influence on the algorithm. template struct compare_ptr_by_name { @@ -303,7 +240,7 @@ namespace RTLIL bool in(IdString rhs) { return *this == rhs; } bool in(const char *rhs) { return *this == rhs; } bool in(const std::string &rhs) { return *this == rhs; } - bool in(const nodict &rhs) { return rhs.count(*this) != 0; } + bool in(const pool &rhs) { return rhs.count(*this) != 0; } }; static inline std::string escape_id(std::string str) { @@ -470,8 +407,8 @@ namespace RTLIL return list_p->size(); } - operator nodict() const { - nodict result; + operator pool() const { + pool result; for (auto &it : *list_p) result.insert(it.second); return result; @@ -485,7 +422,7 @@ namespace RTLIL return result; } - nodict to_set() const { return *this; } + pool to_set() const { return *this; } std::vector to_vector() const { return *this; } }; }; @@ -619,7 +556,7 @@ public: SigSpec(RTLIL::SigBit bit, int width = 1); SigSpec(std::vector chunks); SigSpec(std::vector bits); - SigSpec(nodict bits); + SigSpec(pool bits); SigSpec(std::set bits); SigSpec(bool bit); @@ -676,15 +613,15 @@ public: void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); - void remove(const nodict &pattern); - void remove(const nodict &pattern, RTLIL::SigSpec *other) const; - void remove2(const nodict &pattern, RTLIL::SigSpec *other); + void remove(const pool &pattern); + void remove(const pool &pattern, RTLIL::SigSpec *other) const; + void remove2(const pool &pattern, RTLIL::SigSpec *other); void remove(int offset, int length = 1); void remove_const(); RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; - RTLIL::SigSpec extract(const nodict &pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const pool &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; void append(const RTLIL::SigSpec &signal); @@ -717,7 +654,7 @@ public: bool match(std::string pattern) const; std::set to_sigbit_set() const; - nodict to_sigbit_nodict() const; + pool to_sigbit_nodict() const; std::vector to_sigbit_vector() const; std::map to_sigbit_map(const RTLIL::SigSpec &other) const; dict to_sigbit_dict(const RTLIL::SigSpec &other) const; @@ -742,8 +679,8 @@ public: struct RTLIL::Selection { bool full_selection; - nodict selected_modules; - dict> selected_members; + pool selected_modules; + dict> selected_members; Selection(bool full = true) : full_selection(full) { } @@ -782,7 +719,7 @@ struct RTLIL::Monitor struct RTLIL::Design { - nodict monitors; + pool monitors; dict scratchpad; int refcount_modules_; @@ -869,7 +806,7 @@ protected: public: RTLIL::Design *design; - nodict monitors; + pool monitors; int refcount_wires_; int refcount_cells_; @@ -879,7 +816,7 @@ public: std::vector connections_; RTLIL::IdString name; - nodict avail_parameters; + pool avail_parameters; dict memories; dict processes; RTLIL_ATTRIBUTE_MEMBERS @@ -923,7 +860,7 @@ public: RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const nodict &wires); + void remove(const pool &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); @@ -1313,35 +1250,4 @@ void RTLIL::Process::rewrite_sigspecs(T functor) YOSYS_NAMESPACE_END -inline size_t std::hash::operator()(const Yosys::RTLIL::IdString &arg) const { - return arg.index_; -} - -inline bool std::equal_to::operator()(const Yosys::RTLIL::IdString &lhs, const Yosys::RTLIL::IdString &rhs) const { - return lhs.index_ == rhs.index_; -} - -inline size_t std::hash::operator()(const Yosys::RTLIL::SigBit &arg) const { - if (arg.wire) { - size_t hash = arg.wire->name.index_; - hash = ((hash << 5) + hash) + arg.offset; - return hash; - } - return arg.data; -} - -inline bool std::equal_to::operator()(const Yosys::RTLIL::SigBit &lhs, const Yosys::RTLIL::SigBit &rhs) const { - if (lhs.wire || rhs.wire) - return lhs.wire == rhs.wire && lhs.offset == rhs.offset; - return lhs.data == rhs.data; -} - -inline size_t std::hash::operator()(const Yosys::RTLIL::SigSpec &arg) const { - return arg.get_hash(); -} - -inline bool std::equal_to::operator()(const Yosys::RTLIL::SigSpec &lhs, const Yosys::RTLIL::SigSpec &rhs) const { - return lhs == rhs; -} - #endif diff --git a/kernel/yosys.h b/kernel/yosys.h index 9b76d28c6..012b40c1f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -124,7 +124,6 @@ YOSYS_NAMESPACE_BEGIN -#define nodict std::unordered_set #include "kernel/hashmap.h" using std::vector; -- cgit v1.2.3 From 6ce6689b639785f3d526c73faad6faba811beaf8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 22:08:44 +0100 Subject: Using Yosys::dict and Yosys::pool in sigtools.h --- kernel/sigtools.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/sigtools.h b/kernel/sigtools.h index c3c6a8db1..5281b7a45 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -29,9 +29,10 @@ struct SigPool struct bitDef_t : public std::pair { bitDef_t() : std::pair(NULL, 0) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + unsigned int hash() const { return first->name.hash() + second; } }; - std::set bits; + pool bits; void clear() { @@ -122,7 +123,7 @@ struct SigPool RTLIL::SigSpec export_all() { - std::set sig; + pool sig; for (auto &bit : bits) sig.insert(RTLIL::SigBit(bit.first, bit.second)); return sig; @@ -140,9 +141,10 @@ struct SigSet struct bitDef_t : public std::pair { bitDef_t() : std::pair(NULL, 0) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + unsigned int hash() const { return first->name.hash() + second; } }; - std::map> bits; + dict> bits; void clear() { @@ -214,6 +216,7 @@ struct SigMap struct bitDef_t : public std::pair { bitDef_t() : std::pair(NULL, 0) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + unsigned int hash() const { return first->name.hash() + second; } }; struct shared_bit_data_t { @@ -221,7 +224,7 @@ struct SigMap std::set bits; }; - std::map bits; + dict bits; SigMap(RTLIL::Module *module = NULL) { -- cgit v1.2.3 From 88d08e8f24cb2d43907a9d28d65fedc9638554ca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 26 Dec 2014 23:21:23 +0100 Subject: Some cleanups in dict/pool hashtable implementation --- kernel/hashmap.h | 94 ++++++++++++++++++++------------------------------------ 1 file changed, 33 insertions(+), 61 deletions(-) (limited to 'kernel') diff --git a/kernel/hashmap.h b/kernel/hashmap.h index 50098ac35..91df68a71 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -65,7 +65,7 @@ struct hash_cstr_ops { return true; } unsigned int hash(const char *a) const { - size_t hash = 5381; + unsigned int hash = 5381; while (*a) hash = mkhash(hash, *(a++)); return hash; @@ -81,6 +81,34 @@ struct hash_ptr_ops { } }; +inline int hashtable_size(int old_size) +{ + if (old_size < 53) return 53; + if (old_size < 113) return 113; + if (old_size < 251) return 251; + if (old_size < 503) return 503; + if (old_size < 1129) return 1129; + if (old_size < 2503) return 2503; + if (old_size < 5023) return 5023; + if (old_size < 11299) return 11299; + if (old_size < 25097) return 25097; + if (old_size < 50291) return 50291; + if (old_size < 112997) return 112997; + if (old_size < 251003) return 251003; + if (old_size < 503003) return 503003; + if (old_size < 1129991) return 1129991; + if (old_size < 2509993) return 2509993; + if (old_size < 5029991) return 5029991; + if (old_size < 11299997) return 11299997; + if (old_size < 25099999) return 25099999; + if (old_size < 50299999) return 50299999; + if (old_size < 113000009) return 113000009; + if (old_size < 250999999) return 250999999; + if (old_size < 503000009) return 503000009; + if (old_size < 1129999999) return 1129999999; + throw std::length_error("hash table exceeded maximum size"); +} + template> class dict { @@ -116,7 +144,7 @@ class dict entries.clear(); counter = other.size(); - int new_size = grow_size(counter); + int new_size = hashtable_size(counter); entries.reserve(new_size); for (auto &it : other) @@ -125,34 +153,6 @@ class dict rehash(); } - size_t grow_size(size_t old_size) - { - if (old_size < 53) return 53; - if (old_size < 113) return 113; - if (old_size < 251) return 251; - if (old_size < 503) return 503; - if (old_size < 1130) return 1130; - if (old_size < 2510) return 2510; - if (old_size < 5030) return 5030; - if (old_size < 11300) return 11300; - if (old_size < 25100) return 25100; - if (old_size < 50300) return 50300; - if (old_size < 113000) return 113000; - if (old_size < 251000) return 251000; - if (old_size < 503000) return 503000; - if (old_size < 1130000) return 1130000; - if (old_size < 2510000) return 2510000; - if (old_size < 5030000) return 5030000; - if (old_size < 11300000) return 11300000; - if (old_size < 25100000) return 25100000; - if (old_size < 50300000) return 50300000; - if (old_size < 113000000) return 113000000; - if (old_size < 251000000) return 251000000; - if (old_size < 503000000) return 503000000; - if (old_size < 1130000000) return 1130000000; - throw std::length_error("maximum size for dict reached"); - } - int mkhash(const K &key) const { unsigned int hash = 0; @@ -221,7 +221,7 @@ class dict if (free_list < 0) { int i = entries.size(); - entries.resize(grow_size(i)); + entries.resize(hashtable_size(i)); entries[i].udata = value; entries[i].set_next_used(0); counter++; @@ -473,7 +473,7 @@ class pool entries.clear(); counter = other.size(); - int new_size = grow_size(counter); + int new_size = hashtable_size(counter); entries.reserve(new_size); for (auto &it : other) @@ -482,34 +482,6 @@ class pool rehash(); } - size_t grow_size(size_t old_size) - { - if (old_size < 53) return 53; - if (old_size < 113) return 113; - if (old_size < 251) return 251; - if (old_size < 503) return 503; - if (old_size < 1130) return 1130; - if (old_size < 2510) return 2510; - if (old_size < 5030) return 5030; - if (old_size < 11300) return 11300; - if (old_size < 25100) return 25100; - if (old_size < 50300) return 50300; - if (old_size < 113000) return 113000; - if (old_size < 251000) return 251000; - if (old_size < 503000) return 503000; - if (old_size < 1130000) return 1130000; - if (old_size < 2510000) return 2510000; - if (old_size < 5030000) return 5030000; - if (old_size < 11300000) return 11300000; - if (old_size < 25100000) return 25100000; - if (old_size < 50300000) return 50300000; - if (old_size < 113000000) return 113000000; - if (old_size < 251000000) return 251000000; - if (old_size < 503000000) return 503000000; - if (old_size < 1130000000) return 1130000000; - throw std::length_error("maximum size for pool reached"); - } - int mkhash(const K &key) const { unsigned int hash = 0; @@ -578,7 +550,7 @@ class pool if (free_list < 0) { int i = entries.size(); - entries.resize(grow_size(i)); + entries.resize(hashtable_size(i)); entries[i].key = key; entries[i].set_next_used(0); counter++; -- cgit v1.2.3 From 66ab88d7b0636c21d5df74f753ed379a799fd783 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 03:04:50 +0100 Subject: More hashtable finetuning --- kernel/hashmap.h | 31 +++++++++++++++++++++++++------ kernel/rtlil.cc | 4 ++-- kernel/rtlil.h | 8 +++++--- kernel/yosys.h | 3 ++- 4 files changed, 34 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/hashmap.h b/kernel/hashmap.h index 91df68a71..729b4916c 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -23,6 +23,8 @@ #include #include +#define YOSYS_HASHTABLE_SIZE_FACTOR 3 + inline unsigned int mkhash(unsigned int a, unsigned int b) { return ((a << 5) + a) ^ b; } @@ -81,8 +83,19 @@ struct hash_ptr_ops { } }; +struct hash_obj_ops { + bool cmp(const void *a, const void *b) const { + return a == b; + } + template + unsigned int hash(const T *a) const { + return a->name.hash(); + } +}; + inline int hashtable_size(int old_size) { + // prime numbers, approx. in powers of two if (old_size < 53) return 53; if (old_size < 113) return 113; if (old_size < 251) return 251; @@ -144,7 +157,9 @@ class dict entries.clear(); counter = other.size(); - int new_size = hashtable_size(counter); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; entries.reserve(new_size); for (auto &it : other) @@ -165,7 +180,6 @@ class dict { free_list = -1; - hashtable.resize(entries.size()); for (auto &h : hashtable) h = -1; @@ -221,7 +235,9 @@ class dict if (free_list < 0) { int i = entries.size(); - entries.resize(hashtable_size(i)); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); entries[i].udata = value; entries[i].set_next_used(0); counter++; @@ -473,7 +489,9 @@ class pool entries.clear(); counter = other.size(); - int new_size = hashtable_size(counter); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; entries.reserve(new_size); for (auto &it : other) @@ -494,7 +512,6 @@ class pool { free_list = -1; - hashtable.resize(entries.size()); for (auto &h : hashtable) h = -1; @@ -550,7 +567,9 @@ class pool if (free_list < 0) { int i = entries.size(); - entries.resize(hashtable_size(i)); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); entries[i].key = key; entries[i].set_next_used(0); counter++; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8f65f5273..0114cbd60 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1132,7 +1132,7 @@ namespace { struct DeleteWireWorker { RTLIL::Module *module; - const pool *wires_p; + const pool *wires_p; void operator()(RTLIL::SigSpec &sig) { std::vector chunks = sig; @@ -1146,7 +1146,7 @@ namespace { }; } -void RTLIL::Module::remove(const pool &wires) +void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ae37c350c..c50a58619 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -708,6 +708,8 @@ struct RTLIL::Selection struct RTLIL::Monitor { + RTLIL::IdString name; + Monitor() { name = stringf("$%d", autoidx++); } virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } @@ -719,7 +721,7 @@ struct RTLIL::Monitor struct RTLIL::Design { - pool monitors; + pool monitors; dict scratchpad; int refcount_modules_; @@ -806,7 +808,7 @@ protected: public: RTLIL::Design *design; - pool monitors; + pool monitors; int refcount_wires_; int refcount_cells_; @@ -860,7 +862,7 @@ public: RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const pool &wires); + void remove(const pool &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); diff --git a/kernel/yosys.h b/kernel/yosys.h index 012b40c1f..d47f3a958 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -149,6 +149,8 @@ void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); +extern int autoidx; + YOSYS_NAMESPACE_END #include "kernel/log.h" @@ -164,7 +166,6 @@ void yosys_shutdown(); Tcl_Interp *yosys_get_tcl_interp(); #endif -extern int autoidx; extern RTLIL::Design *yosys_design; RTLIL::IdString new_id(std::string file, int line, std::string func); -- cgit v1.2.3 From d6ee6f653fa795efcea910fd4ad4bc6ee09a4784 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 11:01:59 +0100 Subject: Better help message printing for command line tool --- kernel/driver.cc | 149 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 72 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 6ba0c1134..90f479307 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -92,6 +92,82 @@ int main(int argc, char **argv) } #endif + if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) + { + printf("\n"); + printf("Usage: %s [options] [ [..]]\n", argv[0]); + printf("\n"); + printf(" -Q\n"); + printf(" suppress printing of banner (copyright, disclaimer, version)\n"); + printf("\n"); + printf(" -T\n"); + printf(" suppress printing of footer (log hash, version, timing statistics)\n"); + printf("\n"); + printf(" -q\n"); + printf(" quiet operation. only write warnings and error messages to console\n"); + printf(" use this option twice to also quiet warning messages\n"); + printf("\n"); + printf(" -v \n"); + printf(" print log headers up to level to the console. (implies -q)\n"); + printf("\n"); + printf(" -t\n"); + printf(" annotate all log messages with a time stamp\n"); + printf("\n"); + printf(" -d\n"); + printf(" print more detailed timing stats at exit\n"); + printf("\n"); + printf(" -l logfile\n"); + printf(" write log messages to the specified file\n"); + printf("\n"); + printf(" -o outfile\n"); + printf(" write the design to the specified file on exit\n"); + printf("\n"); + printf(" -b backend\n"); + printf(" use this backend for the output file specified on the command line\n"); + printf("\n"); + printf(" -f backend\n"); + printf(" use the specified front for the input files on the command line\n"); + printf("\n"); + printf(" -H\n"); + printf(" print the command list\n"); + printf("\n"); + printf(" -h command\n"); + printf(" print the help message for the specified command\n"); + printf("\n"); + printf(" -s scriptfile\n"); + printf(" execute the commands in the script file\n"); + printf("\n"); + printf(" -c tcl_scriptfile\n"); + printf(" execute the commands in the tcl script file (see 'help tcl' for details)\n"); + printf("\n"); + printf(" -p command\n"); + printf(" execute the commands\n"); + printf("\n"); + printf(" -m module_file\n"); + printf(" load the specified module (aka plugin)\n"); + printf("\n"); + printf(" -A\n"); + printf(" will call abort() at the end of the script. useful for debugging\n"); + printf("\n"); + printf(" -V\n"); + printf(" print version information and exit\n"); + printf("\n"); + printf("The option -S is an shortcut for calling the \"synth\" command, a default\n"); + printf("script for transforming the verilog input to a gate-level netlist. For example:\n"); + printf("\n"); + printf(" yosys -o output.blif -S input.v\n"); + printf("\n"); + printf("For more complex synthesis jobs it is recommended to use the read_* and write_*\n"); + printf("commands in a script file instead of specifying input and output files on the\n"); + printf("command line.\n"); + printf("\n"); + printf("When no commands, script files or input files are specified on the command\n"); + printf("line, yosys automatically enters the interactive command mode. Use the 'help'\n"); + printf("command to get information on the individual commands.\n"); + printf("\n"); + exit(0); + } + int opt; while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) { @@ -165,78 +241,7 @@ int main(int argc, char **argv) scriptfile_tcl = true; break; default: - fprintf(stderr, "\n"); - fprintf(stderr, "Usage: %s [-V -S -Q -T -q] [-v [-t] [-l ] [-o ] [-f ] [-h cmd] \\\n", argv[0]); - fprintf(stderr, " %*s[{-s|-c} ] [-p [-p ..]] [-b ] [-m ] [ [..]]\n", int(strlen(argv[0])+1), ""); - fprintf(stderr, "\n"); - fprintf(stderr, " -Q\n"); - fprintf(stderr, " suppress printing of banner (copyright, disclaimer, version)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -T\n"); - fprintf(stderr, " suppress printing of footer (log hash, version, timing statistics)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -q\n"); - fprintf(stderr, " quiet operation. only write warnings and error messages to console\n"); - fprintf(stderr, " use this option twice to also quiet warning messages\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -v \n"); - fprintf(stderr, " print log headers up to level to the console. (implies -q)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -t\n"); - fprintf(stderr, " annotate all log messages with a time stamp\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -d\n"); - fprintf(stderr, " print more detailed timing stats at exit\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -l logfile\n"); - fprintf(stderr, " write log messages to the specified file\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -o outfile\n"); - fprintf(stderr, " write the design to the specified file on exit\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -b backend\n"); - fprintf(stderr, " use this backend for the output file specified on the command line\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -f backend\n"); - fprintf(stderr, " use the specified front for the input files on the command line\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -H\n"); - fprintf(stderr, " print the command list\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -h command\n"); - fprintf(stderr, " print the help message for the specified command\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -s scriptfile\n"); - fprintf(stderr, " execute the commands in the script file\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -c tcl_scriptfile\n"); - fprintf(stderr, " execute the commands in the tcl script file (see 'help tcl' for details)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -p command\n"); - fprintf(stderr, " execute the commands\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -m module_file\n"); - fprintf(stderr, " load the specified module (aka plugin)\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -A\n"); - fprintf(stderr, " will call abort() at the end of the script. useful for debugging\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " -V\n"); - fprintf(stderr, " print version information and exit\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "The option -S is an shortcut for calling the \"synth\" command, a default\n"); - fprintf(stderr, "script for transforming the verilog input to a gate-level netlist. For example:\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " yosys -o output.blif -S input.v\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "For more complex synthesis jobs it is recommended to use the read_* and write_*\n"); - fprintf(stderr, "commands in a script file instead of specifying input and output files on the\n"); - fprintf(stderr, "command line.\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "When no commands, script files or input files are specified on the command\n"); - fprintf(stderr, "line, yosys automatically enters the interactive command mode. Use the 'help'\n"); - fprintf(stderr, "command to get information on the individual commands.\n"); - fprintf(stderr, "\n"); + fprintf(stderr, "Run '%s -h' for help.\n", argv[0]); exit(1); } } -- cgit v1.2.3 From 2c2f8e6e9f4eadbb191df8a8dbeee95443fc9f08 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 11:25:51 +0100 Subject: Added memory statistics (at least on linux) --- kernel/driver.cc | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 90f479307..4700bf61b 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -30,6 +30,11 @@ #include #include +#ifdef __linux__ +# include +# include +#endif + #if !defined(_WIN32) || defined(__MINGW32__) # include #else @@ -320,11 +325,26 @@ int main(int argc, char **argv) #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash.c_str()); #else + std::string meminfo; + std::string stats_divider = ", "; +# ifdef __linux__ + std::ifstream statm; + statm.open(stringf("/proc/%lld/statm", (long long)getpid())); + if (statm.is_open()) { + int sz_total, sz_resident; + statm >> sz_total >> sz_resident; + meminfo = stringf(", MEM: %.2f MB total, %.2f MB resident", + sz_total * (getpagesize() / 1024.0 / 1024.0), + sz_resident * (getpagesize() / 1024.0 / 1024.0)); + stats_divider = "\n"; + } +# endif + struct rusage ru_buffer; getrusage(RUSAGE_SELF, &ru_buffer); - log("End of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(), - ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, - ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); + log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(), + stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, + ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str()); #endif log("%s\n", yosys_version_str); -- cgit v1.2.3 From 6c8b0a5fd138d19b47191400f020c2472944f826 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 12:02:57 +0100 Subject: More dict/pool related changes --- kernel/hashmap.h | 8 ++++++ kernel/modtools.h | 81 +++++++++++++++++++++++++++++++++---------------------- kernel/rtlil.cc | 16 +++++------ kernel/rtlil.h | 4 +-- 4 files changed, 66 insertions(+), 43 deletions(-) (limited to 'kernel') diff --git a/kernel/hashmap.h b/kernel/hashmap.h index 729b4916c..431e8122e 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -25,10 +25,18 @@ #define YOSYS_HASHTABLE_SIZE_FACTOR 3 +// The XOR version of DJB2 +// (traditionally 5381 is used as starting value for the djb2 hash) inline unsigned int mkhash(unsigned int a, unsigned int b) { return ((a << 5) + a) ^ b; } +// The ADD version of DJB2 +// (use this version as last call for cache locality in b) +inline unsigned int mkhash_add(unsigned int a, unsigned int b) { + return ((a << 5) + a) + b; +} + template struct hash_ops { bool cmp(const T &a, const T &b) const { return a == b; diff --git a/kernel/modtools.h b/kernel/modtools.h index e3020ae3c..439699eaf 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -33,6 +33,7 @@ struct ModIndex : public RTLIL::Monitor RTLIL::IdString port; int offset; + PortInfo() : cell(), port(), offset() { } PortInfo(RTLIL::Cell* _c, RTLIL::IdString _p, int _o) : cell(_c), port(_p), offset(_o) { } bool operator<(const PortInfo &other) const { @@ -42,19 +43,27 @@ struct ModIndex : public RTLIL::Monitor return offset < other.offset; return port < other.port; } + + bool operator==(const PortInfo &other) const { + return cell == other.cell && port == other.port && offset == other.offset; + } + + unsigned int hash() const { + return mkhash_add(mkhash(cell->name.hash(), port.hash()), offset); + } }; struct SigBitInfo { bool is_input, is_output; - std::set ports; + pool ports; SigBitInfo() : is_input(false), is_output(false) { } }; SigMap sigmap; RTLIL::Module *module; - std::map database; + dict database; bool auto_reload_module; void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) @@ -168,9 +177,9 @@ struct ModIndex : public RTLIL::Monitor return info->is_output; } - std::set &query_ports(RTLIL::SigBit bit) + pool &query_ports(RTLIL::SigBit bit) { - static std::set empty_result_set; + static pool empty_result_set; SigBitInfo *info = query(bit); if (info == nullptr) return empty_result_set; @@ -193,6 +202,14 @@ struct ModWalker return port < other.port; return offset < other.offset; } + + bool operator==(const PortBit &other) const { + return cell == other.cell && port == other.port && offset == other.offset; + } + + unsigned int hash() const { + return mkhash_add(mkhash(cell->name.hash(), port.hash()), offset); + } }; RTLIL::Design *design; @@ -201,11 +218,11 @@ struct ModWalker CellTypes ct; SigMap sigmap; - std::map> signal_drivers; - std::map> signal_consumers; - std::set signal_inputs, signal_outputs; + dict> signal_drivers; + dict> signal_consumers; + pool signal_inputs, signal_outputs; - std::map> cell_outputs, cell_inputs; + dict, hash_obj_ops> cell_outputs, cell_inputs; void add_wire(RTLIL::Wire *wire) { @@ -286,11 +303,11 @@ struct ModWalker // get_* methods -- single RTLIL::SigBit template - inline bool get_drivers(std::set &result, RTLIL::SigBit bit) const + inline bool get_drivers(pool &result, RTLIL::SigBit bit) const { bool found = false; if (signal_drivers.count(bit)) { - const std::set &r = signal_drivers.at(bit); + const pool &r = signal_drivers.at(bit); result.insert(r.begin(), r.end()); found = true; } @@ -298,11 +315,11 @@ struct ModWalker } template - inline bool get_consumers(std::set &result, RTLIL::SigBit bit) const + inline bool get_consumers(pool &result, RTLIL::SigBit bit) const { bool found = false; if (signal_consumers.count(bit)) { - const std::set &r = signal_consumers.at(bit); + const pool &r = signal_consumers.at(bit); result.insert(r.begin(), r.end()); found = true; } @@ -310,7 +327,7 @@ struct ModWalker } template - inline bool get_inputs(std::set &result, RTLIL::SigBit bit) const + inline bool get_inputs(pool &result, RTLIL::SigBit bit) const { bool found = false; if (signal_inputs.count(bit)) @@ -319,7 +336,7 @@ struct ModWalker } template - inline bool get_outputs(std::set &result, RTLIL::SigBit bit) const + inline bool get_outputs(pool &result, RTLIL::SigBit bit) const { bool found = false; if (signal_outputs.count(bit)) @@ -330,12 +347,12 @@ struct ModWalker // get_* methods -- container of RTLIL::SigBit's (always by reference) template - inline bool get_drivers(std::set &result, const T &bits) const + inline bool get_drivers(pool &result, const T &bits) const { bool found = false; for (RTLIL::SigBit bit : bits) if (signal_drivers.count(bit)) { - const std::set &r = signal_drivers.at(bit); + const pool &r = signal_drivers.at(bit); result.insert(r.begin(), r.end()); found = true; } @@ -343,12 +360,12 @@ struct ModWalker } template - inline bool get_consumers(std::set &result, const T &bits) const + inline bool get_consumers(pool &result, const T &bits) const { bool found = false; for (RTLIL::SigBit bit : bits) if (signal_consumers.count(bit)) { - const std::set &r = signal_consumers.at(bit); + const pool &r = signal_consumers.at(bit); result.insert(r.begin(), r.end()); found = true; } @@ -356,7 +373,7 @@ struct ModWalker } template - inline bool get_inputs(std::set &result, const T &bits) const + inline bool get_inputs(pool &result, const T &bits) const { bool found = false; for (RTLIL::SigBit bit : bits) @@ -366,7 +383,7 @@ struct ModWalker } template - inline bool get_outputs(std::set &result, const T &bits) const + inline bool get_outputs(pool &result, const T &bits) const { bool found = false; for (RTLIL::SigBit bit : bits) @@ -377,25 +394,25 @@ struct ModWalker // get_* methods -- call by RTLIL::SigSpec (always by value) - bool get_drivers(std::set &result, RTLIL::SigSpec signal) const + bool get_drivers(pool &result, RTLIL::SigSpec signal) const { std::vector bits = sigmap(signal); return get_drivers(result, bits); } - bool get_consumers(std::set &result, RTLIL::SigSpec signal) const + bool get_consumers(pool &result, RTLIL::SigSpec signal) const { std::vector bits = sigmap(signal); return get_consumers(result, bits); } - bool get_inputs(std::set &result, RTLIL::SigSpec signal) const + bool get_inputs(pool &result, RTLIL::SigSpec signal) const { std::vector bits = sigmap(signal); return get_inputs(result, bits); } - bool get_outputs(std::set &result, RTLIL::SigSpec signal) const + bool get_outputs(pool &result, RTLIL::SigSpec signal) const { std::vector bits = sigmap(signal); return get_outputs(result, bits); @@ -405,47 +422,47 @@ struct ModWalker template inline bool has_drivers(const T &sig) const { - std::set result; + pool result; return get_drivers(result, sig); } template inline bool has_consumers(const T &sig) const { - std::set result; + pool result; return get_consumers(result, sig); } template inline bool has_inputs(const T &sig) const { - std::set result; + pool result; return get_inputs(result, sig); } template inline bool has_outputs(const T &sig) const { - std::set result; + pool result; return get_outputs(result, sig); } // has_* methods -- call by value inline bool has_drivers(RTLIL::SigSpec sig) const { - std::set result; + pool result; return get_drivers(result, sig); } inline bool has_consumers(RTLIL::SigSpec sig) const { - std::set result; + pool result; return get_consumers(result, sig); } inline bool has_inputs(RTLIL::SigSpec sig) const { - std::set result; + pool result; return get_inputs(result, sig); } inline bool has_outputs(RTLIL::SigSpec sig) const { - std::set result; + pool result; return get_outputs(result, sig); } }; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 0114cbd60..23edcceef 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2256,8 +2256,6 @@ void RTLIL::SigSpec::unpack() const that->hash_ = 0; } -#define DJB2(_hash, _value) (_hash) = (((_hash) << 5) + (_hash)) + (_value) - void RTLIL::SigSpec::updhash() const { RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; @@ -2272,11 +2270,11 @@ void RTLIL::SigSpec::updhash() const 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) @@ -2378,7 +2376,7 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { - pool pattern_bits = pattern.to_sigbit_nodict(); + pool pattern_bits = pattern.to_sigbit_pool(); remove2(pattern_bits, other); } @@ -2439,7 +2437,7 @@ void RTLIL::SigSpec::remove2(const pool &pattern, RTLIL::SigSpec RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const { - pool pattern_bits = pattern.to_sigbit_nodict(); + pool pattern_bits = pattern.to_sigbit_pool(); return extract(pattern_bits, other); } @@ -2943,7 +2941,7 @@ std::set RTLIL::SigSpec::to_sigbit_set() const return sigbits; } -pool RTLIL::SigSpec::to_sigbit_nodict() const +pool RTLIL::SigSpec::to_sigbit_pool() const { cover("kernel.rtlil.sigspec.to_sigbit_pool"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c50a58619..cb654c3af 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -654,7 +654,7 @@ public: bool match(std::string pattern) const; std::set to_sigbit_set() const; - pool to_sigbit_nodict() const; + pool to_sigbit_pool() const; std::vector to_sigbit_vector() const; std::map to_sigbit_map(const RTLIL::SigSpec &other) const; dict to_sigbit_dict(const RTLIL::SigSpec &other) const; @@ -1176,7 +1176,7 @@ inline bool RTLIL::SigBit::operator!=(const RTLIL::SigBit &other) const { inline unsigned int RTLIL::SigBit::hash() const { if (wire) - return wire->name.hash() * 33 + offset; + return mkhash_add(wire->name.hash(), offset); return data; } -- cgit v1.2.3 From 3e8e483233321d7efadbb78ba746a7797c102a3a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 13:04:44 +0100 Subject: Various improvements in ModIndex --- kernel/modtools.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/modtools.h b/kernel/modtools.h index 439699eaf..56362dbc8 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -59,6 +59,13 @@ struct ModIndex : public RTLIL::Monitor pool ports; SigBitInfo() : is_input(false), is_output(false) { } + + void merge(const SigBitInfo &other) + { + is_input = is_input || other.is_input; + is_output = is_output || other.is_output; + ports.insert(other.ports.begin(), other.ports.end()); + } }; SigMap sigmap; @@ -109,30 +116,71 @@ struct ModIndex : public RTLIL::Monitor port_add(cell, conn.first, conn.second); auto_reload_module = false; + // log("Auto-reload in ModIndex -- possible performance bug!\n"); } virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE { + log_assert(module == cell->module); + if (auto_reload_module) - reload_module(); + return; port_del(cell, port, old_sig); port_add(cell, port, sig); } - virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig&) + virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) YS_OVERRIDE { log_assert(module == mod); - auto_reload_module = true; + + if (auto_reload_module) + return; + + for (int i = 0; i < GetSize(sigsig.first); i++) + { + RTLIL::SigBit lhs = sigmap(sigsig.first[i]); + RTLIL::SigBit rhs = sigmap(sigsig.second[i]); + bool has_lhs = database.count(lhs); + bool has_rhs = database.count(rhs); + + if (!has_lhs && !has_rhs) { + sigmap.add(lhs, rhs); + } else + if (!has_rhs) { + SigBitInfo new_info = database.at(lhs); + database.erase(lhs); + sigmap.add(lhs, rhs); + database[sigmap(lhs)] = new_info; + } else + if (!has_lhs) { + SigBitInfo new_info = database.at(rhs); + database.erase(rhs); + sigmap.add(lhs, rhs); + database[sigmap(rhs)] = new_info; + } else { + #if 1 + auto_reload_module = true; + return; + #else + SigBitInfo new_info = database.at(lhs); + new_info.merge(database.at(rhs)); + database.erase(lhs); + database.erase(rhs); + sigmap.add(lhs, rhs); + database[sigmap(rhs)] = new_info; + #endif + } + } } - virtual void notify_connect(RTLIL::Module *mod, const std::vector&) + virtual void notify_connect(RTLIL::Module *mod, const std::vector&) YS_OVERRIDE { log_assert(module == mod); auto_reload_module = true; } - virtual void notify_blackout(RTLIL::Module *mod) + virtual void notify_blackout(RTLIL::Module *mod) YS_OVERRIDE { log_assert(module == mod); auto_reload_module = true; -- cgit v1.2.3 From 3da46d3437f076c27cef5121f26a1fa151dde1f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 17:51:16 +0100 Subject: Renamed hashmap.h to hashlib.h, some related improvements --- kernel/hashlib.h | 774 +++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/hashmap.h | 777 ------------------------------------------------------ kernel/modtools.h | 2 +- kernel/rtlil.cc | 18 +- kernel/rtlil.h | 31 ++- kernel/yosys.h | 36 ++- 6 files changed, 852 insertions(+), 786 deletions(-) create mode 100644 kernel/hashlib.h delete mode 100644 kernel/hashmap.h (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h new file mode 100644 index 000000000..a8d320865 --- /dev/null +++ b/kernel/hashlib.h @@ -0,0 +1,774 @@ +// This is free and unencumbered software released into the public domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. + +// ------------------------------------------------------- +// Written by Clifford Wolf in 2014 +// ------------------------------------------------------- + +#ifndef HASHLIB_H + +#include +#include +#include + +namespace hashlib { + +#define HASHLIB_SIZE_FACTOR 3 + +// The XOR version of DJB2 +// (traditionally 5381 is used as starting value for the djb2 hash) +inline unsigned int mkhash(unsigned int a, unsigned int b) { + return ((a << 5) + a) ^ b; +} + +// The ADD version of DJB2 +// (use this version for cache locality in b) +inline unsigned int mkhash_add(unsigned int a, unsigned int b) { + return ((a << 5) + a) + b; +} + +template struct hash_ops { + bool cmp(const T &a, const T &b) const { + return a == b; + } + unsigned int hash(const T &a) const { + return a.hash(); + } +}; + +template<> struct hash_ops { + template + bool cmp(T a, T b) const { + return a == b; + } + unsigned int hash(unsigned int a) const { + return a; + } +}; + +template<> struct hash_ops { + bool cmp(const std::string &a, const std::string &b) const { + return a == b; + } + unsigned int hash(const std::string &a) const { + unsigned int v = 0; + for (auto c : a) + v = mkhash(v, c); + return v; + } +}; + +struct hash_cstr_ops { + bool cmp(const char *a, const char *b) const { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return false; + return true; + } + unsigned int hash(const char *a) const { + unsigned int hash = 5381; + while (*a) + hash = mkhash(hash, *(a++)); + return hash; + } +}; + +struct hash_ptr_ops { + bool cmp(const void *a, const void *b) const { + return a == b; + } + unsigned int hash(const void *a) const { + return (unsigned long)a; + } +}; + +struct hash_obj_ops { + bool cmp(const void *a, const void *b) const { + return a == b; + } + template + unsigned int hash(const T *a) const { + return a->hash(); + } +}; + +inline int hashtable_size(int old_size) +{ + // prime numbers, approx. in powers of two + if (old_size < 53) return 53; + if (old_size < 113) return 113; + if (old_size < 251) return 251; + if (old_size < 503) return 503; + if (old_size < 1129) return 1129; + if (old_size < 2503) return 2503; + if (old_size < 5023) return 5023; + if (old_size < 11299) return 11299; + if (old_size < 25097) return 25097; + if (old_size < 50291) return 50291; + if (old_size < 112997) return 112997; + if (old_size < 251003) return 251003; + if (old_size < 503003) return 503003; + if (old_size < 1129991) return 1129991; + if (old_size < 2509993) return 2509993; + if (old_size < 5029991) return 5029991; + if (old_size < 11299997) return 11299997; + if (old_size < 25099999) return 25099999; + if (old_size < 50299999) return 50299999; + if (old_size < 113000009) return 113000009; + if (old_size < 250999999) return 250999999; + if (old_size < 503000009) return 503000009; + if (old_size < 1129999999) return 1129999999; + throw std::length_error("hash table exceeded maximum size"); +} + +template> +class dict +{ + struct entry_t + { + int link; + std::pair udata; + + entry_t() : link(-1) { } + entry_t(const std::pair &udata) : link(1), udata(udata) { } + + bool is_free() const { return link < 0; } + int get_next() const { return (link > 0 ? link : -link) - 2; } + bool get_last() const { return get_next() == -1; } + void set_next_used(int next) { link = next + 2; } + void set_next_free(int next) { link = -(next + 2); } + }; + + std::vector hashtable; + std::vector entries; + int free_list, counter; + OPS ops; + + void init() + { + free_list = -1; + counter = 0; + } + + void init_from(const dict &other) + { + hashtable.clear(); + entries.clear(); + + counter = other.size(); + int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / HASHLIB_SIZE_FACTOR + 1; + entries.reserve(new_size); + + for (auto &it : other) + entries.push_back(entry_t(it)); + entries.resize(new_size); + rehash(); + } + + int mkhash(const K &key) const + { + unsigned int hash = 0; + if (!hashtable.empty()) + hash = ops.hash(key) % (unsigned int)(hashtable.size()); + return hash; + } + + void rehash() + { + free_list = -1; + + for (auto &h : hashtable) + h = -1; + + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + entries[i].set_next_free(free_list); + free_list = i; + } else { + int hash = mkhash(entries[i].udata.first); + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + } + } + + void do_erase(const K &key, int hash) + { + int last_index = -1; + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return; + if (ops.cmp(entries[index].udata.first, key)) { + if (last_index < 0) + hashtable[hash] = entries[index].get_next(); + else + entries[last_index].set_next_used(entries[index].get_next()); + entries[index].udata = std::pair(); + entries[index].set_next_free(free_list); + free_list = index; + if (--counter == 0) + init(); + return; + } + last_index = index; + index = entries[index].get_next(); + } + } + + int lookup_index(const K &key, int hash) const + { + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return -1; + if (ops.cmp(entries[index].udata.first, key)) + return index; + index = entries[index].get_next(); + } + } + + int insert_at(const std::pair &value, int hash) + { + if (free_list < 0) + { + int i = entries.size(); + int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / HASHLIB_SIZE_FACTOR + 1); + entries[i].udata = value; + entries[i].set_next_used(0); + counter++; + rehash(); + return i; + } + + int i = free_list; + free_list = entries[i].get_next(); + entries[i].udata = value; + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + counter++; + return i; + } + +public: + class iterator + { + dict *ptr; + int index; + public: + iterator() { } + iterator(dict *ptr, int index) : ptr(ptr), index(index) { } + iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + std::pair &operator*() { return ptr->entries[index].udata; } + std::pair *operator->() { return &ptr->entries[index].udata; } + const std::pair &operator*() const { return ptr->entries[index].udata; } + const std::pair *operator->() const { return &ptr->entries[index].udata; } + }; + + class const_iterator + { + const dict *ptr; + int index; + public: + const_iterator() { } + const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } + const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } + const std::pair &operator*() const { return ptr->entries[index].udata; } + const std::pair *operator->() const { return &ptr->entries[index].udata; } + }; + + dict() + { + init(); + } + + dict(const dict &other) + { + init_from(other); + } + + dict(dict &&other) + { + free_list = -1; + counter = 0; + swap(other); + } + + dict &operator=(const dict &other) { + clear(); + init_from(other); + return *this; + } + + dict &operator=(dict &&other) { + clear(); + swap(other); + return *this; + } + + dict(const std::initializer_list> &list) + { + init(); + for (auto &it : list) + insert(it); + } + + template + dict(InputIterator first, InputIterator last) + { + init(); + insert(first, last); + } + + template + void insert(InputIterator first, InputIterator last) + { + for (; first != last; ++first) + insert(*first); + } + + std::pair insert(const std::pair &value) + { + int hash = mkhash(value.first); + int i = lookup_index(value.first, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = insert_at(value, hash); + return std::pair(iterator(this, i), true); + } + + void erase(const K &key) + { + int hash = mkhash(key); + do_erase(key, hash); + } + + void erase(const iterator it) + { + int hash = mkhash(it->first); + do_erase(it->first, hash); + } + + int count(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i < 0 ? 0 : 1; + } + + iterator find(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return iterator(this, i); + } + + const_iterator find(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return const_iterator(this, i); + } + + T& at(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + throw std::out_of_range("dict::at()"); + return entries[i].udata.second; + } + + const T& at(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + throw std::out_of_range("dict::at()"); + return entries[i].udata.second; + } + + T& operator[](const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + i = insert_at(std::pair(key, T()), hash); + return entries[i].udata.second; + } + + void swap(dict &other) + { + hashtable.swap(other.hashtable); + entries.swap(other.entries); + std::swap(free_list, other.free_list); + std::swap(counter, other.counter); + } + + bool operator==(const dict &other) const { + if (counter != other.counter) + return false; + if (counter == 0) + return true; + if (entries.size() < other.entries.size()) + for (auto &it : *this) { + auto oit = other.find(it.first); + if (oit == other.end() || oit->second != it.second) + return false; + } + else + for (auto &oit : other) { + auto it = find(oit.first); + if (it == end() || it->second != oit.second) + return false; + } + return true; + } + + bool operator!=(const dict &other) const { + return !(*this == other); + } + + size_t size() const { return counter; } + bool empty() const { return counter == 0; } + void clear() { hashtable.clear(); entries.clear(); init(); } + + iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } + iterator end() { return iterator(this, entries.size()); } + + const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } + const_iterator end() const { return const_iterator(this, entries.size()); } +}; + +template> +class pool +{ + struct entry_t + { + int link; + K key; + + entry_t() : link(-1) { } + entry_t(const K &key) : link(1), key(key) { } + + bool is_free() const { return link < 0; } + int get_next() const { return (link > 0 ? link : -link) - 2; } + bool get_last() const { return get_next() == -1; } + void set_next_used(int next) { link = next + 2; } + void set_next_free(int next) { link = -(next + 2); } + }; + + std::vector hashtable; + std::vector entries; + int free_list, counter; + OPS ops; + + void init() + { + free_list = -1; + counter = 0; + } + + void init_from(const pool &other) + { + hashtable.clear(); + entries.clear(); + + counter = other.size(); + int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / HASHLIB_SIZE_FACTOR + 1; + entries.reserve(new_size); + + for (auto &it : other) + entries.push_back(entry_t(it)); + entries.resize(new_size); + rehash(); + } + + int mkhash(const K &key) const + { + unsigned int hash = 0; + if (!hashtable.empty()) + hash = ops.hash(key) % (unsigned int)(hashtable.size()); + return hash; + } + + void rehash() + { + free_list = -1; + + for (auto &h : hashtable) + h = -1; + + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + entries[i].set_next_free(free_list); + free_list = i; + } else { + int hash = mkhash(entries[i].key); + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + } + } + + void do_erase(const K &key, int hash) + { + int last_index = -1; + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return; + if (ops.cmp(entries[index].key, key)) { + if (last_index < 0) + hashtable[hash] = entries[index].get_next(); + else + entries[last_index].set_next_used(entries[index].get_next()); + entries[index].key = K(); + entries[index].set_next_free(free_list); + free_list = index; + if (--counter == 0) + init(); + return; + } + last_index = index; + index = entries[index].get_next(); + } + } + + int lookup_index(const K &key, int hash) const + { + int index = hashtable.empty() ? -1 : hashtable[hash]; + while (1) { + if (index < 0) + return -1; + if (ops.cmp(entries[index].key, key)) + return index; + index = entries[index].get_next(); + } + } + + int insert_at(const K &key, int hash) + { + if (free_list < 0) + { + int i = entries.size(); + int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / HASHLIB_SIZE_FACTOR + 1); + entries[i].key = key; + entries[i].set_next_used(0); + counter++; + rehash(); + return i; + } + + int i = free_list; + free_list = entries[i].get_next(); + entries[i].key = key; + entries[i].set_next_used(hashtable[hash]); + hashtable[hash] = i; + counter++; + return i; + } + +public: + class iterator + { + pool *ptr; + int index; + public: + iterator() { } + iterator(pool *ptr, int index) : ptr(ptr), index(index) { } + iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + K &operator*() { return ptr->entries[index].key; } + K *operator->() { return &ptr->entries[index].key; } + const K &operator*() const { return ptr->entries[index].key; } + const K *operator->() const { return &ptr->entries[index].key; } + }; + + class const_iterator + { + const pool *ptr; + int index; + public: + const_iterator() { } + const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } + const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } + const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } + const K &operator*() const { return ptr->entries[index].key; } + const K *operator->() const { return &ptr->entries[index].key; } + }; + + pool() + { + init(); + } + + pool(const pool &other) + { + init_from(other); + } + + pool(pool &&other) + { + free_list = -1; + counter = 0; + swap(other); + } + + pool &operator=(const pool &other) { + clear(); + init_from(other); + return *this; + } + + pool &operator=(pool &&other) { + clear(); + swap(other); + return *this; + } + + pool(const std::initializer_list &list) + { + init(); + for (auto &it : list) + insert(it); + } + + template + pool(InputIterator first, InputIterator last) + { + init(); + insert(first, last); + } + + template + void insert(InputIterator first, InputIterator last) + { + for (; first != last; ++first) + insert(*first); + } + + std::pair insert(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = insert_at(key, hash); + return std::pair(iterator(this, i), true); + } + + void erase(const K &key) + { + int hash = mkhash(key); + do_erase(key, hash); + } + + void erase(const iterator it) + { + int hash = mkhash(*it); + do_erase(*it, hash); + } + + int count(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i < 0 ? 0 : 1; + } + + iterator find(const K &key) + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return iterator(this, i); + } + + const_iterator find(const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + if (i < 0) + return end(); + return const_iterator(this, i); + } + + bool operator[](const K &key) const + { + int hash = mkhash(key); + int i = lookup_index(key, hash); + return i >= 0; + } + + void swap(pool &other) + { + hashtable.swap(other.hashtable); + entries.swap(other.entries); + std::swap(free_list, other.free_list); + std::swap(counter, other.counter); + } + + bool operator==(const pool &other) const { + if (counter != other.counter) + return false; + if (counter == 0) + return true; + if (entries.size() < other.entries.size()) + for (auto &it : *this) { + auto oit = other.find(it.first); + if (oit == other.end() || oit->second != it.second) + return false; + } + else + for (auto &oit : other) { + auto it = find(oit.first); + if (it == end() || it->second != oit.second) + return false; + } + return true; + } + + bool operator!=(const pool &other) const { + return !(*this == other); + } + + size_t size() const { return counter; } + bool empty() const { return counter == 0; } + void clear() { hashtable.clear(); entries.clear(); init(); } + + iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } + iterator end() { return iterator(this, entries.size()); } + + const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } + const_iterator end() const { return const_iterator(this, entries.size()); } +}; + +} /* namespace hashlib */ + +#endif diff --git a/kernel/hashmap.h b/kernel/hashmap.h deleted file mode 100644 index 431e8122e..000000000 --- a/kernel/hashmap.h +++ /dev/null @@ -1,777 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef YOSYS_HASHMAP_H - -#include -#include -#include - -#define YOSYS_HASHTABLE_SIZE_FACTOR 3 - -// The XOR version of DJB2 -// (traditionally 5381 is used as starting value for the djb2 hash) -inline unsigned int mkhash(unsigned int a, unsigned int b) { - return ((a << 5) + a) ^ b; -} - -// The ADD version of DJB2 -// (use this version as last call for cache locality in b) -inline unsigned int mkhash_add(unsigned int a, unsigned int b) { - return ((a << 5) + a) + b; -} - -template struct hash_ops { - bool cmp(const T &a, const T &b) const { - return a == b; - } - unsigned int hash(const T &a) const { - return a.hash(); - } -}; - -template<> struct hash_ops { - bool cmp(int a, int b) const { - return a == b; - } - unsigned int hash(int a) const { - return a; - } -}; - -template<> struct hash_ops { - bool cmp(const std::string &a, const std::string &b) const { - return a == b; - } - unsigned int hash(const std::string &a) const { - unsigned int v = 0; - for (auto c : a) - v = mkhash(v, c); - return v; - } -}; - -struct hash_cstr_ops { - bool cmp(const char *a, const char *b) const { - for (int i = 0; a[i] || b[i]; i++) - if (a[i] != b[i]) - return false; - return true; - } - unsigned int hash(const char *a) const { - unsigned int hash = 5381; - while (*a) - hash = mkhash(hash, *(a++)); - return hash; - } -}; - -struct hash_ptr_ops { - bool cmp(const void *a, const void *b) const { - return a == b; - } - unsigned int hash(const void *a) const { - return (unsigned long)a; - } -}; - -struct hash_obj_ops { - bool cmp(const void *a, const void *b) const { - return a == b; - } - template - unsigned int hash(const T *a) const { - return a->name.hash(); - } -}; - -inline int hashtable_size(int old_size) -{ - // prime numbers, approx. in powers of two - if (old_size < 53) return 53; - if (old_size < 113) return 113; - if (old_size < 251) return 251; - if (old_size < 503) return 503; - if (old_size < 1129) return 1129; - if (old_size < 2503) return 2503; - if (old_size < 5023) return 5023; - if (old_size < 11299) return 11299; - if (old_size < 25097) return 25097; - if (old_size < 50291) return 50291; - if (old_size < 112997) return 112997; - if (old_size < 251003) return 251003; - if (old_size < 503003) return 503003; - if (old_size < 1129991) return 1129991; - if (old_size < 2509993) return 2509993; - if (old_size < 5029991) return 5029991; - if (old_size < 11299997) return 11299997; - if (old_size < 25099999) return 25099999; - if (old_size < 50299999) return 50299999; - if (old_size < 113000009) return 113000009; - if (old_size < 250999999) return 250999999; - if (old_size < 503000009) return 503000009; - if (old_size < 1129999999) return 1129999999; - throw std::length_error("hash table exceeded maximum size"); -} - -template> -class dict -{ - struct entry_t - { - int link; - std::pair udata; - - entry_t() : link(-1) { } - entry_t(const std::pair &udata) : link(1), udata(udata) { } - - bool is_free() const { return link < 0; } - int get_next() const { return (link > 0 ? link : -link) - 2; } - bool get_last() const { return get_next() == -1; } - void set_next_used(int next) { link = next + 2; } - void set_next_free(int next) { link = -(next + 2); } - }; - - std::vector hashtable; - std::vector entries; - int free_list, counter; - OPS ops; - - void init() - { - free_list = -1; - counter = 0; - } - - void init_from(const dict &other) - { - hashtable.clear(); - entries.clear(); - - counter = other.size(); - int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); - hashtable.resize(new_size); - new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; - entries.reserve(new_size); - - for (auto &it : other) - entries.push_back(entry_t(it)); - entries.resize(new_size); - rehash(); - } - - int mkhash(const K &key) const - { - unsigned int hash = 0; - if (!hashtable.empty()) - hash = ops.hash(key) % (unsigned int)(hashtable.size()); - return hash; - } - - void rehash() - { - free_list = -1; - - for (auto &h : hashtable) - h = -1; - - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - entries[i].set_next_free(free_list); - free_list = i; - } else { - int hash = mkhash(entries[i].udata.first); - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - } - } - - void do_erase(const K &key, int hash) - { - int last_index = -1; - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return; - if (ops.cmp(entries[index].udata.first, key)) { - if (last_index < 0) - hashtable[hash] = entries[index].get_next(); - else - entries[last_index].set_next_used(entries[index].get_next()); - entries[index].udata = std::pair(); - entries[index].set_next_free(free_list); - free_list = index; - if (--counter == 0) - init(); - return; - } - last_index = index; - index = entries[index].get_next(); - } - } - - int lookup_index(const K &key, int hash) const - { - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return -1; - if (ops.cmp(entries[index].udata.first, key)) - return index; - index = entries[index].get_next(); - } - } - - int insert_at(const std::pair &value, int hash) - { - if (free_list < 0) - { - int i = entries.size(); - int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); - hashtable.resize(new_size); - entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); - entries[i].udata = value; - entries[i].set_next_used(0); - counter++; - rehash(); - return i; - } - - int i = free_list; - free_list = entries[i].get_next(); - entries[i].udata = value; - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - counter++; - return i; - } - -public: - class iterator - { - dict *ptr; - int index; - public: - iterator() { } - iterator(dict *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } - bool operator==(const iterator &other) const { return index == other.index; } - bool operator!=(const iterator &other) const { return index != other.index; } - std::pair &operator*() { return ptr->entries[index].udata; } - std::pair *operator->() { return &ptr->entries[index].udata; } - const std::pair &operator*() const { return ptr->entries[index].udata; } - const std::pair *operator->() const { return &ptr->entries[index].udata; } - }; - - class const_iterator - { - const dict *ptr; - int index; - public: - const_iterator() { } - const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } - bool operator==(const const_iterator &other) const { return index == other.index; } - bool operator!=(const const_iterator &other) const { return index != other.index; } - const std::pair &operator*() const { return ptr->entries[index].udata; } - const std::pair *operator->() const { return &ptr->entries[index].udata; } - }; - - dict() - { - init(); - } - - dict(const dict &other) - { - init_from(other); - } - - dict(dict &&other) - { - free_list = -1; - counter = 0; - swap(other); - } - - dict &operator=(const dict &other) { - clear(); - init_from(other); - return *this; - } - - dict &operator=(dict &&other) { - clear(); - swap(other); - return *this; - } - - dict(const std::initializer_list> &list) - { - init(); - for (auto &it : list) - insert(it); - } - - template - dict(InputIterator first, InputIterator last) - { - init(); - insert(first, last); - } - - template - void insert(InputIterator first, InputIterator last) - { - for (; first != last; ++first) - insert(*first); - } - - iterator insert(const std::pair &value) - { - int hash = mkhash(value.first); - int i = lookup_index(value.first, hash); - if (i >= 0) - return iterator(this, i); - i = insert_at(value, hash); - return iterator(this, i); - } - - void erase(const K &key) - { - int hash = mkhash(key); - do_erase(key, hash); - } - - void erase(const iterator it) - { - int hash = mkhash(it->first); - do_erase(it->first, hash); - } - - int count(const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - return i < 0 ? 0 : 1; - } - - iterator find(const K &key) - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - return end(); - return iterator(this, i); - } - - const_iterator find(const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - return end(); - return const_iterator(this, i); - } - - T& at(const K &key) - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - throw std::out_of_range("dict::at()"); - return entries[i].udata.second; - } - - const T& at(const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - throw std::out_of_range("dict::at()"); - return entries[i].udata.second; - } - - T& operator[](const K &key) - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - i = insert_at(std::pair(key, T()), hash); - return entries[i].udata.second; - } - - void swap(dict &other) - { - hashtable.swap(other.hashtable); - entries.swap(other.entries); - std::swap(free_list, other.free_list); - std::swap(counter, other.counter); - } - - bool operator==(const dict &other) const { - if (counter != other.counter) - return false; - if (counter == 0) - return true; - if (entries.size() < other.entries.size()) - for (auto &it : *this) { - auto oit = other.find(it.first); - if (oit == other.end() || oit->second != it.second) - return false; - } - else - for (auto &oit : other) { - auto it = find(oit.first); - if (it == end() || it->second != oit.second) - return false; - } - return true; - } - - bool operator!=(const dict &other) const { - return !(*this == other); - } - - size_t size() const { return counter; } - bool empty() const { return counter == 0; } - void clear() { hashtable.clear(); entries.clear(); init(); } - - iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } - iterator end() { return iterator(this, entries.size()); } - - const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } - const_iterator end() const { return const_iterator(this, entries.size()); } -}; - -template> -class pool -{ - struct entry_t - { - int link; - K key; - - entry_t() : link(-1) { } - entry_t(const K &key) : link(1), key(key) { } - - bool is_free() const { return link < 0; } - int get_next() const { return (link > 0 ? link : -link) - 2; } - bool get_last() const { return get_next() == -1; } - void set_next_used(int next) { link = next + 2; } - void set_next_free(int next) { link = -(next + 2); } - }; - - std::vector hashtable; - std::vector entries; - int free_list, counter; - OPS ops; - - void init() - { - free_list = -1; - counter = 0; - } - - void init_from(const pool &other) - { - hashtable.clear(); - entries.clear(); - - counter = other.size(); - int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); - hashtable.resize(new_size); - new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; - entries.reserve(new_size); - - for (auto &it : other) - entries.push_back(entry_t(it)); - entries.resize(new_size); - rehash(); - } - - int mkhash(const K &key) const - { - unsigned int hash = 0; - if (!hashtable.empty()) - hash = ops.hash(key) % (unsigned int)(hashtable.size()); - return hash; - } - - void rehash() - { - free_list = -1; - - for (auto &h : hashtable) - h = -1; - - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - entries[i].set_next_free(free_list); - free_list = i; - } else { - int hash = mkhash(entries[i].key); - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - } - } - - void do_erase(const K &key, int hash) - { - int last_index = -1; - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return; - if (ops.cmp(entries[index].key, key)) { - if (last_index < 0) - hashtable[hash] = entries[index].get_next(); - else - entries[last_index].set_next_used(entries[index].get_next()); - entries[index].key = K(); - entries[index].set_next_free(free_list); - free_list = index; - if (--counter == 0) - init(); - return; - } - last_index = index; - index = entries[index].get_next(); - } - } - - int lookup_index(const K &key, int hash) const - { - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return -1; - if (ops.cmp(entries[index].key, key)) - return index; - index = entries[index].get_next(); - } - } - - int insert_at(const K &key, int hash) - { - if (free_list < 0) - { - int i = entries.size(); - int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); - hashtable.resize(new_size); - entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); - entries[i].key = key; - entries[i].set_next_used(0); - counter++; - rehash(); - return i; - } - - int i = free_list; - free_list = entries[i].get_next(); - entries[i].key = key; - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - counter++; - return i; - } - -public: - class iterator - { - pool *ptr; - int index; - public: - iterator() { } - iterator(pool *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } - bool operator==(const iterator &other) const { return index == other.index; } - bool operator!=(const iterator &other) const { return index != other.index; } - K &operator*() { return ptr->entries[index].key; } - K *operator->() { return &ptr->entries[index].key; } - const K &operator*() const { return ptr->entries[index].key; } - const K *operator->() const { return &ptr->entries[index].key; } - }; - - class const_iterator - { - const pool *ptr; - int index; - public: - const_iterator() { } - const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } - bool operator==(const const_iterator &other) const { return index == other.index; } - bool operator!=(const const_iterator &other) const { return index != other.index; } - const K &operator*() const { return ptr->entries[index].key; } - const K *operator->() const { return &ptr->entries[index].key; } - }; - - pool() - { - init(); - } - - pool(const pool &other) - { - init_from(other); - } - - pool(pool &&other) - { - free_list = -1; - counter = 0; - swap(other); - } - - pool &operator=(const pool &other) { - clear(); - init_from(other); - return *this; - } - - pool &operator=(pool &&other) { - clear(); - swap(other); - return *this; - } - - pool(const std::initializer_list &list) - { - init(); - for (auto &it : list) - insert(it); - } - - template - pool(InputIterator first, InputIterator last) - { - init(); - insert(first, last); - } - - template - void insert(InputIterator first, InputIterator last) - { - for (; first != last; ++first) - insert(*first); - } - - iterator insert(const K &key) - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i >= 0) - return iterator(this, i); - i = insert_at(key, hash); - return iterator(this, i); - } - - void erase(const K &key) - { - int hash = mkhash(key); - do_erase(key, hash); - } - - void erase(const iterator it) - { - int hash = mkhash(it->first); - do_erase(it->first, hash); - } - - int count(const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - return i < 0 ? 0 : 1; - } - - iterator find(const K &key) - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - return end(); - return iterator(this, i); - } - - const_iterator find(const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - if (i < 0) - return end(); - return const_iterator(this, i); - } - - bool operator[](const K &key) const - { - int hash = mkhash(key); - int i = lookup_index(key, hash); - return i >= 0; - } - - void swap(pool &other) - { - hashtable.swap(other.hashtable); - entries.swap(other.entries); - std::swap(free_list, other.free_list); - std::swap(counter, other.counter); - } - - bool operator==(const pool &other) const { - if (counter != other.counter) - return false; - if (counter == 0) - return true; - if (entries.size() < other.entries.size()) - for (auto &it : *this) { - auto oit = other.find(it.first); - if (oit == other.end() || oit->second != it.second) - return false; - } - else - for (auto &oit : other) { - auto it = find(oit.first); - if (it == end() || it->second != oit.second) - return false; - } - return true; - } - - bool operator!=(const pool &other) const { - return !(*this == other); - } - - size_t size() const { return counter; } - bool empty() const { return counter == 0; } - void clear() { hashtable.clear(); entries.clear(); init(); } - - iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } - iterator end() { return iterator(this, entries.size()); } - - const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } - const_iterator end() const { return const_iterator(this, entries.size()); } -}; - -#endif diff --git a/kernel/modtools.h b/kernel/modtools.h index 56362dbc8..558cc08b8 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -270,7 +270,7 @@ struct ModWalker dict> signal_consumers; pool signal_inputs, signal_outputs; - dict, hash_obj_ops> cell_outputs, cell_inputs; + dict> cell_outputs, cell_inputs; void add_wire(RTLIL::Wire *wire) { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 23edcceef..c262801dc 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -236,6 +236,9 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) RTLIL::Design::Design() { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; + refcount_modules_ = 0; selection_stack.push_back(RTLIL::Selection()); } @@ -447,6 +450,9 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const RTLIL::Module::Module() { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; + design = nullptr; refcount_wires_ = 0; refcount_cells_ = 0; @@ -1132,7 +1138,7 @@ namespace { struct DeleteWireWorker { RTLIL::Module *module; - const pool *wires_p; + const pool *wires_p; void operator()(RTLIL::SigSpec &sig) { std::vector chunks = sig; @@ -1146,7 +1152,7 @@ namespace { }; } -void RTLIL::Module::remove(const pool &wires) +void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); @@ -1735,6 +1741,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::Wire::Wire() { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; + module = nullptr; width = 1; start_offset = 0; @@ -1746,12 +1755,17 @@ RTLIL::Wire::Wire() RTLIL::Memory::Memory() { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; + width = 1; size = 0; } RTLIL::Cell::Cell() : module(nullptr) { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; } bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index cb654c3af..8cf707999 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -708,8 +708,14 @@ struct RTLIL::Selection struct RTLIL::Monitor { - RTLIL::IdString name; - Monitor() { name = stringf("$%d", autoidx++); } + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + + Monitor() { + unsigned int hashidx_count = 0; + hashidx_ = hashidx_count++; + } + virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } @@ -721,7 +727,10 @@ struct RTLIL::Monitor struct RTLIL::Design { - pool monitors; + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + + pool monitors; dict scratchpad; int refcount_modules_; @@ -802,13 +811,16 @@ struct RTLIL::Design struct RTLIL::Module { + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + protected: void add(RTLIL::Wire *wire); void add(RTLIL::Cell *cell); public: RTLIL::Design *design; - pool monitors; + pool monitors; int refcount_wires_; int refcount_cells_; @@ -862,7 +874,7 @@ public: RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const pool &wires); + void remove(const pool &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); @@ -1031,6 +1043,9 @@ public: struct RTLIL::Wire { + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + protected: // use module->addWire() and module->remove() to create or destroy wires friend struct RTLIL::Module; @@ -1051,6 +1066,9 @@ public: struct RTLIL::Memory { + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + Memory(); RTLIL::IdString name; @@ -1060,6 +1078,9 @@ struct RTLIL::Memory struct RTLIL::Cell { + unsigned int hashidx_; + unsigned int hash() const { return hashidx_; } + protected: // use module->addCell() and module->remove() to create or destroy cells friend struct RTLIL::Module; diff --git a/kernel/yosys.h b/kernel/yosys.h index d47f3a958..b653941ce 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -124,17 +124,51 @@ YOSYS_NAMESPACE_BEGIN -#include "kernel/hashmap.h" +#include "kernel/hashlib.h" using std::vector; +using std::string; +using hashlib::mkhash; +using hashlib::mkhash_add; +using hashlib::hash_ops; +using hashlib::hash_cstr_ops; +using hashlib::hash_ptr_ops; +using hashlib::hash_obj_ops; +using hashlib::dict; +using hashlib::pool; namespace RTLIL { struct IdString; + struct Const; struct SigBit; struct SigSpec; struct Wire; struct Cell; + struct Module; + struct Design; + struct Monitor; } +using RTLIL::IdString; +using RTLIL::Const; +using RTLIL::SigBit; +using RTLIL::SigSpec; +using RTLIL::Wire; +using RTLIL::Cell; +using RTLIL::Module; +using RTLIL::Design; + +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; + +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; +template<> struct hash_ops : hash_obj_ops {}; + std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); -- cgit v1.2.3 From 89723a45cf86a508d052dd54aa058719e314cc3c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 18:48:48 +0100 Subject: Improved hashlib iterator implementation --- kernel/hashlib.h | 60 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index a8d320865..d363d68b5 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -145,13 +145,14 @@ class dict std::vector hashtable; std::vector entries; - int free_list, counter; + int free_list, counter, begin_n; OPS ops; void init() { free_list = -1; counter = 0; + begin_n = -1; } void init_from(const dict &other) @@ -182,6 +183,7 @@ class dict void rehash() { free_list = -1; + begin_n = -1; for (auto &h : hashtable) h = -1; @@ -194,6 +196,7 @@ class dict int hash = mkhash(entries[i].udata.first); entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; + begin_n = i; } } @@ -213,7 +216,9 @@ class dict entries[index].set_next_free(free_list); free_list = index; if (--counter == 0) - init(); + clear(); + else if (index == begin_n) + do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); return; } last_index = index; @@ -253,6 +258,8 @@ class dict entries[i].udata = value; entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; + if (begin_n < i) + begin_n = i; counter++; return i; } @@ -265,8 +272,7 @@ public: public: iterator() { } iterator(dict *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } std::pair &operator*() { return ptr->entries[index].udata; } @@ -282,8 +288,7 @@ public: public: const_iterator() { } const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + const_iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } const std::pair &operator*() const { return ptr->entries[index].udata; } @@ -308,8 +313,8 @@ public: } dict &operator=(const dict &other) { - clear(); - init_from(other); + if (this != &other) + init_from(other); return *this; } @@ -420,6 +425,7 @@ public: entries.swap(other.entries); std::swap(free_list, other.free_list); std::swap(counter, other.counter); + std::swap(begin_n, other.begin_n); } bool operator==(const dict &other) const { @@ -450,11 +456,11 @@ public: bool empty() const { return counter == 0; } void clear() { hashtable.clear(); entries.clear(); init(); } - iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } - iterator end() { return iterator(this, entries.size()); } + iterator begin() { return iterator(this, begin_n); } + iterator end() { return iterator(this, -1); } - const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } - const_iterator end() const { return const_iterator(this, entries.size()); } + const_iterator begin() const { return const_iterator(this, begin_n); } + const_iterator end() const { return const_iterator(this, -1); } }; template> @@ -477,13 +483,14 @@ class pool std::vector hashtable; std::vector entries; - int free_list, counter; + int free_list, counter, begin_n; OPS ops; void init() { free_list = -1; counter = 0; + begin_n = -1; } void init_from(const pool &other) @@ -514,6 +521,7 @@ class pool void rehash() { free_list = -1; + begin_n = -1; for (auto &h : hashtable) h = -1; @@ -526,6 +534,7 @@ class pool int hash = mkhash(entries[i].key); entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; + begin_n = i; } } @@ -545,7 +554,9 @@ class pool entries[index].set_next_free(free_list); free_list = index; if (--counter == 0) - init(); + clear(); + else if (index == begin_n) + do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); return; } last_index = index; @@ -585,6 +596,8 @@ class pool entries[i].key = key; entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; + if (begin_n < i) + begin_n = i; counter++; return i; } @@ -597,8 +610,7 @@ public: public: iterator() { } iterator(pool *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } K &operator*() { return ptr->entries[index].key; } @@ -614,8 +626,7 @@ public: public: const_iterator() { } const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index++; while (index != int(ptr->entries.size()) && ptr->entries[index].is_free()); return *this; } - const_iterator operator--() { do index--; while (index != 0 && ptr->entries[index].is_free()); return *this; } + const_iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } const K &operator*() const { return ptr->entries[index].key; } @@ -640,8 +651,8 @@ public: } pool &operator=(const pool &other) { - clear(); - init_from(other); + if (this != &other) + init_from(other); return *this; } @@ -732,6 +743,7 @@ public: entries.swap(other.entries); std::swap(free_list, other.free_list); std::swap(counter, other.counter); + std::swap(begin_n, other.begin_n); } bool operator==(const pool &other) const { @@ -762,11 +774,11 @@ public: bool empty() const { return counter == 0; } void clear() { hashtable.clear(); entries.clear(); init(); } - iterator begin() { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return iterator(this, index); } - iterator end() { return iterator(this, entries.size()); } + iterator begin() { return iterator(this, begin_n); } + iterator end() { return iterator(this, -1); } - const_iterator begin() const { int index = 0; while (index != int(entries.size()) && entries[index].is_free()) index++; return const_iterator(this, index); } - const_iterator end() const { return const_iterator(this, entries.size()); } + const_iterator begin() const { return const_iterator(this, begin_n); } + const_iterator end() const { return const_iterator(this, -1); } }; } /* namespace hashlib */ -- cgit v1.2.3 From f3a97b75c78bd6f3670445129405213c0a015481 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 19:03:18 +0100 Subject: Fixed performance bug in object hashing --- kernel/rtlil.cc | 10 +++++----- kernel/rtlil.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c262801dc..6f2d367d6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -236,7 +236,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) RTLIL::Design::Design() { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; refcount_modules_ = 0; @@ -450,7 +450,7 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const RTLIL::Module::Module() { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; design = nullptr; @@ -1741,7 +1741,7 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::Wire::Wire() { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; module = nullptr; @@ -1755,7 +1755,7 @@ RTLIL::Wire::Wire() RTLIL::Memory::Memory() { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; width = 1; @@ -1764,7 +1764,7 @@ RTLIL::Memory::Memory() RTLIL::Cell::Cell() : module(nullptr) { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8cf707999..f759a014f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -712,7 +712,7 @@ struct RTLIL::Monitor unsigned int hash() const { return hashidx_; } Monitor() { - unsigned int hashidx_count = 0; + static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; } -- cgit v1.2.3 From 137f35373f4ef0d1ddf212187e537e48d077b1f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 19:24:24 +0100 Subject: Changed more code to dict<> and pool<> --- kernel/celltypes.h | 12 ++++++------ kernel/utils.h | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 5ba4dd88b..32e144194 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -27,13 +27,13 @@ YOSYS_NAMESPACE_BEGIN struct CellType { RTLIL::IdString type; - std::set inputs, outputs; + pool inputs, outputs; bool is_evaluable; }; struct CellTypes { - std::map cell_types; + dict cell_types; CellTypes() { @@ -55,7 +55,7 @@ struct CellTypes setup_stdcells_mem(); } - void setup_type(RTLIL::IdString type, const std::set &inputs, const std::set &outputs, bool is_evaluable = false) + void setup_type(RTLIL::IdString type, const pool &inputs, const pool &outputs, bool is_evaluable = false) { CellType ct = {type, inputs, outputs, is_evaluable}; cell_types[ct.type] = ct; @@ -63,7 +63,7 @@ struct CellTypes void setup_module(RTLIL::Module *module) { - std::set inputs, outputs; + pool inputs, outputs; for (RTLIL::IdString wire_name : module->ports) { RTLIL::Wire *wire = module->wire(wire_name); if (wire->port_input) @@ -109,7 +109,7 @@ struct CellTypes setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true); setup_type("$fa", {"\\A", "\\B", "\\C"}, {"\\X", "\\Y"}, true); - setup_type("$assert", {"\\A", "\\EN"}, std::set(), true); + setup_type("$assert", {"\\A", "\\EN"}, pool(), true); } void setup_internals_mem() @@ -123,7 +123,7 @@ struct CellTypes setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); - setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, std::set()); + setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, pool()); setup_type("$mem", {"\\RD_CLK", "\\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/utils.h b/kernel/utils.h index 479effdc9..2ec6182ea 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -31,17 +31,17 @@ YOSYS_NAMESPACE_BEGIN // A map-like container, but you can save and restore the state // ------------------------------------------------ -template> +template> struct stackmap { private: - std::vector> backup_state; - std::map current_state; + std::vector> backup_state; + dict current_state; static T empty_tuple; public: stackmap() { } - stackmap(const std::map &other) : current_state(other) { } + stackmap(const dict &other) : current_state(other) { } template void operator=(const Other &other) @@ -94,7 +94,7 @@ public: current_state.erase(k); } - const std::map &stdmap() + const dict &stdmap() { return current_state; } -- cgit v1.2.3 From 8773fd5897d1057dc8f87d4ffd13c96a708080e8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 21:27:51 +0100 Subject: Added memhasher (yosys -M) --- kernel/driver.cc | 11 +++++++++-- kernel/rtlil.cc | 3 +++ kernel/yosys.cc | 37 +++++++++++++++++++++++++++++++++++++ kernel/yosys.h | 7 +++++++ 4 files changed, 56 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 4700bf61b..9a81d8a48 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -151,8 +151,11 @@ int main(int argc, char **argv) printf(" -m module_file\n"); printf(" load the specified module (aka plugin)\n"); printf("\n"); + printf(" -M\n"); + printf(" will slightly randomize allocated pointer addresses. for debugging\n"); + printf("\n"); printf(" -A\n"); - printf(" will call abort() at the end of the script. useful for debugging\n"); + printf(" will call abort() at the end of the script. for debugging\n"); printf("\n"); printf(" -V\n"); printf(" print version information and exit\n"); @@ -174,10 +177,13 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) + while ((opt = getopt(argc, argv, "MAQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) { switch (opt) { + case 'M': + memhasher_on(); + break; case 'A': call_abort = true; break; @@ -407,6 +413,7 @@ int main(int argc, char **argv) } #endif + memhasher_off(); if (call_abort) abort(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6f2d367d6..cdbaa5bbf 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1766,6 +1766,9 @@ RTLIL::Cell::Cell() : module(nullptr) { static unsigned int hashidx_count = 0; hashidx_ = hashidx_count++; + + // log("#memtrace# %p\n", this); + memhasher(); } bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 6cc643152..52bd066b7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -55,6 +55,43 @@ RTLIL::Design *yosys_design = NULL; Tcl_Interp *yosys_tcl_interp = NULL; #endif +bool memhasher_active = false; +uint32_t memhasher_rng; +std::vector memhasher_store; + +void memhasher_on() +{ + memhasher_rng += time(NULL) << 16 ^ getpid(); + memhasher_store.resize(0x10000); + memhasher_active = true; +} + +void memhasher_off() +{ + for (auto p : memhasher_store) + if (p) free(p); + memhasher_store.clear(); + memhasher_active = false; +} + +void memhasher_do() +{ + memhasher_rng ^= memhasher_rng << 13; + memhasher_rng ^= memhasher_rng >> 17; + memhasher_rng ^= memhasher_rng << 5; + + int size, index = (memhasher_rng >> 4) & 0xffff; + switch (memhasher_rng & 7) { + case 0: size = 16; break; + case 1: size = 256; break; + case 2: size = 1024; break; + case 3: size = 4096; break; + default: size = 0; + } + if (index < 16) size *= 16; + memhasher_store[index] = realloc(memhasher_store[index], size); +} + std::string stringf(const char *fmt, ...) { std::string string; diff --git a/kernel/yosys.h b/kernel/yosys.h index b653941ce..50a159939 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -169,6 +169,13 @@ template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; +void memhasher_on(); +void memhasher_off(); +void memhasher_do(); + +extern bool memhasher_active; +inline void memhasher() { if (memhasher_active) memhasher_do(); } + std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); -- cgit v1.2.3 From 2ad131764fc9b9b3f913650d206a540c2d57dc45 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 21:43:14 +0100 Subject: Some cleanups --- kernel/hashlib.h | 18 +++++++++--------- kernel/yosys.cc | 4 +++- kernel/yosys.h | 9 ++++++++- 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index d363d68b5..e5e76a1e1 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -17,7 +17,7 @@ namespace hashlib { -#define HASHLIB_SIZE_FACTOR 3 +const int config_size_factor = 3; // The XOR version of DJB2 // (traditionally 5381 is used as starting value for the djb2 hash) @@ -161,9 +161,9 @@ class dict entries.clear(); counter = other.size(); - int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * counter); + int new_size = hashtable_size(config_size_factor * counter); hashtable.resize(new_size); - new_size = new_size / HASHLIB_SIZE_FACTOR + 1; + new_size = new_size / config_size_factor + 1; entries.reserve(new_size); for (auto &it : other) @@ -243,9 +243,9 @@ class dict if (free_list < 0) { int i = entries.size(); - int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * entries.size()); + int new_size = hashtable_size(config_size_factor * entries.size()); hashtable.resize(new_size); - entries.resize(new_size / HASHLIB_SIZE_FACTOR + 1); + entries.resize(new_size / config_size_factor + 1); entries[i].udata = value; entries[i].set_next_used(0); counter++; @@ -499,9 +499,9 @@ class pool entries.clear(); counter = other.size(); - int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * counter); + int new_size = hashtable_size(config_size_factor * counter); hashtable.resize(new_size); - new_size = new_size / HASHLIB_SIZE_FACTOR + 1; + new_size = new_size / config_size_factor + 1; entries.reserve(new_size); for (auto &it : other) @@ -581,9 +581,9 @@ class pool if (free_list < 0) { int i = entries.size(); - int new_size = hashtable_size(HASHLIB_SIZE_FACTOR * entries.size()); + int new_size = hashtable_size(config_size_factor * entries.size()); hashtable.resize(new_size); - entries.resize(new_size / HASHLIB_SIZE_FACTOR + 1); + entries.resize(new_size / config_size_factor + 1); entries[i].key = key; entries[i].set_next_used(0); counter++; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 52bd066b7..0faca8d51 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -56,12 +56,14 @@ Tcl_Interp *yosys_tcl_interp = NULL; #endif bool memhasher_active = false; -uint32_t memhasher_rng; +uint32_t memhasher_rng = 123456; std::vector memhasher_store; void memhasher_on() { +#ifdef __linux__ memhasher_rng += time(NULL) << 16 ^ getpid(); +#endif memhasher_store.resize(0x10000); memhasher_active = true; } diff --git a/kernel/yosys.h b/kernel/yosys.h index 50a159939..bbcbd5fed 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -124,7 +124,14 @@ YOSYS_NAMESPACE_BEGIN -#include "kernel/hashlib.h" +#ifdef HASHLIB_H +# undef HASHLIB_H +# include "kernel/hashlib.h" +#else +# include "kernel/hashlib.h" +# undef HASHLIB_H +#endif + using std::vector; using std::string; using hashlib::mkhash; -- cgit v1.2.3 From dede5353b10c1d8fb887fbfd3a46cb1fc0413082 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 28 Dec 2014 22:26:09 +0100 Subject: Some changes to hashlib to make for better stl compatibility --- kernel/hashlib.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index e5e76a1e1..24a1dbf6d 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -200,13 +200,13 @@ class dict } } - void do_erase(const K &key, int hash) + int do_erase(const K &key, int hash) { int last_index = -1; int index = hashtable.empty() ? -1 : hashtable[hash]; while (1) { if (index < 0) - return; + return 0; if (ops.cmp(entries[index].udata.first, key)) { if (last_index < 0) hashtable[hash] = entries[index].get_next(); @@ -219,7 +219,7 @@ class dict clear(); else if (index == begin_n) do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); - return; + return 1; } last_index = index; index = entries[index].get_next(); @@ -355,16 +355,17 @@ public: return std::pair(iterator(this, i), true); } - void erase(const K &key) + int erase(const K &key) { int hash = mkhash(key); - do_erase(key, hash); + return do_erase(key, hash); } - void erase(const iterator it) + iterator erase(iterator it) { int hash = mkhash(it->first); do_erase(it->first, hash); + return ++it; } int count(const K &key) const @@ -538,13 +539,13 @@ class pool } } - void do_erase(const K &key, int hash) + int do_erase(const K &key, int hash) { int last_index = -1; int index = hashtable.empty() ? -1 : hashtable[hash]; while (1) { if (index < 0) - return; + return 0; if (ops.cmp(entries[index].key, key)) { if (last_index < 0) hashtable[hash] = entries[index].get_next(); @@ -557,7 +558,7 @@ class pool clear(); else if (index == begin_n) do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); - return; + return 1; } last_index = index; index = entries[index].get_next(); @@ -693,16 +694,17 @@ public: return std::pair(iterator(this, i), true); } - void erase(const K &key) + int erase(const K &key) { int hash = mkhash(key); - do_erase(key, hash); + return do_erase(key, hash); } - void erase(const iterator it) + iterator erase(iterator it) { int hash = mkhash(*it); do_erase(*it, hash); + return ++it; } int count(const K &key) const -- cgit v1.2.3 From a2226e530791ec9dea45cd905f812de28d2c1c06 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 00:12:36 +0100 Subject: Added mkhash_xorshift() --- kernel/hashlib.h | 20 +++++++++++++++++++- kernel/rtlil.cc | 25 +++++++++++++++---------- kernel/rtlil.h | 5 +++-- kernel/yosys.h | 1 + 4 files changed, 38 insertions(+), 13 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 24a1dbf6d..021cc66ee 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -31,6 +31,20 @@ inline unsigned int mkhash_add(unsigned int a, unsigned int b) { return ((a << 5) + a) + b; } +inline unsigned int mkhash_xorshift(unsigned int a) { + if (sizeof(a) == 4) { + a ^= a << 13; + a ^= a >> 17; + a ^= a << 5; + } else if (sizeof(a) == 8) { + a ^= a << 13; + a ^= a >> 7; + a ^= a << 17; + } else + throw std::runtime_error("mkhash_xorshift() only implemented for 32 bit and 64 bit ints"); + return a; +} + template struct hash_ops { bool cmp(const T &a, const T &b) const { return a == b; @@ -122,7 +136,11 @@ inline int hashtable_size(int old_size) if (old_size < 250999999) return 250999999; if (old_size < 503000009) return 503000009; if (old_size < 1129999999) return 1129999999; - throw std::length_error("hash table exceeded maximum size"); + + if (sizeof(old_size) == 4) + throw std::length_error("hash table exceeded maximum size. recompile with -mint64."); + + return old_size * 2; } template> diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index cdbaa5bbf..f25df175d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -236,8 +236,9 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) RTLIL::Design::Design() { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; refcount_modules_ = 0; selection_stack.push_back(RTLIL::Selection()); @@ -450,8 +451,9 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const RTLIL::Module::Module() { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; design = nullptr; refcount_wires_ = 0; @@ -1741,8 +1743,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::Wire::Wire() { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; module = nullptr; width = 1; @@ -1755,8 +1758,9 @@ RTLIL::Wire::Wire() RTLIL::Memory::Memory() { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; width = 1; size = 0; @@ -1764,8 +1768,9 @@ RTLIL::Memory::Memory() RTLIL::Cell::Cell() : module(nullptr) { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; // log("#memtrace# %p\n", this); memhasher(); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f759a014f..5bca060f4 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -712,8 +712,9 @@ struct RTLIL::Monitor unsigned int hash() const { return hashidx_; } Monitor() { - static unsigned int hashidx_count = 0; - hashidx_ = hashidx_count++; + static unsigned int hashidx_count = 123456789; + hashidx_count = mkhash_xorshift(hashidx_count); + hashidx_ = hashidx_count; } virtual ~Monitor() { } diff --git a/kernel/yosys.h b/kernel/yosys.h index bbcbd5fed..8ddd6f540 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -136,6 +136,7 @@ using std::vector; using std::string; using hashlib::mkhash; using hashlib::mkhash_add; +using hashlib::mkhash_xorshift; using hashlib::hash_ops; using hashlib::hash_cstr_ops; using hashlib::hash_ptr_ops; -- cgit v1.2.3 From cfe0817697c9e7a656fd3a64e3a9014fa86e78d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 02:01:42 +0100 Subject: Converting "share" to dict<> and pool<> complete --- kernel/hashlib.h | 11 +++++++++++ kernel/rtlil.h | 11 +++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 021cc66ee..4e8c00026 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -76,6 +76,17 @@ template<> struct hash_ops { } }; +template struct hash_ops> { + bool cmp(std::pair a, std::pair b) const { + return a == b; + } + unsigned int hash(std::pair a) const { + hash_ops

p_ops; + hash_ops q_ops; + return mkhash(p_ops.hash(a.first), q_ops.hash(a.second)); + } +}; + struct hash_cstr_ops { bool cmp(const char *a, const char *b) const { for (int i = 0; a[i] || b[i]; i++) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 5bca060f4..25477d02e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -219,8 +219,8 @@ namespace RTLIL return index_; } - // The following is a helper key_compare class. Instead of for example pool - // use pool> if the order of cells in the + // The following is a helper key_compare class. Instead of for example std::set + // use std::set> if the order of cells in the // set has an influence on the algorithm. template struct compare_ptr_by_name { @@ -450,6 +450,13 @@ struct RTLIL::Const std::string decode_string() const; inline int size() const { return bits.size(); } + + inline unsigned int hash() const { + unsigned int h = 5381; + for (auto b : bits) + mkhash(h, b); + return h; + } }; struct RTLIL::SigChunk -- cgit v1.2.3 From 397ae5b697e9923bb9d35df425370efd9357b127 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 02:46:59 +0100 Subject: gcc build fixes --- kernel/yosys.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.h b/kernel/yosys.h index 8ddd6f540..700a0603d 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -124,6 +125,8 @@ YOSYS_NAMESPACE_BEGIN +// Note: All headers included in hashlib.h must be included +// outside of YOSYS_NAMESPACE before this or bad things will happen. #ifdef HASHLIB_H # undef HASHLIB_H # include "kernel/hashlib.h" @@ -165,17 +168,19 @@ using RTLIL::Cell; using RTLIL::Module; using RTLIL::Design; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; - -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; -template<> struct hash_ops : hash_obj_ops {}; +namespace hashlib { + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; +} void memhasher_on(); void memhasher_off(); -- cgit v1.2.3 From 90bc71dd906935def78048e13e7c9f214af0486c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 03:11:50 +0100 Subject: dict/pool changes in ast --- kernel/yosys.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.h b/kernel/yosys.h index 700a0603d..c0004abce 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -159,6 +159,10 @@ namespace RTLIL { struct Monitor; } +namespace AST { + struct AstNode; +} + using RTLIL::IdString; using RTLIL::Const; using RTLIL::SigBit; @@ -174,12 +178,14 @@ namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; } void memhasher_on(); -- cgit v1.2.3 From 662cb549e4e11d15b9c1c7e4d3944a05dab2447f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 03:49:45 +0100 Subject: Added newline support to Pass::call() parser --- kernel/register.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 2927a333e..7086e1424 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -182,6 +182,18 @@ void Pass::call(RTLIL::Design *design, std::string command) call(design, "clean -purge"); } else args.push_back(tok); + bool found_nl = false; + for (auto c : cmd_buf) { + if (c == ' ' || c == '\t') + continue; + if (c == '\r' || c == '\n') + found_nl = true; + break; + } + if (found_nl) { + call(design, args); + args.clear(); + } tok = next_token(cmd_buf, " \t\r\n"); } -- cgit v1.2.3 From 7d843adef98ec051acc64f4a04c925c468b562c2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 04:06:52 +0100 Subject: dict/pool changes in opt_clean --- kernel/sigtools.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 5281b7a45..c38736e70 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -195,6 +195,15 @@ struct SigSet } } + void find(RTLIL::SigSpec sig, pool &result) + { + for (auto &bit : sig) + if (bit.wire != NULL) { + auto &data = bits[bit]; + result.insert(data.begin(), data.end()); + } + } + std::set find(RTLIL::SigSpec sig) { std::set result; -- cgit v1.2.3 From 33e25394b447eda249cc9cf7c114093f3069fb62 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 04:15:48 +0100 Subject: Fixed comment parsing in Pass::call() --- kernel/register.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 7086e1424..56dc695aa 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -150,7 +150,7 @@ void Pass::call(RTLIL::Design *design, std::string command) std::string cmd_buf = command; std::string tok = next_token(cmd_buf, " \t\r\n"); - if (tok.empty() || tok[0] == '#') + if (tok.empty()) return; if (tok[0] == '!') { @@ -166,8 +166,13 @@ void Pass::call(RTLIL::Design *design, std::string command) } while (!tok.empty()) { - if (tok == "#") - break; + if (tok == "#") { + int stop; + for (stop = 0; stop < GetSize(cmd_buf); stop++) + if (cmd_buf[stop] == '\r' || cmd_buf[stop] == '\n') + break; + cmd_buf = cmd_buf.substr(stop); + } else if (tok.back() == ';') { int num_semikolon = 0; while (!tok.empty() && tok.back() == ';') -- cgit v1.2.3 From ecd64182c5a3689ef293bccf032e1d7eecada91a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 13:33:33 +0100 Subject: Added "yosys -X" --- kernel/driver.cc | 8 ++++- kernel/log.cc | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/log.h | 1 + kernel/rtlil.cc | 37 ++++++++++++++++++++++ kernel/rtlil.h | 11 +++++++ kernel/yosys.cc | 1 + kernel/yosys.h | 1 + 7 files changed, 153 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 9a81d8a48..cdf784602 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -151,6 +151,9 @@ int main(int argc, char **argv) printf(" -m module_file\n"); printf(" load the specified module (aka plugin)\n"); printf("\n"); + printf(" -X\n"); + printf(" enable tracing of core data structure changes. for debugging\n"); + printf("\n"); printf(" -M\n"); printf(" will slightly randomize allocated pointer addresses. for debugging\n"); printf("\n"); @@ -177,13 +180,16 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "MAQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) + while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) { switch (opt) { case 'M': memhasher_on(); break; + case 'X': + yosys_xtrace++; + break; case 'A': call_abort = true; break; diff --git a/kernel/log.cc b/kernel/log.cc index 5b18e3d6c..b984f0112 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -25,6 +25,10 @@ # include #endif +#ifdef __linux__ +# include +#endif + #include #include #include @@ -243,6 +247,97 @@ void log_pop() log_flush(); } +void log_backtrace(const char *prefix, int levels) +{ +#ifdef __linux__ + if (levels <= 0) return; + + Dl_info dli; + void *p; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(0))) && dladdr(p, &dli)) { + log("%sframe #1: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #1: ---\n", prefix); + return; + } + + if (levels <= 1) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(1))) && dladdr(p, &dli)) { + log("%sframe #2: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #2: ---\n", prefix); + return; + } + + if (levels <= 2) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(2))) && dladdr(p, &dli)) { + log("%sframe #3: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #3: ---\n", prefix); + return; + } + + if (levels <= 3) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(3))) && dladdr(p, &dli)) { + log("%sframe #4: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #4: ---\n", prefix); + return; + } + + if (levels <= 4) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(4))) && dladdr(p, &dli)) { + log("%sframe #5: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #5: ---\n", prefix); + return; + } + + if (levels <= 5) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(5))) && dladdr(p, &dli)) { + log("%sframe #6: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #6: ---\n", prefix); + return; + } + + if (levels <= 6) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(6))) && dladdr(p, &dli)) { + log("%sframe #7: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #7: ---\n", prefix); + return; + } + + if (levels <= 7) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(7))) && dladdr(p, &dli)) { + log("%sframe #8: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #8: ---\n", prefix); + return; + } + + if (levels <= 8) return; + + if ((p = __builtin_extract_return_addr(__builtin_return_address(8))) && dladdr(p, &dli)) { + log("%sframe #9: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr); + } else { + log("%sframe #9: ---\n", prefix); + return; + } + + if (levels <= 9) return; +#endif +} + void log_reset_stack() { while (header_count.size() > 1) diff --git a/kernel/log.h b/kernel/log.h index 9bb2b3621..8096758f6 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -65,6 +65,7 @@ void log_spacer(); void log_push(); void log_pop(); +void log_backtrace(const char *prefix, int levels); void log_reset_stack(); void log_flush(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f25df175d..912df7903 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -269,6 +269,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) @@ -284,6 +289,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; } @@ -353,6 +363,11 @@ 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; @@ -1283,6 +1298,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); } @@ -1300,6 +1320,13 @@ void RTLIL::Module::new_connections(const std::vector &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; } @@ -1795,6 +1822,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); } } @@ -1816,6 +1848,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; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 25477d02e..bb9e85d93 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -120,6 +120,12 @@ namespace RTLIL global_id_storage_.at(idx) = strdup(p); global_id_index_[global_id_storage_.at(idx)] = idx; global_refcount_storage_.at(idx)++; + + if (yosys_xtrace) { + log("#X# New IdString '%s' with index %d.\n", p, idx); + log_backtrace("-X- ", yosys_xtrace-1); + } + return idx; } @@ -135,6 +141,11 @@ namespace RTLIL if (--global_refcount_storage_.at(idx) != 0) return; + if (yosys_xtrace) { + log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx); + log_backtrace("-X- ", yosys_xtrace-1); + } + global_id_index_.erase(global_id_storage_.at(idx)); free(global_id_storage_.at(idx)); global_id_storage_.at(idx) = nullptr; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 0faca8d51..6bc8dd0bb 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -49,6 +49,7 @@ YOSYS_NAMESPACE_BEGIN int autoidx = 1; +int yosys_xtrace = 0; RTLIL::Design *yosys_design = NULL; #ifdef YOSYS_ENABLE_TCL diff --git a/kernel/yosys.h b/kernel/yosys.h index c0004abce..a4836f35a 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -210,6 +210,7 @@ template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); extern int autoidx; +extern int yosys_xtrace; YOSYS_NAMESPACE_END -- cgit v1.2.3 From 0bb6b24c117fa685dce34abf82cb0f9ef73a7661 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 14:30:33 +0100 Subject: Added global yosys_celltypes --- kernel/celltypes.h | 97 ++++++++++++++++++++++++++++++++---------------------- kernel/yosys.cc | 9 +++++ 2 files changed, 66 insertions(+), 40 deletions(-) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 32e144194..3a56de2f7 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -96,88 +96,102 @@ struct CellTypes "$logic_and", "$logic_or", "$concat", "$macc" }; + IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; + IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; + IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; + for (auto type : unary_ops) - setup_type(type, {"\\A"}, {"\\Y"}, true); + setup_type(type, {A}, {Y}, true); for (auto type : binary_ops) - setup_type(type, {"\\A", "\\B"}, {"\\Y"}, true); + setup_type(type, {A, B}, {Y}, true); for (auto type : std::vector({"$mux", "$pmux"})) - setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); + setup_type(type, {A, B, S}, {Y}, true); - setup_type("$lcu", {"\\P", "\\G", "\\CI"}, {"\\CO"}, true); - setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true); - setup_type("$fa", {"\\A", "\\B", "\\C"}, {"\\X", "\\Y"}, true); + setup_type("$lcu", {P, G, CI}, {CO}, true); + setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true); + setup_type("$fa", {A, B, C}, {X, Y}, true); - setup_type("$assert", {"\\A", "\\EN"}, pool(), true); + setup_type("$assert", {A, EN}, pool(), true); } void setup_internals_mem() { - setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"}); - setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"}); - setup_type("$dffe", {"\\CLK", "\\EN", "\\D"}, {"\\Q"}); - setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); - setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"}); - setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"}); - setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); - - setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); - setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, pool()); - setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}); - - setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}); + IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; + IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA"; + 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"; + + setup_type("$sr", {SET, CLR}, {Q}); + setup_type("$dff", {CLK, D}, {Q}); + setup_type("$dffe", {CLK, EN, D}, {Q}); + setup_type("$dffsr", {CLK, SET, CLR, D}, {Q}); + setup_type("$adff", {CLK, ARST, D}, {Q}); + setup_type("$dlatch", {EN, D}, {Q}); + setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); + + setup_type("$memrd", {CLK, ADDR}, {DATA}); + setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool()); + setup_type("$mem", {RD_CLK, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); + + setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT}); } void setup_stdcells() { - setup_type("$_BUF_", {"\\A"}, {"\\Y"}, true); - setup_type("$_NOT_", {"\\A"}, {"\\Y"}, true); - setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_NAND_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_NOR_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_XNOR_", {"\\A", "\\B"}, {"\\Y"}, true); - setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, true); - setup_type("$_AOI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true); - setup_type("$_OAI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true); - setup_type("$_AOI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true); - setup_type("$_OAI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true); + IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D", S = "\\S", Y = "\\Y"; + setup_type("$_BUF_", {A}, {Y}, true); + setup_type("$_NOT_", {A}, {Y}, true); + setup_type("$_AND_", {A, B}, {Y}, true); + setup_type("$_NAND_", {A, B}, {Y}, true); + setup_type("$_OR_", {A, B}, {Y}, true); + setup_type("$_NOR_", {A, B}, {Y}, true); + setup_type("$_XOR_", {A, B}, {Y}, true); + setup_type("$_XNOR_", {A, B}, {Y}, true); + setup_type("$_MUX_", {A, B, S}, {Y}, true); + setup_type("$_AOI3_", {A, B, C}, {Y}, true); + setup_type("$_OAI3_", {A, B, C}, {Y}, true); + setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); + setup_type("$_OAI4_", {A, B, C, D}, {Y}, true); } void setup_stdcells_mem() { + IdString S = "\\S", R = "\\R", C = "\\C"; + IdString D = "\\D", Q = "\\Q", E = "\\E"; + std::vector list_np = {'N', 'P'}, list_01 = {'0', '1'}; for (auto c1 : list_np) for (auto c2 : list_np) - setup_type(stringf("$_SR_%c%c_", c1, c2), {"\\S", "\\R"}, {"\\Q"}); + setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q}); for (auto c1 : list_np) - setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"}); + setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q}); for (auto c1 : list_np) for (auto c2 : list_np) - setup_type(stringf("$_DFFE_%c%c_", c1, c2), {"\\C", "\\D", "\\E"}, {"\\Q"}); + setup_type(stringf("$_DFFE_%c%c_", c1, c2), {C, D, E}, {Q}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_01) - setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {"\\C", "\\R", "\\D"}, {"\\Q"}); + setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {C, R, D}, {Q}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_np) - setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {"\\C", "\\S", "\\R", "\\D"}, {"\\Q"}); + setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {C, S, R, D}, {Q}); for (auto c1 : list_np) - setup_type(stringf("$_DLATCH_%c_", c1), {"\\E", "\\D"}, {"\\Q"}); + setup_type(stringf("$_DLATCH_%c_", c1), {E, D}, {Q}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_np) - setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {"\\E", "\\S", "\\R", "\\D"}, {"\\Q"}); + setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {E, S, R, D}, {Q}); } void clear() @@ -368,6 +382,9 @@ struct CellTypes } }; +// initialized by yosys_setup() +extern CellTypes yosys_celltypes; + YOSYS_NAMESPACE_END #endif diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 6bc8dd0bb..444bdb1d2 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "kernel/celltypes.h" #ifdef YOSYS_ENABLE_READLINE # include @@ -51,6 +52,7 @@ YOSYS_NAMESPACE_BEGIN int autoidx = 1; int yosys_xtrace = 0; RTLIL::Design *yosys_design = NULL; +CellTypes yosys_celltypes; #ifdef YOSYS_ENABLE_TCL Tcl_Interp *yosys_tcl_interp = NULL; @@ -378,8 +380,14 @@ int GetSize(RTLIL::Wire *wire) void yosys_setup() { + // if there are already IdString objects then we have a global initialization order bug + IdString empty_id; + log_assert(empty_id.index_ == 0); + IdString::get_reference(empty_id.index_); + Pass::init_register(); yosys_design = new RTLIL::Design; + yosys_celltypes.setup(); log_push(); } @@ -397,6 +405,7 @@ void yosys_shutdown() log_files.clear(); Pass::done_register(); + yosys_celltypes.clear(); #ifdef YOSYS_ENABLE_TCL if (yosys_tcl_interp != NULL) { -- cgit v1.2.3 From 7a4d5d1c0fb78d49163160bfabb8cd1f5d1a2899 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 15:17:40 +0100 Subject: Less verbose ABC output --- kernel/yosys.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 444bdb1d2..fa9fffa62 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -360,7 +360,6 @@ void remove_directory(std::string dirname) if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { std::string buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name); if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) { - log("Removing `%s'.\n", buffer.c_str()); remove(buffer.c_str()); } else remove_directory(buffer); @@ -368,7 +367,6 @@ void remove_directory(std::string dirname) free(namelist[i]); } free(namelist); - log("Removing `%s'.\n", dirname.c_str()); rmdir(dirname.c_str()); #endif } -- cgit v1.2.3 From 2f1e6aa2564bdc5d9f1a5fd8e879322739e0ffa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 20:24:28 +0100 Subject: Improved free list management in hashlib --- kernel/hashlib.h | 120 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 12 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 4e8c00026..5f977c5f1 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -175,6 +175,7 @@ class dict std::vector hashtable; std::vector entries; int free_list, counter, begin_n; + int begin_seek_count; OPS ops; void init() @@ -182,6 +183,7 @@ class dict free_list = -1; counter = 0; begin_n = -1; + begin_seek_count = 0; } void init_from(const dict &other) @@ -209,6 +211,43 @@ class dict return hash; } + void upd_begin_n() + { + if (begin_n < -1) { + begin_n = -(begin_n+2); + if (begin_n > int(entries.size())) + begin_n = int(entries.size()); + do { + if (begin_seek_count++ > int(entries.size())) + refree(); + else + begin_n--; + } while (begin_n >= 0 && entries[begin_n].is_free()); + } + } + + void refree() + { + free_list = -1; + begin_n = -1; + + int last_free = -1; + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + if (last_free != -1) + entries[last_free].set_next_free(i); + else + free_list = i; + last_free = i; + } else + begin_n = i; + + if (last_free != -1) + entries[last_free].set_next_free(-1); + + begin_seek_count = 0; + } + void rehash() { free_list = -1; @@ -217,16 +256,25 @@ class dict for (auto &h : hashtable) h = -1; + int last_free = -1; for (int i = 0; i < int(entries.size()); i++) if (entries[i].is_free()) { - entries[i].set_next_free(free_list); - free_list = i; + if (last_free != -1) + entries[last_free].set_next_free(i); + else + free_list = i; + last_free = i; } else { int hash = mkhash(entries[i].udata.first); entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; begin_n = i; } + + if (last_free != -1) + entries[last_free].set_next_free(-1); + + begin_seek_count = 0; } int do_erase(const K &key, int hash) @@ -247,7 +295,7 @@ class dict if (--counter == 0) clear(); else if (index == begin_n) - do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); + begin_n = -(begin_n+2); return 1; } last_index = index; @@ -287,7 +335,7 @@ class dict entries[i].udata = value; entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; - if (begin_n < i) + if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i)) begin_n = i; counter++; return i; @@ -486,10 +534,10 @@ public: bool empty() const { return counter == 0; } void clear() { hashtable.clear(); entries.clear(); init(); } - iterator begin() { return iterator(this, begin_n); } + iterator begin() { upd_begin_n(); return iterator(this, begin_n); } iterator end() { return iterator(this, -1); } - const_iterator begin() const { return const_iterator(this, begin_n); } + const_iterator begin() const { ((dict*)this)->upd_begin_n(); return const_iterator(this, begin_n); } const_iterator end() const { return const_iterator(this, -1); } }; @@ -514,6 +562,7 @@ class pool std::vector hashtable; std::vector entries; int free_list, counter, begin_n; + int begin_seek_count; OPS ops; void init() @@ -521,6 +570,7 @@ class pool free_list = -1; counter = 0; begin_n = -1; + begin_seek_count = 0; } void init_from(const pool &other) @@ -548,6 +598,43 @@ class pool return hash; } + void upd_begin_n() + { + if (begin_n < -1) { + begin_n = -(begin_n+2); + if (begin_n > int(entries.size())) + begin_n = int(entries.size()); + do { + if (begin_seek_count++ > int(entries.size())) + refree(); + else + begin_n--; + } while (begin_n >= 0 && entries[begin_n].is_free()); + } + } + + void refree() + { + free_list = -1; + begin_n = -1; + + int last_free = -1; + for (int i = 0; i < int(entries.size()); i++) + if (entries[i].is_free()) { + if (last_free != -1) + entries[last_free].set_next_free(i); + else + free_list = i; + last_free = i; + } else + begin_n = i; + + if (last_free != -1) + entries[last_free].set_next_free(-1); + + begin_seek_count = 0; + } + void rehash() { free_list = -1; @@ -556,16 +643,25 @@ class pool for (auto &h : hashtable) h = -1; + int last_free = -1; for (int i = 0; i < int(entries.size()); i++) if (entries[i].is_free()) { - entries[i].set_next_free(free_list); - free_list = i; + if (last_free != -1) + entries[last_free].set_next_free(i); + else + free_list = i; + last_free = i; } else { int hash = mkhash(entries[i].key); entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; begin_n = i; } + + if (last_free != -1) + entries[last_free].set_next_free(-1); + + begin_seek_count = 0; } int do_erase(const K &key, int hash) @@ -586,7 +682,7 @@ class pool if (--counter == 0) clear(); else if (index == begin_n) - do begin_n--; while (begin_n >= 0 && entries[begin_n].is_free()); + begin_n = -(begin_n+2); return 1; } last_index = index; @@ -626,7 +722,7 @@ class pool entries[i].key = key; entries[i].set_next_used(hashtable[hash]); hashtable[hash] = i; - if (begin_n < i) + if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i)) begin_n = i; counter++; return i; @@ -805,10 +901,10 @@ public: bool empty() const { return counter == 0; } void clear() { hashtable.clear(); entries.clear(); init(); } - iterator begin() { return iterator(this, begin_n); } + iterator begin() { upd_begin_n(); return iterator(this, begin_n); } iterator end() { return iterator(this, -1); } - const_iterator begin() const { return const_iterator(this, begin_n); } + const_iterator begin() const { ((pool*)this)->upd_begin_n(); return const_iterator(this, begin_n); } const_iterator end() const { return const_iterator(this, -1); } }; -- cgit v1.2.3 From d72a66644035d43f81afa78283ecf15c520909ec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 29 Dec 2014 21:26:15 +0100 Subject: Put dummy reference to empty idstring in yosys_shutdown() --- kernel/yosys.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index fa9fffa62..ac1bc7abf 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -420,6 +420,9 @@ void yosys_shutdown() loaded_plugins.clear(); loaded_plugin_aliases.clear(); #endif + + IdString empty_id; + IdString::put_reference(empty_id.index_); } RTLIL::IdString new_id(std::string file, int line, std::string func) -- cgit v1.2.3 From 3857e1cb66e294774745534ce6cc01b5c495b333 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 13:22:33 +0100 Subject: Improvements in hashlib --- kernel/hashlib.h | 159 ++++++++++++++++++++++++++----------------------------- 1 file changed, 74 insertions(+), 85 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 5f977c5f1..b02abfadd 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -17,7 +17,8 @@ namespace hashlib { -const int config_size_factor = 3; +const int hashtable_size_trigger = 2; +const int hashtable_size_factor = 3; // The XOR version of DJB2 // (traditionally 5381 is used as starting value for the djb2 hash) @@ -121,37 +122,29 @@ struct hash_obj_ops { } }; -inline int hashtable_size(int old_size) +inline int hashtable_size(int min_size) { - // prime numbers, approx. in powers of two - if (old_size < 53) return 53; - if (old_size < 113) return 113; - if (old_size < 251) return 251; - if (old_size < 503) return 503; - if (old_size < 1129) return 1129; - if (old_size < 2503) return 2503; - if (old_size < 5023) return 5023; - if (old_size < 11299) return 11299; - if (old_size < 25097) return 25097; - if (old_size < 50291) return 50291; - if (old_size < 112997) return 112997; - if (old_size < 251003) return 251003; - if (old_size < 503003) return 503003; - if (old_size < 1129991) return 1129991; - if (old_size < 2509993) return 2509993; - if (old_size < 5029991) return 5029991; - if (old_size < 11299997) return 11299997; - if (old_size < 25099999) return 25099999; - if (old_size < 50299999) return 50299999; - if (old_size < 113000009) return 113000009; - if (old_size < 250999999) return 250999999; - if (old_size < 503000009) return 503000009; - if (old_size < 1129999999) return 1129999999; - - if (sizeof(old_size) == 4) - throw std::length_error("hash table exceeded maximum size. recompile with -mint64."); - - return old_size * 2; + static std::vector primes = { + 23, 29, 37, 47, 59, 79, 101, 127, 163, 211, 269, 337, 431, 541, 677, + 853, 1069, 1361, 1709, 2137, 2677, 3347, 4201, 5261, 6577, 8231, 10289, + 12889, 16127, 20161, 25219, 31531, 39419, 49277, 61603, 77017, 96281, + 120371, 150473, 188107, 235159, 293957, 367453, 459317, 574157, 717697, + 897133, 1121423, 1401791, 1752239, 2190299, 2737937, 3422429, 4278037, + 5347553, 6684443, 8355563, 10444457, 13055587, 16319519, 20399411, + 25499291, 31874149, 39842687, 49803361, 62254207, 77817767, 97272239, + 121590311, 151987889, 189984863, 237481091, 296851369, 371064217 + }; + + for (auto p : primes) + if (p > min_size) return p; + + if (sizeof(int) == 4) + throw std::length_error("hash table exceeded maximum size. use a ILP64 abi for larger tables."); + + for (auto p : primes) + if (100129 * p > min_size) return 100129 * p; + + throw std::length_error("hash table exceeded maximum size."); } template> @@ -192,14 +185,12 @@ class dict entries.clear(); counter = other.size(); - int new_size = hashtable_size(config_size_factor * counter); - hashtable.resize(new_size); - new_size = new_size / config_size_factor + 1; - entries.reserve(new_size); + begin_n = counter - 1; + entries.reserve(counter); for (auto &it : other) entries.push_back(entry_t(it)); - entries.resize(new_size); + rehash(); } @@ -211,18 +202,12 @@ class dict return hash; } - void upd_begin_n() + void upd_begin_n(bool do_refree = true) { if (begin_n < -1) { begin_n = -(begin_n+2); - if (begin_n > int(entries.size())) - begin_n = int(entries.size()); - do { - if (begin_seek_count++ > int(entries.size())) - refree(); - else - begin_n--; - } while (begin_n >= 0 && entries[begin_n].is_free()); + while (begin_n >= 0 && entries[begin_n].is_free()) { begin_seek_count++; begin_n--; } + if (do_refree && begin_seek_count > int(entries.size() / 2)) refree(); } } @@ -250,11 +235,14 @@ class dict void rehash() { + upd_begin_n(false); + entries.resize(begin_n + 1); + free_list = -1; begin_n = -1; - for (auto &h : hashtable) - h = -1; + hashtable.clear(); + hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); int last_free = -1; for (int i = 0; i < int(entries.size()); i++) @@ -319,15 +307,18 @@ class dict { if (free_list < 0) { - int i = entries.size(); - int new_size = hashtable_size(config_size_factor * entries.size()); - hashtable.resize(new_size); - entries.resize(new_size / config_size_factor + 1); - entries[i].udata = value; - entries[i].set_next_used(0); - counter++; - rehash(); - return i; + free_list = entries.size(); + entries.push_back(entry_t()); + + if (entries.size() * hashtable_size_trigger > hashtable.size()) { + int i = free_list; + entries[i].udata = value; + entries[i].set_next_used(0); + begin_n = i; + counter++; + rehash(); + return i; + } } int i = free_list; @@ -384,8 +375,7 @@ public: dict(dict &&other) { - free_list = -1; - counter = 0; + init(); swap(other); } @@ -504,6 +494,7 @@ public: std::swap(free_list, other.free_list); std::swap(counter, other.counter); std::swap(begin_n, other.begin_n); + std::swap(begin_seek_count, other.begin_seek_count); } bool operator==(const dict &other) const { @@ -579,14 +570,12 @@ class pool entries.clear(); counter = other.size(); - int new_size = hashtable_size(config_size_factor * counter); - hashtable.resize(new_size); - new_size = new_size / config_size_factor + 1; - entries.reserve(new_size); + begin_n = counter - 1; + entries.reserve(counter); for (auto &it : other) entries.push_back(entry_t(it)); - entries.resize(new_size); + rehash(); } @@ -598,18 +587,12 @@ class pool return hash; } - void upd_begin_n() + void upd_begin_n(bool do_refree = true) { if (begin_n < -1) { begin_n = -(begin_n+2); - if (begin_n > int(entries.size())) - begin_n = int(entries.size()); - do { - if (begin_seek_count++ > int(entries.size())) - refree(); - else - begin_n--; - } while (begin_n >= 0 && entries[begin_n].is_free()); + while (begin_n >= 0 && entries[begin_n].is_free()) { begin_seek_count++; begin_n--; } + if (do_refree && begin_seek_count > int(entries.size() / 2)) refree(); } } @@ -637,11 +620,14 @@ class pool void rehash() { + upd_begin_n(false); + entries.resize(begin_n + 1); + free_list = -1; begin_n = -1; - for (auto &h : hashtable) - h = -1; + hashtable.clear(); + hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); int last_free = -1; for (int i = 0; i < int(entries.size()); i++) @@ -706,15 +692,18 @@ class pool { if (free_list < 0) { - int i = entries.size(); - int new_size = hashtable_size(config_size_factor * entries.size()); - hashtable.resize(new_size); - entries.resize(new_size / config_size_factor + 1); - entries[i].key = key; - entries[i].set_next_used(0); - counter++; - rehash(); - return i; + free_list = entries.size(); + entries.push_back(entry_t()); + + if (entries.size() * hashtable_size_trigger > hashtable.size()) { + int i = free_list; + entries[i].key = key; + entries[i].set_next_used(0); + begin_n = i; + counter++; + rehash(); + return i; + } } int i = free_list; @@ -771,8 +760,7 @@ public: pool(pool &&other) { - free_list = -1; - counter = 0; + init(); swap(other); } @@ -871,6 +859,7 @@ public: std::swap(free_list, other.free_list); std::swap(counter, other.counter); std::swap(begin_n, other.begin_n); + std::swap(begin_seek_count, other.begin_seek_count); } bool operator==(const pool &other) const { -- cgit v1.2.3 From 120a8313d915c2ebac43c8bf0b8216b240e769c1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 13:30:22 +0100 Subject: Small optimization in hashlib --- kernel/hashlib.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index b02abfadd..c93e00a09 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -526,10 +526,10 @@ public: void clear() { hashtable.clear(); entries.clear(); init(); } iterator begin() { upd_begin_n(); return iterator(this, begin_n); } - iterator end() { return iterator(this, -1); } + iterator end() { return iterator(nullptr, -1); } const_iterator begin() const { ((dict*)this)->upd_begin_n(); return const_iterator(this, begin_n); } - const_iterator end() const { return const_iterator(this, -1); } + const_iterator end() const { return const_iterator(nullptr, -1); } }; template> @@ -891,10 +891,10 @@ public: void clear() { hashtable.clear(); entries.clear(); init(); } iterator begin() { upd_begin_n(); return iterator(this, begin_n); } - iterator end() { return iterator(this, -1); } + iterator end() { return iterator(nullptr, -1); } const_iterator begin() const { ((pool*)this)->upd_begin_n(); return const_iterator(this, begin_n); } - const_iterator end() const { return const_iterator(this, -1); } + const_iterator end() const { return const_iterator(nullptr, -1); } }; } /* namespace hashlib */ -- cgit v1.2.3 From 06750987331a3d832ea83f2205c56612d3506332 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 18:51:24 +0100 Subject: added hashlib::mkhash_init --- kernel/hashlib.h | 8 +++++--- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 2 +- kernel/yosys.h | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index c93e00a09..0b6e94a32 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -21,13 +21,15 @@ const int hashtable_size_trigger = 2; const int hashtable_size_factor = 3; // The XOR version of DJB2 -// (traditionally 5381 is used as starting value for the djb2 hash) inline unsigned int mkhash(unsigned int a, unsigned int b) { return ((a << 5) + a) ^ b; } +// traditionally 5381 is used as starting value for the djb2 hash +const unsigned int mkhash_init = 5381; + // The ADD version of DJB2 -// (use this version for cache locality in b) +// (usunsigned int mkhashe this version for cache locality in b) inline unsigned int mkhash_add(unsigned int a, unsigned int b) { return ((a << 5) + a) + b; } @@ -96,7 +98,7 @@ struct hash_cstr_ops { return true; } unsigned int hash(const char *a) const { - unsigned int hash = 5381; + unsigned int hash = mkhash_init; while (*a) hash = mkhash(hash, *(a++)); return hash; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 912df7903..cd2232c8c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2325,7 +2325,7 @@ void RTLIL::SigSpec::updhash() 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) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index bb9e85d93..739b701f8 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -463,7 +463,7 @@ struct RTLIL::Const inline int size() const { return bits.size(); } inline unsigned int hash() const { - unsigned int h = 5381; + unsigned int h = mkhash_init; for (auto b : bits) mkhash(h, b); return h; diff --git a/kernel/yosys.h b/kernel/yosys.h index a4836f35a..5f3c3577d 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -138,6 +138,7 @@ YOSYS_NAMESPACE_BEGIN using std::vector; using std::string; using hashlib::mkhash; +using hashlib::mkhash_init; using hashlib::mkhash_add; using hashlib::mkhash_xorshift; using hashlib::hash_ops; -- cgit v1.2.3 From 50fff2b24061208a4b7c0ff9a4839e1938c66140 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 22:31:04 +0100 Subject: print timing details (-d) in -q mode --- kernel/driver.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index cdf784602..b7cb414ce 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -334,6 +334,10 @@ int main(int argc, char **argv) log_hasher = nullptr; log_spacer(); + + if (log_errfile != NULL && timing_details) + log_files.push_back(stderr); + #ifdef _WIN32 log("End of script. Logfile hash: %s\n", hash.c_str()); #else -- cgit v1.2.3 From 1909edfa9c9236b2dc22d18946fd44ff266bce14 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 22:54:42 +0100 Subject: improved -v option --- kernel/driver.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index b7cb414ce..f1bf0657b 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -86,6 +86,8 @@ int main(int argc, char **argv) bool print_stats = true; bool call_abort = false; bool timing_details = false; + bool mode_v = false; + bool mode_q = false; #ifdef YOSYS_ENABLE_READLINE int history_offset = 0; @@ -113,7 +115,8 @@ int main(int argc, char **argv) printf(" use this option twice to also quiet warning messages\n"); printf("\n"); printf(" -v \n"); - printf(" print log headers up to level to the console. (implies -q)\n"); + printf(" print log headers up to level to the console. (this\n"); + printf(" implies -q for everything except the 'End of script.' message.)\n"); printf("\n"); printf(" -t\n"); printf(" annotate all log messages with a time stamp\n"); @@ -235,11 +238,13 @@ int main(int argc, char **argv) } break; case 'q': + mode_q = true; if (log_errfile == stderr) log_quiet_warnings = true; log_errfile = stderr; break; case 'v': + mode_v = true; log_errfile = stderr; log_verbose_level = atoi(optarg); break; @@ -333,9 +338,11 @@ int main(int argc, char **argv) delete log_hasher; log_hasher = nullptr; + log_time = false; + yosys_xtrace = 0; log_spacer(); - if (log_errfile != NULL && timing_details) + if (mode_v && !mode_q) log_files.push_back(stderr); #ifdef _WIN32 -- cgit v1.2.3 From 6fef4b82a2315830f99eeca3a4e80697a90a8447 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Dec 2014 23:45:43 +0100 Subject: using pool<> in bitpattern.h --- kernel/bitpattern.h | 26 +++++++++++++------------- kernel/hashlib.h | 16 +++++++++++++++- kernel/yosys.h | 4 ++++ 3 files changed, 32 insertions(+), 14 deletions(-) (limited to 'kernel') diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 4d88c8e34..7416a488d 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -29,7 +29,7 @@ struct BitPatternPool { int width; typedef std::vector bits_t; - std::set pool; + pool database; BitPatternPool(RTLIL::SigSpec sig) { @@ -42,7 +42,7 @@ struct BitPatternPool else pattern[i] = RTLIL::State::Sa; } - pool.insert(pattern); + database.insert(pattern); } } @@ -53,7 +53,7 @@ struct BitPatternPool std::vector pattern(width); for (int i = 0; i < width; i++) pattern[i] = RTLIL::State::Sa; - pool.insert(pattern); + database.insert(pattern); } } @@ -79,7 +79,7 @@ struct BitPatternPool bool has_any(RTLIL::SigSpec sig) { bits_t bits = sig2bits(sig); - for (auto &it : pool) + for (auto &it : database) if (match(it, bits)) return true; return false; @@ -88,13 +88,13 @@ struct BitPatternPool bool has_all(RTLIL::SigSpec sig) { bits_t bits = sig2bits(sig); - for (auto &it : pool) + for (auto &it : database) if (match(it, bits)) { for (int i = 0; i < width; i++) if (bits[i] > RTLIL::State::S1 && it[i] <= RTLIL::State::S1) - goto next_pool_entry; + goto next_database_entry; return true; - next_pool_entry:; + next_database_entry:; } return false; } @@ -104,17 +104,17 @@ struct BitPatternPool bool status = false; bits_t bits = sig2bits(sig); std::vector pattern_list; - for (auto &it : pool) + for (auto &it : database) if (match(it, bits)) pattern_list.push_back(it); for (auto pattern : pattern_list) { - pool.erase(pattern); + database.erase(pattern); for (int i = 0; i < width; i++) { if (pattern[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa) continue; bits_t new_pattern = pattern; new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1; - pool.insert(new_pattern); + database.insert(new_pattern); } status = true; } @@ -123,15 +123,15 @@ struct BitPatternPool bool take_all() { - if (pool.empty()) + if (database.empty()) return false; - pool.clear(); + database.clear(); return true; } bool empty() { - return pool.empty(); + return database.empty(); } }; diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 0b6e94a32..3164282f2 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -62,7 +62,8 @@ template<> struct hash_ops { bool cmp(T a, T b) const { return a == b; } - unsigned int hash(unsigned int a) const { + template + unsigned int hash(T a) const { return a; } }; @@ -90,6 +91,19 @@ template struct hash_ops> { } }; +template struct hash_ops> { + bool cmp(std::vector a, std::vector b) const { + return a == b; + } + unsigned int hash(std::vector a) const { + hash_ops t_ops; + unsigned int h = mkhash_init; + for (auto k : a) + h = mkhash(h, t_ops.hash(k)); + return h; + } +}; + struct hash_cstr_ops { bool cmp(const char *a, const char *b) const { for (int i = 0; a[i] || b[i]; i++) diff --git a/kernel/yosys.h b/kernel/yosys.h index 5f3c3577d..2c9ca0dd9 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -221,6 +221,10 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN +namespace hashlib { + template<> struct hash_ops : hash_ops {}; +} + void yosys_setup(); void yosys_shutdown(); -- cgit v1.2.3 From 60f16e17afc81d8bbae722c13ef173329129494a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 03:55:13 +0100 Subject: hotfix for ModInfo --- kernel/modtools.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/modtools.h b/kernel/modtools.h index 558cc08b8..113b0918d 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -70,7 +70,7 @@ struct ModIndex : public RTLIL::Monitor SigMap sigmap; RTLIL::Module *module; - dict database; + std::map database; bool auto_reload_module; void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) -- cgit v1.2.3 From 7d6a7fe2ce8936c7af09ba7661e1159bc403483d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 03:56:09 +0100 Subject: IdString optimization --- kernel/rtlil.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 739b701f8..c40af88aa 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -121,6 +121,12 @@ namespace RTLIL global_id_index_[global_id_storage_.at(idx)] = idx; global_refcount_storage_.at(idx)++; + // Avoid Create->Delete->Create pattern + static IdString last_created_id; + put_reference(last_created_id.index_); + last_created_id.index_ = idx; + get_reference(last_created_id.index_); + if (yosys_xtrace) { log("#X# New IdString '%s' with index %d.\n", p, idx); log_backtrace("-X- ", yosys_xtrace-1); -- cgit v1.2.3 From c4bd6cb9d38f445da8db6734411fd7b067c3f499 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 03:58:29 +0100 Subject: major rewrite of hashlib::dict<> --- kernel/hashlib.h | 319 +++++++++++++++++++++---------------------------------- 1 file changed, 123 insertions(+), 196 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 3164282f2..a34d194f1 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -140,8 +140,8 @@ struct hash_obj_ops { inline int hashtable_size(int min_size) { - static std::vector primes = { - 23, 29, 37, 47, 59, 79, 101, 127, 163, 211, 269, 337, 431, 541, 677, + static std::vector zero_and_some_primes = { + 0, 23, 29, 37, 47, 59, 79, 101, 127, 163, 211, 269, 337, 431, 541, 677, 853, 1069, 1361, 1709, 2137, 2677, 3347, 4201, 5261, 6577, 8231, 10289, 12889, 16127, 20161, 25219, 31531, 39419, 49277, 61603, 77017, 96281, 120371, 150473, 188107, 235159, 293957, 367453, 459317, 574157, 717697, @@ -151,13 +151,13 @@ inline int hashtable_size(int min_size) 121590311, 151987889, 189984863, 237481091, 296851369, 371064217 }; - for (auto p : primes) - if (p > min_size) return p; + for (auto p : zero_and_some_primes) + if (p >= min_size) return p; if (sizeof(int) == 4) throw std::length_error("hash table exceeded maximum size. use a ILP64 abi for larger tables."); - for (auto p : primes) + for (auto p : zero_and_some_primes) if (100129 * p > min_size) return 100129 * p; throw std::length_error("hash table exceeded maximum size."); @@ -168,49 +168,26 @@ class dict { struct entry_t { - int link; std::pair udata; + int next; - entry_t() : link(-1) { } - entry_t(const std::pair &udata) : link(1), udata(udata) { } - - bool is_free() const { return link < 0; } - int get_next() const { return (link > 0 ? link : -link) - 2; } - bool get_last() const { return get_next() == -1; } - void set_next_used(int next) { link = next + 2; } - void set_next_free(int next) { link = -(next + 2); } + entry_t() { } + entry_t(const std::pair &udata, int next) : udata(udata), next(next) { } }; std::vector hashtable; std::vector entries; - int free_list, counter, begin_n; - int begin_seek_count; OPS ops; - void init() - { - free_list = -1; - counter = 0; - begin_n = -1; - begin_seek_count = 0; - } - - void init_from(const dict &other) - { - hashtable.clear(); - entries.clear(); - - counter = other.size(); - begin_n = counter - 1; - entries.reserve(counter); - - for (auto &it : other) - entries.push_back(entry_t(it)); - - rehash(); +#if 0 + static inline void do_assert(bool cond) { + if (!cond) throw std::runtime_error("dict<> assert failed."); } +#else + static inline void do_assert(bool) { } +#endif - int mkhash(const K &key) const + int do_hash(const K &key) const { unsigned int hash = 0; if (!hashtable.empty()) @@ -218,145 +195,108 @@ class dict return hash; } - void upd_begin_n(bool do_refree = true) + void do_rehash() { - if (begin_n < -1) { - begin_n = -(begin_n+2); - while (begin_n >= 0 && entries[begin_n].is_free()) { begin_seek_count++; begin_n--; } - if (do_refree && begin_seek_count > int(entries.size() / 2)) refree(); + hashtable.clear(); + hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); + + for (int i = 0; i < int(entries.size()); i++) { + do_assert(-1 <= entries[i].next && entries[i].next < int(entries.size())); + int hash = do_hash(entries[i].udata.first); + entries[i].next = hashtable[hash]; + hashtable[hash] = i; } } - void refree() + int do_erase(int index, int hash) { - free_list = -1; - begin_n = -1; + do_assert(index < int(entries.size())); + if (hashtable.empty() || index < 0) + return 0; - int last_free = -1; - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - if (last_free != -1) - entries[last_free].set_next_free(i); - else - free_list = i; - last_free = i; - } else - begin_n = i; - - if (last_free != -1) - entries[last_free].set_next_free(-1); - - begin_seek_count = 0; - } - - void rehash() - { - upd_begin_n(false); - entries.resize(begin_n + 1); + int k = hashtable[hash]; + if (k == index) { + hashtable[hash] = entries[index].next; + } else { + while (entries[k].next != index) { + k = entries[k].next; + do_assert(0 <= k && k < int(entries.size())); + } + entries[k].next = entries[index].next; + } - free_list = -1; - begin_n = -1; + int back_idx = entries.size()-1; - hashtable.clear(); - hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); + if (index != back_idx) + { + int back_hash = do_hash(entries[back_idx].udata.first); - int last_free = -1; - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - if (last_free != -1) - entries[last_free].set_next_free(i); - else - free_list = i; - last_free = i; + k = hashtable[back_hash]; + if (k == back_idx) { + hashtable[back_hash] = index; } else { - int hash = mkhash(entries[i].udata.first); - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - begin_n = i; + while (entries[k].next != back_idx) { + k = entries[k].next; + do_assert(0 <= k && k < int(entries.size())); + } + entries[k].next = index; } - if (last_free != -1) - entries[last_free].set_next_free(-1); + entries[index] = std::move(entries[back_idx]); + } - begin_seek_count = 0; + entries.pop_back(); + + if (entries.empty()) + hashtable.clear(); + + return 1; } - int do_erase(const K &key, int hash) + int do_lookup(const K &key, int &hash) const { - int last_index = -1; - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return 0; - if (ops.cmp(entries[index].udata.first, key)) { - if (last_index < 0) - hashtable[hash] = entries[index].get_next(); - else - entries[last_index].set_next_used(entries[index].get_next()); - entries[index].udata = std::pair(); - entries[index].set_next_free(free_list); - free_list = index; - if (--counter == 0) - clear(); - else if (index == begin_n) - begin_n = -(begin_n+2); - return 1; - } - last_index = index; - index = entries[index].get_next(); + if (hashtable.empty()) + return -1; + + if (entries.size() * hashtable_size_trigger > hashtable.size()) { + ((dict*)this)->do_rehash(); + hash = do_hash(key); } - } - int lookup_index(const K &key, int hash) const - { - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return -1; - if (ops.cmp(entries[index].udata.first, key)) - return index; - index = entries[index].get_next(); + int index = hashtable[hash]; + + while (index >= 0 && !ops.cmp(entries[index].udata.first, key)) { + index = entries[index].next; + do_assert(-1 <= index && index < int(entries.size())); } + + return index; } - int insert_at(const std::pair &value, int hash) + int do_insert(const std::pair &value, int &hash) { - if (free_list < 0) - { - free_list = entries.size(); - entries.push_back(entry_t()); - - if (entries.size() * hashtable_size_trigger > hashtable.size()) { - int i = free_list; - entries[i].udata = value; - entries[i].set_next_used(0); - begin_n = i; - counter++; - rehash(); - return i; - } + if (hashtable.empty()) { + entries.push_back(entry_t(value, -1)); + do_rehash(); + hash = do_hash(value.first); + } else { + entries.push_back(entry_t(value, hashtable[hash])); + hashtable[hash] = entries.size() - 1; } - - int i = free_list; - free_list = entries[i].get_next(); - entries[i].udata = value; - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i)) - begin_n = i; - counter++; - return i; + return entries.size() - 1; } public: class iterator { + friend dict; + protected: dict *ptr; int index; public: iterator() { } iterator(dict *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } + iterator operator++() { index--; return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } std::pair &operator*() { return ptr->entries[index].udata; } @@ -367,12 +307,14 @@ public: class const_iterator { + friend dict; + protected: const dict *ptr; int index; public: const_iterator() { } const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } + const_iterator operator++() { index--; return *this; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } const std::pair &operator*() const { return ptr->entries[index].udata; } @@ -381,23 +323,22 @@ public: dict() { - init(); } dict(const dict &other) { - init_from(other); + entries = other.entries; + do_rehash(); } dict(dict &&other) { - init(); swap(other); } dict &operator=(const dict &other) { - if (this != &other) - init_from(other); + entries = other.entries; + do_rehash(); return *this; } @@ -409,7 +350,6 @@ public: dict(const std::initializer_list> &list) { - init(); for (auto &it : list) insert(it); } @@ -417,7 +357,6 @@ public: template dict(InputIterator first, InputIterator last) { - init(); insert(first, last); } @@ -430,38 +369,39 @@ public: std::pair insert(const std::pair &value) { - int hash = mkhash(value.first); - int i = lookup_index(value.first, hash); + int hash = do_hash(value.first); + int i = do_lookup(value.first, hash); if (i >= 0) return std::pair(iterator(this, i), false); - i = insert_at(value, hash); + i = do_insert(value, hash); return std::pair(iterator(this, i), true); } int erase(const K &key) { - int hash = mkhash(key); - return do_erase(key, hash); + int hash = do_hash(key); + int index = do_lookup(key, hash); + return do_erase(index, hash); } iterator erase(iterator it) { - int hash = mkhash(it->first); - do_erase(it->first, hash); + int hash = do_hash(it->first); + do_erase(it.index, hash); return ++it; } int count(const K &key) const { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); return i < 0 ? 0 : 1; } iterator find(const K &key) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) return end(); return iterator(this, i); @@ -469,8 +409,8 @@ public: const_iterator find(const K &key) const { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) return end(); return const_iterator(this, i); @@ -478,8 +418,8 @@ public: T& at(const K &key) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) throw std::out_of_range("dict::at()"); return entries[i].udata.second; @@ -487,8 +427,8 @@ public: const T& at(const K &key) const { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) throw std::out_of_range("dict::at()"); return entries[i].udata.second; @@ -496,10 +436,10 @@ public: T& operator[](const K &key) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) - i = insert_at(std::pair(key, T()), hash); + i = do_insert(std::pair(key, T()), hash); return entries[i].udata.second; } @@ -507,29 +447,16 @@ public: { hashtable.swap(other.hashtable); entries.swap(other.entries); - std::swap(free_list, other.free_list); - std::swap(counter, other.counter); - std::swap(begin_n, other.begin_n); - std::swap(begin_seek_count, other.begin_seek_count); } bool operator==(const dict &other) const { - if (counter != other.counter) + if (size() != other.size()) return false; - if (counter == 0) - return true; - if (entries.size() < other.entries.size()) - for (auto &it : *this) { - auto oit = other.find(it.first); - if (oit == other.end() || oit->second != it.second) - return false; - } - else - for (auto &oit : other) { - auto it = find(oit.first); - if (it == end() || it->second != oit.second) - return false; - } + for (auto &it : entries) { + auto oit = other.find(it.udata.first); + if (oit == other.end() || oit->second != it.udata.second) + return false; + } return true; } @@ -537,14 +464,14 @@ public: return !(*this == other); } - size_t size() const { return counter; } - bool empty() const { return counter == 0; } - void clear() { hashtable.clear(); entries.clear(); init(); } + size_t size() const { return entries.size(); } + bool empty() const { return entries.empty(); } + void clear() { hashtable.clear(); entries.clear(); } - iterator begin() { upd_begin_n(); return iterator(this, begin_n); } + iterator begin() { return iterator(this, int(entries.size())-1); } iterator end() { return iterator(nullptr, -1); } - const_iterator begin() const { ((dict*)this)->upd_begin_n(); return const_iterator(this, begin_n); } + const_iterator begin() const { return const_iterator(this, int(entries.size())-1); } const_iterator end() const { return const_iterator(nullptr, -1); } }; -- cgit v1.2.3 From 429ccb62a1c3ea06345b9c8f1ebd3dcbddc42f4c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 04:19:04 +0100 Subject: new hashlib::pool<> (derived from new dict) --- kernel/hashlib.h | 372 ++++++++++++++++++++++--------------------------------- 1 file changed, 151 insertions(+), 221 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index a34d194f1..6330841f3 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -289,13 +289,13 @@ class dict public: class iterator { - friend dict; + friend dict; protected: - dict *ptr; + dict *ptr; int index; public: iterator() { } - iterator(dict *ptr, int index) : ptr(ptr), index(index) { } + iterator(dict *ptr, int index) : ptr(ptr), index(index) { } iterator operator++() { index--; return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } @@ -307,13 +307,13 @@ public: class const_iterator { - friend dict; + friend dict; protected: - const dict *ptr; + const dict *ptr; int index; public: const_iterator() { } - const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } + const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } const_iterator operator++() { index--; return *this; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } @@ -325,24 +325,24 @@ public: { } - dict(const dict &other) + dict(const dict &other) { entries = other.entries; do_rehash(); } - dict(dict &&other) + dict(dict &&other) { swap(other); } - dict &operator=(const dict &other) { + dict &operator=(const dict &other) { entries = other.entries; do_rehash(); return *this; } - dict &operator=(dict &&other) { + dict &operator=(dict &&other) { clear(); swap(other); return *this; @@ -443,13 +443,13 @@ public: return entries[i].udata.second; } - void swap(dict &other) + void swap(dict &other) { hashtable.swap(other.hashtable); entries.swap(other.entries); } - bool operator==(const dict &other) const { + bool operator==(const dict &other) const { if (size() != other.size()) return false; for (auto &it : entries) { @@ -460,7 +460,7 @@ public: return true; } - bool operator!=(const dict &other) const { + bool operator!=(const dict &other) const { return !(*this == other); } @@ -475,54 +475,38 @@ public: const_iterator end() const { return const_iterator(nullptr, -1); } }; +// ******************************************************************************** +// ******************************************************************************** +// ******************************************************************************** +// ******************************************************************************** +// ******************************************************************************** + + template> class pool { struct entry_t { - int link; - K key; - - entry_t() : link(-1) { } - entry_t(const K &key) : link(1), key(key) { } + K udata; + int next; - bool is_free() const { return link < 0; } - int get_next() const { return (link > 0 ? link : -link) - 2; } - bool get_last() const { return get_next() == -1; } - void set_next_used(int next) { link = next + 2; } - void set_next_free(int next) { link = -(next + 2); } + entry_t() { } + entry_t(const K &udata, int next) : udata(udata), next(next) { } }; std::vector hashtable; std::vector entries; - int free_list, counter, begin_n; - int begin_seek_count; OPS ops; - void init() - { - free_list = -1; - counter = 0; - begin_n = -1; - begin_seek_count = 0; - } - - void init_from(const pool &other) - { - hashtable.clear(); - entries.clear(); - - counter = other.size(); - begin_n = counter - 1; - entries.reserve(counter); - - for (auto &it : other) - entries.push_back(entry_t(it)); - - rehash(); +#if 0 + static inline void do_assert(bool cond) { + if (!cond) throw std::runtime_error("pool<> assert failed."); } +#else + static inline void do_assert(bool) { } +#endif - int mkhash(const K &key) const + int do_hash(const K &key) const { unsigned int hash = 0; if (!hashtable.empty()) @@ -530,190 +514,152 @@ class pool return hash; } - void upd_begin_n(bool do_refree = true) + void do_rehash() { - if (begin_n < -1) { - begin_n = -(begin_n+2); - while (begin_n >= 0 && entries[begin_n].is_free()) { begin_seek_count++; begin_n--; } - if (do_refree && begin_seek_count > int(entries.size() / 2)) refree(); + hashtable.clear(); + hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); + + for (int i = 0; i < int(entries.size()); i++) { + do_assert(-1 <= entries[i].next && entries[i].next < int(entries.size())); + int hash = do_hash(entries[i].udata); + entries[i].next = hashtable[hash]; + hashtable[hash] = i; } } - void refree() + int do_erase(int index, int hash) { - free_list = -1; - begin_n = -1; - - int last_free = -1; - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - if (last_free != -1) - entries[last_free].set_next_free(i); - else - free_list = i; - last_free = i; - } else - begin_n = i; - - if (last_free != -1) - entries[last_free].set_next_free(-1); - - begin_seek_count = 0; - } + do_assert(index < int(entries.size())); + if (hashtable.empty() || index < 0) + return 0; - void rehash() - { - upd_begin_n(false); - entries.resize(begin_n + 1); + int k = hashtable[hash]; + if (k == index) { + hashtable[hash] = entries[index].next; + } else { + while (entries[k].next != index) { + k = entries[k].next; + do_assert(0 <= k && k < int(entries.size())); + } + entries[k].next = entries[index].next; + } - free_list = -1; - begin_n = -1; + int back_idx = entries.size()-1; - hashtable.clear(); - hashtable.resize(hashtable_size(entries.size() * hashtable_size_factor), -1); + if (index != back_idx) + { + int back_hash = do_hash(entries[back_idx].udata); - int last_free = -1; - for (int i = 0; i < int(entries.size()); i++) - if (entries[i].is_free()) { - if (last_free != -1) - entries[last_free].set_next_free(i); - else - free_list = i; - last_free = i; + k = hashtable[back_hash]; + if (k == back_idx) { + hashtable[back_hash] = index; } else { - int hash = mkhash(entries[i].key); - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - begin_n = i; + while (entries[k].next != back_idx) { + k = entries[k].next; + do_assert(0 <= k && k < int(entries.size())); + } + entries[k].next = index; } - if (last_free != -1) - entries[last_free].set_next_free(-1); - - begin_seek_count = 0; - } - - int do_erase(const K &key, int hash) - { - int last_index = -1; - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return 0; - if (ops.cmp(entries[index].key, key)) { - if (last_index < 0) - hashtable[hash] = entries[index].get_next(); - else - entries[last_index].set_next_used(entries[index].get_next()); - entries[index].key = K(); - entries[index].set_next_free(free_list); - free_list = index; - if (--counter == 0) - clear(); - else if (index == begin_n) - begin_n = -(begin_n+2); - return 1; - } - last_index = index; - index = entries[index].get_next(); + entries[index] = std::move(entries[back_idx]); } + + entries.pop_back(); + + if (entries.empty()) + hashtable.clear(); + + return 1; } - int lookup_index(const K &key, int hash) const + int do_lookup(const K &key, int &hash) const { - int index = hashtable.empty() ? -1 : hashtable[hash]; - while (1) { - if (index < 0) - return -1; - if (ops.cmp(entries[index].key, key)) - return index; - index = entries[index].get_next(); + if (hashtable.empty()) + return -1; + + if (entries.size() * hashtable_size_trigger > hashtable.size()) { + ((pool*)this)->do_rehash(); + hash = do_hash(key); } + + int index = hashtable[hash]; + + while (index >= 0 && !ops.cmp(entries[index].udata, key)) { + index = entries[index].next; + do_assert(-1 <= index && index < int(entries.size())); + } + + return index; } - int insert_at(const K &key, int hash) + int do_insert(const K &value, int &hash) { - if (free_list < 0) - { - free_list = entries.size(); - entries.push_back(entry_t()); - - if (entries.size() * hashtable_size_trigger > hashtable.size()) { - int i = free_list; - entries[i].key = key; - entries[i].set_next_used(0); - begin_n = i; - counter++; - rehash(); - return i; - } + if (hashtable.empty()) { + entries.push_back(entry_t(value, -1)); + do_rehash(); + hash = do_hash(value); + } else { + entries.push_back(entry_t(value, hashtable[hash])); + hashtable[hash] = entries.size() - 1; } - - int i = free_list; - free_list = entries[i].get_next(); - entries[i].key = key; - entries[i].set_next_used(hashtable[hash]); - hashtable[hash] = i; - if ((begin_n < -1 && -(begin_n+2) <= i) || (begin_n >= -1 && begin_n <= i)) - begin_n = i; - counter++; - return i; + return entries.size() - 1; } public: class iterator { - pool *ptr; + friend pool; + protected: + pool *ptr; int index; public: iterator() { } - iterator(pool *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } + iterator(pool *ptr, int index) : ptr(ptr), index(index) { } + iterator operator++() { index--; return *this; } bool operator==(const iterator &other) const { return index == other.index; } bool operator!=(const iterator &other) const { return index != other.index; } - K &operator*() { return ptr->entries[index].key; } - K *operator->() { return &ptr->entries[index].key; } - const K &operator*() const { return ptr->entries[index].key; } - const K *operator->() const { return &ptr->entries[index].key; } + const K &operator*() const { return ptr->entries[index].udata; } + const K *operator->() const { return &ptr->entries[index].udata; } }; class const_iterator { - const pool *ptr; + friend pool; + protected: + const pool *ptr; int index; public: const_iterator() { } - const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { do index--; while (index >= 0 && ptr->entries[index].is_free()); return *this; } + const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } + const_iterator operator++() { index--; return *this; } bool operator==(const const_iterator &other) const { return index == other.index; } bool operator!=(const const_iterator &other) const { return index != other.index; } - const K &operator*() const { return ptr->entries[index].key; } - const K *operator->() const { return &ptr->entries[index].key; } + const K &operator*() const { return ptr->entries[index].udata; } + const K *operator->() const { return &ptr->entries[index].udata; } }; pool() { - init(); } - pool(const pool &other) + pool(const pool &other) { - init_from(other); + entries = other.entries; + do_rehash(); } - pool(pool &&other) + pool(pool &&other) { - init(); swap(other); } - pool &operator=(const pool &other) { - if (this != &other) - init_from(other); + pool &operator=(const pool &other) { + entries = other.entries; + do_rehash(); return *this; } - pool &operator=(pool &&other) { + pool &operator=(pool &&other) { clear(); swap(other); return *this; @@ -721,7 +667,6 @@ public: pool(const std::initializer_list &list) { - init(); for (auto &it : list) insert(it); } @@ -729,7 +674,6 @@ public: template pool(InputIterator first, InputIterator last) { - init(); insert(first, last); } @@ -740,40 +684,41 @@ public: insert(*first); } - std::pair insert(const K &key) + std::pair insert(const K &value) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(value); + int i = do_lookup(value, hash); if (i >= 0) return std::pair(iterator(this, i), false); - i = insert_at(key, hash); + i = do_insert(value, hash); return std::pair(iterator(this, i), true); } int erase(const K &key) { - int hash = mkhash(key); - return do_erase(key, hash); + int hash = do_hash(key); + int index = do_lookup(key, hash); + return do_erase(index, hash); } iterator erase(iterator it) { - int hash = mkhash(*it); - do_erase(*it, hash); + int hash = do_hash(it->first); + do_erase(it.index, hash); return ++it; } int count(const K &key) const { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); return i < 0 ? 0 : 1; } iterator find(const K &key) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) return end(); return iterator(this, i); @@ -781,62 +726,47 @@ public: const_iterator find(const K &key) const { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); if (i < 0) return end(); return const_iterator(this, i); } - bool operator[](const K &key) const + bool operator[](const K &key) { - int hash = mkhash(key); - int i = lookup_index(key, hash); + int hash = do_hash(key); + int i = do_lookup(key, hash); return i >= 0; } - void swap(pool &other) + void swap(pool &other) { hashtable.swap(other.hashtable); entries.swap(other.entries); - std::swap(free_list, other.free_list); - std::swap(counter, other.counter); - std::swap(begin_n, other.begin_n); - std::swap(begin_seek_count, other.begin_seek_count); } - bool operator==(const pool &other) const { - if (counter != other.counter) + bool operator==(const pool &other) const { + if (size() != other.size()) return false; - if (counter == 0) - return true; - if (entries.size() < other.entries.size()) - for (auto &it : *this) { - auto oit = other.find(it.first); - if (oit == other.end() || oit->second != it.second) - return false; - } - else - for (auto &oit : other) { - auto it = find(oit.first); - if (it == end() || it->second != oit.second) - return false; - } + for (auto &it : entries) + if (!other.count(it.udata)) + return false; return true; } - bool operator!=(const pool &other) const { + bool operator!=(const pool &other) const { return !(*this == other); } - size_t size() const { return counter; } - bool empty() const { return counter == 0; } - void clear() { hashtable.clear(); entries.clear(); init(); } + size_t size() const { return entries.size(); } + bool empty() const { return entries.empty(); } + void clear() { hashtable.clear(); entries.clear(); } - iterator begin() { upd_begin_n(); return iterator(this, begin_n); } + iterator begin() { return iterator(this, int(entries.size())-1); } iterator end() { return iterator(nullptr, -1); } - const_iterator begin() const { ((pool*)this)->upd_begin_n(); return const_iterator(this, begin_n); } + const_iterator begin() const { return const_iterator(this, int(entries.size())-1); } const_iterator end() const { return const_iterator(nullptr, -1); } }; -- cgit v1.2.3 From 12b05dfc040ccdcde193cd1ff81e97b3c5e2c974 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 04:24:04 +0100 Subject: gcc-4.6 compile fixes --- kernel/hashlib.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 6330841f3..7f2575d72 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -289,7 +289,7 @@ class dict public: class iterator { - friend dict; + friend class dict; protected: dict *ptr; int index; @@ -307,7 +307,7 @@ public: class const_iterator { - friend dict; + friend class dict; protected: const dict *ptr; int index; @@ -608,7 +608,7 @@ class pool public: class iterator { - friend pool; + friend class pool; protected: pool *ptr; int index; @@ -624,7 +624,7 @@ public: class const_iterator { - friend pool; + friend class pool; protected: const pool *ptr; int index; -- cgit v1.2.3 From b9e412423a681589b35f73412c43b23fee34560f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 13:05:33 +0100 Subject: hashlib cleanups and a fix --- kernel/hashlib.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 7f2575d72..29f4f68b1 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -49,30 +49,30 @@ inline unsigned int mkhash_xorshift(unsigned int a) { } template struct hash_ops { - bool cmp(const T &a, const T &b) const { + static inline bool cmp(const T &a, const T &b) { return a == b; } - unsigned int hash(const T &a) const { + static inline unsigned int hash(const T &a) { return a.hash(); } }; template<> struct hash_ops { template - bool cmp(T a, T b) const { + static inline bool cmp(T a, T b) { return a == b; } template - unsigned int hash(T a) const { + static inline unsigned int hash(T a) { return a; } }; template<> struct hash_ops { - bool cmp(const std::string &a, const std::string &b) const { + static inline bool cmp(const std::string &a, const std::string &b) { return a == b; } - unsigned int hash(const std::string &a) const { + static inline unsigned int hash(const std::string &a) { unsigned int v = 0; for (auto c : a) v = mkhash(v, c); @@ -81,10 +81,10 @@ template<> struct hash_ops { }; template struct hash_ops> { - bool cmp(std::pair a, std::pair b) const { + static inline bool cmp(std::pair a, std::pair b) { return a == b; } - unsigned int hash(std::pair a) const { + static inline unsigned int hash(std::pair a) { hash_ops

p_ops; hash_ops q_ops; return mkhash(p_ops.hash(a.first), q_ops.hash(a.second)); @@ -92,10 +92,10 @@ template struct hash_ops> { }; template struct hash_ops> { - bool cmp(std::vector a, std::vector b) const { + static inline bool cmp(std::vector a, std::vector b) { return a == b; } - unsigned int hash(std::vector a) const { + static inline unsigned int hash(std::vector a) { hash_ops t_ops; unsigned int h = mkhash_init; for (auto k : a) @@ -105,13 +105,13 @@ template struct hash_ops> { }; struct hash_cstr_ops { - bool cmp(const char *a, const char *b) const { + static inline bool cmp(const char *a, const char *b) { for (int i = 0; a[i] || b[i]; i++) if (a[i] != b[i]) return false; return true; } - unsigned int hash(const char *a) const { + static inline unsigned int hash(const char *a) { unsigned int hash = mkhash_init; while (*a) hash = mkhash(hash, *(a++)); @@ -120,20 +120,20 @@ struct hash_cstr_ops { }; struct hash_ptr_ops { - bool cmp(const void *a, const void *b) const { + static inline bool cmp(const void *a, const void *b) { return a == b; } - unsigned int hash(const void *a) const { + static inline unsigned int hash(const void *a) { return (unsigned long)a; } }; struct hash_obj_ops { - bool cmp(const void *a, const void *b) const { + static inline bool cmp(const void *a, const void *b) { return a == b; } template - unsigned int hash(const T *a) const { + static inline unsigned int hash(const T *a) { return a->hash(); } }; @@ -703,7 +703,7 @@ public: iterator erase(iterator it) { - int hash = do_hash(it->first); + int hash = do_hash(*it); do_erase(it.index, hash); return ++it; } -- cgit v1.2.3 From ba48b6b1e6fb962428c0e4ce4a3f0fb3a5cd59eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 13:15:35 +0100 Subject: improved bitpattern (proc_mux) performance --- kernel/bitpattern.h | 65 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'kernel') diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 7416a488d..00bbc3bfb 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -28,14 +28,34 @@ YOSYS_NAMESPACE_BEGIN struct BitPatternPool { int width; - typedef std::vector bits_t; + struct bits_t { + std::vector bitdata; + unsigned int cached_hash; + bits_t(int width = 0) : bitdata(width), cached_hash(0) { } + RTLIL::State &operator[](int index) { + return bitdata[index]; + } + const RTLIL::State &operator[](int index) const { + return bitdata[index]; + } + bool operator==(const bits_t &other) const { + if (hash() != other.hash()) + return false; + return bitdata == other.bitdata; + } + unsigned int hash() const { + if (!cached_hash) + ((bits_t*)this)->cached_hash = hash_ops>::hash(bitdata); + return cached_hash; + } + }; pool database; BitPatternPool(RTLIL::SigSpec sig) { width = sig.size(); if (width > 0) { - std::vector pattern(width); + bits_t pattern(width); for (int i = 0; i < width; i++) { if (sig[i].wire == NULL && sig[i].data <= RTLIL::State::S1) pattern[i] = sig[i].data; @@ -50,7 +70,7 @@ struct BitPatternPool { this->width = width; if (width > 0) { - std::vector pattern(width); + bits_t pattern(width); for (int i = 0; i < width; i++) pattern[i] = RTLIL::State::Sa; database.insert(pattern); @@ -59,8 +79,9 @@ struct BitPatternPool bits_t sig2bits(RTLIL::SigSpec sig) { - bits_t bits = sig.as_const().bits; - for (auto &b : bits) + bits_t bits; + bits.bitdata = sig.as_const().bits; + for (auto &b : bits.bitdata) if (b > RTLIL::State::S1) b = RTLIL::State::Sa; return bits; @@ -68,8 +89,8 @@ struct BitPatternPool bool match(bits_t a, bits_t b) { - log_assert(int(a.size()) == width); - log_assert(int(b.size()) == width); + log_assert(int(a.bitdata.size()) == width); + log_assert(int(b.bitdata.size()) == width); for (int i = 0; i < width; i++) if (a[i] <= RTLIL::State::S1 && b[i] <= RTLIL::State::S1 && a[i] != b[i]) return false; @@ -103,21 +124,21 @@ struct BitPatternPool { bool status = false; bits_t bits = sig2bits(sig); - std::vector pattern_list; - for (auto &it : database) - if (match(it, bits)) - pattern_list.push_back(it); - for (auto pattern : pattern_list) { - database.erase(pattern); - for (int i = 0; i < width; i++) { - if (pattern[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa) - continue; - bits_t new_pattern = pattern; - new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1; - database.insert(new_pattern); - } - status = true; - } + for (auto it = database.begin(); it != database.end();) + if (match(*it, bits)) { + for (int i = 0; i < width; i++) { + if ((*it)[i] != RTLIL::State::Sa || bits[i] == RTLIL::State::Sa) + continue; + bits_t new_pattern; + new_pattern.bitdata = it->bitdata; + new_pattern[i] = bits[i] == RTLIL::State::S1 ? RTLIL::State::S0 : RTLIL::State::S1; + database.insert(new_pattern); + } + it = database.erase(it); + status = true; + continue; + } else + ++it; return status; } -- cgit v1.2.3 From 1e08621e7e2c219169b3b6c5fe1d581052e4d429 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 14:52:46 +0100 Subject: Added hashlib .count(key, iterator) and it1 < it2 --- kernel/hashlib.h | 87 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 37 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 29f4f68b1..5e00e89d6 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -287,38 +287,41 @@ class dict } public: - class iterator + class const_iterator { friend class dict; protected: - dict *ptr; + const dict *ptr; int index; + const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } public: - iterator() { } - iterator(dict *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { index--; return *this; } - bool operator==(const iterator &other) const { return index == other.index; } - bool operator!=(const iterator &other) const { return index != other.index; } - std::pair &operator*() { return ptr->entries[index].udata; } - std::pair *operator->() { return &ptr->entries[index].udata; } + const_iterator() { } + const_iterator operator++() { index--; return *this; } + bool operator<(const const_iterator &other) const { return index > other.index; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } const std::pair &operator*() const { return ptr->entries[index].udata; } const std::pair *operator->() const { return &ptr->entries[index].udata; } }; - class const_iterator + class iterator { friend class dict; protected: - const dict *ptr; + dict *ptr; int index; + iterator(dict *ptr, int index) : ptr(ptr), index(index) { } public: - const_iterator() { } - const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { index--; return *this; } - bool operator==(const const_iterator &other) const { return index == other.index; } - bool operator!=(const const_iterator &other) const { return index != other.index; } + iterator() { } + iterator operator++() { index--; return *this; } + bool operator<(const iterator &other) const { return index > other.index; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + std::pair &operator*() { return ptr->entries[index].udata; } + std::pair *operator->() { return &ptr->entries[index].udata; } const std::pair &operator*() const { return ptr->entries[index].udata; } const std::pair *operator->() const { return &ptr->entries[index].udata; } + operator const_iterator() const { return const_iterator(ptr, index); } }; dict() @@ -398,6 +401,13 @@ public: return i < 0 ? 0 : 1; } + int count(const K &key, const_iterator it) const + { + int hash = do_hash(key); + int i = do_lookup(key, hash); + return i < 0 || i > it.index ? 0 : 1; + } + iterator find(const K &key) { int hash = do_hash(key); @@ -475,13 +485,6 @@ public: const_iterator end() const { return const_iterator(nullptr, -1); } }; -// ******************************************************************************** -// ******************************************************************************** -// ******************************************************************************** -// ******************************************************************************** -// ******************************************************************************** - - template> class pool { @@ -606,36 +609,39 @@ class pool } public: - class iterator + class const_iterator { friend class pool; protected: - pool *ptr; + const pool *ptr; int index; + const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } public: - iterator() { } - iterator(pool *ptr, int index) : ptr(ptr), index(index) { } - iterator operator++() { index--; return *this; } - bool operator==(const iterator &other) const { return index == other.index; } - bool operator!=(const iterator &other) const { return index != other.index; } + const_iterator() { } + const_iterator operator++() { index--; return *this; } + bool operator==(const const_iterator &other) const { return index == other.index; } + bool operator!=(const const_iterator &other) const { return index != other.index; } const K &operator*() const { return ptr->entries[index].udata; } const K *operator->() const { return &ptr->entries[index].udata; } }; - class const_iterator + class iterator { friend class pool; protected: - const pool *ptr; + pool *ptr; int index; + iterator(pool *ptr, int index) : ptr(ptr), index(index) { } public: - const_iterator() { } - const_iterator(const pool *ptr, int index) : ptr(ptr), index(index) { } - const_iterator operator++() { index--; return *this; } - bool operator==(const const_iterator &other) const { return index == other.index; } - bool operator!=(const const_iterator &other) const { return index != other.index; } + iterator() { } + iterator operator++() { index--; return *this; } + bool operator==(const iterator &other) const { return index == other.index; } + bool operator!=(const iterator &other) const { return index != other.index; } + K &operator*() { return ptr->entries[index].udata; } + K *operator->() { return &ptr->entries[index].udata; } const K &operator*() const { return ptr->entries[index].udata; } const K *operator->() const { return &ptr->entries[index].udata; } + operator const_iterator() const { return const_iterator(ptr, index); } }; pool() @@ -715,6 +721,13 @@ public: return i < 0 ? 0 : 1; } + int count(const K &key, const_iterator it) const + { + int hash = do_hash(key); + int i = do_lookup(key, hash); + return i < 0 || i > it.index ? 0 : 1; + } + iterator find(const K &key) { int hash = do_hash(key); -- cgit v1.2.3 From 94e6b70736934bd8ebb09c7cc74cfd443bd1d9eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 16:53:53 +0100 Subject: Added memory_bram (not functional yet) --- kernel/yosys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/yosys.h b/kernel/yosys.h index 2c9ca0dd9..88f060a52 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -199,7 +199,7 @@ inline void memhasher() { if (memhasher_active) memhasher_do(); } std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); -std::string next_token(std::string &text, const char *sep); +std::string next_token(std::string &text, const char *sep = " \t\r\n"); bool patmatch(const char *pattern, const char *string); int run_command(const std::string &command, std::function process_line = std::function()); std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX"); -- cgit v1.2.3 From 327a5d42b6b396f1c210f1579d03a0806a261d84 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Dec 2014 22:50:08 +0100 Subject: Progress in memory_bram --- kernel/rtlil.h | 10 +++++----- kernel/yosys.h | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c40af88aa..7618780b0 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -250,14 +250,14 @@ namespace RTLIL // of cell types). the following functions helps with that. template - bool in(T first, Args... rest) { + bool in(T first, Args... rest) const { return in(first) || in(rest...); } - bool in(IdString rhs) { return *this == rhs; } - bool in(const char *rhs) { return *this == rhs; } - bool in(const std::string &rhs) { return *this == rhs; } - bool in(const pool &rhs) { return rhs.count(*this) != 0; } + bool in(IdString rhs) const { return *this == rhs; } + bool in(const char *rhs) const { return *this == rhs; } + bool in(const std::string &rhs) const { return *this == rhs; } + bool in(const pool &rhs) const { return rhs.count(*this) != 0; } }; static inline std::string escape_id(std::string str) { diff --git a/kernel/yosys.h b/kernel/yosys.h index 88f060a52..d1e01b19c 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -137,6 +137,8 @@ YOSYS_NAMESPACE_BEGIN using std::vector; using std::string; +using std::pair; + using hashlib::mkhash; using hashlib::mkhash_init; using hashlib::mkhash_add; @@ -221,6 +223,8 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN +using RTLIL::State; + namespace hashlib { template<> struct hash_ops : hash_ops {}; } -- cgit v1.2.3 From e62d838bd424995d2fcdc9cef1f56752905c3b4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 1 Jan 2015 11:41:52 +0100 Subject: Removed SigSpec::extend_xx() api --- kernel/rtlil.cc | 18 ------------------ kernel/rtlil.h | 1 - 2 files changed, 19 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index cd2232c8c..d396d6c24 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2673,24 +2673,6 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) check(); } -void RTLIL::SigSpec::extend_xx(int width, bool is_signed) -{ - cover("kernel.rtlil.sigspec.extend_xx"); - - pack(); - - if (width_ > width) - remove(width, width_ - width); - - if (width_ < width) { - RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::S0; - if (!is_signed && (padding == RTLIL::State::S1 || padding.wire)) - padding = RTLIL::State::S0; - while (width_ < width) - append(padding); - } -} - void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { cover("kernel.rtlil.sigspec.extend_u0"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7618780b0..53ee24c22 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -651,7 +651,6 @@ public: void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); - void extend_xx(int width, bool is_signed = false); void extend_u0(int width, bool is_signed = false); RTLIL::SigSpec repeat(int num) const; -- cgit v1.2.3 From f9304e6c10713f713a17f280507f045451863246 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 3 Jan 2015 22:10:33 +0100 Subject: Print non-errors to stdout --- kernel/driver.cc | 6 ++++-- kernel/log.cc | 6 ++++++ kernel/log.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index f1bf0657b..2cbdba8f3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -268,8 +268,10 @@ int main(int argc, char **argv) } } - if (log_errfile == NULL) - log_files.push_back(stderr); + if (log_errfile == NULL) { + log_files.push_back(stdout); + log_error_stderr = true; + } if (print_banner) { log("\n"); diff --git a/kernel/log.cc b/kernel/log.cc index b984f0112..2be425ffd 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -44,6 +44,7 @@ FILE *log_errfile = NULL; SHA1 *log_hasher = NULL; bool log_time = false; +bool log_error_stderr = false; bool log_cmd_error_throw = false; bool log_quiet_warnings = false; int log_verbose_level; @@ -175,6 +176,11 @@ void logv_error(const char *format, va_list ap) if (log_errfile != NULL) log_files.push_back(log_errfile); + if (log_error_stderr) + for (auto &f : log_files) + if (f == stdout) + f = stderr; + log("ERROR: "); logv(format, ap); log_flush(); diff --git a/kernel/log.h b/kernel/log.h index 8096758f6..fa02d2396 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -46,6 +46,7 @@ extern FILE *log_errfile; extern SHA1 *log_hasher; extern bool log_time; +extern bool log_error_stderr; extern bool log_cmd_error_throw; extern bool log_quiet_warnings; extern int log_verbose_level; -- cgit v1.2.3 From 9fb715dc74b632c74aafec1652d4e66dc28cc341 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 Jan 2015 15:46:58 +0100 Subject: build fix for mxe --- kernel/driver.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 2cbdba8f3..1698e216c 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -409,21 +409,22 @@ int main(int argc, char **argv) #ifdef YOSYS_ENABLE_COVER if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) { - char filename_buffer[4096]; + string filename; FILE *f; if (getenv("YOSYS_COVER_DIR")) { - snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", getenv("YOSYS_COVER_DIR"), getpid()); - f = fdopen(mkstemps(filename_buffer, 4), "w"); + filename = stringf("%s/yosys_cover_%d_XXXXXX.txt", getenv("YOSYS_COVER_DIR"), getpid()); + filename = make_temp_file(filename); } else { - snprintf(filename_buffer, 4096, "%s", getenv("YOSYS_COVER_FILE")); - f = fopen(filename_buffer, "a+"); + filename = getenv("YOSYS_COVER_FILE"); } + f = fopen(filename.c_str(), "a+"); + if (f == NULL) - log_error("Can't create coverage file `%s'.\n", filename_buffer); + log_error("Can't create coverage file `%s'.\n", filename.c_str()); - log("\n", filename_buffer); + log("\n", filename.c_str()); for (auto &it : get_coverage_data()) fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); -- cgit v1.2.3 From 859e3e41e7c96e2442d5ff2d3fb54dc5bdffea94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 Jan 2015 16:05:00 +0100 Subject: hashlib iterator fix --- kernel/hashlib.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 5e00e89d6..72e9bc2ef 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -287,7 +287,7 @@ class dict } public: - class const_iterator + class const_iterator : public std::iterator> { friend class dict; protected: @@ -304,7 +304,7 @@ public: const std::pair *operator->() const { return &ptr->entries[index].udata; } }; - class iterator + class iterator : public std::iterator> { friend class dict; protected: @@ -609,7 +609,7 @@ class pool } public: - class const_iterator + class const_iterator : public std::iterator { friend class pool; protected: @@ -625,7 +625,7 @@ public: const K *operator->() const { return &ptr->entries[index].udata; } }; - class iterator + class iterator : public std::iterator { friend class pool; protected: -- cgit v1.2.3 From 07703bdac40f5b7807b627d289e67897bf2b7396 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 Jan 2015 16:12:43 +0100 Subject: fixed compiler warning on non-linux archs --- kernel/log.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 2be425ffd..70bff8f5b 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -253,9 +253,9 @@ void log_pop() log_flush(); } +#ifdef __linux__ void log_backtrace(const char *prefix, int levels) { -#ifdef __linux__ if (levels <= 0) return; Dl_info dli; @@ -341,8 +341,10 @@ void log_backtrace(const char *prefix, int levels) } if (levels <= 9) return; -#endif } +#else +void log_backtrace(const char*, int) { } +#endif void log_reset_stack() { -- cgit v1.2.3 From 95f1eb9b87064719c17d45f24775c3e97497b6df Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 9 Jan 2015 17:32:53 +0100 Subject: Only enable code coverage counters on linux --- kernel/driver.cc | 2 +- kernel/log.cc | 2 +- kernel/log.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 1698e216c..c7f233c54 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -406,7 +406,7 @@ int main(int argc, char **argv) } } -#ifdef YOSYS_ENABLE_COVER +#if defined(YOSYS_ENABLE_COVER) && defined(__linux__) if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) { string filename; diff --git a/kernel/log.cc b/kernel/log.cc index 70bff8f5b..401dbeeb0 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -402,7 +402,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent) // --------------------------------------------------- // This is the magic behind the code coverage counters // --------------------------------------------------- -#ifdef YOSYS_ENABLE_COVER +#if defined(YOSYS_ENABLE_COVER) && defined(__linux__) dict> extra_coverage_data; diff --git a/kernel/log.h b/kernel/log.h index fa02d2396..e61d19b62 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -92,10 +92,10 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi // This is the magic behind the code coverage counters // --------------------------------------------------- -#ifdef YOSYS_ENABLE_COVER +#if defined(YOSYS_ENABLE_COVER) && defined(__linux__) #define cover(_id) do { \ - static CoverData __d YS_ATTRIBUTE(section("yosys_cover_list"), aligned(1), used) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1), used)) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ __d.counter++; \ } while (0) -- cgit v1.2.3 From b32ba6f56802b7cb8bb6098ee895d4ad37438ff8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Jan 2015 12:04:40 +0100 Subject: Optimizing no-op cell->setPort() --- kernel/rtlil.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d396d6c24..b35cbc3d1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1839,7 +1839,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); -- cgit v1.2.3 From 0217ea0fb82b9170bb6efce734f1965ff2b181e7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 18 Jan 2015 12:12:33 +0100 Subject: Added hashlib::idict<> --- kernel/hashlib.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- kernel/yosys.h | 1 + 2 files changed, 59 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 72e9bc2ef..52b38a064 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -163,7 +163,11 @@ inline int hashtable_size(int min_size) throw std::length_error("hash table exceeded maximum size."); } -template> +template> class dict; +template> class idict; +template> class pool; + +template class dict { struct entry_t @@ -485,9 +489,12 @@ public: const_iterator end() const { return const_iterator(nullptr, -1); } }; -template> +template class pool { + template friend class idict; + +protected: struct entry_t { K udata; @@ -783,6 +790,55 @@ public: const_iterator end() const { return const_iterator(nullptr, -1); } }; +template +class idict +{ + pool database; + +public: + typedef typename pool::const_iterator const_iterator; + + int operator()(const K &key) + { + int hash = database.do_hash(key); + int i = database.do_lookup(key, hash); + if (i < 0) + i = database.do_insert(key, hash); + return i + offset; + } + + int at(const K &key) const + { + int hash = database.do_hash(key); + int i = database.do_lookup(key, hash); + if (i < 0) + throw std::out_of_range("idict::at()"); + return i + offset; + } + + int count(const K &key) const + { + int hash = database.do_hash(key); + int i = database.do_lookup(key, hash); + return i < 0 ? 0 : 1; + } + + void expect(const K &key, int i) + { + int j = (*this)(key); + if (i != j) + throw std::out_of_range("idict::expect()"); + } + + const K &operator[](int index) const + { + return database.entries.at(index - offset).udata; + } + + const_iterator begin() const { return database.begin(); } + const_iterator end() const { return database.end(); } +}; + } /* namespace hashlib */ #endif diff --git a/kernel/yosys.h b/kernel/yosys.h index d1e01b19c..a6f4cb665 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -148,6 +148,7 @@ using hashlib::hash_cstr_ops; using hashlib::hash_ptr_ops; using hashlib::hash_obj_ops; using hashlib::dict; +using hashlib::idict; using hashlib::pool; namespace RTLIL { -- cgit v1.2.3 From e13a45ae61e05705d9ab6890da60737bd05eb24d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 19 Jan 2015 11:55:05 +0100 Subject: Added $equiv cell type --- kernel/celltypes.h | 1 + kernel/rtlil.cc | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 3a56de2f7..60e6606f8 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -114,6 +114,7 @@ struct CellTypes setup_type("$fa", {A, B, C}, {X, Y}, true); setup_type("$assert", {A, EN}, pool(), true); + setup_type("$equiv", {A, B}, {Y}, true); } void setup_internals_mem() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b35cbc3d1..ec61cb529 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -905,6 +905,14 @@ namespace { 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; } -- cgit v1.2.3 From 76c5d863c52253a5709f44e0608c53a8c33ab3b5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 19 Jan 2015 13:59:08 +0100 Subject: Added equiv_make command --- kernel/rtlil.cc | 9 +++++++++ kernel/rtlil.h | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ec61cb529..52293da29 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1618,6 +1618,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"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 53ee24c22..dae684d98 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -439,7 +439,7 @@ namespace RTLIL return result; } - pool to_set() const { return *this; } + pool to_pool() const { return *this; } std::vector to_vector() const { return *this; } }; }; @@ -968,6 +968,7 @@ public: 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* 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); RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true); RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); -- cgit v1.2.3 From abf8398216c772bcd23925353f45a17c5d508e8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 21 Jan 2015 23:59:58 +0000 Subject: Progress in equiv_simple --- kernel/rtlil.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 52293da29..aea993478 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1055,8 +1055,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); -- cgit v1.2.3 From a6aa32e762d29f050d0b6d49e288514964a5aac5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Jan 2015 13:40:26 +0100 Subject: Various equiv_simple improvements --- kernel/satgen.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'kernel') diff --git a/kernel/satgen.h b/kernel/satgen.h index 2c69663c4..c874099b7 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -1163,6 +1163,25 @@ struct SatGen return true; } + if (cell->type == "$_BUF_" || cell->type == "$equiv") + { + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + extendSignalWidthUnary(a, y, cell); + + std::vector yy = model_undef ? ez->vec_var(y.size()) : y; + ez->assume(ez->vec_eq(a, yy)); + + if (model_undef) { + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + extendSignalWidthUnary(undef_a, undef_y, cell, false); + ez->assume(ez->vec_eq(undef_a, undef_y)); + undefGating(y, yy, undef_y); + } + return true; + } + if (cell->type == "$assert") { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); -- cgit v1.2.3 From 43951099cf46b5a0a25bdebb001685a89dfe6c82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 24 Jan 2015 00:13:27 +0100 Subject: Added dict/pool.sort() --- kernel/hashlib.h | 14 ++++++++++++++ kernel/rtlil.cc | 30 ++++++++++++++++++++++++++++++ kernel/rtlil.h | 4 ++++ 3 files changed, 48 insertions(+) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 52b38a064..8c977de2f 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -457,6 +457,13 @@ public: return entries[i].udata.second; } + template> + void sort(Compare comp = Compare()) + { + std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata.first, a.udata.first); }); + do_rehash(); + } + void swap(dict &other) { hashtable.swap(other.hashtable); @@ -760,6 +767,13 @@ public: return i >= 0; } + template> + void sort(Compare comp = Compare()) + { + std::sort(entries.begin(), entries.end(), [comp](const entry_t &a, const entry_t &b){ return comp(b.udata, a.udata); }); + do_rehash(); + } + void swap(pool &other) { hashtable.swap(other.hashtable); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index aea993478..3fb98d1e2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -373,6 +373,14 @@ void RTLIL::Design::remove(RTLIL::Module *module) 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 @@ -976,6 +984,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 @@ -1908,6 +1931,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 diff --git a/kernel/rtlil.h b/kernel/rtlil.h index dae684d98..d8ebae71d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -788,6 +788,7 @@ struct RTLIL::Design bool scratchpad_get_bool(std::string varname, bool default_value = false) const; std::string scratchpad_get_string(std::string varname, std::string default_value = std::string()) const; + void sort(); void check(); void optimize(); @@ -863,6 +864,8 @@ public: virtual ~Module(); virtual RTLIL::IdString derive(RTLIL::Design *design, dict parameters); virtual size_t count_id(RTLIL::IdString id); + + virtual void sort(); virtual void check(); virtual void optimize(); @@ -1136,6 +1139,7 @@ public: void setParam(RTLIL::IdString paramname, RTLIL::Const value); const RTLIL::Const &getParam(RTLIL::IdString paramname) const; + void sort(); void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); -- cgit v1.2.3 From 8fe9ab50e51204e5709eaad0fbf2ffb5397a0194 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 24 Jan 2015 11:49:34 +0100 Subject: Added #ifdef NDEBUG for log_assert() --- kernel/log.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index e61d19b62..8b3d8a3ad 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -79,12 +79,16 @@ template static inline const char *log_id(T *obj) { void log_cell(RTLIL::Cell *cell, std::string indent = ""); +#ifndef NDEBUG static inline void log_assert_worker(bool cond, const char *expr, const char *file, int line) { if (!cond) log_error("Assert `%s' failed in %s:%d.\n", expr, file, line); } +# define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) +#else +# define log_assert(_assert_expr_) +#endif #define log_abort() YOSYS_NAMESPACE_PREFIX log_error("Abort in %s:%d.\n", __FILE__, __LINE__) -#define log_assert(_assert_expr_) YOSYS_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__) #define log_ping() YOSYS_NAMESPACE_PREFIX log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) -- cgit v1.2.3 From 2a9ad48eb63a5f019c528fe46ceca0065364a44d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 24 Jan 2015 12:16:46 +0100 Subject: Added ENABLE_NDEBUG makefile options --- kernel/log.h | 2 +- kernel/macc.h | 4 +++- kernel/modtools.h | 6 +++--- kernel/yosys.cc | 2 ++ 4 files changed, 9 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/log.h b/kernel/log.h index 8b3d8a3ad..fd35c7bf7 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -220,7 +220,7 @@ static inline void log_dump_val_worker(char *v) { log("%s", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } -static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } +static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); } void log_dump_val_worker(RTLIL::SigSpec v); template diff --git a/kernel/macc.h b/kernel/macc.h index ab17f8c41..cac5b00d7 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -105,10 +105,12 @@ struct Macc bit_ports = cell->getPort("\\B"); std::vector config_bits = cell->getParam("\\CONFIG").bits; - int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); int config_cursor = 0; +#ifndef NDEBUG + int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); log_assert(GetSize(config_bits) >= config_width); +#endif int num_bits = 0; if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1; diff --git a/kernel/modtools.h b/kernel/modtools.h index 113b0918d..5fd7ef5a6 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -130,7 +130,7 @@ struct ModIndex : public RTLIL::Monitor port_add(cell, port, sig); } - virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &sigsig) YS_OVERRIDE + virtual void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const RTLIL::SigSig &sigsig) YS_OVERRIDE { log_assert(module == mod); @@ -174,13 +174,13 @@ struct ModIndex : public RTLIL::Monitor } } - virtual void notify_connect(RTLIL::Module *mod, const std::vector&) YS_OVERRIDE + virtual void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const std::vector&) YS_OVERRIDE { log_assert(module == mod); auto_reload_module = true; } - virtual void notify_blackout(RTLIL::Module *mod) YS_OVERRIDE + virtual void notify_blackout(RTLIL::Module *mod YS_ATTRIBUTE(unused)) YS_OVERRIDE { log_assert(module == mod); auto_reload_module = true; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ac1bc7abf..d5467afe1 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -319,11 +319,13 @@ std::string make_temp_dir(std::string template_str) mkdir(template_str.c_str()); return template_str; #else +# ifndef NDEBUG size_t pos = template_str.rfind("XXXXXX"); log_assert(pos != std::string::npos); int suffixlen = GetSize(template_str) - pos - 6; log_assert(suffixlen == 0); +# endif char *p = strdup(template_str.c_str()); p = mkdtemp(p); -- cgit v1.2.3 From 13b50bacfee1ea1651cbdccd7522f3d03cab5675 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 25 Jan 2015 22:57:09 +0100 Subject: Rethrow with "catch(...) throw;" --- kernel/yosys.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d5467afe1..b280d3344 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -720,9 +720,9 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi Pass::call(design, command); } } - catch (log_cmd_error_exception) { + catch (...) { Frontend::current_script_file = backup_script_file; - throw log_cmd_error_exception(); + throw; } Frontend::current_script_file = backup_script_file; -- cgit v1.2.3 From 114a78d11a629f030e5fd0b6e5655ed70ee7ca9b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 30 Jan 2015 22:12:26 +0100 Subject: Some cleanups in log.cc --- kernel/log.cc | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 401dbeeb0..061c5074c 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -49,10 +49,10 @@ bool log_cmd_error_throw = false; bool log_quiet_warnings = false; int log_verbose_level; -std::vector header_count; -std::set log_id_cache; -std::list string_buf; -int string_buf_size = 0; +vector header_count; +pool log_id_cache; +vector string_buf; +int string_buf_index = -1; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; @@ -249,7 +249,7 @@ void log_pop() header_count.pop_back(); log_id_cache.clear(); string_buf.clear(); - string_buf_size = 0; + string_buf_index = -1; log_flush(); } @@ -352,7 +352,7 @@ void log_reset_stack() header_count.pop_back(); log_id_cache.clear(); string_buf.clear(); - string_buf_size = 0; + string_buf_index = -1; log_flush(); } @@ -374,20 +374,22 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) std::stringstream buf; ILANG_BACKEND::dump_sigspec(buf, sig, autoint); - if (string_buf_size < 100) - string_buf_size++; - else - string_buf.pop_front(); - string_buf.push_back(buf.str()); - - return string_buf.back().c_str(); + if (string_buf.size() < 100) { + string_buf.push_back(buf.str()); + return string_buf.back().c_str(); + } else { + if (++string_buf_index == 100) + string_buf_index = 0; + string_buf[string_buf_index] = buf.str(); + return string_buf[string_buf_index].c_str(); + } } const char *log_id(RTLIL::IdString str) { log_id_cache.insert(str); const char *p = str.c_str(); - if (p[0] == '\\' && p[1] != '$' && p[1] != 0) + if (p[0] == '\\' && p[1] != '$' && p[1] != '\\' && p[1] != 0) return p+1; return p; } -- cgit v1.2.3 From aabd5097ed84182c1bd32dc94abcc1205dc25d09 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 30 Jan 2015 22:22:52 +0100 Subject: More log_id() stuff --- kernel/log.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/log.cc b/kernel/log.cc index 061c5074c..ada2cabb2 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -389,9 +389,13 @@ const char *log_id(RTLIL::IdString str) { log_id_cache.insert(str); const char *p = str.c_str(); - if (p[0] == '\\' && p[1] != '$' && p[1] != '\\' && p[1] != 0) - return p+1; - return p; + if (p[0] != '\\') + return p; + if (p[1] == '$' || p[1] == '\\' || p[1] == 0) + return p; + if (p[1] >= '0' && p[1] <= '9') + return p; + return p+1; } void log_cell(RTLIL::Cell *cell, std::string indent) -- cgit v1.2.3 From cb9d0a414dc899c3821af0e8f6231f887540c7a2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 30 Jan 2015 22:51:16 +0100 Subject: Synced RTLIL::unescape_id() to log_id() behavior --- kernel/rtlil.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d8ebae71d..4d13897b9 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -267,9 +267,15 @@ namespace RTLIL } static inline std::string unescape_id(std::string str) { - if (str.size() > 1 && str[0] == '\\' && str[1] != '$') - return str.substr(1); - return str; + if (str.size() < 2) + return str; + if (str[0] != '\\') + return str; + if (str[1] == '$' || str[1] == '\\') + return str; + if (str[1] >= '0' && str[1] <= '9') + return str; + return str.substr(1); } static inline std::string unescape_id(RTLIL::IdString str) { -- cgit v1.2.3 From f80f5b721da8188f2b00cc238075ef4e52a03d35 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 31 Jan 2015 12:08:20 +0100 Subject: Added "equiv_make -blacklist -encfile " --- kernel/rtlil.cc | 15 +++++++++++++++ kernel/rtlil.h | 1 + 2 files changed, 16 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3fb98d1e2..9b55d4255 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -128,6 +128,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; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4d13897b9..c17ede3d0 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -469,6 +469,7 @@ struct RTLIL::Const bool as_bool() const; int as_int(bool is_signed = false) const; std::string as_string() const; + static Const from_string(std::string str); std::string decode_string() const; -- cgit v1.2.3 From e9cfc4a453ac0bdfaee44ab3f6d010a2cfecec5e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 31 Jan 2015 13:06:41 +0100 Subject: Added "equiv_simple -undef" --- kernel/satgen.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'kernel') diff --git a/kernel/satgen.h b/kernel/satgen.h index c874099b7..2f5efe674 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -103,6 +103,20 @@ struct SatGen return importSigSpecWorker(bit, pf, false, false).front(); } + int importDefSigBit(RTLIL::SigBit bit, int timestep = -1) + { + log_assert(timestep != 0); + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + return importSigSpecWorker(bit, pf, false, true).front(); + } + + int importUndefSigBit(RTLIL::SigBit bit, int timestep = -1) + { + log_assert(timestep != 0); + std::string pf = "undef:" + prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + return importSigSpecWorker(bit, pf, true, false).front(); + } + bool importedSigBit(RTLIL::SigBit bit, int timestep = -1) { log_assert(timestep != 0); -- cgit v1.2.3 From bc86b4a7e9c847180e6fd7ed81e0a15d5aee00a0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 31 Jan 2015 13:58:04 +0100 Subject: Added "equiv_induct -undef" --- kernel/sigtools.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/sigtools.h b/kernel/sigtools.h index c38736e70..f92a87dbb 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -129,7 +129,7 @@ struct SigPool return sig; } - size_t size() + size_t size() const { return bits.size(); } -- cgit v1.2.3 From 67218443becc134d552b16a98b87f0cb2318c23d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 31 Jan 2015 21:26:53 +0100 Subject: Log msg change --- kernel/yosys.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index b280d3344..27f210245 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -747,7 +747,7 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi void run_pass(std::string command, RTLIL::Design *design) { - log("\n-- Running pass `%s' --\n", command.c_str()); + log("\n-- Running command `%s' --\n", command.c_str()); Pass::call(design, command); } -- cgit v1.2.3 From 07326943e7e503a214f1c61ce442b1833e450b8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 1 Feb 2015 00:27:07 +0100 Subject: Added include to hashlib.h --- kernel/hashlib.h | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index 8c977de2f..c96023920 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -12,6 +12,7 @@ #ifndef HASHLIB_H #include +#include #include #include -- cgit v1.2.3 From 9948ff2d8a96a3c48188650601a2a75dec4a573d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 1 Feb 2015 00:39:59 +0100 Subject: Added yosys_banner(), Updated Copyright range --- kernel/driver.cc | 27 ++------------------------- kernel/yosys.cc | 27 +++++++++++++++++++++++++++ kernel/yosys.h | 1 + 3 files changed, 30 insertions(+), 25 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index c7f233c54..65b6c5a47 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -273,31 +273,8 @@ int main(int argc, char **argv) log_error_stderr = true; } - if (print_banner) { - log("\n"); - log(" /----------------------------------------------------------------------------\\\n"); - log(" | |\n"); - log(" | yosys -- Yosys Open SYnthesis Suite |\n"); - log(" | |\n"); - log(" | Copyright (C) 2012 Clifford Wolf |\n"); - log(" | |\n"); - log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); - log(" | purpose with or without fee is hereby granted, provided that the above |\n"); - log(" | copyright notice and this permission notice appear in all copies. |\n"); - log(" | |\n"); - log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); - log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); - log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); - log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); - log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); - log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); - log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); - log(" | |\n"); - log(" \\----------------------------------------------------------------------------/\n"); - log("\n"); - log(" %s\n", yosys_version_str); - log("\n"); - } + if (print_banner) + yosys_banner(); if (print_stats) log_hasher = new SHA1; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 27f210245..e4a5c3351 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -97,6 +97,33 @@ void memhasher_do() memhasher_store[index] = realloc(memhasher_store[index], size); } +void yosys_banner() +{ + log("\n"); + log(" /----------------------------------------------------------------------------\\\n"); + log(" | |\n"); + log(" | yosys -- Yosys Open SYnthesis Suite |\n"); + log(" | |\n"); + log(" | Copyright (C) 2012 - 2015 Clifford Wolf |\n"); + log(" | |\n"); + log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); + log(" | purpose with or without fee is hereby granted, provided that the above |\n"); + log(" | copyright notice and this permission notice appear in all copies. |\n"); + log(" | |\n"); + log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); + log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); + log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); + log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); + log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); + log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); + log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); + log(" | |\n"); + log(" \\----------------------------------------------------------------------------/\n"); + log("\n"); + log(" %s\n", yosys_version_str); + log("\n"); +} + std::string stringf(const char *fmt, ...) { std::string string; diff --git a/kernel/yosys.h b/kernel/yosys.h index a6f4cb665..efdc005eb 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -199,6 +199,7 @@ void memhasher_do(); extern bool memhasher_active; inline void memhasher() { if (memhasher_active) memhasher_do(); } +void yosys_banner(); std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); std::string vstringf(const char *fmt, va_list ap); int readsome(std::istream &f, char *s, int n); -- cgit v1.2.3 From 1df81f92ce171ba63cf0e4d10e6f203ca5f7f64e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 1 Feb 2015 13:38:46 +0100 Subject: Added "make mklibyosys", some minor API changes --- kernel/driver.cc | 8 ++++---- kernel/yosys.cc | 20 +++++++++++++++++--- kernel/yosys.h | 7 ++++--- 3 files changed, 25 insertions(+), 10 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 65b6c5a47..e95ef48d3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -291,7 +291,7 @@ int main(int argc, char **argv) } while (optind < argc) - run_frontend(argv[optind++], frontend_command, yosys_design, output_filename == "-" ? &backend_command : NULL, NULL); + run_frontend(argv[optind++], frontend_command, output_filename == "-" ? &backend_command : NULL); if (!scriptfile.empty()) { if (scriptfile_tcl) { @@ -302,14 +302,14 @@ int main(int argc, char **argv) log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n"); #endif } else - run_frontend(scriptfile, "script", yosys_design, output_filename == "-" ? &backend_command : NULL, NULL); + run_frontend(scriptfile, "script", output_filename == "-" ? &backend_command : NULL); } for (auto it = passes_commands.begin(); it != passes_commands.end(); it++) - run_pass(*it, yosys_design); + run_pass(*it); if (!backend_command.empty()) - run_backend(output_filename, backend_command, yosys_design); + run_backend(output_filename, backend_command); if (print_stats) { diff --git a/kernel/yosys.cc b/kernel/yosys.cc index e4a5c3351..530d78796 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -679,8 +679,11 @@ static void handle_label(std::string &command, bool &from_to_active, const std:: } } -void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) +void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label, RTLIL::Design *design) { + if (design == nullptr) + design = yosys_design; + if (command == "auto") { if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") command = "verilog"; @@ -772,8 +775,16 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi Frontend::frontend_call(design, NULL, filename, command); } +void run_frontend(std::string filename, std::string command, RTLIL::Design *design) +{ + run_frontend(filename, command, nullptr, nullptr, design); +} + void run_pass(std::string command, RTLIL::Design *design) { + if (design == nullptr) + design = yosys_design; + log("\n-- Running command `%s' --\n", command.c_str()); Pass::call(design, command); @@ -781,6 +792,9 @@ void run_pass(std::string command, RTLIL::Design *design) void run_backend(std::string filename, std::string command, RTLIL::Design *design) { + if (design == nullptr) + design = yosys_design; + if (command == "auto") { if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") command = "verilog"; @@ -1025,9 +1039,9 @@ struct ScriptPass : public Pass { if (args.size() < 2) log_cmd_error("Missing script file.\n"); else if (args.size() == 2) - run_frontend(args[1], "script", design, NULL, NULL); + run_frontend(args[1], "script", design); else if (args.size() == 3) - run_frontend(args[1], "script", design, NULL, &args[2]); + run_frontend(args[1], "script", NULL, &args[2], design); else extra_args(args, 2, design, false); } diff --git a/kernel/yosys.h b/kernel/yosys.h index efdc005eb..47275ecd4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -253,9 +253,10 @@ std::string proc_self_dirname(); std::string proc_share_dirname(); const char *create_prompt(RTLIL::Design *design, int recursion_counter); -void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label); -void run_pass(std::string command, RTLIL::Design *design); -void run_backend(std::string filename, std::string command, RTLIL::Design *design); +void run_pass(std::string command, RTLIL::Design *design = nullptr); +void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label = nullptr, RTLIL::Design *design = nullptr); +void run_frontend(std::string filename, std::string command, RTLIL::Design *design = nullptr); +void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr); void shell(RTLIL::Design *design); // from kernel/version_*.o (cc source generated from Makefile) -- cgit v1.2.3 From 8514fe79dbabb8ed95b24d29e98c16e4027dfc57 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 3 Feb 2015 23:04:58 +0100 Subject: Added "yosys -L logfile" --- kernel/driver.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index e95ef48d3..116df542c 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -127,6 +127,9 @@ int main(int argc, char **argv) printf(" -l logfile\n"); printf(" write log messages to the specified file\n"); printf("\n"); + printf(" -L logfile\n"); + printf(" like -l but open log file in line buffered mode\n"); + printf("\n"); printf(" -o outfile\n"); printf(" write the design to the specified file on exit\n"); printf("\n"); @@ -183,7 +186,7 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:qv:tds:c:")) != -1) + while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:")) != -1) { switch (opt) { @@ -231,11 +234,14 @@ int main(int argc, char **argv) got_output_filename = true; break; case 'l': + case 'L': log_files.push_back(fopen(optarg, "wt")); if (log_files.back() == NULL) { fprintf(stderr, "Can't open log file `%s' for writing!\n", optarg); exit(1); } + if (opt == 'L') + setvbuf(log_files.back(), NULL, _IOLBF, 0); break; case 'q': mode_q = true; -- cgit v1.2.3 From 5b41470e151e3b1019e87dfddf900cea51922409 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 3 Feb 2015 23:11:57 +0100 Subject: Skip blackbox modules in design->selected_modules() --- kernel/rtlil.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9b55d4255..8c64217bb 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -460,7 +460,7 @@ std::vector RTLIL::Design::selected_modules() const std::vector 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; } @@ -470,7 +470,7 @@ std::vector RTLIL::Design::selected_whole_modules() const std::vector 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; } @@ -480,7 +480,9 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const std::vector 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)); -- cgit v1.2.3 From dce1fae777bcc9791c2f49be4b53f1de53df7502 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Feb 2015 11:40:19 +0100 Subject: Added cell->known(), cell->input(portname), cell->output(portname) --- kernel/rtlil.cc | 34 ++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 5 +++++ 2 files changed, 39 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8c64217bb..b1e2c0e8e 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" @@ -1928,6 +1929,39 @@ const dict &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) != 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c17ede3d0..985bffe5e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1140,6 +1140,11 @@ public: const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const; const dict &connections() const; + // information about cell ports + bool known() const; + bool input(RTLIL::IdString portname) const; + bool output(RTLIL::IdString portname) const; + // access cell parameters bool hasParam(RTLIL::IdString paramname) const; void unsetParam(RTLIL::IdString paramname); -- cgit v1.2.3 From 05d4223fb675ee063ded20cf24eb922c4570634a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Feb 2015 00:01:51 +0100 Subject: Added SigSpec::has_const() --- kernel/rtlil.cc | 12 ++++++++++++ kernel/rtlil.h | 1 + 2 files changed, 13 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b1e2c0e8e..776625b9c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1078,6 +1078,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(); } @@ -2968,6 +2969,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"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 985bffe5e..dd40e2fba 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -672,6 +672,7 @@ public: bool is_fully_const() const; bool is_fully_def() const; bool is_fully_undef() const; + bool has_const() const; bool has_marked_bits() const; bool as_bool() const; -- cgit v1.2.3 From 6d2f31c04afaaa0f8d0768dfc73232620a6a2445 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Feb 2015 14:23:12 +0100 Subject: Various ModIndex improvements --- kernel/modtools.h | 67 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) (limited to 'kernel') diff --git a/kernel/modtools.h b/kernel/modtools.h index 5fd7ef5a6..69c13bd3b 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -60,6 +60,10 @@ struct ModIndex : public RTLIL::Monitor SigBitInfo() : is_input(false), is_output(false) { } + bool operator==(const SigBitInfo &other) const { + return is_input == other.is_input && is_output == other.is_output && ports == other.ports; + } + void merge(const SigBitInfo &other) { is_input = is_input || other.is_input; @@ -71,6 +75,7 @@ struct ModIndex : public RTLIL::Monitor SigMap sigmap; RTLIL::Module *module; std::map database; + int auto_reload_counter; bool auto_reload_module; void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) @@ -96,10 +101,12 @@ struct ModIndex : public RTLIL::Monitor return database[sigmap(bit)]; } - void reload_module() + void reload_module(bool reset_sigmap = true) { - sigmap.clear(); - sigmap.set(module); + if (reset_sigmap) { + sigmap.clear(); + sigmap.set(module); + } database.clear(); for (auto wire : module->wires()) @@ -115,8 +122,40 @@ struct ModIndex : public RTLIL::Monitor for (auto &conn : cell->connections()) port_add(cell, conn.first, conn.second); - auto_reload_module = false; - // log("Auto-reload in ModIndex -- possible performance bug!\n"); + if (auto_reload_module) { + if (++auto_reload_counter > 2) + log_warning("Auto-reload in ModIndex -- possible performance bug!\n"); + auto_reload_module = false; + } + } + + void check() + { +#ifndef NDEBUG + if (auto_reload_module) + return; + + for (auto it : database) + log_assert(it.first == sigmap(it.first)); + + auto database_bak = std::move(database); + reload_module(false); + + if (!(database == database_bak)) + { + for (auto &it : database_bak) + if (!database.count(it.first)) + log("ModuleIndex::check(): Only in database_bak, not database: %s\n", log_signal(it.first)); + + for (auto &it : database) + if (!database_bak.count(it.first)) + log("ModuleIndex::check(): Only in database, not database_bak: %s\n", log_signal(it.first)); + else if (!(it.second == database_bak.at(it.first))) + log("ModuleIndex::check(): Different content for database[%s].\n", log_signal(it.first)); + + log_assert(database == database_bak); + } +#endif } virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE @@ -151,25 +190,26 @@ struct ModIndex : public RTLIL::Monitor SigBitInfo new_info = database.at(lhs); database.erase(lhs); sigmap.add(lhs, rhs); - database[sigmap(lhs)] = new_info; + lhs = sigmap(lhs); + if (lhs.wire) + database[lhs] = new_info; } else if (!has_lhs) { SigBitInfo new_info = database.at(rhs); database.erase(rhs); sigmap.add(lhs, rhs); - database[sigmap(rhs)] = new_info; + rhs = sigmap(rhs); + if (rhs.wire) + database[rhs] = new_info; } else { - #if 1 - auto_reload_module = true; - return; - #else SigBitInfo new_info = database.at(lhs); new_info.merge(database.at(rhs)); database.erase(lhs); database.erase(rhs); sigmap.add(lhs, rhs); - database[sigmap(rhs)] = new_info; - #endif + rhs = sigmap(rhs); + if (rhs.wire) + database[rhs] = new_info; } } } @@ -188,6 +228,7 @@ struct ModIndex : public RTLIL::Monitor ModIndex(RTLIL::Module *_m) : module(_m) { + auto_reload_counter = 0; auto_reload_module = true; module->monitors.insert(this); } -- cgit v1.2.3 From 09ee65a050ffc8fe1a208140cce32a6a5f15c4ab Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Feb 2015 18:56:06 +0100 Subject: Added eval_select_args() and eval_select_op() --- kernel/register.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'kernel') diff --git a/kernel/register.h b/kernel/register.h index 5214dd9a3..9b247172e 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -100,6 +100,8 @@ struct Backend : Pass // implemented in passes/cmds/select.cc extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); +extern RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *design); +extern void eval_select_op(vector &work, string &op, RTLIL::Design *design); extern std::map pass_register; extern std::map frontend_register; -- cgit v1.2.3 From bcd8a2fc567e0bbc1b04467ac7a3b32ed332f7f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Feb 2015 19:06:16 +0100 Subject: Fixed eval_select_op() api --- kernel/register.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/register.h b/kernel/register.h index 9b247172e..71ab6ea6e 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -101,7 +101,7 @@ struct Backend : Pass // implemented in passes/cmds/select.cc extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); extern RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *design); -extern void eval_select_op(vector &work, string &op, RTLIL::Design *design); +extern void eval_select_op(vector &work, const string &op, RTLIL::Design *design); extern std::map pass_register; extern std::map frontend_register; -- cgit v1.2.3 From a779a09771f7373b8d1e77d7a9182fd3ed9008e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Feb 2015 13:24:29 +0100 Subject: Fixed creation of command reference in manual --- kernel/register.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index 56dc695aa..cdba4c36f 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -545,11 +545,10 @@ struct HelpPass : public Pass { } void escape_tex(std::string &tex) { - size_t pos = 0; - while ((pos = tex.find('_', pos)) != std::string::npos) { + for (size_t pos = 0; (pos = tex.find('_', pos)) != std::string::npos; pos += 2) tex.replace(pos, 1, "\\_"); - pos += 2; - } + for (size_t pos = 0; (pos = tex.find('$', pos)) != std::string::npos; pos += 2) + tex.replace(pos, 1, "\\$"); } void write_tex(FILE *f, std::string cmd, std::string title, std::string text) { -- cgit v1.2.3 From adf4ecbc1f571d26bed2b1c264c38a5f3c25e9b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Feb 2015 20:11:51 +0100 Subject: Some hashlib improvements --- kernel/hashlib.h | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index c96023920..94b573e47 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -178,18 +178,19 @@ class dict entry_t() { } entry_t(const std::pair &udata, int next) : udata(udata), next(next) { } + entry_t(std::pair &&udata, int next) : udata(std::move(udata)), next(next) { } }; std::vector hashtable; std::vector entries; OPS ops; -#if 0 +#ifdef NDEBUG + static inline void do_assert(bool) { } +#else static inline void do_assert(bool cond) { if (!cond) throw std::runtime_error("dict<> assert failed."); } -#else - static inline void do_assert(bool) { } #endif int do_hash(const K &key) const @@ -220,6 +221,8 @@ class dict return 0; int k = hashtable[hash]; + do_assert(0 <= k && k < int(entries.size())); + if (k == index) { hashtable[hash] = entries[index].next; } else { @@ -237,6 +240,8 @@ class dict int back_hash = do_hash(entries[back_idx].udata.first); k = hashtable[back_hash]; + do_assert(0 <= k && k < int(entries.size())); + if (k == back_idx) { hashtable[back_hash] = index; } else { @@ -278,6 +283,19 @@ class dict return index; } + int do_insert(const K &key, int &hash) + { + if (hashtable.empty()) { + entries.push_back(entry_t(std::pair(key, T()), -1)); + do_rehash(); + hash = do_hash(key); + } else { + entries.push_back(entry_t(std::pair(key, T()), hashtable[hash])); + hashtable[hash] = entries.size() - 1; + } + return entries.size() - 1; + } + int do_insert(const std::pair &value, int &hash) { if (hashtable.empty()) { @@ -375,6 +393,16 @@ public: insert(*first); } + std::pair insert(const K &key) + { + int hash = do_hash(key); + int i = do_lookup(key, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(key, hash); + return std::pair(iterator(this, i), true); + } + std::pair insert(const std::pair &value) { int hash = do_hash(value.first); @@ -476,14 +504,14 @@ public: return false; for (auto &it : entries) { auto oit = other.find(it.udata.first); - if (oit == other.end() || oit->second != it.udata.second) + if (oit == other.end() || !(oit->second == it.udata.second)) return false; } return true; } bool operator!=(const dict &other) const { - return !(*this == other); + return !operator==(other); } size_t size() const { return entries.size(); } @@ -516,12 +544,12 @@ protected: std::vector entries; OPS ops; -#if 0 +#ifdef NDEBUG + static inline void do_assert(bool) { } +#else static inline void do_assert(bool cond) { if (!cond) throw std::runtime_error("pool<> assert failed."); } -#else - static inline void do_assert(bool) { } #endif int do_hash(const K &key) const @@ -791,7 +819,7 @@ public: } bool operator!=(const pool &other) const { - return !(*this == other); + return !operator==(other); } size_t size() const { return entries.size(); } -- cgit v1.2.3 From 910556560fbf26df4f2960b7d94039a1f399f1a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Feb 2015 10:23:03 +0100 Subject: Added $meminit cell type --- kernel/celltypes.h | 1 + kernel/rtlil.cc | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 60e6606f8..57bcde471 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -135,6 +135,7 @@ struct CellTypes setup_type("$memrd", {CLK, ADDR}, {DATA}); setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool()); + setup_type("$meminit", {ADDR, DATA}, pool()); setup_type("$mem", {RD_CLK, 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/rtlil.cc b/kernel/rtlil.cc index 776625b9c..9fd3d2959 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -904,6 +904,15 @@ 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"); -- cgit v1.2.3 From dcf2e242406d563254013ea7db4b29b55be96eff Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Feb 2015 12:55:03 +0100 Subject: Added $meminit support to "memory" command --- kernel/rtlil.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'kernel') diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9fd3d2959..c10261b23 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -917,6 +917,7 @@ namespace { 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")); -- cgit v1.2.3 From 3216f9420e2f5aed0aa3e38ff89ab616db9b0849 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Feb 2015 12:09:30 +0100 Subject: More emscripten stuff, Added example app --- kernel/driver.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 116df542c..6df7cf2e8 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -72,6 +72,32 @@ int getopt(int argc, char **argv, const char *optstring) USING_YOSYS_NAMESPACE +#ifdef EMSCRIPTEN + +extern "C" int main(int, char**); +extern "C" void run(const char*); +extern "C" const char *prompt(); + +int main(int, char**) +{ + log_files.push_back(stdout); + log_error_stderr = true; + yosys_banner(); + yosys_setup(); +} + +void run(const char *command) +{ + run_pass(command); +} + +const char *prompt() +{ + return create_prompt(yosys_get_design(), 0); +} + +#else /* EMSCRIPTEN */ + int main(int argc, char **argv) { std::string frontend_command = "auto"; @@ -440,3 +466,5 @@ int main(int argc, char **argv) return 0; } +#endif /* EMSCRIPTEN */ + -- cgit v1.2.3 From 8d45f81046a159df38e20b00cf0d74b1bb02a073 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Feb 2015 17:14:09 +0100 Subject: More emcc stuff --- kernel/yosys.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 530d78796..b54836621 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -619,26 +619,33 @@ std::string proc_self_dirname() #error Dont know how to determine process executable base path! #endif +#ifdef EMSCRIPTEN +std::string proc_share_dirname() +{ + return "/share"; +} +#else std::string proc_share_dirname() { std::string proc_self_path = proc_self_dirname(); -#ifdef _WIN32 +# ifdef _WIN32 std::string proc_share_path = proc_self_path + "share\\"; if (check_file_exists(proc_share_path, true)) return proc_share_path; proc_share_path = proc_self_path + "..\\share\\"; if (check_file_exists(proc_share_path, true)) return proc_share_path; -#else +# else std::string proc_share_path = proc_self_path + "share/"; if (check_file_exists(proc_share_path, true)) return proc_share_path; proc_share_path = proc_self_path + "../share/yosys/"; if (check_file_exists(proc_share_path, true)) return proc_share_path; -#endif +# endif log_error("proc_share_dirname: unable to determine share/ directory!\n"); } +#endif bool fgetline(FILE *f, std::string &buffer) { -- cgit v1.2.3 From 33e80b96c7aac6b93e6bee18572abf529f8cc1fa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Feb 2015 12:41:48 +0100 Subject: Added YosysJS wrapper --- kernel/driver.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 6df7cf2e8..69a7b8e15 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -93,7 +93,9 @@ void run(const char *command) const char *prompt() { - return create_prompt(yosys_get_design(), 0); + const char *p = create_prompt(yosys_get_design(), 0); + while (*p == '\n') p++; + return p; } #else /* EMSCRIPTEN */ -- cgit v1.2.3 From 3e5e9a38895b0ce45c185916fa946dec38ffbab3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Feb 2015 13:23:54 +0100 Subject: More YosysJS stuff --- kernel/driver.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index 69a7b8e15..d0ebdde77 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -73,6 +73,8 @@ int getopt(int argc, char **argv, const char *optstring) USING_YOSYS_NAMESPACE #ifdef EMSCRIPTEN +# include +# include extern "C" int main(int, char**); extern "C" void run(const char*); @@ -80,6 +82,8 @@ extern "C" const char *prompt(); int main(int, char**) { + mkdir("/work", 0777); + chdir("/work"); log_files.push_back(stdout); log_error_stderr = true; yosys_banner(); -- cgit v1.2.3 From f41378af8c463f2f49f3a04bcbc39419b83c9553 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 18 Feb 2015 14:54:22 +0100 Subject: Fixed clang (svn trunk) warnings --- kernel/register.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/register.h b/kernel/register.h index 71ab6ea6e..0a10483fd 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -71,7 +71,7 @@ struct Frontend : Pass std::string frontend_name; Frontend(std::string name, std::string short_help = "** document me **"); - virtual void run_register(); + virtual void run_register() YS_OVERRIDE; virtual ~Frontend(); virtual void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; @@ -87,7 +87,7 @@ struct Backend : Pass { std::string backend_name; Backend(std::string name, std::string short_help = "** document me **"); - virtual void run_register(); + virtual void run_register() YS_OVERRIDE; virtual ~Backend(); virtual void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL; virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; -- cgit v1.2.3 From e0e6d130cd083a8285ea2991629e0049023da234 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 19 Feb 2015 13:36:54 +0100 Subject: YosysJS stuff --- kernel/driver.cc | 17 ++++++++++++++++- kernel/log.cc | 19 +++++++++++++++---- kernel/log.h | 1 + 3 files changed, 32 insertions(+), 5 deletions(-) (limited to 'kernel') diff --git a/kernel/driver.cc b/kernel/driver.cc index d0ebdde77..dda27c6a6 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -78,6 +78,7 @@ USING_YOSYS_NAMESPACE extern "C" int main(int, char**); extern "C" void run(const char*); +extern "C" const char *errmsg(); extern "C" const char *prompt(); int main(int, char**) @@ -92,7 +93,21 @@ int main(int, char**) void run(const char *command) { - run_pass(command); + int selSize = GetSize(yosys_get_design()->selection_stack); + try { + log_last_error = "Internal error (see JavaScript console for details)"; + run_pass(command); + log_last_error = ""; + } catch (...) { + while (GetSize(yosys_get_design()->selection_stack) > selSize) + yosys_get_design()->selection_stack.pop_back(); + throw; + } +} + +const char *errmsg() +{ + return log_last_error.c_str(); } const char *prompt() diff --git a/kernel/log.cc b/kernel/log.cc index ada2cabb2..bf92daced 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -48,6 +48,7 @@ bool log_error_stderr = false; bool log_cmd_error_throw = false; bool log_quiet_warnings = false; int log_verbose_level; +string log_last_error; vector header_count; pool log_id_cache; @@ -173,6 +174,10 @@ void logv_warning(const char *format, va_list ap) void logv_error(const char *format, va_list ap) { +#ifdef EMSCRIPTEN + auto backup_log_files = log_files; +#endif + if (log_errfile != NULL) log_files.push_back(log_errfile); @@ -181,10 +186,16 @@ void logv_error(const char *format, va_list ap) if (f == stdout) f = stderr; - log("ERROR: "); - logv(format, ap); + log_last_error = vstringf(format, ap); + log("ERROR: %s", log_last_error.c_str()); log_flush(); + +#ifdef EMSCRIPTEN + log_files = backup_log_files; + throw 0; +#else exit(1); +#endif } void log(const char *format, ...) @@ -224,8 +235,8 @@ void log_cmd_error(const char *format, ...) va_start(ap, format); if (log_cmd_error_throw) { - log("ERROR: "); - logv(format, ap); + log_last_error = vstringf(format, ap); + log("ERROR: %s", log_last_error.c_str()); log_flush(); throw log_cmd_error_exception(); } diff --git a/kernel/log.h b/kernel/log.h index fd35c7bf7..16ad7b6c9 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -50,6 +50,7 @@ extern bool log_error_stderr; extern bool log_cmd_error_throw; extern bool log_quiet_warnings; extern int log_verbose_level; +extern string log_last_error; void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); -- cgit v1.2.3 From 4e6ca7760f801ce5ea16c6ea9be3ad4a86aa3b1d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Feb 2015 12:15:41 +0100 Subject: Replaced ezDefaultSAT with ezSatPtr --- kernel/register.cc | 14 ++++++++++++++ kernel/satgen.h | 32 +++++++++++++++++++++++++++++++- kernel/yosys.h | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/register.cc b/kernel/register.cc index cdba4c36f..af1cb77b5 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -18,6 +18,8 @@ */ #include "kernel/yosys.h" +#include "kernel/satgen.h" + #include #include #include @@ -691,6 +693,18 @@ struct EchoPass : public Pass { log("echo %s\n", echo_mode ? "on" : "off"); } } EchoPass; + +SatSolver *yosys_satsolver_list; +SatSolver *yosys_satsolver; + +struct MinisatSatSolver : public SatSolver { + MinisatSatSolver() : SatSolver("minisat") { + yosys_satsolver = this; + } + virtual ezSAT *create() YS_OVERRIDE { + return new ezMiniSAT(); + } +} MinisatSatSolver; YOSYS_NAMESPACE_END diff --git a/kernel/satgen.h b/kernel/satgen.h index 2f5efe674..093d248d4 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -29,7 +29,37 @@ YOSYS_NAMESPACE_BEGIN -typedef ezMiniSAT ezDefaultSAT; +// defined in kernel/register.cc +extern struct SatSolver *yosys_satsolver_list; +extern struct SatSolver *yosys_satsolver; + +struct SatSolver +{ + string name; + SatSolver *next; + virtual ezSAT *create() = 0; + + SatSolver(string name) : name(name) { + next = yosys_satsolver_list; + yosys_satsolver_list = this; + } + + virtual ~SatSolver() { + auto p = &yosys_satsolver_list; + while (*p) { + if (*p == this) + *p = next; + else + p = &(*p)->next; + } + if (yosys_satsolver == this) + yosys_satsolver = yosys_satsolver_list; + } +}; + +struct ezSatPtr : public std::unique_ptr { + ezSatPtr() : unique_ptr(yosys_satsolver->create()) { } +}; struct SatGen { diff --git a/kernel/yosys.h b/kernel/yosys.h index 47275ecd4..467d2074f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -49,6 +49,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 9ae21263f0de0c0011c7de290af3600ddeb51a34 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 24 Feb 2015 22:31:30 +0100 Subject: Some cleanups in "clean" --- kernel/rtlil.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'kernel') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index dd40e2fba..1d0008f9d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -807,6 +807,14 @@ struct RTLIL::Design bool selected_module(RTLIL::Module *mod) const; bool selected_whole_module(RTLIL::Module *mod) const; + RTLIL::Selection &selection() { + return selection_stack.back(); + } + + const RTLIL::Selection &selection() const { + return selection_stack.back(); + } + bool full_selection() const { return selection_stack.back().full_selection; } -- cgit v1.2.3 From b005eedf369bc60ce5f7cba9a0db4694f22a360f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 26 Feb 2015 18:04:10 +0100 Subject: Added $assume cell type --- kernel/celltypes.h | 1 + kernel/rtlil.cc | 7 +++++++ kernel/satgen.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) (limited to 'kernel') diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 57bcde471..533c370fe 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -114,6 +114,7 @@ struct CellTypes setup_type("$fa", {A, B, C}, {X, Y}, true); setup_type("$assert", {A, EN}, pool(), true); + setup_type("$assume", {A, EN}, pool(), true); setup_type("$equiv", {A, B}, {Y}, true); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c10261b23..adf89a245 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -941,6 +941,13 @@ 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); diff --git a/kernel/satgen.h b/kernel/satgen.h index 093d248d4..719b0a83a 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -68,6 +68,7 @@ struct SatGen std::string prefix; SigPool initial_state; std::map asserts_a, asserts_en; + std::map assumes_a, assumes_en; std::map> imported_signals; bool ignore_div_by_zero; bool model_undef; @@ -161,6 +162,13 @@ struct SatGen sig_en = asserts_en[pf]; } + void getAssumes(RTLIL::SigSpec &sig_a, RTLIL::SigSpec &sig_en, int timestep = -1) + { + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + sig_a = assumes_a[pf]; + sig_en = assumes_en[pf]; + } + int importAsserts(int timestep = -1) { std::vector check_bits, enable_bits; @@ -175,6 +183,20 @@ struct SatGen return ez->vec_reduce_and(ez->vec_or(check_bits, ez->vec_not(enable_bits))); } + int importAssumes(int timestep = -1) + { + std::vector check_bits, enable_bits; + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + if (model_undef) { + check_bits = ez->vec_and(ez->vec_not(importUndefSigSpec(assumes_a[pf], timestep)), importDefSigSpec(assumes_a[pf], timestep)); + enable_bits = ez->vec_and(ez->vec_not(importUndefSigSpec(assumes_en[pf], timestep)), importDefSigSpec(assumes_en[pf], timestep)); + } else { + check_bits = importDefSigSpec(assumes_a[pf], timestep); + enable_bits = importDefSigSpec(assumes_en[pf], timestep); + } + return ez->vec_reduce_and(ez->vec_or(check_bits, ez->vec_not(enable_bits))); + } + int signals_eq(RTLIL::SigSpec lhs, RTLIL::SigSpec rhs, int timestep_lhs = -1, int timestep_rhs = -1) { if (timestep_rhs < 0) @@ -1234,6 +1256,14 @@ struct SatGen return true; } + if (cell->type == "$assume") + { + std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); + assumes_a[pf].append((*sigmap)(cell->getPort("\\A"))); + assumes_en[pf].append((*sigmap)(cell->getPort("\\EN"))); + return true; + } + // Unsupported internal cell types: $pow $lut // .. and all sequential cells except $dff and $_DFF_[NP]_ return false; -- cgit v1.2.3 From 68bbb15214e0048e4f32e0c38e192eab62dea7bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 22 Mar 2015 11:03:56 +0100 Subject: Fixed detection of absolute paths in ABC for win32 --- kernel/yosys.cc | 9 +++++++++ kernel/yosys.h | 1 + 2 files changed, 10 insertions(+) (limited to 'kernel') diff --git a/kernel/yosys.cc b/kernel/yosys.cc index b54836621..884b2c59b 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -376,6 +376,15 @@ bool check_file_exists(std::string filename, bool is_exec) } #endif +bool is_absolute_path(std::string filename) +{ +#ifdef _WIN32 + return filename[0] == '/' || filename[0] == '\\' || (filename[0] != 0 && filename[1] == ':'); +#else + return filename[0] == '/'; +#endif +} + void remove_directory(std::string dirname) { #ifdef _WIN32 diff --git a/kernel/yosys.h b/kernel/yosys.h index 467d2074f..231dd4de6 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -210,6 +210,7 @@ int run_command(const std::string &command, std::function int GetSize(const T &obj) { return obj.size(); } -- cgit v1.2.3