summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2019-03-28 23:35:03 +0100
committerRuben Undheim <ruben.undheim@gmail.com>2019-03-28 23:35:03 +0100
commitff5734b20220e6fb4a3913cf5279ed94bb5156ea (patch)
tree4c438282926d7bac304ad3ad6ad89523c4c1d784 /kernel
parentdb3c67fd6e140893450a44870ee9a75dd1f48b27 (diff)
Imported GIT HEAD: 0.8+20190328git32bd0f2
Diffstat (limited to 'kernel')
-rw-r--r--kernel/celltypes.h66
-rw-r--r--kernel/consteval.h9
-rw-r--r--kernel/driver.cc18
-rw-r--r--kernel/hashlib.h6
-rw-r--r--kernel/log.cc4
-rw-r--r--kernel/log.h6
-rw-r--r--kernel/register.cc2
-rw-r--r--kernel/rtlil.cc34
-rw-r--r--kernel/rtlil.h78
-rw-r--r--kernel/yosys.cc49
10 files changed, 220 insertions, 52 deletions
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index fcc4fcc4..ae88f4aa 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -82,6 +82,27 @@ struct CellTypes
void setup_internals()
{
+ setup_internals_eval();
+
+ IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y";
+
+ setup_type("$tribuf", {A, EN}, {Y}, true);
+
+ setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true);
+ setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true);
+ setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true);
+ setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true);
+ setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true);
+ setup_type("$equiv", {A, B}, {Y}, true);
+ }
+
+ void setup_internals_eval()
+ {
std::vector<RTLIL::IdString> unary_ops = {
"$not", "$pos", "$neg",
"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
@@ -111,20 +132,6 @@ struct CellTypes
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("$tribuf", {A, EN}, {Y}, true);
-
- setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$equiv", {A, B}, {Y}, true);
}
void setup_internals_mem()
@@ -154,10 +161,19 @@ struct CellTypes
void setup_stdcells()
{
+ setup_stdcells_eval();
+
+ IdString A = "\\A", E = "\\E", Y = "\\Y";
+
+ setup_type("$_TBUF_", {A, E}, {Y}, true);
+ }
+
+ void setup_stdcells_eval()
+ {
IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D";
IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H";
IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L";
- IdString M = "\\I", N = "\\N", O = "\\O", P = "\\P";
+ IdString M = "\\M", N = "\\N", O = "\\O", P = "\\P";
IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V";
IdString Y = "\\Y";
@@ -179,7 +195,6 @@ struct CellTypes
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);
- setup_type("$_TBUF_", {A, E}, {Y}, true);
}
void setup_stdcells_mem()
@@ -257,7 +272,7 @@ struct CellTypes
return v;
}
- static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
+ static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
{
if (type == "$sshr" && !signed1)
type = "$shr";
@@ -329,10 +344,15 @@ struct CellTypes
if (type == "$_ORNOT_")
return const_or(arg1, eval_not(arg2), false, false, 1);
+ if (errp != nullptr) {
+ *errp = true;
+ return State::Sm;
+ }
+
log_abort();
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
{
if (cell->type == "$slice") {
RTLIL::Const ret;
@@ -415,10 +435,10 @@ struct CellTypes
bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1;
- return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len);
+ return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
{
if (cell->type.in("$mux", "$pmux", "$_MUX_")) {
RTLIL::Const ret = arg1;
@@ -436,10 +456,10 @@ struct CellTypes
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
log_assert(arg3.bits.size() == 0);
- return eval(cell, arg1, arg2);
+ return eval(cell, arg1, arg2, errp);
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
{
if (cell->type == "$_AOI4_")
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
@@ -447,7 +467,7 @@ struct CellTypes
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
log_assert(arg4.bits.size() == 0);
- return eval(cell, arg1, arg2, arg3);
+ return eval(cell, arg1, arg2, arg3, errp);
}
};
diff --git a/kernel/consteval.h b/kernel/consteval.h
index 0229f504..154373a8 100644
--- a/kernel/consteval.h
+++ b/kernel/consteval.h
@@ -321,8 +321,13 @@ struct ConstEval
if (sig_d.size() > 0 && !eval(sig_d, undef, cell))
return false;
- set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(),
- sig_c.as_const(), sig_d.as_const()));
+ bool eval_err = false;
+ RTLIL::Const eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err);
+
+ if (eval_err)
+ return false;
+
+ set(sig_y, eval_ret);
}
return true;
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 17864110..a0bb7e60 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -179,6 +179,7 @@ int main(int argc, char **argv)
{
std::string frontend_command = "auto";
std::string backend_command = "auto";
+ std::vector<std::string> vlog_defines;
std::vector<std::string> passes_commands;
std::vector<std::string> plugin_filenames;
std::string output_filename = "";
@@ -268,7 +269,10 @@ int main(int argc, char **argv)
printf(" -A\n");
printf(" will call abort() at the end of the script. for debugging\n");
printf("\n");
- printf(" -D <header_id>[:<filename>]\n");
+ printf(" -D <macro>[=<value>]\n");
+ printf(" set the specified Verilog define (via \"read -define\")\n");
+ printf("\n");
+ printf(" -P <header_id>[:<filename>]\n");
printf(" dump the design when printing the specified log header to a file.\n");
printf(" yosys_dump_<header_id>.il is used as filename if none is specified.\n");
printf(" Use 'ALL' as <header_id> to dump at every header.\n");
@@ -307,7 +311,7 @@ int main(int argc, char **argv)
}
int opt;
- while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:E:")) != -1)
+ while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:")) != -1)
{
switch (opt)
{
@@ -408,6 +412,9 @@ int main(int argc, char **argv)
std::regex_constants::egrep));
break;
case 'D':
+ vlog_defines.push_back(optarg);
+ break;
+ case 'P':
{
auto args = split_tokens(optarg, ":");
if (!args.empty() && args[0] == "ALL") {
@@ -473,6 +480,13 @@ int main(int argc, char **argv)
shell(yosys_design);
}
+ if (!vlog_defines.empty()) {
+ std::string vdef_cmd = "read -define";
+ for (auto vdef : vlog_defines)
+ vdef_cmd += " " + vdef;
+ run_pass(vdef_cmd);
+ }
+
while (optind < argc)
run_frontend(argv[optind++], frontend_command, output_filename == "-" ? &backend_command : NULL);
diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index df534ec1..e7cb312e 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -557,9 +557,11 @@ public:
void clear() { hashtable.clear(); entries.clear(); }
iterator begin() { return iterator(this, int(entries.size())-1); }
+ iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
iterator end() { return iterator(nullptr, -1); }
const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
+ const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
const_iterator end() const { return const_iterator(nullptr, -1); }
};
@@ -881,9 +883,11 @@ public:
void clear() { hashtable.clear(); entries.clear(); }
iterator begin() { return iterator(this, int(entries.size())-1); }
+ iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
iterator end() { return iterator(nullptr, -1); }
const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
+ const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
const_iterator end() const { return const_iterator(nullptr, -1); }
};
@@ -952,6 +956,7 @@ public:
void clear() { database.clear(); }
const_iterator begin() const { return database.begin(); }
+ const_iterator element(int n) const { return database.element(n); }
const_iterator end() const { return database.end(); }
};
@@ -1051,6 +1056,7 @@ public:
void clear() { database.clear(); parents.clear(); }
const_iterator begin() const { return database.begin(); }
+ const_iterator element(int n) const { return database.element(n); }
const_iterator end() const { return database.end(); }
};
diff --git a/kernel/log.cc b/kernel/log.cc
index 0ee2170a..400a549d 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -196,7 +196,11 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap)
if (log_hdump.count(header_id) && design != nullptr)
for (auto &filename : log_hdump.at(header_id)) {
log("Dumping current design to '%s'.\n", filename.c_str());
+ if (yosys_xtrace)
+ IdString::xtrace_db_dump();
Pass::call(design, {"dump", "-o", filename});
+ if (yosys_xtrace)
+ log("#X# -- end of dump --\n");
}
if (pop_errfile)
diff --git a/kernel/log.h b/kernel/log.h
index 0b4905c3..75993902 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -94,7 +94,9 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
const char *log_const(const RTLIL::Const &value, bool autoint = true);
const char *log_id(RTLIL::IdString id);
-template<typename T> static inline const char *log_id(T *obj) {
+template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {
+ if (nullstr && obj == nullptr)
+ return nullstr;
return log_id(obj->name);
}
@@ -195,7 +197,7 @@ struct PerformanceTimer
t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL;
return t;
# else
-# error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?).
+# error "Don't know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?)."
# endif
}
diff --git a/kernel/register.cc b/kernel/register.cc
index 402a5b3e..64956401 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -86,6 +86,8 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
void Pass::post_execute(Pass::pre_post_exec_state_t state)
{
+ IdString::checkpoint();
+
int64_t time_ns = PerformanceTimer::query() - state.begin_ns;
runtime_ns += time_ns;
current_pass = state.parent_pass;
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index a4fa2cf0..b3214579 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -33,6 +33,8 @@ std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<char*> RTLIL::IdString::global_id_storage_;
dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_;
std::vector<int> RTLIL::IdString::global_free_idx_list_;
+int RTLIL::IdString::last_created_idx_[8];
+int RTLIL::IdString::last_created_idx_ptr_;
RTLIL::Const::Const()
{
@@ -639,6 +641,11 @@ RTLIL::Module::~Module()
delete it->second;
}
+void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
+{
+ log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name));
+}
+
RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail)
{
if (mayfail)
@@ -646,6 +653,14 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLI
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
}
+
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, dict<RTLIL::IdString, RTLIL::Module*>, dict<RTLIL::IdString, RTLIL::IdString>, bool mayfail)
+{
+ if (mayfail)
+ return RTLIL::IdString();
+ log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
+}
+
size_t RTLIL::Module::count_id(RTLIL::IdString id)
{
return wires_.count(id) + memories.count(id) + cells_.count(id) + processes.count(id);
@@ -745,7 +760,7 @@ namespace {
void check()
{
- if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" ||
+ if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || cell->type.substr(0,10) == "$fmcombine" ||
cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:")
return;
@@ -2345,7 +2360,7 @@ void RTLIL::Cell::check()
void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
{
- if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" ||
+ if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || type.substr(0,10) == "$fmcombine" ||
type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
return;
@@ -2397,6 +2412,9 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
if (connections_.count("\\Y"))
parameters["\\Y_WIDTH"] = GetSize(connections_["\\Y"]);
+ if (connections_.count("\\Q"))
+ parameters["\\WIDTH"] = GetSize(connections_["\\Q"]);
+
check();
}
@@ -3219,7 +3237,7 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
remove(width, width_ - width);
if (width_ < width) {
- RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::S0;
+ RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::Sx;
if (!is_signed)
padding = RTLIL::State::S0;
while (width_ < width)
@@ -3780,6 +3798,11 @@ RTLIL::CaseRule::~CaseRule()
delete *it;
}
+bool RTLIL::CaseRule::empty() const
+{
+ return actions.empty() && switches.empty();
+}
+
RTLIL::CaseRule *RTLIL::CaseRule::clone() const
{
RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
@@ -3796,6 +3819,11 @@ RTLIL::SwitchRule::~SwitchRule()
delete *it;
}
+bool RTLIL::SwitchRule::empty() const
+{
+ return cases.empty();
+}
+
RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
{
RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 027faf41..52496e70 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -76,6 +76,9 @@ namespace RTLIL
struct IdString
{
+ #undef YOSYS_XTRACE_GET_PUT
+ #undef YOSYS_SORT_ID_FREE_LIST
+
// the global id string cache
static struct destruct_guard_t {
@@ -89,9 +92,43 @@ namespace RTLIL
static dict<char*, int, hash_cstr_ops> global_id_index_;
static std::vector<int> global_free_idx_list_;
+ static int last_created_idx_ptr_;
+ static int last_created_idx_[8];
+
+ static inline void xtrace_db_dump()
+ {
+ #ifdef YOSYS_XTRACE_GET_PUT
+ for (int idx = 0; idx < GetSize(global_id_storage_); idx++)
+ {
+ if (global_id_storage_.at(idx) == nullptr)
+ log("#X# DB-DUMP index %d: FREE\n", idx);
+ else
+ log("#X# DB-DUMP index %d: '%s' (ref %d)\n", idx, global_id_storage_.at(idx), global_refcount_storage_.at(idx));
+ }
+ #endif
+ }
+
+ static inline void checkpoint()
+ {
+ last_created_idx_ptr_ = 0;
+ for (int i = 0; i < 8; i++) {
+ if (last_created_idx_[i])
+ put_reference(last_created_idx_[i]);
+ last_created_idx_[i] = 0;
+ }
+ #ifdef YOSYS_SORT_ID_FREE_LIST
+ std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>());
+ #endif
+ }
+
static inline int get_reference(int idx)
{
global_refcount_storage_.at(idx)++;
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace) {
+ log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ }
+ #endif
return idx;
}
@@ -107,6 +144,11 @@ namespace RTLIL
auto it = global_id_index_.find((char*)p);
if (it != global_id_index_.end()) {
global_refcount_storage_.at(it->second)++;
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace) {
+ log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second));
+ }
+ #endif
return it->second;
}
@@ -124,16 +166,22 @@ namespace RTLIL
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 (last_created_idx_[last_created_idx_ptr_])
+ put_reference(last_created_idx_[last_created_idx_ptr_]);
+ last_created_idx_[last_created_idx_ptr_] = idx;
+ get_reference(last_created_idx_[last_created_idx_ptr_]);
+ last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7;
if (yosys_xtrace) {
log("#X# New IdString '%s' with index %d.\n", p, idx);
log_backtrace("-X- ", yosys_xtrace-1);
}
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace) {
+ log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ }
+ #endif
return idx;
}
@@ -144,6 +192,12 @@ namespace RTLIL
if (!destruct_guard.ok)
return;
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace) {
+ log("#X# PUT '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ }
+ #endif
+
log_assert(global_refcount_storage_.at(idx) > 0);
if (--global_refcount_storage_.at(idx) != 0)
@@ -492,6 +546,14 @@ struct RTLIL::Const
return ret;
}
+ void extu(int width) {
+ bits.resize(width, RTLIL::State::S0);
+ }
+
+ void exts(int width) {
+ bits.resize(width, bits.empty() ? RTLIL::State::Sx : bits.back());
+ }
+
inline unsigned int hash() const {
unsigned int h = mkhash_init;
for (auto b : bits)
@@ -907,7 +969,9 @@ public:
Module();
virtual ~Module();
virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail = false);
+ virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail = false);
virtual size_t count_id(RTLIL::IdString id);
+ virtual void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces);
virtual void sort();
virtual void check();
@@ -1225,6 +1289,8 @@ struct RTLIL::CaseRule
~CaseRule();
void optimize();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::CaseRule *clone() const;
};
@@ -1236,6 +1302,8 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
~SwitchRule();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
RTLIL::SwitchRule *clone() const;
};
@@ -1276,7 +1344,7 @@ inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
return wire ? (offset < other.offset) : (data < other.data);
if (wire != nullptr && other.wire != nullptr)
return wire->name < other.wire->name;
- return wire < other.wire;
+ return (wire != nullptr) < (other.wire != nullptr);
}
inline bool RTLIL::SigBit::operator==(const RTLIL::SigBit &other) const {
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index ad032899..450e4e4c 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -33,7 +33,7 @@
# include <dlfcn.h>
#endif
-#ifdef _WIN32
+#if defined(_WIN32)
# include <windows.h>
# include <io.h>
#elif defined(__APPLE__)
@@ -41,13 +41,15 @@
# include <unistd.h>
# include <dirent.h>
# include <sys/stat.h>
-# include <glob.h>
#else
# include <unistd.h>
# include <dirent.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <sys/stat.h>
+#endif
+
+#if !defined(_WIN32) && defined(YOSYS_ENABLE_GLOB)
# include <glob.h>
#endif
@@ -166,7 +168,7 @@ std::string vstringf(const char *fmt, va_list ap)
std::string string;
char *str = NULL;
-#if defined(_WIN32 )|| defined(__CYGWIN__)
+#if defined(_WIN32 )|| defined(__CYGWIN__)
int sz = 64, rc;
while (1) {
va_list apc;
@@ -216,12 +218,18 @@ std::string next_token(std::string &text, const char *sep, bool long_strings)
if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') {
string sep_string = sep;
- for (size_t i = pos_begin+1; i < text.size(); i++)
+ for (size_t i = pos_begin+1; i < text.size(); i++) {
if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) {
std::string token = text.substr(pos_begin, i-pos_begin+1);
text = text.substr(i+1);
return token;
}
+ if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) {
+ std::string token = text.substr(pos_begin, i-pos_begin+1);
+ text = text.substr(i+2);
+ return token + ";";
+ }
+ }
}
size_t pos_end = text.find_first_of(sep, pos_begin);
@@ -564,7 +572,7 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern)
{
std::vector<std::string> results;
-#ifdef _WIN32
+#if defined(_WIN32) || !defined(YOSYS_ENABLE_GLOB)
results.push_back(filename_pattern);
#else
glob_t globbuf;
@@ -637,8 +645,9 @@ extern Tcl_Interp *yosys_get_tcl_interp()
struct TclPass : public Pass {
TclPass() : Pass("tcl", "execute a TCL script file") { }
void help() YS_OVERRIDE {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" tcl <filename>\n");
+ log(" tcl <filename> [args]\n");
log("\n");
log("This command executes the tcl commands in the specified file.\n");
log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n");
@@ -648,14 +657,24 @@ struct TclPass : public Pass {
log("'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'\n");
log("in order to avoid a name collision with the built in commands.\n");
log("\n");
+ log("If any arguments are specified, these arguments are provided to the script via\n");
+ log("the standard $argc and $argv variables.\n");
+ log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
+ void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE {
if (args.size() < 2)
log_cmd_error("Missing script file.\n");
- if (args.size() > 2)
- extra_args(args, 1, design, false);
- if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK)
- log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp()));
+
+ std::vector<Tcl_Obj*> script_args;
+ for (auto it = args.begin() + 2; it != args.end(); ++it)
+ script_args.push_back(Tcl_NewStringObj((*it).c_str(), (*it).size()));
+
+ Tcl_Interp *interp = yosys_get_tcl_interp();
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argc", 4), NULL, Tcl_NewIntObj(script_args.size()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv", 4), NULL, Tcl_NewListObj(script_args.size(), script_args.data()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv0", 5), NULL, Tcl_NewStringObj(args[1].c_str(), args[1].size()), 0);
+ if (Tcl_EvalFile(interp, args[1].c_str()) != TCL_OK)
+ log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
}
} TclPass;
#endif
@@ -733,7 +752,7 @@ std::string proc_self_dirname()
return "/";
}
#else
- #error Dont know how to determine process executable base path!
+ #error "Don't know how to determine process executable base path!"
#endif
#ifdef EMSCRIPTEN
@@ -799,7 +818,7 @@ static void handle_label(std::string &command, bool &from_to_active, const std::
while (pos < GetSize(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n')
label += command[pos++];
- if (label.back() == ':' && GetSize(label) > 1)
+ if (GetSize(label) > 1 && label.back() == ':')
{
label = label.substr(0, GetSize(label)-1);
command = command.substr(pos);
@@ -821,7 +840,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command = "verilog";
else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv")
command = "verilog -sv";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".vhd")
+ else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd")
command = "vhdl";
else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif")
command = "blif";
@@ -833,7 +852,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command = "ilang";
else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys")
command = "script";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".tcl")
+ else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl")
command = "tcl";
else if (filename == "-")
command = "script";