interchange: reduce run-time to check dedicated interconnect
Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
parent
6829e4c197
commit
dc0819b01a
@ -855,7 +855,7 @@ struct Arch : ArchAPI<ArchRanges>
|
||||
const CellInfo *cell = tile_status.boundcells[bel.index];
|
||||
|
||||
if (cell != nullptr) {
|
||||
if (cell->cluster == ClusterId() && !dedicated_interconnect.isBelLocationValid(bel, cell))
|
||||
if (!dedicated_interconnect.isBelLocationValid(bel, cell))
|
||||
return false;
|
||||
|
||||
if (io_port_types.count(cell->type)) {
|
||||
|
@ -193,6 +193,8 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel,
|
||||
const Context *ctx = getCtx();
|
||||
const Cluster &packed_cluster = clusters.at(cluster);
|
||||
|
||||
auto &cluster_data = cluster_info(chip_info, packed_cluster.index);
|
||||
|
||||
CellInfo *root_cell = getClusterRootCell(cluster);
|
||||
if (!ctx->isValidBelForCellType(root_cell->type, root_bel))
|
||||
return false;
|
||||
@ -205,8 +207,6 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel,
|
||||
next_bel = root_bel;
|
||||
} else {
|
||||
// Find next chained cluster node
|
||||
auto &cluster_data = cluster_info(chip_info, packed_cluster.index);
|
||||
|
||||
IdString next_bel_pin(cluster_data.chainable_ports[0].bel_source);
|
||||
WireId next_bel_pin_wire = ctx->getBelPinWire(next_bel, next_bel_pin);
|
||||
next_bel = BelId();
|
||||
@ -256,7 +256,8 @@ bool Arch::getClusterPlacement(ClusterId cluster, BelId root_bel,
|
||||
WireId bel_pin_wire = ctx->getBelPinWire(next_bel, bel_pin);
|
||||
|
||||
ExpansionDirection direction = port_type == PORT_IN ? CLUSTER_UPHILL_DIR : CLUSTER_DOWNHILL_DIR;
|
||||
pool<BelId> cluster_bels = find_cluster_bels(ctx, bel_pin_wire, direction);
|
||||
pool<BelId> cluster_bels =
|
||||
find_cluster_bels(ctx, bel_pin_wire, direction, (bool)cluster_data.out_of_site_clusters);
|
||||
|
||||
if (cluster_bels.size() == 0)
|
||||
continue;
|
||||
|
@ -421,6 +421,7 @@ NPNR_PACKED_STRUCT(struct ClusterPOD {
|
||||
RelSlice<uint32_t> root_cell_types;
|
||||
RelSlice<ChainablePortPOD> chainable_ports;
|
||||
RelSlice<ClusterCellPortPOD> cluster_cells_map;
|
||||
uint32_t out_of_site_clusters;
|
||||
});
|
||||
|
||||
NPNR_PACKED_STRUCT(struct ChipInfoPOD {
|
||||
|
@ -39,6 +39,12 @@ enum WireNodeState
|
||||
IN_SOURCE_SITE = 2
|
||||
};
|
||||
|
||||
enum ExpansionDirection
|
||||
{
|
||||
EXPAND_DOWNHILL = 0,
|
||||
EXPAND_UPHILL = 1
|
||||
};
|
||||
|
||||
struct WireNode
|
||||
{
|
||||
WireId wire;
|
||||
@ -52,6 +58,50 @@ struct WireNode
|
||||
// interconnect.
|
||||
constexpr int kMaxDepth = 6;
|
||||
|
||||
static uint32_t get_num_pips(const Context *ctx, WireId wire, ExpansionDirection direction)
|
||||
{
|
||||
uint32_t num_pips = 0;
|
||||
|
||||
if (direction == EXPAND_DOWNHILL) {
|
||||
for (PipId pip : ctx->getPipsDownhill(wire)) {
|
||||
auto &pip_data = pip_info(ctx->chip_info, pip);
|
||||
if (pip_data.pseudo_cell_wires.size() > 0)
|
||||
continue;
|
||||
|
||||
if (ctx->getPipDstWire(pip) == WireId())
|
||||
continue;
|
||||
|
||||
if (ctx->is_pip_synthetic(pip))
|
||||
continue;
|
||||
|
||||
if (ctx->is_site_port(pip))
|
||||
continue;
|
||||
|
||||
num_pips++;
|
||||
}
|
||||
} else {
|
||||
NPNR_ASSERT(direction == EXPAND_UPHILL);
|
||||
for (PipId pip : ctx->getPipsUphill(wire)) {
|
||||
auto &pip_data = pip_info(ctx->chip_info, pip);
|
||||
if (pip_data.pseudo_cell_wires.size() > 0)
|
||||
continue;
|
||||
|
||||
if (ctx->getPipSrcWire(pip) == WireId())
|
||||
continue;
|
||||
|
||||
if (ctx->is_pip_synthetic(pip))
|
||||
continue;
|
||||
|
||||
if (ctx->is_site_port(pip))
|
||||
continue;
|
||||
|
||||
num_pips++;
|
||||
}
|
||||
}
|
||||
|
||||
return num_pips;
|
||||
}
|
||||
|
||||
void DedicatedInterconnect::init(const Context *ctx)
|
||||
{
|
||||
this->ctx = ctx;
|
||||
@ -99,6 +149,16 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B
|
||||
WireNode node_to_expand = nodes_to_expand.back();
|
||||
nodes_to_expand.pop_back();
|
||||
|
||||
auto num_pips = get_num_pips(ctx, node_to_expand.wire, EXPAND_DOWNHILL);
|
||||
|
||||
// Usually, dedicated interconnects do not have more than one PIPs in the out-of-site
|
||||
if (node_to_expand.depth > 1 && node_to_expand.state == IN_ROUTING && num_pips > 1) {
|
||||
if (ctx->verbose)
|
||||
log_info("Wire %s is on a non-dedicated path (number of pips %d)\n",
|
||||
ctx->nameOfWire(node_to_expand.wire), num_pips);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (PipId pip : ctx->getPipsDownhill(node_to_expand.wire)) {
|
||||
if (ctx->is_pip_synthetic(pip)) {
|
||||
continue;
|
||||
@ -147,7 +207,7 @@ bool DedicatedInterconnect::check_routing(BelId src_bel, IdString src_bel_pin, B
|
||||
#ifdef DEBUG_EXPANSION
|
||||
log_info(" - Not dedicated site routing because loop!");
|
||||
#endif
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
next_node.state = IN_SINK_SITE;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user