diff options
-rw-r--r-- | backends/cxxrtl/cxxrtl.h | 11 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 39 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl_capi.h | 11 |
3 files changed, 44 insertions, 17 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 5f74899fd..30f4667c5 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -742,6 +742,17 @@ struct debug_item : ::cxxrtl_object { } template<size_t Bits> + debug_item(const value<Bits> &item) { + static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t), + "value<Bits> is not compatible with C layout"); + type = VALUE; + width = Bits; + depth = 1; + curr = const_cast<uint32_t*>(item.data); + next = nullptr; + } + + template<size_t Bits> debug_item(wire<Bits> &item) { static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) && sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t), diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 01caa3793..b3aec2110 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -540,6 +540,7 @@ struct CxxrtlWorker { dict<const RTLIL::Module*, std::vector<FlowGraph::Node>> schedule; pool<const RTLIL::Wire*> localized_wires; dict<const RTLIL::Wire*, const RTLIL::Wire*> debug_alias_wires; + dict<const RTLIL::Wire*, RTLIL::Const> debug_const_wires; dict<const RTLIL::Module*, pool<std::string>> blackbox_specializations; dict<const RTLIL::Module*, bool> eval_converges; @@ -1607,29 +1608,36 @@ struct CxxrtlWorker { void dump_debug_info_method(RTLIL::Module *module) { - size_t count_member_wires = 0; + size_t count_const_wires = 0; size_t count_alias_wires = 0; + size_t count_member_wires = 0; size_t count_skipped_wires = 0; inc_indent(); f << indent << "assert(path.empty() || path[path.size() - 1] == ' ');\n"; for (auto wire : module->wires()) { if (wire->name[0] != '\\') continue; - if (debug_alias_wires.count(wire)) { + if (debug_const_wires.count(wire)) { + // Wire tied to a constant + f << indent << "static const value<" << wire->width << "> const_" << mangle(wire) << " = "; + dump_const(debug_const_wires[wire]); + f << ";\n"; + f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); + f << ", debug_item(const_" << mangle(wire) << "));\n"; + count_const_wires++; + } else if (debug_alias_wires.count(wire)) { // Alias of a member wire f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); f << ", debug_item(" << mangle(debug_alias_wires[wire]) << "));\n"; count_alias_wires++; - continue; - } - if (!localized_wires.count(wire)) { + } else if (!localized_wires.count(wire)) { // Member wire f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(wire)); f << ", debug_item(" << mangle(wire) << "));\n"; count_member_wires++; - continue; + } else { + count_skipped_wires++; } - count_skipped_wires++; } for (auto &memory_it : module->memories) { if (memory_it.first[0] != '\\') @@ -1647,8 +1655,9 @@ struct CxxrtlWorker { dec_indent(); log_debug("Debug information statistics for module %s:\n", log_id(module)); - log_debug(" Member wires: %zu\n", count_member_wires); + log_debug(" Const wires: %zu\n", count_const_wires); log_debug(" Alias wires: %zu\n", count_alias_wires); + log_debug(" Member wires: %zu\n", count_member_wires); log_debug(" Other wires: %zu (no debug information)\n", count_skipped_wires); } @@ -2163,8 +2172,8 @@ struct CxxrtlWorker { eval_converges[module] = feedback_wires.empty() && buffered_wires.empty(); if (debug_info) { - // Find wires that alias other wires; debug information can be enriched with these at essentially zero - // additional cost. + // Find wires that alias other wires or are tied to a constant; debug information can be enriched with these + // at essentially zero additional cost. // // Note that the information collected here can't be used for optimizing the netlist: debug information queries // are pure and run on a design in a stable state, which allows assumptions that do not otherwise hold. @@ -2179,14 +2188,20 @@ struct CxxrtlWorker { break; // not an alias: complex def log_assert(flow.wire_comb_defs[wire_it].size() == 1); FlowGraph::Node *node = *flow.wire_comb_defs[wire_it].begin(); - if (node->connect.second.is_wire()) { - RTLIL::Wire *rhs_wire = node->connect.second.as_wire(); + if (node->type != FlowGraph::Node::Type::CONNECT) + break; // not an alias: def by cell + RTLIL::SigSpec rhs_sig = node->connect.second; + if (rhs_sig.is_wire()) { + RTLIL::Wire *rhs_wire = rhs_sig.as_wire(); if (localized_wires[rhs_wire]) { wire_it = rhs_wire; // maybe an alias } else { debug_alias_wires[wire] = rhs_wire; // is an alias break; } + } else if (rhs_sig.is_fully_const()) { + debug_const_wires[wire] = rhs_sig.as_const(); // is a const + break; } else { break; // not an alias: complex rhs } diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h index bee5a94c7..46aa662b2 100644 --- a/backends/cxxrtl/cxxrtl_capi.h +++ b/backends/cxxrtl/cxxrtl_capi.h @@ -64,9 +64,10 @@ enum cxxrtl_type { // Values correspond to singly buffered netlist nodes, i.e. nodes driven exclusively by // combinatorial cells, or toplevel input nodes. // - // Values can be inspected via the `curr` pointer and modified via the `next` pointer (which are - // equal for values); however, note that changes to the bits driven by combinatorial cells will - // be ignored. + // Values can be inspected via the `curr` pointer. If the `next` pointer is NULL, the value is + // driven by a constant and can never be modified. Otherwise, the value can be modified through + // the `next` pointer (which is equal to `curr` if not NULL). Note that changes to the bits + // driven by combinatorial cells will be ignored. // // Values always have depth 1. CXXRTL_VALUE = 0, @@ -75,8 +76,8 @@ enum cxxrtl_type { // storage cells, or by combinatorial cells that are a part of a feedback path. // // Wires can be inspected via the `curr` pointer and modified via the `next` pointer (which are - // distinct for wires); however, note that changes to the bits driven by combinatorial cells will - // be ignored. + // distinct for wires). Note that changes to the bits driven by combinatorial cells will be + // ignored. // // Wires always have depth 1. CXXRTL_WIRE = 1, |