diff options
author | gatecat <gatecat@ds0.me> | 2021-05-12 20:35:02 +0100 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2021-05-15 14:54:33 +0100 |
commit | d39e67da7ed08b790fcc0b3c7ff9551164070fb2 (patch) | |
tree | e2ae7c00050b7580fd83b5b9bcc1ac1763a604fe /mistral/pack.cc | |
parent | 7574eab2b603bd850d6f3819d2183d8600b59cd3 (diff) | |
download | nextpnr-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.cc | 41 |
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 |