Fixed handling of unconnected output ports
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
diff --git a/ql-qlf-plugin/ql-dsp-simd.cc b/ql-qlf-plugin/ql-dsp-simd.cc
index 9f656a6..1bd0850 100644
--- a/ql-qlf-plugin/ql-dsp-simd.cc
+++ b/ql-qlf-plugin/ql-dsp-simd.cc
@@ -164,31 +164,32 @@
auto sport = RTLIL::escape_id(it.first);
auto dport = RTLIL::escape_id(it.second);
+ size_t width;
+ bool isOutput;
+
+ std::tie(width, isOutput) = getPortInfo(simd, dport);
+
+ auto getConnection = [&](const RTLIL::Cell *cell) {
+ RTLIL::SigSpec sigspec;
+ if (cell->hasPort(sport)) {
+ const auto &sig = cell->getPort(sport);
+ sigspec.append(sig);
+ }
+ if (sigspec.bits().size() < width / 2) {
+ if (isOutput) {
+ for (size_t i = 0; i < width / 2 - sigspec.bits().size(); ++i) {
+ sigspec.append(RTLIL::SigSpec());
+ }
+ } else {
+ sigspec.append(RTLIL::SigSpec(RTLIL::Sx, width / 2 - sigspec.bits().size()));
+ }
+ }
+ return sigspec;
+ };
+
RTLIL::SigSpec sigspec;
- size_t width = getPortWidth(simd, dport);
-
- // A part
- if (dsp_a->hasPort(sport)) {
- const auto &sig = dsp_a->getPort(sport);
- sigspec.append(sig);
- if (sig.bits().size() < width / 2) {
- sigspec.append(RTLIL::SigSpec(RTLIL::Sx, sig.bits().size() - width / 2));
- }
- } else {
- sigspec.append(RTLIL::SigSpec(RTLIL::Sx, width / 2));
- }
-
- // B part
- if (dsp_b->hasPort(sport)) {
- const auto &sig = dsp_b->getPort(sport);
- sigspec.append(sig);
- if (sig.bits().size() < width / 2) {
- sigspec.append(RTLIL::SigSpec(RTLIL::Sx, sig.bits().size() - width / 2));
- }
- } else {
- sigspec.append(RTLIL::SigSpec(RTLIL::Sx, width / 2));
- }
-
+ sigspec.append(getConnection(dsp_a));
+ sigspec.append(getConnection(dsp_b));
simd->setPort(dport, sigspec);
}
@@ -214,29 +215,28 @@
// ..........................................
- /// Looks up port width in the cell definition and returns it. Returns 0
- /// if it cannot be determined.
- size_t getPortWidth(RTLIL::Cell *a_Cell, RTLIL::IdString a_Port)
+ /// Looks up port width and direction in the cell definition and returns it.
+ /// Returns (0, false) if it cannot be determined.
+ std::pair<size_t, bool> getPortInfo(RTLIL::Cell *a_Cell, RTLIL::IdString a_Port)
{
-
if (!a_Cell->known()) {
- return 0;
+ return std::make_pair(0, false);
}
// Get the module defining the cell (the previous condition ensures
// that the pointers are valid)
RTLIL::Module *mod = a_Cell->module->design->module(a_Cell->type);
if (mod == nullptr) {
- return 0;
+ return std::make_pair(0, false);
}
// Get the wire representing the port
RTLIL::Wire *wire = mod->wire(a_Port);
if (wire == nullptr) {
- return 0;
+ return std::make_pair(0, false);
}
- return wire->width;
+ return std::make_pair(wire->width, wire->port_output);
}
/// Given a DSP cell populates and returns a DspConfig struct for it.