aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fstdata.cc28
-rw-r--r--kernel/log.h5
-rw-r--r--kernel/mem.cc1
-rw-r--r--kernel/register.cc109
4 files changed, 135 insertions, 8 deletions
diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc
index b2e574b02..1b8043f9a 100644
--- a/kernel/fstdata.cc
+++ b/kernel/fstdata.cc
@@ -78,7 +78,18 @@ uint64_t FstData::getStartTime() { return fstReaderGetStartTime(ctx); }
uint64_t FstData::getEndTime() { return fstReaderGetEndTime(ctx); }
+static void normalize_brackets(std::string &str)
+{
+ for (auto &c : str) {
+ if (c == '<')
+ c = '[';
+ else if (c == '>')
+ c = ']';
+ }
+}
+
fstHandle FstData::getHandle(std::string name) {
+ normalize_brackets(name);
if (name_to_handle.find(name) != name_to_handle.end())
return name_to_handle[name];
else
@@ -120,6 +131,7 @@ void FstData::extractVarNames()
var.is_reg = (fstVarType)h->u.var.typ == FST_VT_VCD_REG;
var.name = remove_spaces(h->u.var.name);
var.scope = fst_scope_name;
+ normalize_brackets(var.scope);
var.width = h->u.var.length;
vars.push_back(var);
if (!var.is_alias)
@@ -134,35 +146,34 @@ void FstData::extractVarNames()
if (clean_name[0]=='\\')
clean_name = clean_name.substr(1);
size_t pos = clean_name.find_last_of("<");
- if (pos != std::string::npos) {
+ if (pos != std::string::npos && clean_name.back() == '>') {
std::string mem_cell = clean_name.substr(0, pos);
+ normalize_brackets(mem_cell);
std::string addr = clean_name.substr(pos+1);
addr.pop_back(); // remove closing bracket
char *endptr;
int mem_addr = strtol(addr.c_str(), &endptr, 16);
if (*endptr) {
- log_warning("Error parsing memory address in : %s\n", clean_name.c_str());
+ log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
} else {
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
- name_to_handle[stringf("%s.%s[%d]",var.scope.c_str(),mem_cell.c_str(),mem_addr)] = h->u.var.handle;
- continue;
}
}
pos = clean_name.find_last_of("[");
- if (pos != std::string::npos) {
+ if (pos != std::string::npos && clean_name.back() == ']') {
std::string mem_cell = clean_name.substr(0, pos);
+ normalize_brackets(mem_cell);
std::string addr = clean_name.substr(pos+1);
addr.pop_back(); // remove closing bracket
char *endptr;
int mem_addr = strtol(addr.c_str(), &endptr, 10);
if (*endptr) {
- log_warning("Error parsing memory address in : %s\n", clean_name.c_str());
+ log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
} else {
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
- name_to_handle[stringf("%s.%s[%d]",var.scope.c_str(),mem_cell.c_str(),mem_addr)] = h->u.var.handle;
- continue;
}
}
+ normalize_brackets(clean_name);
name_to_handle[var.scope+"."+clean_name] = h->u.var.handle;
break;
}
@@ -241,6 +252,7 @@ void FstData::reconstructAllAtTimes(std::vector<fstHandle> &signal, uint64_t sta
past_data = last_data;
callback(last_time);
}
+ past_data = last_data;
callback(end_time);
}
diff --git a/kernel/log.h b/kernel/log.h
index 8ef6e6d0e..822816cb4 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -393,6 +393,11 @@ void log_dump_val_worker(RTLIL::IdString v);
void log_dump_val_worker(RTLIL::SigSpec v);
void log_dump_val_worker(RTLIL::State v);
+template<typename K, typename T, typename OPS> static inline void log_dump_val_worker(dict<K, T, OPS> &v);
+template<typename K, typename OPS> static inline void log_dump_val_worker(pool<K, OPS> &v);
+template<typename K> static inline void log_dump_val_worker(std::vector<K> &v);
+template<typename T> static inline void log_dump_val_worker(T *ptr);
+
template<typename K, typename T, typename OPS>
static inline void log_dump_val_worker(dict<K, T, OPS> &v) {
log("{");
diff --git a/kernel/mem.cc b/kernel/mem.cc
index e5e855ef7..ed01a0867 100644
--- a/kernel/mem.cc
+++ b/kernel/mem.cc
@@ -504,6 +504,7 @@ void Mem::check() {
int mask = (1 << max_wide_log2) - 1;
log_assert(!(start_offset & mask));
log_assert(!(size & mask));
+ log_assert(width != 0);
}
namespace {
diff --git a/kernel/register.cc b/kernel/register.cc
index 226963fda..9449890b1 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -822,6 +822,100 @@ struct HelpPass : public Pass {
fclose(f);
}
+ void write_rst(std::string cmd, std::string title, std::string text)
+ {
+ FILE *f = fopen(stringf("docs/source/cmd/%s.rst", cmd.c_str()).c_str(), "wt");
+ // make header
+ size_t char_len = cmd.length() + 3 + title.length();
+ std::string title_line = "\n";
+ title_line.insert(0, char_len, '=');
+ fprintf(f, "%s", title_line.c_str());
+ fprintf(f, "%s - %s\n", cmd.c_str(), title.c_str());
+ fprintf(f, "%s\n", title_line.c_str());
+ fprintf(f, ".. raw:: latex\n\n \\begin{comment}\n\n");
+
+ // render html
+ fprintf(f, ":code:`yosys> help %s`\n", cmd.c_str());
+ fprintf(f, "--------------------------------------------------------------------------------\n\n");
+ fprintf(f, ".. container:: cmdref\n");
+ std::stringstream ss;
+ std::string textcp = text;
+ ss << text;
+ bool IsUsage = true;
+ int blank_count = 0;
+ size_t def_strip_count = 0;
+ bool WasDefinition = false;
+ for (std::string line; std::getline(ss, line, '\n');) {
+ // find position of first non space character
+ std::size_t first_pos = line.find_first_not_of(" \t");
+ std::size_t last_pos = line.find_last_not_of(" \t");
+ if (first_pos == std::string::npos) {
+ // skip formatting empty lines
+ if (!WasDefinition)
+ fputc('\n', f);
+ blank_count += 1;
+ continue;
+ }
+
+ // strip leading and trailing whitespace
+ std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1);
+ bool IsDefinition = stripped_line[0] == '-';
+ IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>';
+ bool IsDedent = def_strip_count && first_pos <= def_strip_count;
+ bool IsIndent = first_pos == 2 || first_pos == 4;
+ if (cmd.compare(0, 7, "verific") == 0)
+ // verific.cc has strange and different formatting from the rest
+ IsIndent = false;
+
+ // another usage block
+ bool NewUsage = stripped_line.find(cmd) == 0;
+
+ if (IsUsage) {
+ if (stripped_line.compare(0, 4, "See ") == 0) {
+ // description refers to another function
+ fprintf(f, "\n %s\n", stripped_line.c_str());
+ } else {
+ // usage should be the first line of help output
+ fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
+ WasDefinition = true;
+ }
+ IsUsage = false;
+ } else if (IsIndent && NewUsage && (blank_count >= 2 || WasDefinition)) {
+ // another usage block
+ fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
+ WasDefinition = true;
+ def_strip_count = 0;
+ } else if (IsIndent && IsDefinition && (blank_count || WasDefinition)) {
+ // format definition term
+ fprintf(f, "\n\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
+ WasDefinition = true;
+ def_strip_count = first_pos;
+ } else {
+ if (IsDedent) {
+ fprintf(f, "\n\n ::\n");
+ def_strip_count = first_pos;
+ } else if (WasDefinition) {
+ fprintf(f, " ::\n");
+ WasDefinition = false;
+ }
+ fprintf(f, "\n %s", line.substr(def_strip_count, std::string::npos).c_str());
+ }
+
+ blank_count = 0;
+ }
+ fputc('\n', f);
+
+ // render latex
+ fprintf(f, ".. raw:: latex\n\n \\end{comment}\n\n");
+ fprintf(f, ".. only:: latex\n\n");
+ fprintf(f, " ::\n\n");
+ std::stringstream ss2;
+ ss2 << textcp;
+ for (std::string line; std::getline(ss2, line, '\n');) {
+ fprintf(f, " %s\n", line.c_str());
+ }
+ fclose(f);
+ }
void execute(std::vector<std::string> args, RTLIL::Design*) override
{
if (args.size() == 1) {
@@ -882,6 +976,21 @@ struct HelpPass : public Pass {
fclose(f);
}
// this option is undocumented as it is for internal use only
+ else if (args[1] == "-write-rst-command-reference-manual") {
+ for (auto &it : pass_register) {
+ std::ostringstream buf;
+ log_streams.push_back(&buf);
+ it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
+ log_streams.pop_back();
+ write_rst(it.first, it.second->short_help, buf.str());
+ }
+ }
+ // this option is undocumented as it is for internal use only
else if (args[1] == "-write-web-command-reference-manual") {
FILE *f = fopen("templates/cmd_index.in", "wt");
for (auto &it : pass_register) {