Skip to content

Commit

Permalink
Merge pull request #706 from acomodi/fix-illegal-site-thru
Browse files Browse the repository at this point in the history
interchange: pseudo pips: fix illegal tile pseudo PIPs
  • Loading branch information
gatecat committed May 14, 2021
2 parents 21d594a + 428b565 commit 1b57679
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 21 deletions.
52 changes: 37 additions & 15 deletions fpga_interchange/pseudo_pip_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand Down
30 changes: 24 additions & 6 deletions fpga_interchange/site_router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions fpga_interchange/site_router.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 1b57679

Please sign in to comment.