mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 09:55:20 +00:00
cxxrtl: expose port direction in debug information.
This can be useful to distinguish e.g. a combinatorially driven wire with type `CXXRTL_VALUE` from a module input with the same type, as well as general introspection.
This commit is contained in:
parent
8d6e5c6391
commit
b025ee0aa6
|
@ -452,7 +452,7 @@ struct value : public expr_base<value<Bits>> {
|
||||||
bool carry = CarryIn;
|
bool carry = CarryIn;
|
||||||
for (size_t n = 0; n < result.chunks; n++) {
|
for (size_t n = 0; n < result.chunks; n++) {
|
||||||
result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry;
|
result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry;
|
||||||
if (result.chunks - 1 == n)
|
if (result.chunks - 1 == n)
|
||||||
result.data[result.chunks - 1] &= result.msb_mask;
|
result.data[result.chunks - 1] &= result.msb_mask;
|
||||||
carry = (result.data[n] < data[n]) ||
|
carry = (result.data[n] < data[n]) ||
|
||||||
(result.data[n] == data[n] && carry);
|
(result.data[n] == data[n] && carry);
|
||||||
|
@ -824,6 +824,7 @@ struct debug_alias {};
|
||||||
// To avoid violating strict aliasing rules, this structure has to be a subclass of the one used
|
// To avoid violating strict aliasing rules, this structure has to be a subclass of the one used
|
||||||
// in the C API, or it would not be possible to cast between the pointers to these.
|
// in the C API, or it would not be possible to cast between the pointers to these.
|
||||||
struct debug_item : ::cxxrtl_object {
|
struct debug_item : ::cxxrtl_object {
|
||||||
|
// Object types.
|
||||||
enum : uint32_t {
|
enum : uint32_t {
|
||||||
VALUE = CXXRTL_VALUE,
|
VALUE = CXXRTL_VALUE,
|
||||||
WIRE = CXXRTL_WIRE,
|
WIRE = CXXRTL_WIRE,
|
||||||
|
@ -831,13 +832,21 @@ struct debug_item : ::cxxrtl_object {
|
||||||
ALIAS = CXXRTL_ALIAS,
|
ALIAS = CXXRTL_ALIAS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Object flags.
|
||||||
|
enum : uint32_t {
|
||||||
|
INPUT = CXXRTL_INPUT,
|
||||||
|
OUTPUT = CXXRTL_OUTPUT,
|
||||||
|
INOUT = CXXRTL_INOUT,
|
||||||
|
};
|
||||||
|
|
||||||
debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {}
|
debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {}
|
||||||
|
|
||||||
template<size_t Bits>
|
template<size_t Bits>
|
||||||
debug_item(value<Bits> &item, size_t lsb_offset = 0) {
|
debug_item(value<Bits> &item, size_t lsb_offset = 0, uint32_t flags_ = 0) {
|
||||||
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
||||||
"value<Bits> is not compatible with C layout");
|
"value<Bits> is not compatible with C layout");
|
||||||
type = VALUE;
|
type = VALUE;
|
||||||
|
flags = flags_;
|
||||||
width = Bits;
|
width = Bits;
|
||||||
lsb_at = lsb_offset;
|
lsb_at = lsb_offset;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
@ -847,10 +856,11 @@ struct debug_item : ::cxxrtl_object {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t Bits>
|
template<size_t Bits>
|
||||||
debug_item(const value<Bits> &item, size_t lsb_offset = 0) {
|
debug_item(const value<Bits> &item, size_t lsb_offset = 0, uint32_t flags_ = 0) {
|
||||||
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
||||||
"value<Bits> is not compatible with C layout");
|
"value<Bits> is not compatible with C layout");
|
||||||
type = VALUE;
|
type = VALUE;
|
||||||
|
flags = flags_;
|
||||||
width = Bits;
|
width = Bits;
|
||||||
lsb_at = lsb_offset;
|
lsb_at = lsb_offset;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
@ -860,11 +870,12 @@ struct debug_item : ::cxxrtl_object {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t Bits>
|
template<size_t Bits>
|
||||||
debug_item(wire<Bits> &item, size_t lsb_offset = 0) {
|
debug_item(wire<Bits> &item, size_t lsb_offset = 0, uint32_t flags_ = 0) {
|
||||||
static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) &&
|
static_assert(sizeof(item.curr) == value<Bits>::chunks * sizeof(chunk_t) &&
|
||||||
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
|
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
|
||||||
"wire<Bits> is not compatible with C layout");
|
"wire<Bits> is not compatible with C layout");
|
||||||
type = WIRE;
|
type = WIRE;
|
||||||
|
flags = flags_;
|
||||||
width = Bits;
|
width = Bits;
|
||||||
lsb_at = lsb_offset;
|
lsb_at = lsb_offset;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
@ -878,6 +889,7 @@ struct debug_item : ::cxxrtl_object {
|
||||||
static_assert(sizeof(item.data[0]) == value<Width>::chunks * sizeof(chunk_t),
|
static_assert(sizeof(item.data[0]) == value<Width>::chunks * sizeof(chunk_t),
|
||||||
"memory<Width> is not compatible with C layout");
|
"memory<Width> is not compatible with C layout");
|
||||||
type = MEMORY;
|
type = MEMORY;
|
||||||
|
flags = 0;
|
||||||
width = Width;
|
width = Width;
|
||||||
lsb_at = 0;
|
lsb_at = 0;
|
||||||
depth = item.data.size();
|
depth = item.data.size();
|
||||||
|
@ -891,6 +903,7 @@ struct debug_item : ::cxxrtl_object {
|
||||||
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
|
||||||
"value<Bits> is not compatible with C layout");
|
"value<Bits> is not compatible with C layout");
|
||||||
type = ALIAS;
|
type = ALIAS;
|
||||||
|
flags = 0;
|
||||||
width = Bits;
|
width = Bits;
|
||||||
lsb_at = lsb_offset;
|
lsb_at = lsb_offset;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
@ -905,6 +918,7 @@ struct debug_item : ::cxxrtl_object {
|
||||||
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
|
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
|
||||||
"wire<Bits> is not compatible with C layout");
|
"wire<Bits> is not compatible with C layout");
|
||||||
type = ALIAS;
|
type = ALIAS;
|
||||||
|
flags = 0;
|
||||||
width = Bits;
|
width = Bits;
|
||||||
lsb_at = lsb_offset;
|
lsb_at = lsb_offset;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
|
|
@ -1662,7 +1662,14 @@ struct CxxrtlWorker {
|
||||||
// Member wire
|
// Member wire
|
||||||
f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire));
|
f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(wire));
|
||||||
f << ", debug_item(" << mangle(wire) << ", ";
|
f << ", debug_item(" << mangle(wire) << ", ";
|
||||||
f << wire->start_offset << "));\n";
|
f << wire->start_offset;
|
||||||
|
if (wire->port_input && wire->port_output)
|
||||||
|
f << ", debug_item::INOUT";
|
||||||
|
else if (wire->port_input)
|
||||||
|
f << ", debug_item::INPUT";
|
||||||
|
else if (wire->port_output)
|
||||||
|
f << ", debug_item::OUTPUT";
|
||||||
|
f << "));\n";
|
||||||
count_member_wires++;
|
count_member_wires++;
|
||||||
} else {
|
} else {
|
||||||
count_skipped_wires++;
|
count_skipped_wires++;
|
||||||
|
|
|
@ -112,6 +112,28 @@ enum cxxrtl_type {
|
||||||
// More object types may be added in the future, but the existing ones will never change.
|
// More object types may be added in the future, but the existing ones will never change.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags of a simulated object.
|
||||||
|
enum cxxrtl_flag {
|
||||||
|
// Node is a module input port.
|
||||||
|
//
|
||||||
|
// This flag can be set on objects of type `CXXRTL_VALUE` and `CXXRTL_WIRE`. It may be combined
|
||||||
|
// with `CXXRTL_OUTPUT`, as well as other flags.
|
||||||
|
CXXRTL_INPUT = 1 << 0,
|
||||||
|
|
||||||
|
// Node is a module output port.
|
||||||
|
//
|
||||||
|
// This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with `CXXRTL_INPUT`,
|
||||||
|
// as well as other flags.
|
||||||
|
CXXRTL_OUTPUT = 1 << 1,
|
||||||
|
|
||||||
|
// Node is a module inout port.
|
||||||
|
//
|
||||||
|
// This flag can be set on objects of type `CXXRTL_WIRE`. It may be combined with other flags.
|
||||||
|
CXXRTL_INOUT = (CXXRTL_INPUT|CXXRTL_OUTPUT),
|
||||||
|
|
||||||
|
// More object flags may be added in the future, but the existing ones will never change.
|
||||||
|
};
|
||||||
|
|
||||||
// Description of a simulated object.
|
// Description of a simulated object.
|
||||||
//
|
//
|
||||||
// The `data` array can be accessed directly to inspect and, if applicable, modify the bits
|
// The `data` array can be accessed directly to inspect and, if applicable, modify the bits
|
||||||
|
@ -123,6 +145,9 @@ struct cxxrtl_object {
|
||||||
// determines all other properties of the object.
|
// determines all other properties of the object.
|
||||||
uint32_t type; // actually `enum cxxrtl_type`
|
uint32_t type; // actually `enum cxxrtl_type`
|
||||||
|
|
||||||
|
// Flags of the object.
|
||||||
|
uint32_t flags; // actually bit mask of `enum cxxrtl_flags`
|
||||||
|
|
||||||
// Width of the object in bits.
|
// Width of the object in bits.
|
||||||
size_t width;
|
size_t width;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue