Merge pull request #706 from acomodi/fix-illegal-site-thru
interchange: pseudo pips: fix illegal tile pseudo PIPs
This commit is contained in:
commit
1b5767928d
@ -353,6 +353,37 @@ void PseudoPipModel::update_site(const Context *ctx, size_t site)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CellInfo> lut_thru_cells;
|
||||
lut_thru_cells.reserve(tile_status.sites[site].lut_thrus.size());
|
||||
for (auto input_bel_pin : tile_status.sites[site].lut_thrus) {
|
||||
if (ctx->wire_lut == nullptr)
|
||||
break;
|
||||
|
||||
BelId bel;
|
||||
bel.index = input_bel_pin.second;
|
||||
bel.tile = tile;
|
||||
const auto &bel_data = bel_info(ctx->chip_info, bel);
|
||||
|
||||
NPNR_ASSERT(bel_data.lut_element != -1);
|
||||
|
||||
lut_thru_cells.emplace_back();
|
||||
CellInfo &cell = lut_thru_cells.back();
|
||||
|
||||
cell.bel = bel;
|
||||
|
||||
cell.type = IdString(ctx->wire_lut->cell);
|
||||
NPNR_ASSERT(ctx->wire_lut->input_pins.size() == 1);
|
||||
cell.lut_cell.pins.push_back(IdString(ctx->wire_lut->input_pins[0]));
|
||||
|
||||
cell.lut_cell.equation.resize(2);
|
||||
cell.lut_cell.equation.set(0, false);
|
||||
cell.lut_cell.equation.set(1, true);
|
||||
|
||||
cell.cell_bel_pins[IdString(ctx->wire_lut->input_pins[0])].push_back(input_bel_pin.first);
|
||||
|
||||
lut_mappers[bel_data.lut_element].cells.push_back(&cell);
|
||||
}
|
||||
|
||||
std::vector<CellInfo> lut_cells;
|
||||
lut_cells.reserve(used_bels.size());
|
||||
for (const auto &bel_pair : used_bels) {
|
||||
@ -370,9 +401,8 @@ void PseudoPipModel::update_site(const Context *ctx, size_t site)
|
||||
cell.bel.tile = tile;
|
||||
cell.bel.index = bel_pair.first;
|
||||
|
||||
if (ctx->wire_lut == nullptr) {
|
||||
if (ctx->wire_lut == nullptr)
|
||||
continue;
|
||||
}
|
||||
|
||||
cell.type = IdString(ctx->wire_lut->cell);
|
||||
NPNR_ASSERT(ctx->wire_lut->input_pins.size() == 1);
|
||||
@ -437,11 +467,6 @@ void PseudoPipModel::update_site(const Context *ctx, size_t site)
|
||||
}
|
||||
}
|
||||
|
||||
if (blocked_by_bel) {
|
||||
allowed_pseudo_pips.set(pseudo_pip, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool blocked_by_lut_eq = false;
|
||||
|
||||
// See if any BELs are part of a LUT element. If so, see if using
|
||||
@ -480,20 +505,17 @@ void PseudoPipModel::update_site(const Context *ctx, size_t site)
|
||||
}
|
||||
}
|
||||
|
||||
if (blocked_by_lut_eq) {
|
||||
#ifdef DEBUG_PSEUDO_PIP
|
||||
if (ctx->verbose) {
|
||||
log_info("Pseudo pip %s is blocked by lut eq\n", ctx->nameOfPip(pip));
|
||||
}
|
||||
#endif
|
||||
allowed_pseudo_pips.set(pseudo_pip, false);
|
||||
continue;
|
||||
if (blocked_by_lut_eq && ctx->verbose) {
|
||||
log_info("Pseudo pip %s is blocked by invalid LUT equation\n", ctx->nameOfPip(pip));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Pseudo pip should be allowed, mark as such.
|
||||
//
|
||||
// FIXME: Handle non-LUT constraint cases, as needed.
|
||||
allowed_pseudo_pips.set(pseudo_pip, true);
|
||||
bool allow_pip = !blocked_by_lut_eq && !blocked_by_bel;
|
||||
allowed_pseudo_pips.set(pseudo_pip, allow_pip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -964,7 +964,7 @@ static void apply_constant_routing(Context *ctx, const SiteArch &site_arch, NetI
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_routing(Context *ctx, const SiteArch &site_arch)
|
||||
static void apply_routing(Context *ctx, const SiteArch &site_arch, HashTables::HashSet<std::pair<IdString, int32_t>, PairHash> &lut_thrus)
|
||||
{
|
||||
IdString gnd_net_name(ctx->chip_info->constants->gnd_net_name);
|
||||
NetInfo *gnd_net = ctx->nets.at(gnd_net_name).get();
|
||||
@ -993,6 +993,26 @@ static void apply_routing(Context *ctx, const SiteArch &site_arch)
|
||||
continue;
|
||||
}
|
||||
|
||||
auto &pip_data = pip_info(ctx->chip_info, site_pip.pip);
|
||||
|
||||
BelId bel;
|
||||
bel.tile = site_pip.pip.tile;
|
||||
bel.index = pip_data.bel;
|
||||
const auto &bel_data = bel_info(ctx->chip_info, bel);
|
||||
|
||||
// Detect and store LUT thrus for allowance check during routing
|
||||
if (bel_data.lut_element != -1) {
|
||||
WireId src_wire = ctx->getPipSrcWire(site_pip.pip);
|
||||
|
||||
for (BelPin bel_pin : ctx->getWireBelPins(src_wire)) {
|
||||
if (bel_pin.bel != bel)
|
||||
continue;
|
||||
|
||||
lut_thrus.insert(std::make_pair(bel_pin.pin, bel_pin.bel.index));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->bindPip(site_pip.pip, net, STRENGTH_PLACER);
|
||||
}
|
||||
}
|
||||
@ -1094,10 +1114,9 @@ static bool visit_downhill_pips(const SiteArch *site_arch, const SiteWire &site_
|
||||
|
||||
// Checks all downhill PIPs starting from driver wires.
|
||||
// All valid PIPs are stored and returned in a vector.
|
||||
static std::vector<PipId> check_downhill_pips(Context *ctx, const SiteArch *site_arch) {
|
||||
static void check_downhill_pips(Context *ctx, const SiteArch *site_arch, std::vector<PipId> &valid_pips) {
|
||||
auto &cells_in_site = site_arch->site_info->cells_in_site;
|
||||
|
||||
std::vector<PipId> valid_pips;
|
||||
for (auto &net_pair : site_arch->nets) {
|
||||
NetInfo *net = net_pair.first;
|
||||
const SiteNetInfo *site_net = &net_pair.second;
|
||||
@ -1108,7 +1127,6 @@ static std::vector<PipId> check_downhill_pips(Context *ctx, const SiteArch *site
|
||||
visit_downhill_pips(site_arch, site_wire, valid_pips);
|
||||
}
|
||||
}
|
||||
return valid_pips;
|
||||
}
|
||||
|
||||
bool SiteRouter::checkSiteRouting(const Context *ctx, const TileStatus &tile_status) const
|
||||
@ -1251,9 +1269,9 @@ void SiteRouter::bindSiteRouting(Context *ctx)
|
||||
NPNR_ASSERT(route_site(&site_arch, &ctx->site_routing_cache, &ctx->node_storage, /*explain=*/false));
|
||||
|
||||
check_routing(site_arch);
|
||||
apply_routing(ctx, site_arch);
|
||||
apply_routing(ctx, site_arch, lut_thrus);
|
||||
|
||||
valid_pips = check_downhill_pips(ctx, &site_arch);
|
||||
check_downhill_pips(ctx, &site_arch, valid_pips);
|
||||
if (verbose_site_router(ctx)) {
|
||||
print_current_state(&site_arch);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ struct SiteRouter
|
||||
|
||||
std::unordered_set<CellInfo *> cells_in_site;
|
||||
std::vector<PipId> valid_pips;
|
||||
HashTables::HashSet<std::pair<IdString, int32_t>, PairHash> lut_thrus;
|
||||
const int16_t site;
|
||||
|
||||
mutable bool dirty;
|
||||
|
Loading…
Reference in New Issue
Block a user