aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJim Lawson <ucbjrl@berkeley.edu>2019-07-24 10:20:46 -0700
committerJim Lawson <ucbjrl@berkeley.edu>2019-07-24 10:20:46 -0700
commitc66b7402c06455535bb43ee65fe20515b5b9c0ee (patch)
treead135d83bf75e72b65e3136b4f6746c1f9cafab3 /kernel
parent349c47250a9779bc58634870d2e3facfe95fbff8 (diff)
parenta66f17b6a78af8f6989235f0c72d5548b0560a58 (diff)
downloadyosys-c66b7402c06455535bb43ee65fe20515b5b9c0ee.tar.gz
yosys-c66b7402c06455535bb43ee65fe20515b5b9c0ee.tar.bz2
yosys-c66b7402c06455535bb43ee65fe20515b5b9c0ee.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'kernel')
-rw-r--r--kernel/celltypes.h9
-rw-r--r--kernel/log.cc30
-rw-r--r--kernel/log.h1
-rw-r--r--kernel/register.cc1
-rw-r--r--kernel/rtlil.cc29
-rw-r--r--kernel/rtlil.h14
-rw-r--r--kernel/yosys.cc55
7 files changed, 118 insertions, 21 deletions
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index 4e91eddda..758661c02 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -246,24 +246,24 @@ struct CellTypes
cell_types.clear();
}
- bool cell_known(RTLIL::IdString type)
+ bool cell_known(RTLIL::IdString type) const
{
return cell_types.count(type) != 0;
}
- bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
+ bool cell_output(RTLIL::IdString type, RTLIL::IdString port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.outputs.count(port) != 0;
}
- bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
+ bool cell_input(RTLIL::IdString type, RTLIL::IdString port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.inputs.count(port) != 0;
}
- bool cell_evaluable(RTLIL::IdString type)
+ bool cell_evaluable(RTLIL::IdString type) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.is_evaluable;
@@ -482,4 +482,3 @@ extern CellTypes yosys_celltypes;
YOSYS_NAMESPACE_END
#endif
-
diff --git a/kernel/log.cc b/kernel/log.cc
index fa74a6a3c..e0a60ca12 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -61,7 +61,7 @@ int log_force_debug = 0;
int log_debug_suppressed = 0;
vector<int> header_count;
-pool<RTLIL::IdString> log_id_cache;
+vector<char*> log_id_cache;
vector<shared_str> string_buf;
int string_buf_index = -1;
@@ -69,6 +69,13 @@ static struct timeval initial_tv = { 0, 0 };
static bool next_print_log = false;
static int log_newline_count = 0;
+static void log_id_cache_clear()
+{
+ for (auto p : log_id_cache)
+ free(p);
+ log_id_cache.clear();
+}
+
#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)
@@ -277,11 +284,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)
@@ -403,7 +421,7 @@ void log_push()
void log_pop()
{
header_count.pop_back();
- log_id_cache.clear();
+ log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
@@ -510,7 +528,7 @@ void log_reset_stack()
{
while (header_count.size() > 1)
header_count.pop_back();
- log_id_cache.clear();
+ log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
@@ -569,8 +587,8 @@ const char *log_const(const RTLIL::Const &value, bool autoint)
const char *log_id(RTLIL::IdString str)
{
- log_id_cache.insert(str);
- const char *p = str.c_str();
+ log_id_cache.push_back(strdup(str.c_str()));
+ const char *p = log_id_cache.back();
if (p[0] != '\\')
return p;
if (p[1] == '$' || p[1] == '\\' || p[1] == 0)
diff --git a/kernel/log.h b/kernel/log.h
index e6afae716..3e1facae8 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -80,6 +80,7 @@ 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);
diff --git a/kernel/register.cc b/kernel/register.cc
index 71eb6b187..26da96b95 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -545,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 790ba52a3..a09f4a0d1 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1381,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_) {
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 8509670ff..82cbfaf28 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -276,6 +276,18 @@ namespace RTLIL
return std::string(c_str() + pos, len);
}
+ bool begins_with(const char* prefix) const {
+ size_t len = strlen(prefix);
+ if (size() < len) return false;
+ return substr(0, len) == prefix;
+ }
+
+ bool ends_with(const char* suffix) const {
+ size_t len = strlen(suffix);
+ if (size() < len) return false;
+ return substr(size()-len) == suffix;
+ }
+
size_t size() const {
return str().size();
}
@@ -1315,7 +1327,7 @@ public:
#endif
};
-struct RTLIL::CaseRule
+struct RTLIL::CaseRule : public RTLIL::AttrObject
{
std::vector<RTLIL::SigSpec> compare;
std::vector<RTLIL::SigSig> actions;
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 377572fc2..a42a7c0b8 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -651,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
@@ -1250,24 +1254,59 @@ struct HistoryPass : public Pass {
#endif
struct ScriptCmdPass : public Pass {
- ScriptCmdPass() : Pass("script", "execute commands from script file") { }
+ ScriptCmdPass() : Pass("script", "execute commands from file or wire") { }
void help() YS_OVERRIDE {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" script <filename> [<from_label>:<to_label>]\n");
+ log(" script -scriptwire [selection]\n");
log("\n");
- log("This command executes the yosys commands in the specified file.\n");
+ log("This command executes the yosys commands in the specified file (default\n");
+ log("behaviour), or commands embedded in the constant text value connected to the\n");
+ log("selected wires.\n");
log("\n");
- log("The 2nd argument can be used to only execute the section of the\n");
- log("file between the specified labels. An empty from label is synonymous\n");
- log("for the beginning of the file and an empty to label is synonymous\n");
- log("for the end of the file.\n");
+ log("In the default (file) case, the 2nd argument can be used to only execute the\n");
+ log("section of the file between the specified labels. An empty from label is\n");
+ log("synonymous with the beginning of the file and an empty to label is synonymous\n");
+ log("with the end of the file.\n");
log("\n");
log("If only one label is specified (without ':') then only the block\n");
log("marked with that label (until the next label) is executed.\n");
log("\n");
+ log("In \"-scriptwire\" mode, the commands on the selected wire(s) will be executed\n");
+ log("in the scope of (and thus, relative to) the wires' owning module(s). This\n");
+ log("'-module' mode can be exited by using the 'cd' command.\n");
+ log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
- if (args.size() < 2)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ bool scriptwire = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-scriptwire") {
+ scriptwire = true;
+ continue;
+ }
+ break;
+ }
+ if (scriptwire) {
+ extra_args(args, argidx, design);
+
+ for (auto mod : design->selected_modules())
+ for (auto &c : mod->connections()) {
+ if (!c.first.is_wire())
+ continue;
+ auto w = c.first.as_wire();
+ if (!mod->selected(w))
+ continue;
+ if (!c.second.is_fully_const())
+ log_error("RHS of selected wire %s.%s is not constant.\n", log_id(mod), log_id(w));
+ auto v = c.second.as_const();
+ Pass::call_on_module(design, mod, v.decode_string());
+ }
+ }
+ else if (args.size() < 2)
log_cmd_error("Missing script file.\n");
else if (args.size() == 2)
run_frontend(args[1], "script", design);