From a7421399f776ed9aebfa7b940bbaf5f327244f17 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 5 Feb 2021 14:18:38 -0800 Subject: Working on standing up initial constraints system. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fpga_interchange/arch.cc | 87 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 11 deletions(-) (limited to 'fpga_interchange/arch.cc') diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index c24ec660..41659861 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -25,6 +25,7 @@ #include #include #include +#include "constraints.impl.h" #include "fpga_interchange.h" #include "log.h" #include "nextpnr.h" @@ -89,11 +90,8 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unable to read chipdb %s\n", args.chipdb.c_str()); } - tileStatus.resize(chip_info->tiles.size()); - for (int i = 0; i < chip_info->tiles.ssize(); i++) { - tileStatus[i].boundcells.resize(chip_info->tile_types[chip_info->tiles[i].type].bel_data.size()); - } - + // Read strings from constids into IdString database, checking that list + // is unique and matches expected constid value. const RelSlice> &constids = *chip_info->constids; for (size_t i = 0; i < constids.size(); ++i) { IdString::initialize_add(this, constids[i].get(), i + 1); @@ -155,6 +153,30 @@ Arch::Arch(ArchArgs args) : args(args) pads.emplace(bel); } } + + explain_constraints = false; + + int tile_type_index = 0; + size_t max_tag_count = 0; + for (const TileTypeInfoPOD &tile_type : chip_info->tile_types) { + max_tag_count = std::max(max_tag_count, tile_type.tags.size()); + + auto &type_definition = constraints.definitions[tile_type_index]; + for (const ConstraintTagPOD &tag : tile_type.tags) { + type_definition.emplace_back(); + auto &definition = type_definition.back(); + definition.prefix = IdString(tag.tag_prefix); + definition.default_state = IdString(tag.default_state); + NPNR_ASSERT(tag.states.size() < kMaxState); + + definition.states.reserve(tag.states.size()); + for (auto state : tag.states) { + definition.states.push_back(IdString(state)); + } + } + } + + default_tags.resize(max_tag_count); } // ----------------------------------------------------------------------- @@ -563,20 +585,55 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay bool Arch::pack() { - // FIXME: Implement this - return false; + pack_ports(); + return true; } bool Arch::place() { - // FIXME: Implement this - return false; + std::string placer = str_or_default(settings, id("placer"), defaultPlacer); + + if (placer == "heap") { + PlacerHeapCfg cfg(getCtx()); + cfg.criticalityExponent = 7; + cfg.alpha = 0.08; + cfg.beta = 0.4; + cfg.placeAllAtOnce = true; + cfg.hpwl_scale_x = 1; + cfg.hpwl_scale_y = 2; + cfg.spread_scale_x = 2; + cfg.spread_scale_y = 1; + cfg.solverTolerance = 0.6e-6; + if (!placer_heap(getCtx(), cfg)) + return false; + } else if (placer == "sa") { + if (!placer1(getCtx(), Placer1Cfg(getCtx()))) + return false; + } else { + log_error("FPGA interchange architecture does not support placer '%s'\n", placer.c_str()); + } + + getCtx()->attrs[getCtx()->id("step")] = std::string("place"); + archInfoToAttributes(); + return true; } bool Arch::route() { - // FIXME: Implement this - return false; + 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()); + } + getCtx()->attrs[getCtx()->id("step")] = std::string("route"); + archInfoToAttributes(); + return result; } // ----------------------------------------------------------------------- @@ -771,4 +828,12 @@ bool Arch::is_net_within_site(const NetInfo &net) const return true; } +// Instance constraint templates. +template void Arch::ArchConstraints::bindBel(Arch::ArchConstraints::TagState *, const Arch::ConstraintRange); +template void Arch::ArchConstraints::unbindBel(Arch::ArchConstraints::TagState *, const Arch::ConstraintRange); +template bool Arch::ArchConstraints::isValidBelForCellType(const Context *, uint32_t, + const Arch::ArchConstraints::TagState *, + const Arch::ConstraintRange, IdString, IdString, BelId, + bool) const; + NEXTPNR_NAMESPACE_END -- cgit v1.2.3