Skip to content

Commit

Permalink
Merge pull request #700 from acomodi/fix-illegal-site-thru
Browse files Browse the repository at this point in the history
interchange: arch: do not allow site pips within sites
  • Loading branch information
gatecat authored May 13, 2021
2 parents ced31aa + 8c468ac commit 21d594a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
30 changes: 14 additions & 16 deletions fpga_interchange/arch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand All @@ -1797,18 +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);
valid_pip = true;
}
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);

if (dst_wire_data.site == bel_data.site && src_wire_data.site == bel_data.site) {
// This is site pip for the same site as the driver, allow
// this site pip.
const auto& pips = site_router.valid_pips;
auto result = std::find(pips.begin(), pips.end(), pip);
if (result != pips.end()) {
valid_pip = true;
}
}
Expand Down
43 changes: 43 additions & 0 deletions fpga_interchange/site_router.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
}
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 @@ -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;
Expand Down

0 comments on commit 21d594a

Please sign in to comment.