3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-12 20:18:20 +00:00

Merge pull request #2496 from whitequark/cxxrtl-fixes

cxxrtl: various improvements
This commit is contained in:
whitequark 2020-12-21 04:32:18 +00:00 committed by GitHub
commit a679a761b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 9 deletions

View file

@ -317,6 +317,14 @@ struct value : public expr_base<value<Bits>> {
return sext_cast<NewBits>()(*this); return sext_cast<NewBits>()(*this);
} }
// Bit replication is far more efficient than the equivalent concatenation.
template<size_t Count>
CXXRTL_ALWAYS_INLINE
value<Bits * Count> repeat() const {
static_assert(Bits == 1, "repeat() is implemented only for 1-bit values");
return *this ? value<Bits * Count>().bit_not() : value<Bits * Count>();
}
// Operations with run-time parameters (offsets, amounts, etc). // Operations with run-time parameters (offsets, amounts, etc).
// //
// These operations are used for computations. // These operations are used for computations.

View file

@ -832,11 +832,26 @@ struct CxxrtlWorker {
} else if (sig.is_chunk()) { } else if (sig.is_chunk()) {
return dump_sigchunk(sig.as_chunk(), is_lhs, for_debug); return dump_sigchunk(sig.as_chunk(), is_lhs, for_debug);
} else { } else {
dump_sigchunk(*sig.chunks().rbegin(), is_lhs, for_debug); bool first = true;
for (auto it = sig.chunks().rbegin() + 1; it != sig.chunks().rend(); ++it) { auto chunks = sig.chunks();
f << ".concat("; for (auto it = chunks.rbegin(); it != chunks.rend(); it++) {
dump_sigchunk(*it, is_lhs, for_debug); if (!first)
f << ")"; f << ".concat(";
bool is_complex = dump_sigchunk(*it, is_lhs, for_debug);
if (!is_lhs && it->width == 1) {
size_t repeat = 1;
while ((it + repeat) != chunks.rend() && *(it + repeat) == *it)
repeat++;
if (repeat > 1) {
if (is_complex)
f << ".val()";
f << ".repeat<" << repeat << ">()";
}
it += repeat - 1;
}
if (!first)
f << ")";
first = false;
} }
return true; return true;
} }
@ -1702,19 +1717,19 @@ struct CxxrtlWorker {
continue; continue;
} }
if (!module->get_bool_attribute(ID(cxxrtl_blackbox)) || wire->port_id != 0) if (!module->get_bool_attribute(ID(cxxrtl_blackbox)) || wire->port_id != 0)
f << indent << "changed |= " << mangle(wire) << ".commit();\n"; f << indent << "if (" << mangle(wire) << ".commit()) changed = true;\n";
} }
if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) {
for (auto memory : module->memories) { for (auto memory : module->memories) {
if (!writable_memories[memory.second]) if (!writable_memories[memory.second])
continue; continue;
f << indent << "changed |= " << mangle(memory.second) << ".commit();\n"; f << indent << "if (" << mangle(memory.second) << ".commit()) changed = true;\n";
} }
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
if (is_internal_cell(cell->type)) if (is_internal_cell(cell->type))
continue; continue;
const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : "."; const char *access = is_cxxrtl_blackbox_cell(cell) ? "->" : ".";
f << indent << "changed |= " << mangle(cell) << access << "commit();\n"; f << indent << "if (" << mangle(cell) << access << "commit()) changed = true;\n";
} }
} }
f << indent << "return changed;\n"; f << indent << "return changed;\n";

View file

@ -272,7 +272,7 @@ struct cxxrtl_object *cxxrtl_get_parts(cxxrtl_handle handle, const char *name, s
// This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that, // This function is a shortcut for the most common use of `cxxrtl_get_parts`. It asserts that,
// if the object exists, it consists of a single part. If assertions are disabled, it returns NULL // if the object exists, it consists of a single part. If assertions are disabled, it returns NULL
// for multi-part objects. // for multi-part objects.
inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) { static inline struct cxxrtl_object *cxxrtl_get(cxxrtl_handle handle, const char *name) {
size_t parts = 0; size_t parts = 0;
struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts); struct cxxrtl_object *object = cxxrtl_get_parts(handle, name, &parts);
assert(object == NULL || parts == 1); assert(object == NULL || parts == 1);