summaryrefslogtreecommitdiff
path: root/passes/sat
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-07-20 17:06:36 +0200
committerClifford Wolf <clifford@clifford.at>2014-07-20 17:06:36 +0200
commitff28029fdb4fe97dca0e93b175dd2d6411671cb0 (patch)
treed8dd4475736fd1d7ce34758261871b89dbc9a729 /passes/sat
parent4af8d84f015edd229328a09c462c8ad81e06892f (diff)
Fixed creation of shift supercells in "share" pass
Diffstat (limited to 'passes/sat')
-rw-r--r--passes/sat/share.cc24
1 files changed, 20 insertions, 4 deletions
diff --git a/passes/sat/share.cc b/passes/sat/share.cc
index 9ad1d621..27b21207 100644
--- a/passes/sat/share.cc
+++ b/passes/sat/share.cc
@@ -135,7 +135,7 @@ struct ShareWorker
continue;
// FIXME: Creation of super cells is broken for this cell types
- if (cell->type == "$shr" || cell->type == "$mod")
+ if (cell->type == "$div" || cell->type == "$mod")
continue;
if (config.opt_force) {
@@ -246,6 +246,9 @@ struct ShareWorker
log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool());
log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool());
+ if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr")
+ b_signed = false;
+
RTLIL::SigSpec a1 = c1->connections.at("\\A");
RTLIL::SigSpec b1 = c1->connections.at("\\B");
RTLIL::SigSpec y1 = c1->connections.at("\\Y");
@@ -258,10 +261,23 @@ struct ShareWorker
int b_width = std::max(b1.width, b2.width);
int y_width = std::max(y1.width, y2.width);
- if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y");
- if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y");
+ if (c1->type == "$shr" && a_signed)
+ {
+ a_width = std::max(y_width, a_width);
+
+ if (a1.width < y1.width) a1 = module->addPos(NEW_ID, a1, module->new_wire(y1.width, NEW_ID), true)->connections.at("\\Y");
+ if (a2.width < y2.width) a2 = module->addPos(NEW_ID, a2, module->new_wire(y2.width, NEW_ID), true)->connections.at("\\Y");
+
+ if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y");
+ if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y");
+ }
+ else
+ {
+ if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y");
+ if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y");
+ }
- if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y");
+ if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y");
if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y");
RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act);