cxxrtl: expose RTLIL::{Wire,Memory}->start_offset in debug info.

This commit is contained in:
whitequark 2020-06-11 12:42:37 +00:00
parent 8a4841d786
commit fa04b19670
3 changed files with 62 additions and 40 deletions

View File

@ -734,71 +734,83 @@ struct debug_item : ::cxxrtl_object {
debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {}
template<size_t Bits>
debug_item(value<Bits> &item) {
debug_item(value<Bits> &item, size_t lsb_offset = 0) {
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 = item.data;
next = item.data;
type = VALUE;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
zero_at = 0;
curr = item.data;
next = item.data;
}
template<size_t Bits>
debug_item(const value<Bits> &item) {
debug_item(const value<Bits> &item, size_t lsb_offset = 0) {
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<chunk_t*>(item.data);
next = nullptr;
type = VALUE;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
zero_at = 0;
curr = const_cast<chunk_t*>(item.data);
next = nullptr;
}
template<size_t Bits>
debug_item(wire<Bits> &item) {
debug_item(wire<Bits> &item, size_t lsb_offset = 0) {
static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) &&
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
"wire<Bits> is not compatible with C layout");
type = WIRE;
width = Bits;
depth = 1;
curr = item.curr.data;
next = item.next.data;
type = WIRE;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
zero_at = 0;
curr = item.curr.data;
next = item.next.data;
}
template<size_t Width>
debug_item(memory<Width> &item) {
debug_item(memory<Width> &item, size_t zero_offset = 0) {
static_assert(sizeof(item.data[0]) == value<Width>::chunks * sizeof(chunk_t),
"memory<Width> is not compatible with C layout");
type = MEMORY;
width = Width;
depth = item.data.size();
curr = item.data.empty() ? nullptr : item.data[0].data;
next = nullptr;
type = MEMORY;
width = Width;
lsb_at = 0;
depth = item.data.size();
zero_at = zero_offset;
curr = item.data.empty() ? nullptr : item.data[0].data;
next = nullptr;
}
template<size_t Bits>
debug_item(debug_alias, const value<Bits> &item) {
debug_item(debug_alias, const value<Bits> &item, size_t lsb_offset = 0) {
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
"value<Bits> is not compatible with C layout");
type = ALIAS;
width = Bits;
depth = 1;
curr = const_cast<chunk_t*>(item.data);
next = nullptr;
type = ALIAS;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
zero_at = 0;
curr = const_cast<chunk_t*>(item.data);
next = nullptr;
}
template<size_t Bits>
debug_item(debug_alias, const wire<Bits> &item) {
debug_item(debug_alias, const wire<Bits> &item, size_t lsb_offset = 0) {
static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) &&
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
"wire<Bits> is not compatible with C layout");
type = ALIAS;
width = Bits;
depth = 1;
curr = const_cast<chunk_t*>(item.curr.data);
next = nullptr;
type = ALIAS;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
zero_at = 0;
curr = const_cast<chunk_t*>(item.curr.data);
next = nullptr;
}
};
static_assert(std::is_standard_layout<debug_item>::value, "debug_item is not compatible with C layout");

View File

@ -1641,17 +1641,20 @@ struct CxxrtlWorker {
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";
f << ", debug_item(const_" << mangle(wire) << ", ";
f << wire->start_offset << "));\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(debug_alias(), " << mangle(debug_alias_wires[wire]) << "));\n";
f << ", debug_item(debug_alias(), " << mangle(debug_alias_wires[wire]) << ", ";
f << wire->start_offset << "));\n";
count_alias_wires++;
} 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";
f << ", debug_item(" << mangle(wire) << ", ";
f << wire->start_offset << "));\n";
count_member_wires++;
} else {
count_skipped_wires++;
@ -1661,7 +1664,8 @@ struct CxxrtlWorker {
if (memory_it.first[0] != '\\')
continue;
f << indent << "items.emplace(path + " << escape_cxx_string(get_hdl_name(memory_it.second));
f << ", debug_item(" << mangle(memory_it.second) << "));\n";
f << ", debug_item(" << mangle(memory_it.second) << ", ";
f << memory_it.second->start_offset << "));\n";
}
for (auto cell : module->cells()) {
if (is_internal_cell(cell->type))

View File

@ -113,9 +113,15 @@ struct cxxrtl_object {
// Width of the object in bits.
size_t width;
// Index of the least significant bit.
size_t lsb_at;
// Depth of the object. Only meaningful for memories; for other objects, always 1.
size_t depth;
// Index of the first word. Only meaningful for memories; for other objects, always 0;
size_t zero_at;
// Bits stored in the object, as 32-bit chunks, least significant bits first.
//
// The width is rounded up to a multiple of 32; the padding bits are always set to 0 by