interchange: site router: add valid pips list to check during routing

Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
Alessandro Comodi 2021-05-12 18:25:47 +02:00
parent fd93697a2d
commit 8c468acff8
3 changed files with 59 additions and 11 deletions

View File

@ -1776,15 +1776,15 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
}
}
auto tile_status_iter = tileStatus.find(pip.tile);
if (pip_data.pseudo_cell_wires.size() > 0) {
// FIXME: This pseudo pip check is incomplete, because constraint
// failures will not be detected. However the current FPGA
// interchange schema does not provide a cell type to place.
auto iter = tileStatus.find(pip.tile);
if (iter != tileStatus.end()) {
if (!iter->second.pseudo_pip_model.checkPipAvail(getCtx(), pip)) {
return false;
}
if (tile_status_iter != tileStatus.end() &&
!tile_status_iter->second.pseudo_pip_model.checkPipAvail(getCtx(), pip)) {
return false;
}
}
@ -1797,12 +1797,16 @@ bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
bool valid_pip = false;
if (pip.tile == net->driver.cell->bel.tile) {
const BelInfoPOD &bel_data = tile_type.bel_data[net->driver.cell->bel.index];
if (bel_data.site == pip_data.site) {
// Only allow site pips or output site ports.
if (dst_wire_data.site == -1) {
// Allow output site port from this site.
NPNR_ASSERT(src_wire_data.site == pip_data.site);
if (tile_status_iter == tileStatus.end()) {
// there is no tile status and nothing blocks the validity of this PIP
valid_pip = true;
} else {
const BelInfoPOD &bel_data = tile_type.bel_data[net->driver.cell->bel.index];
const SiteRouter &site_router = get_site_status(tile_status_iter->second, bel_data);
const auto& pips = site_router.valid_pips;
auto result = std::find(pips.begin(), pips.end(), pip);
if (result != pips.end()) {
valid_pip = true;
}
}

View File

@ -1070,6 +1070,47 @@ static void block_lut_outputs(SiteArch *site_arch,
}
}
// Recursively visit downhill PIPs until a SITE_PORT_SINK is reached.
// Marks all PIPs for all valid paths.
static bool visit_downhill_pips(const SiteArch *site_arch, const SiteWire &site_wire, std::vector<PipId> &valid_pips) {
bool valid_path_exists = false;
for (SitePip site_pip : site_arch->getPipsDownhill(site_wire)) {
const SiteWire &dst_wire = site_arch->getPipDstWire(site_pip);
if (dst_wire.type == SiteWire::SITE_PORT_SINK) {
valid_pips.push_back(site_pip.pip);
return true;
}
bool path_ok = visit_downhill_pips(site_arch, dst_wire, valid_pips);
valid_path_exists |= path_ok;
if (path_ok) {
valid_pips.push_back(site_pip.pip);
}
}
return valid_path_exists;
}
// 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) {
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;
if (net->driver.cell && cells_in_site.count(net->driver.cell)) {
const SiteWire &site_wire = site_net->driver;
visit_downhill_pips(site_arch, site_wire, valid_pips);
}
}
return valid_pips;
}
bool SiteRouter::checkSiteRouting(const Context *ctx, const TileStatus &tile_status) const
{
// Overview:
@ -1211,6 +1252,8 @@ void SiteRouter::bindSiteRouting(Context *ctx)
check_routing(site_arch);
apply_routing(ctx, site_arch);
valid_pips = check_downhill_pips(ctx, &site_arch);
if (verbose_site_router(ctx)) {
print_current_state(&site_arch);
}

View File

@ -38,6 +38,7 @@ struct SiteRouter
SiteRouter(int16_t site) : site(site), dirty(false), site_ok(true) {}
std::unordered_set<CellInfo *> cells_in_site;
std::vector<PipId> valid_pips;
const int16_t site;
mutable bool dirty;