diff options
author | gatecat <gatecat@ds0.me> | 2021-07-10 23:24:38 +0100 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2021-07-10 23:24:38 +0100 |
commit | 8531658019a5d8f7834c6054e10c8438d8006505 (patch) | |
tree | 9ed98754646aeea1c7c2cae749c7f3f20f57fc40 | |
parent | d290766101a62d575c3e6aacbecde46ecab349f6 (diff) | |
parent | 478456e6e98c05ee5f810de0c0206daee25482f3 (diff) | |
download | nextpnr-8531658019a5d8f7834c6054e10c8438d8006505.tar.gz nextpnr-8531658019a5d8f7834c6054e10c8438d8006505.tar.bz2 nextpnr-8531658019a5d8f7834c6054e10c8438d8006505.zip |
Merge branch 'master' of github.com:YosysHQ/nextpnr
-rw-r--r-- | .github/workflows/interchange_ci.yml | 2 | ||||
-rw-r--r-- | fpga_interchange/arch.h | 2 | ||||
-rw-r--r-- | fpga_interchange/arch_pack_clusters.cc | 7 | ||||
-rw-r--r-- | fpga_interchange/chipdb.h | 3 | ||||
-rw-r--r-- | fpga_interchange/dedicated_interconnect.cc | 62 | ||||
-rw-r--r-- | gowin/arch.cc | 40 |
6 files changed, 93 insertions, 23 deletions
diff --git a/.github/workflows/interchange_ci.yml b/.github/workflows/interchange_ci.yml index d7dca9da..9b2ba027 100644 --- a/.github/workflows/interchange_ci.yml +++ b/.github/workflows/interchange_ci.yml @@ -114,7 +114,7 @@ jobs: env: RAPIDWRIGHT_PATH: ${{ github.workspace }}/RapidWright PYTHON_INTERCHANGE_PATH: ${{ github.workspace }}/python-fpga-interchange - PYTHON_INTERCHANGE_TAG: v0.0.15 + PYTHON_INTERCHANGE_TAG: v0.0.16 PRJOXIDE_REVISION: 1bf30dee9c023c4c66cfc44fd0bc28addd229c89 DEVICE: ${{ matrix.device }} run: | diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 896a603a..630c4480 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -855,7 +855,7 @@ struct Arch : ArchAPI<ArchRanges> const CellInfo *cell = tile_status.boundcells[bel.index]; if (cell != nullptr) { - if (cell->cluster == ClusterId() && !dedicated_interconnect.isBelLocationValid(bel, cell)) + if (!dedicated_interconnect.isBelLocationValid(bel, cell)) return false; if (io_port_types.count(cell->type)) { diff --git a/fpga_interchange/arch_pack_clusters.cc b/fpga_interchange/arch_pack_clusters.cc index 18162aa4..f4e50233 100644 --- a/fpga_interchange/arch_pack_clusters.cc +++ b/fpga_interchange/arch_pack_clusters.cc @@ -193,6 +193,8 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel, const Context *ctx = getCtx(); const Cluster &packed_cluster = clusters.at(cluster); + auto &cluster_data = cluster_info(chip_info, packed_cluster.index); + CellInfo *root_cell = getClusterRootCell(cluster); if (!ctx->isValidBelForCellType(root_cell->type, root_bel)) return false; @@ -205,8 +207,6 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel, next_bel = root_bel; } else { // Find next chained cluster node - auto &cluster_data = cluster_info(chip_info, packed_cluster.index); - IdString next_bel_pin(cluster_data.chainable_ports[0].bel_source); WireId next_bel_pin_wire = ctx->getBelPinWire(next_bel, next_bel_pin); next_bel = BelId(); @@ -256,7 +256,8 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel, WireId bel_pin_wire = ctx->getBelPinWire(next_bel, bel_pin); ExpansionDirection direction = port_type == PORT_IN ? CLUSTER_UPHILL_DIR : CLUSTER_DOWNHILL_DIR; - pool<BelId> cluster_bels = find_cluster_bels(ctx, bel_pin_wire, direction); + pool<BelId> cluster_bels = + find_cluster_bels(ctx, bel_pin_wire, direction, (bool)cluster_data.out_of_site_clusters); if (cluster_bels.size() == 0) continue; diff --git a/fpga_interchange/chipdb.h b/fpga_interchange/chipdb.h index fde35e7f..15ef8b07 100644 --- a/fpga_interchange/chipdb.h +++ b/fpga_interchange/chipdb.h @@ -34,7 +34,7 @@ NEXTPNR_NAMESPACE_BEGIN * kExpectedChipInfoVersion */ -static constexpr int32_t kExpectedChipInfoVersion = 11; +static constexpr int32_t kExpectedChipInfoVersion = 12; // Flattened site indexing. // @@ -421,6 +421,7 @@ NPNR_PACKED_STRUCT(struct ClusterPOD { RelSlice<uint32_t> root_cell_types; RelSlice<ChainablePortPOD> chainable_ports; RelSlice<ClusterCellPortPOD> cluster_cells_map; + uint32_t out_of_site_clusters; }); NPNR_PACKED_STRUCT(struct ChipInfoPOD { diff --git a/fpga_interchange/dedicated_interconnect.cc b/fpga_interchange/dedicated_interconnect.cc index 1254b367..7658d579 100644 --- a/fpga_interchange/dedicated_interconnect.cc +++ b/fpga_interchange/dedicated_interconnect.cc @@ -39,6 +39,12 @@ enum WireNodeState IN_SOURCE_SITE = 2 }; +enum ExpansionDirection +{ + EXPAND_DOWNHILL = 0, + EXPAND_UPHILL = 1 +}; + struct WireNode { WireId wire; @@ -52,6 +58,50 @@ struct WireNode // interconnect. constexpr int kMaxDepth = 6; +static uint32_t get_num_pips(const Context *ctx, WireId wire, ExpansionDirection direction) +{ + uint32_t num_pips = 0; + + if (direction == EXPAND_DOWNHILL) { + for (PipId pip : ctx->getPipsDownhill(wire)) { + auto &pip_data = pip_info(ctx->chip_info, pip); + if (pip_data.pseudo_cell_wires.size() > 0) + continue; + + if (ctx->getPipDstWire(pip) == WireId()) + continue; + + if (ctx->is_pip_synthetic(pip)) + continue; + + if (ctx->is_site_port(pip)) + continue; + + num_pips++; + } + } else { + NPNR_ASSERT(direction == EXPAND_UPHILL); + for (PipId pip : ctx->getPipsUphill(wire)) { + auto &pip_data = pip_info(ctx->chip_info, pip); + if (pip_data.pseudo_cell_wires.size() > 0) + continue; + + if (ctx->getPipSrcWire(pip) == WireId()) + continue; + + if (ctx->is_pip_synthetic(pip)) + continue; + + if (ctx->is_site_port(pip)) + continue; + + num_pips++; + } + } + + return num_pips; +} + void DedicatedInterconnect::init(const Context *ctx) { this->ctx = ctx; @@ -99,6 +149,16 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B WireNode node_to_expand = nodes_to_expand.back(); nodes_to_expand.pop_back(); + auto num_pips = get_num_pips(ctx, node_to_expand.wire, EXPAND_DOWNHILL); + + // Usually, dedicated interconnects do not have more than one PIPs in the out-of-site + if (node_to_expand.depth > 1 && node_to_expand.state == IN_ROUTING && num_pips > 1) { + if (ctx->verbose) + log_info("Wire %s is on a non-dedicated path (number of pips %d)\n", + ctx->nameOfWire(node_to_expand.wire), num_pips); + continue; + } + for (PipId pip : ctx->getPipsDownhill(node_to_expand.wire)) { if (ctx->is_pip_synthetic(pip)) { continue; @@ -147,7 +207,7 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B #ifdef DEBUG_EXPANSION log_info(" - Not dedicated site routing because loop!"); #endif - return false; + continue; } next_node.state = IN_SINK_SITE; break; diff --git a/gowin/arch.cc b/gowin/arch.cc index e8a14522..e4dce329 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -18,6 +18,7 @@ * */ +#include <boost/algorithm/string.hpp> #include <iostream> #include <math.h> #include <regex> @@ -483,37 +484,44 @@ DelayQuad Arch::getWireTypeDelay(IdString wire) void Arch::read_cst(std::istream &in) { - std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+);"); + std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+) *;.*"); + std::regex portre = std::regex("IO_PORT +\"([^\"]+)\" +([^ =;]+=[^ =;]+) *;.*"); std::smatch match; std::string line; + bool io_loc; while (!in.eof()) { std::getline(in, line); + io_loc = true; if (!std::regex_match(line, match, iobre)) { - // empty line or comment - if (line.empty() || line.rfind("//", 0) == 0) { - continue; + if (std::regex_match(line, match, portre)) { + io_loc = false; } else { - log_warning("Invalid constraint: %s\n", line.c_str()); + if ((!line.empty()) && (line.rfind("//", 0) == std::string::npos)) { + log_warning("Invalid constraint: %s\n", line.c_str()); + } continue; } } - // std::cout << match[1] << " " << match[2] << std::endl; + IdString net = id(match[1]); - IdString pinname = id(match[2]); - const PairPOD *belname = pairLookup(package->pins.get(), package->num_pins, pinname.index); - if (belname == nullptr) - log_error("Pin %s not found\n", pinname.c_str(this)); - // BelId bel = getBelByName(belname->src_id); - // for (auto cell : sorted(cells)) { - // std::cout << cell.first.str(this) << std::endl; - // } auto it = cells.find(net); if (it == cells.end()) { log_info("Cell %s not found\n", net.c_str(this)); continue; } - std::string bel = IdString(belname->src_id).str(this); - it->second->attrs[IdString(ID_BEL)] = bel; + if (io_loc) { // IO_LOC name pin + IdString pinname = id(match[2]); + const PairPOD *belname = pairLookup(package->pins.get(), package->num_pins, pinname.index); + if (belname == nullptr) + log_error("Pin %s not found\n", pinname.c_str(this)); + std::string bel = IdString(belname->src_id).str(this); + it->second->attrs[IdString(ID_BEL)] = bel; + } else { // IO_PORT attr=value + std::string attr = "&"; + attr += match[2]; + boost::algorithm::to_upper(attr); + it->second->attrs[id(attr)] = 1; + } } } |