Skip to content

Clock Modeling: Added two Stage router #928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ static void SetupRouterOpts(const t_options& Options, t_router_opts* RouterOpts)
RouterOpts->congested_routing_iteration_threshold_frac = Options.congested_routing_iteration_threshold_frac;
RouterOpts->route_bb_update = Options.route_bb_update;
RouterOpts->clock_modeling = Options.clock_modeling;
RouterOpts->two_stage_routing = Options.two_stage_routing;
RouterOpts->high_fanout_threshold = Options.router_high_fanout_threshold;
RouterOpts->router_debug_net = Options.router_debug_net;
RouterOpts->router_debug_sink_rr = Options.router_debug_sink_rr;
Expand Down
17 changes: 13 additions & 4 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,9 +899,7 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
"Specifies how constant nets (i.e. those driven to a constant\n"
"value) are handled:\n"
" * global: Treat constant nets as globals (not routed)\n"
" * route : Treat constant nets as normal nets (routed)\n"
" * dedicated_network : Build a dedicated clock network based on the\n"
" clock network specified in the architecture file\n")
" * route : Treat constant nets as normal nets (routed)\n")
.default_value("global")
.show_in(argparse::ShowIn::HELP_ONLY);

Expand All @@ -911,10 +909,21 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
" * ideal: Treat clock pins as ideal\n"
" (i.e. no routing delays on clocks)\n"
" * route: Treat the clock pins as normal nets\n"
" (i.e. routed using inter-block routing)\n")
" (i.e. routed using inter-block routing)\n"
" * dedicated_network : Build a dedicated clock network based on the\n"
" clock network specified in the architecture file\n")
.default_value("ideal")
.show_in(argparse::ShowIn::HELP_ONLY);

gen_grp.add_argument<bool, ParseOnOff>(args.two_stage_routing, "--two_stage_routing")
.help(
"Routes clock nets in two stages if using a dedicated clock network.\n"
" * First stage: From the Net source to a dedicated clock network source\n"
" * Second stage: From the clock network source to net sinks\n")
.default_value("off")
.action(argparse::Action::STORE_TRUE)
.show_in(argparse::ShowIn::HELP_ONLY);

