aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-09-02 15:18:44 +0000
committerwhitequark <whitequark@whitequark.org>2020-09-02 17:19:11 +0000
commitb025ee0aa646268747c121c97cf0673eb06e632b (patch)
tree2bcfbcc21c8cfc2c572418c79e43b99b5cfda83e /backends
parent8d6e5c63916bcff84164240cccce0e717e489a8d (diff)
downloadyosys-b025ee0aa646268747c121c97cf0673eb06e632b.tar.gz
yosys-b025ee0aa646268747c121c97cf0673eb06e632b.tar.bz2
yosys-b025ee0aa646268747c121c97cf0673eb06e632b.zip
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.
Diffstat (limited to 'backends')
-rw-r--r--backends/cxxrtl/cxxrtl.h22
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc9
-rw-r--r--backends/cxxrtl/cxxrtl_capi.h25
3 files changed, 51 insertions, 5 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index e3c96d422..df42f5807 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -452,7 +452,7 @@ struct value : public expr_base<value<Bits>> {
bool carry = CarryIn;
for (size_t n = 0; n < result.chunks; n++) {
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;
carry = (result.data[n] < data[n]) ||
(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
// in the C API, or it would not be possible to cast between the pointers to these.
struct debug_item : ::cxxrtl_object {
+ // Object types.
enum : uint32_t {
VALUE = CXXRTL_VALUE,
WIRE = CXXRTL_WIRE,
@@ -831,13 +832,21 @@ struct debug_item : ::cxxrtl_object {
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) {}
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),
"value<Bits> is not compatible with C layout");
type = VALUE;
+ flags = flags_;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
@@ -847,10 +856,11 @@ struct debug_item : ::cxxrtl_object {
}
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),
"value<Bits> is not compatible with C layout");
type = VALUE;
+ flags = flags_;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
@@ -860,11 +870,12 @@ struct debug_item : ::cxxrtl_object {
}
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) &&
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
"wire<Bits> is not compatible with C layout");
type = WIRE;
+ flags = flags_;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
@@ -878,6 +889,7 @@ struct debug_item : ::cxxrtl_object {
static_assert(sizeof(item.data[0]) == value<Width>::chunks * sizeof(chunk_t),
"memory<Width> is not compatible with C layout");
type = MEMORY;
+ flags = 0;
width = Width;
lsb_at = 0;
depth = item.data.size();
@@ -891,6 +903,7 @@ struct debug_item : ::cxxrtl_object {
static_assert(sizeof(item) == value<Bits>::chunks * sizeof(chunk_t),
"value<Bits> is not compatible with C layout");
type = ALIAS;
+ flags = 0;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
@@ -905,6 +918,7 @@ struct debug_item : ::cxxrtl_object {
sizeof(item.next) == value<Bits>::chunks * sizeof(chunk_t),
"wire<Bits> is not compatible with C layout");
type = ALIAS;
+ flags = 0;
width = Bits;
lsb_at = lsb_offset;
depth = 1;
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index c045af692..07f42d375 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -1662,7 +1662,14 @@ struct CxxrtlWorker {
// Member wire
f << indent << "items.add(path + " << escape_cxx_string(get_hdl_name(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++;
} else {
count_skipped_wires++;
diff --git a/backends/cxxrtl/cxxrtl_capi.h b/backends/cxxrtl/cxxrtl_capi.h
index 447c9e1f3..d2e9787dd 100644
--- a/backends/cxxrtl/cxxrtl_capi.h
+++ b/backends/cxxrtl/cxxrtl_capi.h
@@ -112,6 +112,28 @@ enum cxxrtl_type {
// 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.
//
// 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.
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.
size_t width;