[core] dev
This commit is contained in:
parent
6f2572324e
commit
bd2608d3e0
|
@ -10,12 +10,68 @@
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Append a programmable clock network to an existing routing resource graph
|
* Route a clock tree on an existing routing resource graph
|
||||||
|
* The strategy is to route spine one by one
|
||||||
|
* - route the spine from the starting point to the ending point
|
||||||
|
* - route the spine-to-spine switching points
|
||||||
|
* - route the spine-to-IPIN connections (only for the last level)
|
||||||
|
*******************************************************************/
|
||||||
|
static
|
||||||
|
int route_clock_tree_rr_graph() {
|
||||||
|
for (auto ispine : clk_ntwk.spines(clk_tree)) {
|
||||||
|
for (auto ipin : clk_ntwk.pins(clk_tree)) {
|
||||||
|
/* Route the spine from starting point to ending point */
|
||||||
|
std::vector<vtr::Point<size_t>> spine_coords = clk_ntwk.spine_coords(ispine);
|
||||||
|
for (size_t icoord = 0; icoord < spine_coords.size() - 1; ++icoord) {
|
||||||
|
vtr::Point<size_t> src_coord = spine_coords[icoord];
|
||||||
|
vtr::Point<size_t> des_coord = spine_coords[icoord + 1];
|
||||||
|
Direction src_spine_direction = clk_ntwk.spine_direction(ispine);
|
||||||
|
Direction des_spine_direction = clk_ntwk.spine_direction(ispine);
|
||||||
|
ClockLevelId src_spine_level = clk_ntwk.spine_level(ispine);
|
||||||
|
ClockLevelId des_spine_level = clk_ntwk.spine_level(ispine);
|
||||||
|
RRNodeId src_node = clk_rr_lookup.find_node(src_coord.x(), src_coord.y(), clk_tree, src_spine_level, ipin, src_spine_direction);
|
||||||
|
RRNodeId des_node = clk_rr_lookup.find_node(des_coord.x(), des_coord.y(), clk_tree, des_spine_level, ipin, des_spine_direction);
|
||||||
|
vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, src_node);
|
||||||
|
}
|
||||||
|
/* Route the spine-to-spine switching points */
|
||||||
|
for (ClockSwitchPointId switch_point_id : clk_ntwk.spine_switch_points(ispine)) {
|
||||||
|
vtr::Point<size_t> src_coord = clk_ntwk.spine_switch_point(ispine, switch_point_id);
|
||||||
|
ClockSpineId des_spine = clk_ntwk.spine_switch_point_tap(ispine, switch_point_id);
|
||||||
|
vtr::Point<size_t> des_coord = clk_ntwk.spine_start_point(des_spine);
|
||||||
|
Direction src_spine_direction = clk_ntwk.spine_direction(ispine);
|
||||||
|
Direction des_spine_direction = clk_ntwk.spine_direction(des_spine);
|
||||||
|
ClockLevelId src_spine_level = clk_ntwk.spine_level(ispine);
|
||||||
|
ClockLevelId des_spine_level = clk_ntwk.spine_level(des_spine);
|
||||||
|
RRNodeId src_node = clk_rr_lookup.find_node(src_coord.x(), src_coord.y(), clk_tree, src_spine_level, ipin, src_spine_direction);
|
||||||
|
RRNodeId des_node = clk_rr_lookup.find_node(des_coord.x(), des_coord.y(), clk_tree, des_spine_level, ipin, des_spine_direction);
|
||||||
|
vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, src_node);
|
||||||
|
}
|
||||||
|
/* Route the spine-to-IPIN connections (only for the last level) */
|
||||||
|
if (clk_ntwk.is_last_level(clk_tree, ispine)) {
|
||||||
|
/* Connect to any fan-out node which is IPIN */
|
||||||
|
for (size_t icoord = 0; icoord < spine_coords.size(); ++icoord) {
|
||||||
|
vtr::Point<size_t> src_coord = spine_coords[icoord];
|
||||||
|
Direction src_spine_direction = clk_ntwk.spine_direction(ispine);
|
||||||
|
ClockLevelId src_spine_level = clk_ntwk.spine_level(ispine);
|
||||||
|
RRNodeId src_node = clk_rr_lookup.find_node(src_coord.x(), src_coord.y(), clk_tree, src_spine_level, ipin, src_spine_direction);
|
||||||
|
for (RREdgeId edge : rr_graph.edges(src_node)) {
|
||||||
|
RRNodeId des_node = rr_graph.edge_sink_node(edge);
|
||||||
|
if (rr_graph.node_type(des_node) == IPIN) {
|
||||||
|
vpr_routing_annotation.set_rr_node_prev_node(rr_graph, des_node, src_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CMD_EXEC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* Route a clock network based on an existing routing resource graph
|
||||||
* This function will do the following jobs:
|
* This function will do the following jobs:
|
||||||
* - Estimate the number of clock nodes and pre-allocate memory
|
* - configure the routing annotation w.r.t. the clock node connections
|
||||||
* - Add clock nodes
|
* - quick check to ensure routing is valid
|
||||||
* - Build edges between clock nodes
|
|
||||||
* - Sanity checks
|
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
int route_clock_rr_graph(VprRoutingAnnotation& vpr_routing_annotation,
|
int route_clock_rr_graph(VprRoutingAnnotation& vpr_routing_annotation,
|
||||||
const DeviceContext& vpr_device_ctx,
|
const DeviceContext& vpr_device_ctx,
|
||||||
|
@ -41,6 +97,12 @@ int route_clock_rr_graph(VprRoutingAnnotation& vpr_routing_annotation,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Route spines one by one */
|
/* TODO: Route spines one by one */
|
||||||
|
for (auto itree : clk_ntwk.trees()) {
|
||||||
|
int status = route_clock_tree_rr_graph();
|
||||||
|
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Sanity checks */
|
/* TODO: Sanity checks */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue