aboutsummaryrefslogtreecommitdiffstats
path: root/mistral/pack.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-05-12 20:35:02 +0100
committergatecat <gatecat@ds0.me>2021-05-15 14:54:33 +0100
commitd39e67da7ed08b790fcc0b3c7ff9551164070fb2 (patch)
treee2ae7c00050b7580fd83b5b9bcc1ac1763a604fe /mistral/pack.cc
parent7574eab2b603bd850d6f3819d2183d8600b59cd3 (diff)
downloadnextpnr-d39e67da7ed08b790fcc0b3c7ff9551164070fb2.tar.gz
nextpnr-d39e67da7ed08b790fcc0b3c7ff9551164070fb2.tar.bz2
nextpnr-d39e67da7ed08b790fcc0b3c7ff9551164070fb2.zip
mistral: First pass at carry packing
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'mistral/pack.cc')
-rw-r--r--mistral/pack.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/mistral/pack.cc b/mistral/pack.cc
index 78657321..aed9572e 100644
--- a/mistral/pack.cc
+++ b/mistral/pack.cc
@@ -275,11 +275,52 @@ struct MistralPacker
}
}
+ void constrain_carries()
+ {
+ for (auto cell : sorted(ctx->cells)) {
+ CellInfo *ci = cell.second;
+ if (ci->type != id_MISTRAL_ALUT_ARITH)
+ continue;
+ const NetInfo *cin = get_net_or_empty(ci, id_CI);
+ if (cin != nullptr && cin->driver.cell != nullptr)
+ continue; // not the start of a chain
+ std::vector<CellInfo *> chain;
+ CellInfo *cursor = ci;
+ while (true) {
+ chain.push_back(cursor);
+ const NetInfo *co = get_net_or_empty(cursor, id_CO);
+ if (co == nullptr || co->users.empty())
+ break;
+ if (co->users.size() > 1)
+ log_error("Carry net %s has more than one sink!\n", ctx->nameOf(co));
+ auto &usr = co->users.at(0);
+ if (usr.port != id_CI)
+ log_error("Carry net %s drives port %s, expected CI\n", ctx->nameOf(co), ctx->nameOf(usr.port));
+ cursor = usr.cell;
+ }
+
+ chain.at(0)->constr_abs_z = true;
+ chain.at(0)->constr_z = 0;
+ chain.at(0)->cluster = chain.at(0)->name;
+
+ for (int i = 1; i < int(chain.size()); i++) {
+ chain.at(i)->constr_x = 0;
+ chain.at(i)->constr_y = (i / 20);
+ // 2 COMB, 4 FF per ALM
+ chain.at(i)->constr_z = ((i / 2) % 10) * 6 + (i % 2);
+ chain.at(i)->constr_abs_z = true;
+ chain.at(i)->cluster = chain.at(0)->name;
+ chain.at(0)->constr_children.push_back(chain.at(i));
+ }
+ }
+ }
+
void run()
{
init_constant_nets();
pack_constants();
pack_io();
+ constrain_carries();
}
};
}; // namespace