diff options
author | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-16 17:25:16 -0800 |
---|---|---|
committer | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-17 12:03:16 -0800 |
commit | f9bd692f75dbbd3f4cfba605e8438462885d27c8 (patch) | |
tree | 86391cdcc0fcd8ed1b95374c008bc0058e077e43 | |
parent | cc687b3b726d538be4a8dfa6cb8e1b4b96a837e2 (diff) | |
download | nextpnr-f9bd692f75dbbd3f4cfba605e8438462885d27c8.tar.gz nextpnr-f9bd692f75dbbd3f4cfba605e8438462885d27c8.tar.bz2 nextpnr-f9bd692f75dbbd3f4cfba605e8438462885d27c8.zip |
Change how package pin IO sites are selected.
The first site type that matches is now selected, under the premise that
the early site types are more general.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
-rw-r--r-- | fpga_interchange/arch.cc | 18 | ||||
-rw-r--r-- | fpga_interchange/arch_pack_io.cc | 48 | ||||
-rw-r--r-- | fpga_interchange/main.cc | 2 |
3 files changed, 52 insertions, 16 deletions
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index fb4b1b3d..561f495d 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -174,6 +174,22 @@ Arch::Arch(ArchArgs args) : args(args) definition.states.push_back(IdString(state)); } } + + // Logic BELs (e.g. placable BELs) should always appear first in the + // bel data list. + // + // When iterating over BELs this property is depended on to skip + // non-placable BELs (e.g. routing BELs and site ports). + bool in_logic_bels = true; + for (const BelInfoPOD &bel_info : tile_type.bel_data) { + if (in_logic_bels && bel_info.category != BEL_CATEGORY_LOGIC) { + in_logic_bels = false; + } + + if (!in_logic_bels) { + NPNR_ASSERT(bel_info.category != BEL_CATEGORY_LOGIC); + } + } } default_tags.resize(max_tag_count); @@ -832,7 +848,7 @@ size_t Arch::get_cell_type_index(IdString cell_type) const { const CellMapPOD &cell_map = *chip_info->cell_map; int cell_offset = cell_type.index - cell_map.cell_names[0]; - if((cell_offset < 0 || cell_offset >= cell_map.cell_names.ssize())) { + if ((cell_offset < 0 || cell_offset >= cell_map.cell_names.ssize())) { log_error("Cell %s is not a placable element.\n", cell_type.c_str(this)); } NPNR_ASSERT(cell_map.cell_names[cell_offset] == cell_type.index); diff --git a/fpga_interchange/arch_pack_io.cc b/fpga_interchange/arch_pack_io.cc index 2bddad8b..8a0fdc05 100644 --- a/fpga_interchange/arch_pack_io.cc +++ b/fpga_interchange/arch_pack_io.cc @@ -67,7 +67,7 @@ void Arch::pack_ports() // set(site_types) for package pins std::unordered_set<IdString> package_sites; // Package pin -> (Site type -> BelId) - std::unordered_map<IdString, std::unordered_map<IdString, BelId>> package_pin_bels; + std::unordered_map<IdString, std::vector<std::pair<IdString, BelId>>> package_pin_bels; for (const PackagePinPOD &package_pin : chip_info->packages[package_index].pins) { IdString pin(package_pin.package_pin); IdString bel(package_pin.bel); @@ -94,7 +94,7 @@ void Arch::pack_ports() BelId bel; bel.tile = i; bel.index = j; - package_pin_bels[pin][site_type] = bel; + package_pin_bels[pin].push_back(std::make_pair(site_type, bel)); } } } @@ -136,9 +136,9 @@ void Arch::pack_ports() } } - if(getCtx()->verbose) { + if (getCtx()->verbose) { log_info("Tightly attached BELs for port %s\n", port_name.c_str(getCtx())); - for(CellInfo * cell : tightly_attached_bels) { + for (CellInfo *cell : tightly_attached_bels) { log_info(" - %s : %s\n", cell->name.c_str(getCtx()), cell->type.c_str(getCtx())); } } @@ -156,6 +156,10 @@ void Arch::pack_ports() for (const TileTypeInfoPOD &tile_type : chip_info->tile_types) { IdString tile_type_name(tile_type.name); for (const BelInfoPOD &bel_info : tile_type.bel_data) { + if (bel_info.category != BEL_CATEGORY_LOGIC) { + break; + } + for (IdString cell_type : cell_types_in_io_group) { size_t cell_type_index = get_cell_type_index(cell_type); if (bel_info.category == BEL_CATEGORY_LOGIC && bel_info.pin_map[cell_type_index] != -1) { @@ -171,10 +175,17 @@ void Arch::pack_ports() } } - if(possible_site_types.empty()) { + if (possible_site_types.empty()) { log_error("Port '%s' has no possible site types!\n", port_name.c_str(getCtx())); } + if (getCtx()->verbose) { + log_info("Possible site types for port %s\n", port_name.c_str(getCtx())); + for (IdString site_type : possible_site_types) { + log_info(" - %s\n", site_type.c_str(getCtx())); + } + } + auto iter = port_cell->attrs.find(id("PACKAGE_PIN")); if (iter == port_cell->attrs.end()) { // FIXME: Relax this constraint @@ -188,28 +199,37 @@ void Arch::pack_ports() log_error("Package pin '%s' not found in part %s\n", package_pin_id.c_str(getCtx()), get_part().c_str()); } NPNR_ASSERT(pin_iter != package_pin_bels.end()); - const auto &site_type_to_bel = pin_iter->second; + // Select the first BEL from package_bel_pins that is a legal site + // type. + // + // This is likely the most generic (versus specialized) site type. BelId package_bel; - for (IdString site_type : possible_site_types) { - auto site_iter = site_type_to_bel.find(site_type); - if (site_iter != site_type_to_bel.end()) { + for (auto site_type_and_bel : pin_iter->second) { + IdString legal_site_type = site_type_and_bel.first; + BelId bel = site_type_and_bel.second; + + if (possible_site_types.count(legal_site_type)) { // FIXME: Need to handle case where a port can be in multiple // modes, but only one of the modes works. - // - // NPNR_ASSERT(package_bel == BelId()); - package_bel = site_iter->second; + package_bel = bel; + break; } } - if(package_bel == BelId()) { - log_info("Failed to find BEL for package pin '%s' in any possible site types:\n", package_pin_id.c_str(getCtx())); + if (package_bel == BelId()) { + log_info("Failed to find BEL for package pin '%s' in any possible site types:\n", + package_pin_id.c_str(getCtx())); for (IdString site_type : possible_site_types) { log_info(" - %s\n", site_type.c_str(getCtx())); } log_error("Failed to find BEL for package pin '%s'\n", package_pin_id.c_str(getCtx())); } + if (getCtx()->verbose) { + log_info("Binding port %s to BEL %s\n", port_name.c_str(getCtx()), getCtx()->nameOfBel(package_bel)); + } + std::unordered_set<CellInfo *> placed_cells; bindBel(package_bel, port_cell, STRENGTH_FIXED); placed_cells.emplace(port_cell); diff --git a/fpga_interchange/main.cc b/fpga_interchange/main.cc index ca9b1704..5a49cbdc 100644 --- a/fpga_interchange/main.cc +++ b/fpga_interchange/main.cc @@ -20,8 +20,8 @@ #ifdef MAIN_EXECUTABLE -#include <fstream> #include <chrono> +#include <fstream> #include "command.h" #include "design_utils.h" |