diff options
author | whitequark <whitequark@whitequark.org> | 2020-12-19 04:14:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-19 04:14:31 +0000 |
commit | ab9e2f4fda1da455643579537d0ae6ffc6d46aab (patch) | |
tree | e292e0193ad5f61409c9f2581d62a036653dc93d /backends/cxxrtl/cxxrtl_vcd.h | |
parent | eaf6b551b68f44bc31c2d4274c91944451b01649 (diff) | |
parent | d889a3df35e539b6dcfbee9c6a98461eca1a0b0e (diff) | |
download | yosys-ab9e2f4fda1da455643579537d0ae6ffc6d46aab.tar.gz yosys-ab9e2f4fda1da455643579537d0ae6ffc6d46aab.tar.bz2 yosys-ab9e2f4fda1da455643579537d0ae6ffc6d46aab.zip |
Merge pull request #2487 from whitequark/cxxrtl-outlining
CXXRTL: implement zero-cost full coverage debug information through the magic✨ of outlining🪄🎀🧹
Diffstat (limited to 'backends/cxxrtl/cxxrtl_vcd.h')
-rw-r--r-- | backends/cxxrtl/cxxrtl_vcd.h | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h index dbeabbaf2..6ee98b428 100644 --- a/backends/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/cxxrtl_vcd.h @@ -28,10 +28,13 @@ class vcd_writer { size_t ident; size_t width; chunk_t *curr; - size_t prev_off; + size_t cache_offset; + debug_outline *outline; + bool *outline_warm; }; std::vector<std::string> current_scope; + std::map<debug_outline*, bool> outlines; std::vector<variable> variables; std::vector<chunk_t> cache; std::map<chunk_t*, size_t> aliases; @@ -112,16 +115,22 @@ class vcd_writer { buffer += '\n'; } - const variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false) { + void reset_outlines() { + for (auto &outline_it : outlines) + outline_it.second = /*warm=*/(outline_it.first == nullptr); + } + + variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false, debug_outline *outline = nullptr) { if (aliases.count(curr)) { return variables[aliases[curr]]; } else { + auto outline_it = outlines.emplace(outline, /*warm=*/(outline == nullptr)).first; const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8); aliases[curr] = variables.size(); if (constant) { - variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1 }); + variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1, outline_it->first, &outline_it->second }); } else { - variables.emplace_back(variable { variables.size(), width, curr, cache.size() }); + variables.emplace_back(variable { variables.size(), width, curr, cache.size(), outline_it->first, &outline_it->second }); cache.insert(cache.end(), &curr[0], &curr[chunks]); } return variables.back(); @@ -129,13 +138,17 @@ class vcd_writer { } bool test_variable(const variable &var) { - if (var.prev_off == (size_t)-1) + if (var.cache_offset == (size_t)-1) return false; // constant + if (!*var.outline_warm) { + var.outline->eval(); + *var.outline_warm = true; + } 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])) { + if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset])) { return false; } else { - std::copy(&var.curr[0], &var.curr[chunks], &cache[var.prev_off]); + std::copy(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset]); return true; } } @@ -197,6 +210,10 @@ public: emit_var(register_variable(item.width, item.curr), "wire", name, item.lsb_at, multipart); break; + case debug_item::OUTLINE: + emit_var(register_variable(item.width, item.curr, /*constant=*/false, item.outline), + "wire", name, item.lsb_at, multipart); + break; } } @@ -228,6 +245,7 @@ public: emit_scope({}); emit_enddefinitions(); } + reset_outlines(); emit_time(timestamp); for (auto var : variables) if (test_variable(var) || first_sample) { |