Skip to content

Commit 7ffd6d4

Browse files
authored
Merge pull request #928 from verilog-to-routing/two_stage_routing
Clock Modeling: Added two Stage router
2 parents 190dbbe + ba55efb commit 7ffd6d4

17 files changed

+252
-16
lines changed

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
342342
RouterOpts->congested_routing_iteration_threshold_frac = Options.congested_routing_iteration_threshold_frac;
343343
RouterOpts->route_bb_update = Options.route_bb_update;
344344
RouterOpts->clock_modeling = Options.clock_modeling;
345+
RouterOpts->two_stage_clock_routing = Options.two_stage_clock_routing;
345346
RouterOpts->high_fanout_threshold = Options.router_high_fanout_threshold;
346347
RouterOpts->router_debug_net = Options.router_debug_net;
347348
RouterOpts->router_debug_sink_rr = Options.router_debug_sink_rr;

vpr/src/base/read_options.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -907,9 +907,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
907907
"Specifies how constant nets (i.e. those driven to a constant\n"
908908
"value) are handled:\n"
909909
" * global: Treat constant nets as globals (not routed)\n"
910-
" * route : Treat constant nets as normal nets (routed)\n"
911-
" * dedicated_network : Build a dedicated clock network based on the\n"
912-
" clock network specified in the architecture file\n")
910+
" * route : Treat constant nets as normal nets (routed)\n")
913911
.default_value("global")
914912
.show_in(argparse::ShowIn::HELP_ONLY);
915913

@@ -919,10 +917,21 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
919917
" * ideal: Treat clock pins as ideal\n"
920918
" (i.e. no routing delays on clocks)\n"
921919
" * route: Treat the clock pins as normal nets\n"
922-
" (i.e. routed using inter-block routing)\n")
920+
" (i.e. routed using inter-block routing)\n"
921+
" * dedicated_network : Build a dedicated clock network based on the\n"
922+
" clock network specified in the architecture file\n")
923923
.default_value("ideal")
924924
.show_in(argparse::ShowIn::HELP_ONLY);
925925

