diff options
Diffstat (limited to 'backends/cxxrtl/cxxrtl_vcd.h')
-rw-r--r-- | backends/cxxrtl/cxxrtl_vcd.h | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index 5706917ca..5f5f612b5 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -34,6 +34,7 @@ class vcd_writer { std::vector<std::string> current_scope; std::vector<variable> variables; std::vector<chunk_t> cache; + std::map<chunk_t*, size_t> aliases; bool streaming = false; void emit_timescale(unsigned number, const std::string &unit) { @@ -103,13 +104,25 @@ class vcd_writer { buffer += '\n'; } - void append_variable(size_t width, chunk_t *curr) { - const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); - variables.emplace_back(variable { variables.size(), width, curr, cache.size() }); - cache.insert(cache.end(), &curr[0], &curr[chunks]); + const variable ®ister_variable(size_t width, chunk_t *curr, bool immutable = false) { + if (aliases.count(curr)) { + return variables[aliases[curr]]; + } else { + const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); + aliases[curr] = variables.size(); + if (immutable) { + variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1 }); + } else { + variables.emplace_back(variable { variables.size(), width, curr, cache.size() }); + cache.insert(cache.end(), &curr[0], &curr[chunks]); + } + return variables.back(); + } } bool test_variable(const variable &var) { + if (var.prev_off == (size_t)-1) + return false; // immutable const size_t chunks = (var.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.prev_off])) { return false; @@ -151,20 +164,17 @@ public: switch (item.type) { // Not the best naming but oh well... case debug_item::VALUE: - append_variable(item.width, item.curr); - emit_var(variables.back(), "wire", name); + emit_var(register_variable(item.width, item.curr, /*immutable=*/item.next == nullptr), "wire", name); break; case debug_item::WIRE: - append_variable(item.width, item.curr); - emit_var(variables.back(), "reg", name); + emit_var(register_variable(item.width, item.curr), "reg", name); break; case debug_item::MEMORY: { const size_t stride = (item.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); for (size_t index = 0; index < item.depth; index++) { chunk_t *nth_curr = &item.curr[stride * index]; std::string nth_name = name + '[' + std::to_string(index) + ']'; - append_variable(item.width, nth_curr); - emit_var(variables.back(), "reg", nth_name); + emit_var(register_variable(item.width, nth_curr), "reg", nth_name); } break; } |