gen_grp.add_argument<bool, ParseOnOff>(args.exit_before_pack, "--exit_before_pack")
.help("Causes VPR to exit before packing starts (useful for statistics collection)")
.default_value("off")
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct t_options {
argparse::ArgValue<float> target_device_utilization;
argparse::ArgValue<e_constant_net_method> constant_net_method;
argparse::ArgValue<e_clock_modeling> clock_modeling;
argparse::ArgValue<bool> two_stage_routing;
argparse::ArgValue<bool> exit_before_pack;
argparse::ArgValue<bool> strict_checks;
argparse::ArgValue<std::string> disable_errors;
Expand Down
1 change: 1 addition & 0 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ void vpr_init_with_options(const t_options* options, t_vpr_setup* vpr_setup, t_a
vpr_setup->device_layout = options->device_layout;
vpr_setup->constant_net_method = options->constant_net_method;
vpr_setup->clock_modeling = options->clock_modeling;
vpr_setup->two_stage_routing = options->two_stage_routing;
vpr_setup->exit_before_pack = options->exit_before_pack;

VTR_LOG("\n");
Expand Down
6 changes: 6 additions & 0 deletions vpr/src/base/vpr_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ struct DeviceContext : public Context {
std::vector<std::unique_ptr<ClockNetwork>> clock_networks;
std::vector<std::unique_ptr<ClockConnection>> clock_connections;

// rr_node idx that connects to the input of all clock network wires
// Useful for two stage clock routing
// XXX: currently only one place to source the clock networks so only storing
// a single value
int virtual_clock_network_sink_idx;

/** Attributes for each rr_node.
* key: rr_node index
* value: map of <attribute_name, attribute_value>
Expand Down
2 changes: 2 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ struct t_router_opts {
float congested_routing_iteration_threshold_frac;
e_route_bb_update route_bb_update;
enum e_clock_modeling clock_modeling; //How clock pins and nets should be handled
bool two_stage_routing; //How clock nets on dedicated networks should be routed
int high_fanout_threshold;
int router_debug_net;
int router_debug_sink_rr;
Expand Down Expand Up @@ -1298,6 +1299,7 @@ struct t_vpr_setup {
std::string device_layout;
e_constant_net_method constant_net_method; //How constant nets should be handled
e_clock_modeling clock_modeling; //How clocks should be handled
bool two_stage_routing; //How clocks should be routed in the presence of a dedicated clock network
bool exit_before_pack; //Exits early before starting packing (useful for collecting statistics without running/loading any stages)
};

Expand Down
6 changes: 4 additions & 2 deletions vpr/src/route/check_route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ static bool check_adjacent(int from_node, int to_node) {
} else if (to_type == CHANY) {
num_adj += chanx_chany_adjacent(from_node, to_node);
} else {
VTR_ASSERT(0);
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
"in check_adjacent: %d and %d are not adjacent", from_node, to_node);
}
break;

Expand Down Expand Up @@ -469,7 +470,8 @@ static bool check_adjacent(int from_node, int to_node) {
} else if (to_type == CHANX) {
num_adj += chanx_chany_adjacent(to_node, from_node);
} else {
VTR_ASSERT(0);
VPR_FATAL_ERROR(VPR_ERROR_ROUTE,
"in check_adjacent: %d and %d are not adjacent", from_node, to_node);
}
break;

Expand Down
29 changes: 29 additions & 0 deletions vpr/src/route/clock_connection_builders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
auto& rr_nodes = device_ctx.rr_nodes;
auto& rr_node_indices = device_ctx.rr_node_indices;

int virtual_clock_network_sink_idx =
create_virtual_clock_network_sink_node(switch_location.x, switch_location.y);
device_ctx.virtual_clock_network_sink_idx = virtual_clock_network_sink_idx;

// rr_node indices for x and y channel routing wires and clock wires to connect to
auto x_wire_indices = get_rr_node_chan_wires_at_location(
rr_node_indices, CHANX, switch_location.x, switch_location.y);
Expand All @@ -73,9 +77,34 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_
for (size_t i = 0; i < num_wires_y; i++) {
rr_nodes[y_wire_indices[i]].add_edge(clock_index, rr_switch_idx);
}

// Connect to virtual clock sink node
// used by the two stage router
rr_nodes[clock_index].add_edge(virtual_clock_network_sink_idx, rr_switch_idx);
}
}

int RoutingToClockConnection::create_virtual_clock_network_sink_node(
int x,
int y)
{
auto& device_ctx = g_vpr_ctx.mutable_device();
auto& rr_nodes = device_ctx.rr_nodes;
rr_nodes.emplace_back();
auto node_index = rr_nodes.size() - 1;

rr_nodes[node_index].set_coordinates(x, y, x, y);
rr_nodes[node_index].set_capacity(1);
rr_nodes[node_index].set_cost_index(SINK_COST_INDEX);
rr_nodes[node_index].set_type(SINK);
float R = 0.;
float C = 0.;
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(R, C));

return node_index;
}


/*
* ClockToClockConneciton (setters)
*/
Expand Down
1 change: 1 addition & 0 deletions vpr/src/route/clock_connection_builders.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class RoutingToClockConnection : public ClockConnection {
*/
/* Connects the inter-block routing to the clock source at the specified coordinates */
void create_switches(const ClockRRGraphBuilder& clock_graph);
int create_virtual_clock_network_sink_node(int x, int y);
};

class ClockToClockConneciton : public ClockConnection {
Expand Down
8 changes: 4 additions & 4 deletions vpr/src/route/clock_network_builders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ int ClockRib::create_chanx_wire(int x_start,
rr_nodes[node_index].set_type(CHANX);
rr_nodes[node_index].set_capacity(1);
rr_nodes[node_index].set_track_num(ptc_num);
auto rc_index = find_create_rr_rc_data(x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal);
rr_nodes[node_index].set_rc_index(rc_index);
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(
x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal));
rr_nodes[node_index].set_direction(direction);

short seg_index = 0;
Expand Down Expand Up @@ -523,8 +523,8 @@ int ClockSpine::create_chany_wire(int y_start,
rr_nodes[node_index].set_type(CHANY);
rr_nodes[node_index].set_capacity(1);
rr_nodes[node_index].set_track_num(ptc_num);
auto rc_index = find_create_rr_rc_data(y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal);
rr_nodes[node_index].set_rc_index(rc_index);
rr_nodes[node_index].set_rc_index(find_create_rr_rc_data(
y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal));
rr_nodes[node_index].set_direction(direction);

short seg_index = 0;
Expand Down
20 changes: 20 additions & 0 deletions vpr/src/route/route_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,26 @@ void node_to_heap(int inode, float total_cost, int prev_node, int prev_edge, flo
add_to_heap(hptr);
}

void drop_traceback_tail(ClusterNetId net_id) {
auto& route_ctx = g_vpr_ctx.mutable_routing();

auto* tail_ptr = route_ctx.trace[net_id].tail;
auto node = tail_ptr->index;
route_ctx.trace_nodes[net_id].erase(node);
auto* trace_ptr = route_ctx.trace[net_id].head;
while (trace_ptr!= nullptr) {
t_trace* next_ptr = trace_ptr->next;
if (next_ptr == tail_ptr) {
trace_ptr->iswitch = tail_ptr->iswitch;
trace_ptr->next = nullptr;
route_ctx.trace[net_id].tail = trace_ptr;
break;
}
trace_ptr = next_ptr;
}
free_trace_data(tail_ptr);
}

void free_traceback(ClusterNetId net_id) {
/* Puts the entire traceback (old routing) for this net on the free list *
* and sets the route_ctx.trace_head pointers etc. for the net to NULL. */
Expand Down
1 change: 1 addition & 0 deletions vpr/src/route/route_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void node_to_heap(int inode, float cost, int prev_node, int prev_edge, float bac
bool is_empty_heap();

void free_traceback(ClusterNetId net_id);
void drop_traceback_tail(ClusterNetId net_id);
void free_traceback(t_trace* tptr);

void add_to_mod_list(int inode, std::vector<int>& modified_rr_node_inf);
Expand Down
Loading