926+
gen_grp.add_argument<bool, ParseOnOff>(args.two_stage_clock_routing, "--two_stage_clock_routing")
927+
.help(
928+
"Routes clock nets in two stages if using a dedicated clock network.\n"
929+
" * First stage: From the Net source to a dedicated clock network source\n"
930+
" * Second stage: From the clock network source to net sinks\n")
931+
.default_value("off")
932+
.action(argparse::Action::STORE_TRUE)
933+
.show_in(argparse::ShowIn::HELP_ONLY);
934+
926935
gen_grp.add_argument<bool, ParseOnOff>(args.exit_before_pack, "--exit_before_pack")
927936
.help("Causes VPR to exit before packing starts (useful for statistics collection)")
928937
.default_value("off")

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct t_options {
5656
argparse::ArgValue<float> target_device_utilization;
5757
argparse::ArgValue<e_constant_net_method> constant_net_method;
5858
argparse::ArgValue<e_clock_modeling> clock_modeling;
59+
argparse::ArgValue<bool> two_stage_clock_routing;
5960
argparse::ArgValue<bool> exit_before_pack;
6061
argparse::ArgValue<bool> strict_checks;
6162
argparse::ArgValue<std::string> disable_errors;

vpr/src/base/vpr_api.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ void vpr_init_with_options(const t_options* options, t_vpr_setup* vpr_setup, t_a
216216
vpr_setup->device_layout = options->device_layout;
217217
vpr_setup->constant_net_method = options->constant_net_method;
218218
vpr_setup->clock_modeling = options->clock_modeling;
219+
vpr_setup->two_stage_clock_routing = options->two_stage_clock_routing;
219220
vpr_setup->exit_before_pack = options->exit_before_pack;
220221

221222
VTR_LOG("\n");

vpr/src/base/vpr_context.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ struct DeviceContext : public Context {
162162
std::vector<std::unique_ptr<ClockNetwork>> clock_networks;
163163
std::vector<std::unique_ptr<ClockConnection>> clock_connections;
164164

165+
// rr_node idx that connects to the input of all clock network wires
166+
// Useful for two stage clock routing
167+
// XXX: currently only one place to source the clock networks so only storing
168+
// a single value
169+
int virtual_clock_network_root_idx;
170+
165171
/** Attributes for each rr_node.
166172
* key: rr_node index
167173
* value: map of <attribute_name, attribute_value>

vpr/src/base/vpr_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ struct t_router_opts {
939939
float congested_routing_iteration_threshold_frac;
940940
e_route_bb_update route_bb_update;
941941
enum e_clock_modeling clock_modeling; //How clock pins and nets should be handled
942+
bool two_stage_clock_routing; //How clock nets on dedicated networks should be routed
942943
int high_fanout_threshold;
943944
int router_debug_net;
944945
int router_debug_sink_rr;
@@ -1292,6 +1293,7 @@ struct t_vpr_setup {
12921293
std::string device_layout;
12931294
e_constant_net_method constant_net_method; //How constant nets should be handled
12941295
e_clock_modeling clock_modeling; //How clocks should be handled
1296+
bool two_stage_clock_routing; //How clocks should be routed in the presence of a dedicated clock network
12951297
bool exit_before_pack; //Exits early before starting packing (useful for collecting statistics without running/loading any stages)
12961298
};
12971299

vpr/src/route/check_route.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,8 @@ static bool check_adjacent(int from_node, int to_node) {
442442
} else if (to_type == CHANY) {
443443
num_adj += chanx_chany_adjacent(from_node, to_node);
444444
} else {
445-
VTR_ASSERT(0);
445+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
446+
"in check_adjacent: %d and %d are not adjacent", from_node, to_node);
446447
}
447448
break;
448449

@@ -473,7 +474,8 @@ static bool check_adjacent(int from_node, int to_node) {
473474
} else if (to_type == CHANX) {
474475
num_adj += chanx_chany_adjacent(to_node, from_node);
475476
} else {
476-
VTR_ASSERT(0);
477+
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
478+
"in check_adjacent: %d and %d are not adjacent", from_node, to_node);
477479
}
478480
break;
479481

vpr/src/route/clock_connection_builders.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
4949
auto& rr_nodes = device_ctx.rr_nodes;
5050
auto& rr_node_indices = device_ctx.rr_node_indices;
5151

52+
int virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
53+
device_ctx.virtual_clock_network_root_idx = virtual_clock_network_root_idx;
54+
5255
// rr_node indices for x and y channel routing wires and clock wires to connect to
5356
auto x_wire_indices = get_rr_node_chan_wires_at_location(
5457
rr_node_indices, CHANX, switch_location.x, switch_location.y);
@@ -73,9 +76,32 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
7376
for (size_t i = 0; i < num_wires_y; i++) {
7477
rr_nodes[y_wire_indices[i]].add_edge(clock_index, rr_switch_idx);
7578
}
79+
80+
// Connect to virtual clock sink node
81+
// used by the two stage router
82+
rr_nodes[clock_index].add_edge(virtual_clock_network_root_idx, rr_switch_idx);
7683
}
7784
}
7885

86+
int RoutingToClockConnection::create_virtual_clock_network_sink_node(
87+
int x,
88+
int y) {
89+
auto& device_ctx = g_vpr_ctx.mutable_device();
90+
auto& rr_nodes = device_ctx.rr_nodes;
91+
rr_nodes.emplace_back();
92+
auto node_index = rr_nodes.size() - 1;
93+
94+
rr_nodes[node_index].set_coordinates(x, y, x, y);
95+
rr_nodes[node_index].set_capacity(1);
96+
rr_nodes[node_index].set_cost_index(SINK_COST_INDEX);
97+
rr_nodes[node_index].set_type(SINK);
98+
float R = 0.;
99+
float C = 0.;
100+
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(R, C));
101+
102+
return node_index;
103+
}
104+
79105
/*
80106
* ClockToClockConneciton (setters)
81107
*/

vpr/src/route/clock_connection_builders.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class RoutingToClockConnection : public ClockConnection {
5454
*/
5555
/* Connects the inter-block routing to the clock source at the specified coordinates */
5656
void create_switches(const ClockRRGraphBuilder& clock_graph);
57+
int create_virtual_clock_network_sink_node(int x, int y);
5758
};
5859

5960
class ClockToClockConneciton : public ClockConnection {

vpr/src/route/clock_network_builders.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ int ClockRib::create_chanx_wire(int x_start,
274274
rr_nodes[node_index].set_type(CHANX);
275275
rr_nodes[node_index].set_capacity(1);
276276
rr_nodes[node_index].set_track_num(ptc_num);
277-
auto rc_index = find_create_rr_rc_data(x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal);
278-
rr_nodes[node_index].set_rc_index(rc_index);
277+
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(
278+
x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal));
279279
rr_nodes[node_index].set_direction(direction);
280280

281281
short seg_index = 0;
@@ -523,8 +523,8 @@ int ClockSpine::create_chany_wire(int y_start,
523523
rr_nodes[node_index].set_type(CHANY);
524524
rr_nodes[node_index].set_capacity(1);
525525
rr_nodes[node_index].set_track_num(ptc_num);
526-
auto rc_index = find_create_rr_rc_data(y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal);
527-
rr_nodes[node_index].set_rc_index(rc_index);
526+
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(
527+
y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal));
528528
rr_nodes[node_index].set_direction(direction);
529529

530530
short seg_index = 0;

vpr/src/route/route_common.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,31 @@ void node_to_heap(int inode, float total_cost, int prev_node, int prev_edge, flo
799799
add_to_heap(hptr);
800800
}
801801

802+
void drop_traceback_tail(ClusterNetId net_id) {
803+
/* Removes the tail node from the routing traceback and updates
804+
* it with the previous node from the traceback.
805+
* This funtion is primarily called to remove the virtual clock
806+
* sink from the routing traceback and replace it with the clock
807+
* network root. */
808+
auto& route_ctx = g_vpr_ctx.mutable_routing();
809+
810+
auto* tail_ptr = route_ctx.trace[net_id].tail;
811+
auto node = tail_ptr->index;
812+
route_ctx.trace_nodes[net_id].erase(node);
813+
auto* trace_ptr = route_ctx.trace[net_id].head;
814+
while (trace_ptr != nullptr) {
815+
t_trace* next_ptr = trace_ptr->next;
816+
if (next_ptr == tail_ptr) {
817+
trace_ptr->iswitch = tail_ptr->iswitch;
818+
trace_ptr->next = nullptr;
819+
route_ctx.trace[net_id].tail = trace_ptr;
820+
break;
821+
}
822+
trace_ptr = next_ptr;
823+
}
824+
free_trace_data(tail_ptr);
825+
}
826+
802827
void free_traceback(ClusterNetId net_id) {
803828
/* Puts the entire traceback (old routing) for this net on the free list *
804829
* and sets the route_ctx.trace_head pointers etc. for the net to NULL. */

vpr/src/route/route_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void node_to_heap(int inode, float cost, int prev_node, int prev_edge, float bac
7979
bool is_empty_heap();
8080

8181
void free_traceback(ClusterNetId net_id);
82+
void drop_traceback_tail(ClusterNetId net_id);
8283
void free_traceback(t_trace* tptr);
8384

8485
void add_to_mod_list(int inode, std::vector<int>& modified_rr_node_inf);

0 commit comments

Comments
 (0)