Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interchange: pseudo pips: fix illegal tile pseudo PIPs #706

Merged
merged 1 commit into from
May 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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