aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/arch.cc
diff options
context:
space:
mode:
authorKeith Rothman <537074+litghost@users.noreply.github.com>2021-03-24 16:25:15 -0700
committerKeith Rothman <537074+litghost@users.noreply.github.com>2021-03-25 17:20:13 -0700
commit91ca5f110bdea0dbf1b6183d8129c3ea7b0c71c6 (patch)
treeab411c5dfb8543540da838991a454807670d96eb /fpga_interchange/arch.cc
parent5dda3a14ffd962407217cff4bb2859bebc503b8b (diff)
downloadnextpnr-91ca5f110bdea0dbf1b6183d8129c3ea7b0c71c6.tar.gz
nextpnr-91ca5f110bdea0dbf1b6183d8129c3ea7b0c71c6.tar.bz2
nextpnr-91ca5f110bdea0dbf1b6183d8129c3ea7b0c71c6.zip
Re-work LUT mapping logic to only put VCC pins when required.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'fpga_interchange/arch.cc')
-rw-r--r--fpga_interchange/arch.cc133
1 files changed, 35 insertions, 98 deletions
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc
index ceb023d4..e6e784f7 100644
--- a/fpga_interchange/arch.cc
+++ b/fpga_interchange/arch.cc
@@ -794,89 +794,11 @@ static void prepare_sites_for_routing(Context *ctx)
site_router.bindSiteRouting(ctx);
}
}
-}
-
-bool Arch::route()
-{
- getCtx()->check();
- prepare_sites_for_routing(getCtx());
- getCtx()->check();
-#ifdef IDEMPOTENT_CHECK
- prepare_sites_for_routing(getCtx());
- getCtx()->check();
-#endif
-
- std::string router = str_or_default(settings, id("router"), defaultRouter);
-
- bool result;
- if (router == "router1") {
- result = router1(getCtx(), Router1Cfg(getCtx()));
- } else if (router == "router2") {
- router2(getCtx(), Router2Cfg(getCtx()));
- result = true;
- } else {
- log_error("FPGA interchange architecture does not support router '%s'\n", router.c_str());
- }
-
- if (result) {
- result = route_vcc_to_unused_lut_pins();
- }
-
- getCtx()->attrs[getCtx()->id("step")] = std::string("route");
- archInfoToAttributes();
-
- getCtx()->check();
-
- // Now that routing is complete, unmask BEL pins.
- unmask_bel_pins();
-
- getCtx()->check();
-
- return result;
-}
-
-bool Arch::route_vcc_to_unused_lut_pins()
-{
- std::string router = str_or_default(settings, id("router"), defaultRouter);
-
- HashTables::HashMap<WireId, const NetInfo *> bound_wires;
- for (auto &net_pair : nets) {
- const NetInfo *net = net_pair.second.get();
- for (auto &wire_pair : net->wires) {
- auto result = bound_wires.emplace(wire_pair.first, net);
- NPNR_ASSERT(result.first->second == net);
-
- PipId pip = wire_pair.second.pip;
- if (pip == PipId()) {
- continue;
- }
-
- const PipInfoPOD &pip_data = pip_info(chip_info, pip);
-#ifdef DEBUG_LUT_MAPPING
- if (getCtx()->verbose) {
- log_info("Pip %s in use, has %zu pseudo wires!\n", nameOfPip(pip), pip_data.pseudo_cell_wires.size());
- }
-#endif
-
- WireId wire;
- wire.tile = pip.tile;
- for (int32_t wire_index : pip_data.pseudo_cell_wires) {
- wire.index = wire_index;
-#ifdef DEBUG_LUT_MAPPING
- if (getCtx()->verbose) {
- log_info("Marking wire %s as in use due to pseudo pip\n", nameOfWire(wire));
- }
-#endif
- auto result = bound_wires.emplace(wire, net);
- NPNR_ASSERT(result.first->second == net);
- }
- }
- }
// Fixup LUT vcc pins.
- IdString vcc_net_name(chip_info->constants->vcc_net_name);
- for (BelId bel : getBels()) {
- CellInfo *cell = getBoundBelCell(bel);
+ IdString vcc_net_name(ctx->chip_info->constants->vcc_net_name);
+ for (BelId bel : ctx->getBels()) {
+ CellInfo *cell = ctx->getBoundBelCell(bel);
if (cell == nullptr) {
continue;
}
@@ -891,45 +813,60 @@ bool Arch::route_vcc_to_unused_lut_pins()
port_info.type = PORT_IN;
port_info.net = nullptr;
- WireId lut_pin_wire = getBelPinWire(bel, bel_pin);
- auto iter = bound_wires.find(lut_pin_wire);
- if (iter != bound_wires.end()) {
-#ifdef DEBUG_LUT_MAPPING
- if (getCtx()->verbose) {
- log_info("%s is now used as a LUT route-through, not tying to VCC\n", nameOfWire(lut_pin_wire));
- }
-#endif
- continue;
- }
-
#ifdef DEBUG_LUT_MAPPING
- if (getCtx()->verbose) {
- log_info("%s is an unused LUT pin, tying to VCC\n", nameOfWire(lut_pin_wire));
+ if (ctx->verbose) {
+ log_info("%s must be tied to VCC, tying now\n", ctx->nameOfWire(lut_pin_wire));
}
#endif
auto result = cell->ports.emplace(bel_pin, port_info);
if (result.second) {
cell->cell_bel_pins[bel_pin].push_back(bel_pin);
- connectPort(vcc_net_name, cell->name, bel_pin);
+ ctx->connectPort(vcc_net_name, cell->name, bel_pin);
cell->const_ports.emplace(bel_pin);
} else {
- NPNR_ASSERT(result.first->second.net == getNetByAlias(vcc_net_name));
+ NPNR_ASSERT(result.first->second.net == ctx->getNetByAlias(vcc_net_name));
auto result2 = cell->cell_bel_pins.emplace(bel_pin, std::vector<IdString>({bel_pin}));
NPNR_ASSERT(result2.first->second.at(0) == bel_pin);
NPNR_ASSERT(result2.first->second.size() == 1);
}
}
}
+}
+
+bool Arch::route()
+{
+ getCtx()->check();
+ prepare_sites_for_routing(getCtx());
+ getCtx()->check();
+#ifdef IDEMPOTENT_CHECK
+ prepare_sites_for_routing(getCtx());
+ getCtx()->check();
+#endif
+
+ std::string router = str_or_default(settings, id("router"), defaultRouter);
+ bool result;
if (router == "router1") {
- return router1(getCtx(), Router1Cfg(getCtx()));
+ result = router1(getCtx(), Router1Cfg(getCtx()));
} else if (router == "router2") {
router2(getCtx(), Router2Cfg(getCtx()));
- return true;
+ result = true;
} else {
log_error("FPGA interchange architecture does not support router '%s'\n", router.c_str());
}
+
+ getCtx()->attrs[getCtx()->id("step")] = std::string("route");
+ archInfoToAttributes();
+
+ getCtx()->check();
+
+ // Now that routing is complete, unmask BEL pins.
+ unmask_bel_pins();
+
+ getCtx()->check();
+
+ return result;
}
// -----------------------------------------------------------------------