aboutsummaryrefslogtreecommitdiffstats
path: root/passes/techmap
diff options
context:
space:
mode:
Diffstat (limited to 'passes/techmap')
-rw-r--r--passes/techmap/abc9_map.cc13
-rw-r--r--passes/techmap/abc9_ops.cc39
2 files changed, 48 insertions, 4 deletions
diff --git a/passes/techmap/abc9_map.cc b/passes/techmap/abc9_map.cc
index e6e4e3e72..c01feedb6 100644
--- a/passes/techmap/abc9_map.cc
+++ b/passes/techmap/abc9_map.cc
@@ -438,19 +438,24 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
if (existing_cell) {
cell->parameters = existing_cell->parameters;
cell->attributes = existing_cell->attributes;
- if (cell->attributes.erase("\\abc9_box_seq")) {
- module->swap_names(cell, existing_cell);
- module->remove(existing_cell);
- }
}
else {
cell->parameters = mapped_cell->parameters;
cell->attributes = mapped_cell->attributes;
}
+ auto abc9_box = cell->attributes.erase("\\abc9_box_seq");
+ if (abc9_box) {
+ module->swap_names(cell, existing_cell);
+ module->remove(existing_cell);
+ }
RTLIL::Module* box_module = design->module(mapped_cell->type);
auto abc9_flop = box_module && box_module->attributes.count("\\abc9_flop");
for (auto &conn : mapped_cell->connections()) {
+ // Skip entire box ports composed entirely of padding only
+ if (abc9_box && conn.second.is_wire() && conn.second.as_wire()->get_bool_attribute(ID(abc9_padding)))
+ continue;
+
RTLIL::SigSpec newsig;
for (auto c : conn.second.chunks()) {
if (c.width == 0)
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index 730431ebf..ab5aa9f8d 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -254,6 +254,45 @@ void prep_holes(RTLIL::Module *module, bool dff)
RTLIL::Module* box_module = design->module(cell->type);
if (!box_module || !box_module->attributes.count("\\abc9_box_id"))
continue;
+
+ bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */);
+
+ // Fully pad all unused input connections of this box cell with S0
+ // Fully pad all undriven output connections of this box cell with anonymous wires
+ for (const auto &port_name : box_module->ports) {
+ RTLIL::Wire* w = box_module->wire(port_name);
+ log_assert(w);
+ auto it = cell->connections_.find(port_name);
+ if (w->port_input) {
+ RTLIL::SigSpec rhs;
+ if (it != cell->connections_.end()) {
+ if (GetSize(it->second) < GetSize(w))
+ it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second)));
+ rhs = it->second;
+ }
+ else {
+ rhs = RTLIL::SigSpec(State::S0, GetSize(w));
+ cell->setPort(port_name, rhs);
+ }
+ }
+ if (w->port_output) {
+ RTLIL::SigSpec rhs;
+ auto it = cell->connections_.find(w->name);
+ if (it != cell->connections_.end()) {
+ if (GetSize(it->second) < GetSize(w))
+ it->second.append(module->addWire(NEW_ID, GetSize(w)-GetSize(it->second)));
+ rhs = it->second;
+ }
+ else {
+ Wire *wire = module->addWire(NEW_ID, GetSize(w));
+ if (blackbox)
+ wire->set_bool_attribute(ID(abc9_padding));
+ rhs = wire;
+ cell->setPort(port_name, rhs);
+ }
+ }
+ }
+
cell->attributes["\\abc9_box_seq"] = box_list.size();
box_list.emplace_back(cell);
}