summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2019-10-18 19:56:51 +0000
committerRuben Undheim <ruben.undheim@gmail.com>2019-10-18 19:56:51 +0000
commit1f6bb85359149a016811e7e7fef980c3d45211e7 (patch)
tree749672f9a104cbfb25bb02acad6cb731724b9d56 /kernel
parentff5734b20220e6fb4a3913cf5279ed94bb5156ea (diff)
New upstream version 0.9
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cellaigs.cc2
-rw-r--r--kernel/celltypes.h7
-rw-r--r--kernel/cost.h4
-rw-r--r--kernel/driver.cc20
-rw-r--r--kernel/log.cc29
-rw-r--r--kernel/log.h44
-rw-r--r--kernel/register.cc2
-rw-r--r--kernel/rtlil.cc243
-rw-r--r--kernel/rtlil.h102
-rw-r--r--kernel/yosys.cc64
-rw-r--r--kernel/yosys.h20
11 files changed, 504 insertions, 33 deletions
diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc
index 5fd76afe..26c625f8 100644
--- a/kernel/cellaigs.cc
+++ b/kernel/cellaigs.cc
@@ -453,7 +453,7 @@ Aig::Aig(Cell *cell)
int B = mk.inport("\\B");
int C = mk.inport("\\C");
int D = mk.inport("\\D");
- int Y = mk.nand_gate(mk.nor_gate(A, B), mk.nor_gate(C, D));
+ int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
mk.outport(Y, "\\Y");
goto optimize;
}
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index ae88f4aa..4e91eddd 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -85,6 +85,8 @@ struct CellTypes
setup_internals_eval();
IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y";
+ IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT";
+ IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST";
setup_type("$tribuf", {A, EN}, {Y}, true);
@@ -99,6 +101,9 @@ struct CellTypes
setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true);
setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true);
setup_type("$equiv", {A, B}, {Y}, true);
+ setup_type("$specify2", {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
+ setup_type("$specify3", {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
+ setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
}
void setup_internals_eval()
@@ -464,7 +469,7 @@ struct CellTypes
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));
if (cell->type == "$_OAI4_")
- return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
+ return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));
log_assert(arg4.bits.size() == 0);
return eval(cell, arg1, arg2, arg3, errp);
diff --git a/kernel/cost.h b/kernel/cost.h
index e795b571..41a09eb6 100644
--- a/kernel/cost.h
+++ b/kernel/cost.h
@@ -26,7 +26,7 @@ YOSYS_NAMESPACE_BEGIN
int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
-int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
+inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
{
static dict<RTLIL::IdString, int> gate_cost = {
@@ -76,7 +76,7 @@ int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const
return 1;
}
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
+inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
{
return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
}
diff --git a/kernel/driver.cc b/kernel/driver.cc
index a0bb7e60..f273057d 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -110,6 +110,10 @@ int main(int argc, char **argv)
log_error_stderr = true;
yosys_banner();
yosys_setup();
+#ifdef WITH_PYTHON
+ PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
+ PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
+#endif
if (argc == 2)
{
@@ -291,6 +295,9 @@ int main(int argc, char **argv)
printf(" -E <depsfile>\n");
printf(" write a Makefile dependencies file with in- and output file names\n");
printf("\n");
+ printf(" -g\n");
+ printf(" globally enable debug log messages\n");
+ printf("\n");
printf(" -V\n");
printf(" print version information and exit\n");
printf("\n");
@@ -311,7 +318,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:P:E:")) != -1)
+ while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:")) != -1)
{
switch (opt)
{
@@ -336,6 +343,9 @@ int main(int argc, char **argv)
case 'S':
passes_commands.push_back("synth");
break;
+ case 'g':
+ log_force_debug++;
+ break;
case 'm':
plugin_filenames.push_back(optarg);
break;
@@ -469,6 +479,10 @@ int main(int argc, char **argv)
#endif
yosys_setup();
+#ifdef WITH_PYTHON
+ PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
+ PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
+#endif
log_error_atexit = yosys_atexit;
for (auto &fn : plugin_filenames)
@@ -515,13 +529,13 @@ int main(int argc, char **argv)
log_error("Can't open dependencies file for writing: %s\n", strerror(errno));
bool first = true;
for (auto fn : yosys_output_files) {
- fprintf(f, "%s%s", first ? "" : " ", fn.c_str());
+ fprintf(f, "%s%s", first ? "" : " ", escape_filename_spaces(fn).c_str());
first = false;
}
fprintf(f, ":");
for (auto fn : yosys_input_files) {
if (yosys_output_files.count(fn) == 0)
- fprintf(f, " %s", fn.c_str());
+ fprintf(f, " %s", escape_filename_spaces(fn).c_str());
}
fprintf(f, "\n");
}
diff --git a/kernel/log.cc b/kernel/log.cc
index 400a549d..a7820950 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -56,6 +56,10 @@ int log_verbose_level;
string log_last_error;
void (*log_error_atexit)() = NULL;
+int log_make_debug = 0;
+int log_force_debug = 0;
+int log_debug_suppressed = 0;
+
vector<int> header_count;
pool<RTLIL::IdString> log_id_cache;
vector<shared_str> string_buf;
@@ -92,6 +96,9 @@ void logv(const char *format, va_list ap)
format++;
}
+ if (log_make_debug && !ys_debug(1))
+ return;
+
std::string str = vstringf(format, ap);
if (str.empty())
@@ -223,6 +230,9 @@ static void logv_warning_with_prefix(const char *prefix,
}
else
{
+ int bak_log_make_debug = log_make_debug;
+ log_make_debug = 0;
+
for (auto &re : log_werror_regexes)
if (std::regex_search(message, re))
log_error("%s", message.c_str());
@@ -247,6 +257,7 @@ static void logv_warning_with_prefix(const char *prefix,
}
log_warnings_count++;
+ log_make_debug = bak_log_make_debug;
}
}
@@ -266,11 +277,22 @@ void log_file_warning(const std::string &filename, int lineno,
va_list ap;
va_start(ap, format);
std::string prefix = stringf("%s:%d: Warning: ",
- filename.c_str(), lineno);
+ filename.c_str(), lineno);
logv_warning_with_prefix(prefix.c_str(), format, ap);
va_end(ap);
}
+void log_file_info(const std::string &filename, int lineno,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ std::string fmt = stringf("%s:%d: Info: %s",
+ filename.c_str(), lineno, format);
+ logv(fmt.c_str(), ap);
+ va_end(ap);
+}
+
YS_ATTRIBUTE(noreturn)
static void logv_error_with_prefix(const char *prefix,
const char *format, va_list ap)
@@ -278,6 +300,9 @@ static void logv_error_with_prefix(const char *prefix,
#ifdef EMSCRIPTEN
auto backup_log_files = log_files;
#endif
+ int bak_log_make_debug = log_make_debug;
+ log_make_debug = 0;
+ log_suppressed();
if (log_errfile != NULL)
log_files.push_back(log_errfile);
@@ -291,6 +316,8 @@ static void logv_error_with_prefix(const char *prefix,
log("%s%s", prefix, log_last_error.c_str());
log_flush();
+ log_make_debug = bak_log_make_debug;
+
if (log_error_atexit)
log_error_atexit();
diff --git a/kernel/log.h b/kernel/log.h
index 75993902..3e1facae 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -64,6 +64,10 @@ extern int log_verbose_level;
extern string log_last_error;
extern void (*log_error_atexit)();
+extern int log_make_debug;
+extern int log_force_debug;
+extern int log_debug_suppressed;
+
void logv(const char *format, va_list ap);
void logv_header(RTLIL::Design *design, const char *format, va_list ap);
void logv_warning(const char *format, va_list ap);
@@ -76,12 +80,52 @@ void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
// Log with filename to report a problem in a source file.
void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
+void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn);
void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4), noreturn);
YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn);
+#ifndef NDEBUG
+static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
+# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0)
+#else
+static inline bool ys_debug(int n = 0) { return false; }
+# define log_debug(_fmt, ...) do { } while (0)
+#endif
+
+static inline void log_suppressed() {
+ if (log_debug_suppressed && !log_make_debug) {
+ log("<suppressed ~%d debug messages>\n", log_debug_suppressed);
+ log_debug_suppressed = 0;
+ }
+}
+
+struct LogMakeDebugHdl {
+ bool status = false;
+ LogMakeDebugHdl(bool start_on = false) {
+ if (start_on)
+ on();
+ }
+ ~LogMakeDebugHdl() {
+ off();
+ }
+ void on() {
+ if (status) return;
+ status=true;
+ log_make_debug++;
+ }
+ void off_silent() {
+ if (!status) return;
+ status=false;
+ log_make_debug--;
+ }
+ void off() {
+ off_silent();
+ }
+};
+
void log_spacer();
void log_push();
void log_pop();
diff --git a/kernel/register.cc b/kernel/register.cc
index 64956401..26da96b9 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -87,6 +87,7 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
void Pass::post_execute(Pass::pre_post_exec_state_t state)
{
IdString::checkpoint();
+ log_suppressed();
int64_t time_ns = PerformanceTimer::query() - state.begin_ns;
runtime_ns += time_ns;
@@ -544,6 +545,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
}
filename = arg;
+ rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
yosys_output_files.insert(filename);
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index b3214579..a09f4a0d 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -76,6 +76,13 @@ RTLIL::Const::Const(const std::vector<bool> &bits)
this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0);
}
+RTLIL::Const::Const(const RTLIL::Const &c)
+{
+ flags = c.flags;
+ for (auto b : c.bits)
+ this->bits.push_back(b);
+}
+
bool RTLIL::Const::operator <(const RTLIL::Const &other) const
{
if (bits.size() != other.bits.size())
@@ -207,16 +214,23 @@ bool RTLIL::Const::is_fully_undef() const
return true;
}
-void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id)
+void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)
{
- attributes[id] = RTLIL::Const(1);
+ if (value)
+ attributes[id] = RTLIL::Const(1);
+ else {
+ const auto it = attributes.find(id);
+ if (it != attributes.end())
+ attributes.erase(it);
+ }
}
bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
{
- if (attributes.count(id) == 0)
+ const auto it = attributes.find(id);
+ if (it == attributes.end())
return false;
- return attributes.at(id).as_bool();
+ return it->second.as_bool();
}
void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
@@ -360,6 +374,10 @@ RTLIL::Design::Design()
refcount_modules_ = 0;
selection_stack.push_back(RTLIL::Selection());
+
+#ifdef WITH_PYTHON
+ RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
+#endif
}
RTLIL::Design::~Design()
@@ -370,7 +388,18 @@ RTLIL::Design::~Design()
delete n;
for (auto n : verilog_globals)
delete n;
+#ifdef WITH_PYTHON
+ RTLIL::Design::get_all_designs()->erase(hashidx_);
+#endif
+}
+
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Design*> all_designs;
+std::map<unsigned int, RTLIL::Design*> *RTLIL::Design::get_all_designs(void)
+{
+ return &all_designs;
}
+#endif
RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules()
{
@@ -589,7 +618,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
+ if (selected_module(it.first) && !it.second->get_blackbox_attribute())
result.push_back(it.second);
return result;
}
@@ -599,7 +628,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_whole_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
+ if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute())
result.push_back(it.second);
return result;
}
@@ -609,7 +638,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (it.second->get_bool_attribute("\\blackbox"))
+ if (it.second->get_blackbox_attribute())
continue;
else if (selected_whole_module(it.first))
result.push_back(it.second);
@@ -627,6 +656,10 @@ RTLIL::Module::Module()
design = nullptr;
refcount_wires_ = 0;
refcount_cells_ = 0;
+
+#ifdef WITH_PYTHON
+ RTLIL::Module::get_all_modules()->insert(std::pair<unsigned int, RTLIL::Module*>(hashidx_, this));
+#endif
}
RTLIL::Module::~Module()
@@ -639,6 +672,41 @@ RTLIL::Module::~Module()
delete it->second;
for (auto it = processes.begin(); it != processes.end(); ++it)
delete it->second;
+#ifdef WITH_PYTHON
+ RTLIL::Module::get_all_modules()->erase(hashidx_);
+#endif
+}
+
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Module*> all_modules;
+std::map<unsigned int, RTLIL::Module*> *RTLIL::Module::get_all_modules(void)
+{
+ return &all_modules;
+}
+#endif
+
+void RTLIL::Module::makeblackbox()
+{
+ pool<RTLIL::Wire*> delwires;
+
+ for (auto it = wires_.begin(); it != wires_.end(); ++it)
+ if (!it->second->port_input && !it->second->port_output)
+ delwires.insert(it->second);
+
+ for (auto it = memories.begin(); it != memories.end(); ++it)
+ delete it->second;
+ memories.clear();
+
+ for (auto it = cells_.begin(); it != cells_.end(); ++it)
+ delete it->second;
+ cells_.clear();
+
+ for (auto it = processes.begin(); it != processes.end(); ++it)
+ delete it->second;
+ processes.clear();
+
+ remove(delwires);
+ set_bool_attribute("\\blackbox");
}
void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
@@ -1130,6 +1198,46 @@ namespace {
return;
}
+ if (cell->type.in("$specify2", "$specify3")) {
+ param_bool("\\FULL");
+ param_bool("\\SRC_DST_PEN");
+ param_bool("\\SRC_DST_POL");
+ param("\\T_RISE_MIN");
+ param("\\T_RISE_TYP");
+ param("\\T_RISE_MAX");
+ param("\\T_FALL_MIN");
+ param("\\T_FALL_TYP");
+ param("\\T_FALL_MAX");
+ port("\\EN", 1);
+ port("\\SRC", param("\\SRC_WIDTH"));
+ port("\\DST", param("\\DST_WIDTH"));
+ if (cell->type == "$specify3") {
+ param_bool("\\EDGE_EN");
+ param_bool("\\EDGE_POL");
+ param_bool("\\DAT_DST_PEN");
+ param_bool("\\DAT_DST_POL");
+ port("\\DAT", param("\\DST_WIDTH"));
+ }
+ check_expected();
+ return;
+ }
+
+ if (cell->type == "$specrule") {
+ param("\\TYPE");
+ param_bool("\\SRC_PEN");
+ param_bool("\\SRC_POL");
+ param_bool("\\DST_PEN");
+ param_bool("\\DST_POL");
+ param("\\T_LIMIT");
+ param("\\T_LIMIT2");
+ port("\\SRC_EN", 1);
+ port("\\DST_EN", 1);
+ port("\\SRC", param("\\SRC_WIDTH"));
+ port("\\DST", param("\\DST_WIDTH"));
+ 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; }
@@ -1273,7 +1381,34 @@ void RTLIL::Module::check()
for (auto &it : processes) {
log_assert(it.first == it.second->name);
log_assert(!it.first.empty());
- // FIXME: More checks here..
+ log_assert(it.second->root_case.compare.empty());
+ std::vector<CaseRule*> all_cases = {&it.second->root_case};
+ for (size_t i = 0; i < all_cases.size(); i++) {
+ for (auto &switch_it : all_cases[i]->switches) {
+ for (auto &case_it : switch_it->cases) {
+ for (auto &compare_it : case_it->compare) {
+ log_assert(switch_it->signal.size() == compare_it.size());
+ }
+ all_cases.push_back(case_it);
+ }
+ }
+ }
+ for (auto &sync_it : it.second->syncs) {
+ switch (sync_it->type) {
+ case SyncType::ST0:
+ case SyncType::ST1:
+ case SyncType::STp:
+ case SyncType::STn:
+ case SyncType::STe:
+ log_assert(!sync_it->signal.empty());
+ break;
+ case SyncType::STa:
+ case SyncType::STg:
+ case SyncType::STi:
+ log_assert(sync_it->signal.empty());
+ break;
+ }
+ }
}
for (auto &it : connections_) {
@@ -1406,7 +1541,10 @@ void RTLIL::Module::add(RTLIL::Cell *cell)
cell->module = this;
}
-namespace {
+void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
+{
+ log_assert(refcount_wires_ == 0);
+
struct DeleteWireWorker
{
RTLIL::Module *module;
@@ -1421,17 +1559,29 @@ namespace {
}
sig = chunks;
}
- };
-}
-void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
-{
- log_assert(refcount_wires_ == 0);
+ void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) {
+ log_assert(GetSize(lhs) == GetSize(rhs));
+ RTLIL::SigSpec new_lhs, new_rhs;
+ for (int i = 0; i < GetSize(lhs); i++) {
+ RTLIL::SigBit lhs_bit = lhs[i];
+ if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire))
+ continue;
+ RTLIL::SigBit rhs_bit = rhs[i];
+ if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))
+ continue;
+ new_lhs.append(lhs_bit);
+ new_rhs.append(rhs_bit);
+ }
+ lhs = new_lhs;
+ rhs = new_rhs;
+ }
+ };
DeleteWireWorker delete_wire_worker;
delete_wire_worker.module = this;
delete_wire_worker.wires_p = &wires;
- rewrite_sigspecs(delete_wire_worker);
+ rewrite_sigspecs2(delete_wire_worker);
for (auto &it : wires) {
log_assert(wires_.count(it->name) != 0);
@@ -2202,8 +2352,27 @@ RTLIL::Wire::Wire()
port_input = false;
port_output = false;
upto = false;
+
+#ifdef WITH_PYTHON
+ RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
+#endif
}
+RTLIL::Wire::~Wire()
+{
+#ifdef WITH_PYTHON
+ RTLIL::Wire::get_all_wires()->erase(hashidx_);
+#endif
+}
+
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Wire*> all_wires;
+std::map<unsigned int, RTLIL::Wire*> *RTLIL::Wire::get_all_wires(void)
+{
+ return &all_wires;
+}
+#endif
+
RTLIL::Memory::Memory()
{
static unsigned int hashidx_count = 123456789;
@@ -2213,6 +2382,9 @@ RTLIL::Memory::Memory()
width = 1;
start_offset = 0;
size = 0;
+#ifdef WITH_PYTHON
+ RTLIL::Memory::get_all_memorys()->insert(std::pair<unsigned int, RTLIL::Memory*>(hashidx_, this));
+#endif
}
RTLIL::Cell::Cell() : module(nullptr)
@@ -2223,8 +2395,27 @@ RTLIL::Cell::Cell() : module(nullptr)
// log("#memtrace# %p\n", this);
memhasher();
+
+#ifdef WITH_PYTHON
+ RTLIL::Cell::get_all_cells()->insert(std::pair<unsigned int, RTLIL::Cell*>(hashidx_, this));
+#endif
+}
+
+RTLIL::Cell::~Cell()
+{
+#ifdef WITH_PYTHON
+ RTLIL::Cell::get_all_cells()->erase(hashidx_);
+#endif
}
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Cell*> all_cells;
+std::map<unsigned int, RTLIL::Cell*> *RTLIL::Cell::get_all_cells(void)
+{
+ return &all_cells;
+}
+#endif
+
bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
{
return connections_.count(portname) != 0;
@@ -2484,6 +2675,14 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
width = 1;
}
+RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data)
+{
+ wire = sigchunk.wire;
+ data = sigchunk.data;
+ width = sigchunk.width;
+ offset = sigchunk.offset;
+}
+
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
{
RTLIL::SigChunk ret;
@@ -3343,7 +3542,7 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
pack();
other.pack();
- if (chunks_.size() != chunks_.size())
+ if (chunks_.size() != other.chunks_.size())
return false;
updhash();
@@ -3868,5 +4067,15 @@ RTLIL::Process *RTLIL::Process::clone() const
return new_proc;
}
+#ifdef WITH_PYTHON
+RTLIL::Memory::~Memory()
+{
+ RTLIL::Memory::get_all_memorys()->erase(hashidx_);
+}
+static std::map<unsigned int, RTLIL::Memory*> all_memorys;
+std::map<unsigned int, RTLIL::Memory*> *RTLIL::Memory::get_all_memorys(void)
+{
+ return &all_memorys;
+}
+#endif
YOSYS_NAMESPACE_END
-
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 52496e70..7b7367fb 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -50,7 +50,7 @@ namespace RTLIL
CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1,
CONST_FLAG_SIGNED = 2, // only used for parameters
- CONST_FLAG_REAL = 4 // unused -- to be used for parameters
+ CONST_FLAG_REAL = 4 // only used for parameters
};
struct Const;
@@ -517,6 +517,8 @@ struct RTLIL::Const
Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<bool> &bits);
+ Const(const RTLIL::Const &c);
+ RTLIL::Const &operator =(const RTLIL::Const &other) = default;
bool operator <(const RTLIL::Const &other) const;
bool operator ==(const RTLIL::Const &other) const;
@@ -566,9 +568,13 @@ struct RTLIL::AttrObject
{
dict<RTLIL::IdString, RTLIL::Const> attributes;
- void set_bool_attribute(RTLIL::IdString id);
+ void set_bool_attribute(RTLIL::IdString id, bool value=true);
bool get_bool_attribute(RTLIL::IdString id) const;
+ bool get_blackbox_attribute(bool ignore_wb=false) const {
+ return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox"));
+ }
+
void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
pool<string> get_strpool_attribute(RTLIL::IdString id) const;
@@ -591,8 +597,11 @@ struct RTLIL::SigChunk
SigChunk(int val, int width = 32);
SigChunk(RTLIL::State bit, int width = 1);
SigChunk(RTLIL::SigBit bit);
+ SigChunk(const RTLIL::SigChunk &sigchunk);
+ RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default;
RTLIL::SigChunk extract(int offset, int length) const;
+ inline int size() const { return width; }
bool operator <(const RTLIL::SigChunk &other) const;
bool operator ==(const RTLIL::SigChunk &other) const;
@@ -615,6 +624,8 @@ struct RTLIL::SigBit
SigBit(const RTLIL::SigChunk &chunk);
SigBit(const RTLIL::SigChunk &chunk, int index);
SigBit(const RTLIL::SigSpec &sig);
+ SigBit(const RTLIL::SigBit &sigbit);
+ RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default;
bool operator <(const RTLIL::SigBit &other) const;
bool operator ==(const RTLIL::SigBit &other) const;
@@ -936,9 +947,13 @@ struct RTLIL::Design
}
}
+
std::vector<RTLIL::Module*> selected_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules_warn() const;
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void);
+#endif
};
struct RTLIL::Module : public RTLIL::AttrObject
@@ -976,6 +991,7 @@ public:
virtual void sort();
virtual void check();
virtual void optimize();
+ virtual void makeblackbox();
void connect(const RTLIL::SigSig &conn);
void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs);
@@ -986,6 +1002,7 @@ public:
void fixup_ports();
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
void cloneInto(RTLIL::Module *new_mod) const;
virtual RTLIL::Module *clone() const;
@@ -1194,6 +1211,10 @@ public:
RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = "");
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void);
+#endif
};
struct RTLIL::Wire : public RTLIL::AttrObject
@@ -1205,7 +1226,7 @@ protected:
// use module->addWire() and module->remove() to create or destroy wires
friend struct RTLIL::Module;
Wire();
- ~Wire() { };
+ ~Wire();
public:
// do not simply copy wires
@@ -1216,6 +1237,10 @@ public:
RTLIL::IdString name;
int width, start_offset, port_id;
bool port_input, port_output, upto;
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
+#endif
};
struct RTLIL::Memory : public RTLIL::AttrObject
@@ -1227,6 +1252,10 @@ struct RTLIL::Memory : public RTLIL::AttrObject
RTLIL::IdString name;
int width, start_offset, size;
+#ifdef WITH_PYTHON
+ ~Memory();
+ static std::map<unsigned int, RTLIL::Memory*> *get_all_memorys(void);
+#endif
};
struct RTLIL::Cell : public RTLIL::AttrObject
@@ -1238,6 +1267,7 @@ protected:
// use module->addCell() and module->remove() to create or destroy cells
friend struct RTLIL::Module;
Cell();
+ ~Cell();
public:
// do not simply copy cells
@@ -1278,9 +1308,14 @@ public:
}
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void);
+#endif
};
-struct RTLIL::CaseRule
+struct RTLIL::CaseRule : public RTLIL::AttrObject
{
std::vector<RTLIL::SigSpec> compare;
std::vector<RTLIL::SigSig> actions;
@@ -1292,6 +1327,7 @@ struct RTLIL::CaseRule
bool empty() const;
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::CaseRule *clone() const;
};
@@ -1305,6 +1341,7 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
bool empty() const;
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::SwitchRule *clone() const;
};
@@ -1315,6 +1352,7 @@ struct RTLIL::SyncRule
std::vector<RTLIL::SigSig> actions;
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::SyncRule *clone() const;
};
@@ -1327,6 +1365,7 @@ struct RTLIL::Process : public RTLIL::AttrObject
~Process();
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::Process *clone() const;
};
@@ -1338,6 +1377,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as
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 RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;}
inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
if (wire == other.wire)
@@ -1388,12 +1428,30 @@ void RTLIL::Module::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::Module::rewrite_sigspecs2(T &functor)
+{
+ for (auto &it : cells_)
+ it.second->rewrite_sigspecs2(functor);
+ for (auto &it : processes)
+ it.second->rewrite_sigspecs2(functor);
+ for (auto &it : connections_) {
+ functor(it.first, it.second);
+ }
+}
+
+template<typename T>
void RTLIL::Cell::rewrite_sigspecs(T &functor) {
for (auto &it : connections_)
functor(it.second);
}
template<typename T>
+void RTLIL::Cell::rewrite_sigspecs2(T &functor) {
+ for (auto &it : connections_)
+ functor(it.second);
+}
+
+template<typename T>
void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {
for (auto &it : compare)
functor(it);
@@ -1406,6 +1464,17 @@ void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {
}
template<typename T>
+void RTLIL::CaseRule::rewrite_sigspecs2(T &functor) {
+ for (auto &it : compare)
+ functor(it);
+ for (auto &it : actions) {
+ functor(it.first, it.second);
+ }
+ for (auto it : switches)
+ it->rewrite_sigspecs2(functor);
+}
+
+template<typename T>
void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)
{
functor(signal);
@@ -1414,6 +1483,14 @@ void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::SwitchRule::rewrite_sigspecs2(T &functor)
+{
+ functor(signal);
+ for (auto it : cases)
+ it->rewrite_sigspecs2(functor);
+}
+
+template<typename T>
void RTLIL::SyncRule::rewrite_sigspecs(T &functor)
{
functor(signal);
@@ -1424,6 +1501,15 @@ void RTLIL::SyncRule::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::SyncRule::rewrite_sigspecs2(T &functor)
+{
+ functor(signal);
+ for (auto &it : actions) {
+ functor(it.first, it.second);
+ }
+}
+
+template<typename T>
void RTLIL::Process::rewrite_sigspecs(T &functor)
{
root_case.rewrite_sigspecs(functor);
@@ -1431,6 +1517,14 @@ void RTLIL::Process::rewrite_sigspecs(T &functor)
it->rewrite_sigspecs(functor);
}
+template<typename T>
+void RTLIL::Process::rewrite_sigspecs2(T &functor)
+{
+ root_case.rewrite_sigspecs2(functor);
+ for (auto it : syncs)
+ it->rewrite_sigspecs2(functor);
+}
+
YOSYS_NAMESPACE_END
#endif
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 450e4e4c..69a14176 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -57,6 +57,16 @@
# include <sys/sysctl.h>
#endif
+#ifdef WITH_PYTHON
+#if PY_MAJOR_VERSION >= 3
+# define INIT_MODULE PyInit_libyosys
+ extern "C" PyObject* INIT_MODULE();
+#else
+# define INIT_MODULE initlibyosys
+ extern "C" void INIT_MODULE();
+#endif
+#endif
+
#include <limits.h>
#include <errno.h>
@@ -119,7 +129,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2018 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at> |\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");
@@ -141,14 +151,16 @@ void yosys_banner()
int ceil_log2(int x)
{
+#if defined(__GNUC__)
+ return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0;
+#else
if (x <= 0)
return 0;
-
for (int i = 0; i < 32; i++)
if (((x-1) >> i) == 0)
return i;
-
log_abort();
+#endif
}
std::string stringf(const char *fmt, ...)
@@ -472,26 +484,61 @@ void remove_directory(std::string dirname)
#endif
}
+std::string escape_filename_spaces(const std::string& filename)
+{
+ std::string out;
+ out.reserve(filename.size());
+ for (auto c : filename)
+ {
+ if (c == ' ')
+ out += "\\ ";
+ else
+ out.push_back(c);
+ }
+ return out;
+}
+
int GetSize(RTLIL::Wire *wire)
{
return wire->width;
}
+bool already_setup = false;
+
void yosys_setup()
{
+ if(already_setup)
+ return;
+ already_setup = true;
// 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_);
+ #ifdef WITH_PYTHON
+ PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
+ Py_Initialize();
+ PyRun_SimpleString("import sys");
+ #endif
+
Pass::init_register();
yosys_design = new RTLIL::Design;
yosys_celltypes.setup();
log_push();
}
+bool yosys_already_setup()
+{
+ return already_setup;
+}
+
+bool already_shutdown = false;
+
void yosys_shutdown()
{
+ if(already_shutdown)
+ return;
+ already_shutdown = true;
log_pop();
delete yosys_design;
@@ -519,9 +566,16 @@ void yosys_shutdown()
dlclose(it.second);
loaded_plugins.clear();
+#ifdef WITH_PYTHON
+ loaded_python_plugins.clear();
+#endif
loaded_plugin_aliases.clear();
#endif
+#ifdef WITH_PYTHON
+ Py_Finalize();
+#endif
+
IdString empty_id;
IdString::put_reference(empty_id.index_);
}
@@ -597,6 +651,10 @@ void rewrite_filename(std::string &filename)
filename = filename.substr(1, GetSize(filename)-2);
if (filename.substr(0, 2) == "+/")
filename = proc_share_dirname() + filename.substr(2);
+#ifndef _WIN32
+ if (filename.substr(0, 2) == "~/")
+ filename = filename.replace(0, 1, getenv("HOME"));
+#endif
}
#ifdef YOSYS_ENABLE_TCL
diff --git a/kernel/yosys.h b/kernel/yosys.h
index c9f97331..730efe82 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -66,6 +66,10 @@
#include <stdio.h>
#include <limits.h>
+#ifdef WITH_PYTHON
+#include <Python.h>
+#endif
+
#ifndef _YOSYS_
# 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 \
@@ -83,6 +87,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);
extern void Tcl_Finalize(void);
extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);
extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
+extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length);
+extern Tcl_Obj *Tcl_NewIntObj(int intValue);
+extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
+extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);
# endif
#endif
@@ -115,6 +123,7 @@ extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
# define PATH_MAX 4096
#endif
+#define YOSYS_NAMESPACE Yosys
#define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END }
#define YOSYS_NAMESPACE_BEGIN namespace Yosys {
@@ -239,7 +248,7 @@ extern bool memhasher_active;
inline void memhasher() { if (memhasher_active) memhasher_do(); }
void yosys_banner();
-int ceil_log2(int x);
+int ceil_log2(int x) YS_ATTRIBUTE(const);
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);
@@ -252,6 +261,7 @@ std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX");
bool check_file_exists(std::string filename, bool is_exec = false);
bool is_absolute_path(std::string filename);
void remove_directory(std::string dirname);
+std::string escape_filename_spaces(const std::string& filename);
template<typename T> int GetSize(const T &obj) { return obj.size(); }
int GetSize(RTLIL::Wire *wire);
@@ -276,6 +286,11 @@ namespace hashlib {
}
void yosys_setup();
+
+#ifdef WITH_PYTHON
+bool yosys_already_setup();
+#endif
+
void yosys_shutdown();
#ifdef YOSYS_ENABLE_TCL
@@ -317,6 +332,9 @@ extern std::vector<RTLIL::Design*> pushed_designs;
// from passes/cmds/pluginc.cc
extern std::map<std::string, void*> loaded_plugins;
+#ifdef WITH_PYTHON
+extern std::map<std::string, void*> loaded_python_plugins;
+#endif
extern std::map<std::string, std::string> loaded_plugin_aliases;
void load_plugin(std::string filename, std::vector<std::string> aliases);