diff --git a/vpr/src/route/check_rr_graph.cpp b/vpr/src/route/check_rr_graph.cpp index a9793297db8..6a1fc6b7de4 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/vpr/src/route/check_rr_graph.cpp @@ -44,6 +44,11 @@ void check_rr_graph(const t_graph_type graph_type, continue; } + // Virtual clock network sink is special, ignore. + if (device_ctx.virtual_clock_network_root_idx == int(inode)) { + continue; + } + t_rr_type rr_type = device_ctx.rr_nodes[inode].type(); int num_edges = device_ctx.rr_nodes[inode].num_edges(); diff --git a/vpr/src/route/clock_connection_builders.cpp b/vpr/src/route/clock_connection_builders.cpp index 911bb5cb035..26d0dbb70fc 100644 --- a/vpr/src/route/clock_connection_builders.cpp +++ b/vpr/src/route/clock_connection_builders.cpp @@ -27,8 +27,8 @@ void RoutingToClockConnection::set_switch_location(int x, int y) { switch_location.y = y; } -void RoutingToClockConnection::set_switch(int rr_switch_index) { - rr_switch_idx = rr_switch_index; +void RoutingToClockConnection::set_switch(int arch_switch_index) { + arch_switch_idx = arch_switch_index; } void RoutingToClockConnection::set_fc_val(float fc_val) { @@ -39,18 +39,25 @@ void RoutingToClockConnection::set_fc_val(float fc_val) { * RoutingToClockConnection (member functions) */ -void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_graph) { +size_t RoutingToClockConnection::estimate_additional_nodes() { + // 1 rr node is being added as the virtual clock sink. + return 1; +} + +void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) { // Initialize random seed // Must be done during every call in order for restored rr_graphs after a binary // search to be consistent std::srand(seed); - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_nodes = device_ctx.rr_nodes; + auto& device_ctx = g_vpr_ctx.device(); auto& rr_node_indices = device_ctx.rr_node_indices; int virtual_clock_network_root_idx = create_virtual_clock_network_sink_node(switch_location.x, switch_location.y); - device_ctx.virtual_clock_network_root_idx = virtual_clock_network_root_idx; + { + auto& mut_device_ctx = g_vpr_ctx.mutable_device(); + mut_device_ctx.virtual_clock_network_root_idx = virtual_clock_network_root_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( @@ -68,18 +75,18 @@ void RoutingToClockConnection::create_switches(const ClockRRGraphBuilder& clock_ // Connect to x-channel wires unsigned num_wires_x = x_wire_indices.size() * fc; for (size_t i = 0; i < num_wires_x; i++) { - rr_nodes[x_wire_indices[i]].add_edge(clock_index, rr_switch_idx); + clock_graph.add_edge(rr_edges_to_create, x_wire_indices[i], clock_index, arch_switch_idx); } // Connect to y-channel wires unsigned num_wires_y = y_wire_indices.size() * fc; for (size_t i = 0; i < num_wires_y; i++) { - rr_nodes[y_wire_indices[i]].add_edge(clock_index, rr_switch_idx); + clock_graph.add_edge(rr_edges_to_create, y_wire_indices[i], clock_index, arch_switch_idx); } // Connect to virtual clock sink node // used by the two stage router - rr_nodes[clock_index].add_edge(virtual_clock_network_root_idx, rr_switch_idx); + clock_graph.add_edge(rr_edges_to_create, clock_index, virtual_clock_network_root_idx, arch_switch_idx); } } @@ -122,8 +129,8 @@ void ClockToClockConneciton::set_to_clock_switch_point_name(std::string switch_p to_switch = switch_point_name; } -void ClockToClockConneciton::set_switch(int rr_switch_index) { - rr_switch_idx = rr_switch_index; +void ClockToClockConneciton::set_switch(int arch_switch_index) { + arch_switch_idx = arch_switch_index; } void ClockToClockConneciton::set_fc_val(float fc_val) { @@ -134,10 +141,12 @@ void ClockToClockConneciton::set_fc_val(float fc_val) { * ClockToClockConneciton (member functions) */ -void ClockToClockConneciton::create_switches(const ClockRRGraphBuilder& clock_graph) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& grid = device_ctx.grid; - auto& rr_nodes = device_ctx.rr_nodes; +size_t ClockToClockConneciton::estimate_additional_nodes() { + return 0; +} + +void ClockToClockConneciton::create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) { + auto& grid = clock_graph.grid(); auto to_locations = clock_graph.get_switch_locations(to_clock, to_switch); @@ -179,7 +188,7 @@ void ClockToClockConneciton::create_switches(const ClockRRGraphBuilder& clock_gr if (from_itter == from_rr_node_indices.end()) { from_itter = from_rr_node_indices.begin(); } - rr_nodes[*from_itter].add_edge(to_index, rr_switch_idx); + clock_graph.add_edge(rr_edges_to_create, *from_itter, to_index, arch_switch_idx); from_itter++; } } @@ -199,8 +208,8 @@ void ClockToPinsConnection::set_clock_switch_point_name( switch_point_name = connection_switch_point_name; } -void ClockToPinsConnection::set_switch(int rr_switch_index) { - rr_switch_idx = rr_switch_index; +void ClockToPinsConnection::set_switch(int arch_switch_index) { + arch_switch_idx = arch_switch_index; } void ClockToPinsConnection::set_fc_val(float fc_val) { @@ -211,11 +220,14 @@ void ClockToPinsConnection::set_fc_val(float fc_val) { * ClockToPinsConnection (member functions) */ -void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_graph) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_nodes = device_ctx.rr_nodes; +size_t ClockToPinsConnection::estimate_additional_nodes() { + return 0; +} + +void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) { + auto& device_ctx = g_vpr_ctx.device(); auto& rr_node_indices = device_ctx.rr_node_indices; - auto& grid = device_ctx.grid; + auto& grid = clock_graph.grid(); for (size_t x = 0; x < grid.width(); x++) { for (size_t y = 0; y < grid.height(); y++) { @@ -290,7 +302,7 @@ void ClockToPinsConnection::create_switches(const ClockRRGraphBuilder& clock_gra //Create edges depending on Fc for (size_t i = 0; i < clock_network_indices.size() * fc; i++) { - rr_nodes[clock_network_indices[i]].add_edge(clock_pin_node_idx, rr_switch_idx); + clock_graph.add_edge(rr_edges_to_create, clock_network_indices[i], clock_pin_node_idx, arch_switch_idx); } } } diff --git a/vpr/src/route/clock_connection_builders.h b/vpr/src/route/clock_connection_builders.h index 8076907b656..110ecb24d7c 100644 --- a/vpr/src/route/clock_connection_builders.h +++ b/vpr/src/route/clock_connection_builders.h @@ -5,6 +5,7 @@ #include "clock_fwd.h" +#include "rr_graph2.h" #include "rr_graph_clock.h" class ClockRRGraphBuilder; @@ -26,7 +27,8 @@ class ClockConnection { /* * Member functions */ - virtual void create_switches(const ClockRRGraphBuilder& clock_graph) = 0; + virtual void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) = 0; + virtual size_t estimate_additional_nodes() = 0; }; class RoutingToClockConnection : public ClockConnection { @@ -34,7 +36,7 @@ class RoutingToClockConnection : public ClockConnection { std::string clock_to_connect_to; std::string switch_point_name; Coordinates switch_location; - int rr_switch_idx; + int arch_switch_idx; float fc; int seed = 101; @@ -46,14 +48,15 @@ class RoutingToClockConnection : public ClockConnection { void set_clock_name_to_connect_to(std::string clock_name); void set_clock_switch_point_name(std::string clock_switch_point_name); void set_switch_location(int x, int y); - void set_switch(int rr_switch_index); + void set_switch(int arch_switch_index); void set_fc_val(float fc_val); /* * Member functions */ /* Connects the inter-block routing to the clock source at the specified coordinates */ - void create_switches(const ClockRRGraphBuilder& clock_graph); + void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) override; + size_t estimate_additional_nodes() override; int create_virtual_clock_network_sink_node(int x, int y); }; @@ -63,7 +66,7 @@ class ClockToClockConneciton : public ClockConnection { std::string from_switch; std::string to_clock; std::string to_switch; - int rr_switch_idx; + int arch_switch_idx; float fc; public: @@ -74,14 +77,15 @@ class ClockToClockConneciton : public ClockConnection { void set_from_clock_switch_point_name(std::string switch_point_name); void set_to_clock_name(std::string clock_name); void set_to_clock_switch_point_name(std::string switch_point_name); - void set_switch(int rr_switch_index); + void set_switch(int arch_switch_index); void set_fc_val(float fc_val); /* * Member functions */ /* Connects a clock tap to a clock source */ - void create_switches(const ClockRRGraphBuilder& clock_graph); + void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) override; + size_t estimate_additional_nodes() override; }; /* This class currently only supports Clock Network to clock pin connection. @@ -90,7 +94,7 @@ class ClockToPinsConnection : public ClockConnection { private: std::string clock_to_connect_from; std::string switch_point_name; - int rr_switch_idx; + int arch_switch_idx; float fc; public: @@ -99,14 +103,15 @@ class ClockToPinsConnection : public ClockConnection { */ void set_clock_name_to_connect_from(std::string clock_name); void set_clock_switch_point_name(std::string connection_switch_point_name); - void set_switch(int rr_switch_index); + void set_switch(int arch_switch_index); void set_fc_val(float fc_val); /* * Member functions */ /* Connects the clock tap to block pins */ - void create_switches(const ClockRRGraphBuilder& clock_graph); + void create_switches(const ClockRRGraphBuilder& clock_graph, t_rr_edge_info_set* rr_edges_to_create) override; + size_t estimate_additional_nodes() override; }; #endif diff --git a/vpr/src/route/clock_network_builders.cpp b/vpr/src/route/clock_network_builders.cpp index ea367bdbb6b..1f1f5cc06a6 100644 --- a/vpr/src/route/clock_network_builders.cpp +++ b/vpr/src/route/clock_network_builders.cpp @@ -61,9 +61,11 @@ void ClockNetwork::set_num_instance(int num_inst) { */ void ClockNetwork::create_rr_nodes_for_clock_network_wires(ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, int num_segments) { for (int inst_num = 0; inst_num < get_num_inst(); inst_num++) { - create_rr_nodes_and_internal_edges_for_one_instance(clock_graph, num_segments); + create_rr_nodes_and_internal_edges_for_one_instance(clock_graph, rr_nodes, rr_edges_to_create, num_segments); } } @@ -173,15 +175,54 @@ void ClockRib::create_segments(std::vector& segment_inf) { populate_segment_values(index, name, length, x_chan_wire.layer, segment_inf); } +size_t ClockRib::estimate_additional_nodes(const DeviceGrid& grid) { + // Avoid an infinite loop + VTR_ASSERT(repeat.y > 0); + VTR_ASSERT(repeat.x > 0); + + size_t num_additional_nodes = 0; + for (unsigned y = x_chan_wire.position; y < grid.height() - 1; y += repeat.y) { + for (unsigned x_start = x_chan_wire.start; x_start < grid.width() - 1; x_start += repeat.x) { + unsigned drive_x = x_start + drive.offset; + unsigned x_end = x_start + x_chan_wire.length; + + // Adjust for boundry conditions + int x_offset = 0; + if ((x_start == 0) || // CHANX wires left boundry + (x_start + repeat.x == x_end)) // Avoid overlap + { + x_offset = 1; + } + if (x_end > grid.width() - 2) { + x_end = grid.width() - 2; // CHANX wires right boundry + } + + // Dont create rib if drive point is not reachable + if (drive_x > grid.width() - 2 || drive_x >= x_end || drive_x <= (x_start + x_offset)) { + continue; + } + + // Dont create rib if wire segment is too small + if ((x_start + x_offset) >= x_end) { + continue; + } + + num_additional_nodes += 3; + } + } + + return num_additional_nodes; +} + void ClockRib::create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, int num_segments) { // Only chany wires need to know the number of segments inorder // to calculate the cost_index (void)num_segments; - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_nodes = device_ctx.rr_nodes; - auto& grid = device_ctx.grid; + const auto& grid = clock_graph.grid(); int ptc_num = clock_graph.get_and_increment_chanx_ptc_num(); // used for drawing @@ -255,8 +296,8 @@ void ClockRib::create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphB clock_graph); // connect drive point to each half rib using a directed switch - rr_nodes[drive_node_idx].add_edge(left_node_idx, drive.switch_idx); - rr_nodes[drive_node_idx].add_edge(right_node_idx, drive.switch_idx); + clock_graph.add_edge(rr_edges_to_create, drive_node_idx, left_node_idx, drive.switch_idx); + clock_graph.add_edge(rr_edges_to_create, drive_node_idx, right_node_idx, drive.switch_idx); } } } @@ -266,17 +307,18 @@ int ClockRib::create_chanx_wire(int x_start, int y, int ptc_num, e_direction direction, - std::vector& rr_nodes) { - rr_nodes.emplace_back(); - auto node_index = rr_nodes.size() - 1; - - rr_nodes[node_index].set_coordinates(x_start, y, x_end, y); - rr_nodes[node_index].set_type(CHANX); - rr_nodes[node_index].set_capacity(1); - rr_nodes[node_index].set_track_num(ptc_num); - rr_nodes[node_index].set_rc_index(find_create_rr_rc_data( + std::vector* rr_nodes) { + rr_nodes->emplace_back(); + auto node_index = rr_nodes->size() - 1; + auto& node = rr_nodes->back(); + + node.set_coordinates(x_start, y, x_end, y); + node.set_type(CHANX); + node.set_capacity(1); + node.set_track_num(ptc_num); + node.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); + node.set_direction(direction); short seg_index = 0; switch (direction) { @@ -293,7 +335,7 @@ int ClockRib::create_chanx_wire(int x_start, VTR_ASSERT_MSG(false, "Unidentified direction type for clock rib"); break; } - rr_nodes[node_index].set_cost_index(CHANX_COST_INDEX_START + seg_index); // Actual value set later + node.set_cost_index(CHANX_COST_INDEX_START + seg_index); // Actual value set later return node_index; } @@ -419,11 +461,51 @@ void ClockSpine::create_segments(std::vector& segment_inf) { populate_segment_values(index, name, length, y_chan_wire.layer, segment_inf); } +size_t ClockSpine::estimate_additional_nodes(const DeviceGrid& grid) { + size_t num_additional_nodes = 0; + + // Avoid an infinite loop + VTR_ASSERT(repeat.y > 0); + VTR_ASSERT(repeat.x > 0); + + for (unsigned x = y_chan_wire.position; x < grid.width() - 1; x += repeat.x) { + for (unsigned y_start = y_chan_wire.start; y_start < grid.height() - 1; y_start += repeat.y) { + unsigned drive_y = y_start + drive.offset; + unsigned y_end = y_start + y_chan_wire.length; + + // Adjust for boundry conditions + unsigned y_offset = 0; + if ((y_start == 0) || // CHANY wires bottom boundry, start above the LB + (y_start + repeat.y == y_end)) // Avoid overlap + { + y_offset = 1; + } + if (y_end > grid.height() - 2) { + y_end = grid.height() - 2; // CHANY wires top boundry, dont go above the LB + } + + // Dont create spine if drive point is not reachable + if (drive_y > grid.width() - 2 || drive_y >= y_end || drive_y <= (y_start + y_offset)) { + continue; + } + + // Dont create spine if wire segment is too small + if ((y_start + y_offset) >= y_end) { + continue; + } + + num_additional_nodes += 3; + } + } + + return num_additional_nodes; +} + void ClockSpine::create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, int num_segments) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_nodes = device_ctx.rr_nodes; - auto& grid = device_ctx.grid; + auto& grid = clock_graph.grid(); int ptc_num = clock_graph.get_and_increment_chany_ptc_num(); // used for drawing @@ -503,8 +585,8 @@ void ClockSpine::create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGrap clock_graph); // connect drive point to each half spine using a directed switch - rr_nodes[drive_node_idx].add_edge(left_node_idx, drive.switch_idx); - rr_nodes[drive_node_idx].add_edge(right_node_idx, drive.switch_idx); + clock_graph.add_edge(rr_edges_to_create, drive_node_idx, left_node_idx, drive.switch_idx); + clock_graph.add_edge(rr_edges_to_create, drive_node_idx, right_node_idx, drive.switch_idx); } } } @@ -514,18 +596,19 @@ int ClockSpine::create_chany_wire(int y_start, int x, int ptc_num, e_direction direction, - std::vector& rr_nodes, + std::vector* rr_nodes, int num_segments) { - rr_nodes.emplace_back(); - auto node_index = rr_nodes.size() - 1; - - rr_nodes[node_index].set_coordinates(x, y_start, x, y_end); - rr_nodes[node_index].set_type(CHANY); - rr_nodes[node_index].set_capacity(1); - rr_nodes[node_index].set_track_num(ptc_num); - rr_nodes[node_index].set_rc_index(find_create_rr_rc_data( + rr_nodes->emplace_back(); + auto node_index = rr_nodes->size() - 1; + auto& node = rr_nodes->back(); + + node.set_coordinates(x, y_start, x, y_end); + node.set_type(CHANY); + node.set_capacity(1); + node.set_track_num(ptc_num); + node.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); + node.set_direction(direction); short seg_index = 0; switch (direction) { @@ -542,7 +625,7 @@ int ClockSpine::create_chany_wire(int y_start, VTR_ASSERT_MSG(false, "Unidentified direction type for clock rib"); break; } - rr_nodes[node_index].set_cost_index(CHANX_COST_INDEX_START + num_segments + seg_index); + node.set_cost_index(CHANX_COST_INDEX_START + num_segments + seg_index); return node_index; } @@ -573,11 +656,20 @@ void ClockHTree::create_segments(std::vector& segment_inf) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "HTrees are not yet supported.\n"); } + +size_t ClockHTree::estimate_additional_nodes(const DeviceGrid& /*grid*/) { + return 0; +} + void ClockHTree::create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, int num_segments) { //Remove unused parameter warning (void)clock_graph; (void)num_segments; + (void)rr_nodes; + (void)rr_edges_to_create; VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "HTrees are not yet supported.\n"); } diff --git a/vpr/src/route/clock_network_builders.h b/vpr/src/route/clock_network_builders.h index c4db346ae00..c4caa039b2e 100644 --- a/vpr/src/route/clock_network_builders.h +++ b/vpr/src/route/clock_network_builders.h @@ -8,6 +8,7 @@ #include "vpr_types.h" +#include "rr_graph2.h" #include "rr_graph_clock.h" class ClockRRGraphBuilder; @@ -101,9 +102,17 @@ class ClockNetwork { /* Creates the RR nodes for the clock network wires and adds them to the reverse lookup * in ClockRRGraphBuilder. The reverse lookup maps the nodes to their switch point locations */ void create_rr_nodes_for_clock_network_wires(ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, int num_segments); virtual void create_segments(std::vector& segment_inf) = 0; - virtual void create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, int num_segments) = 0; + virtual void create_rr_nodes_and_internal_edges_for_one_instance( + ClockRRGraphBuilder& clock_graph, + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, + int num_segments) + = 0; + virtual size_t estimate_additional_nodes(const DeviceGrid& grid) = 0; }; class ClockRib : public ClockNetwork { @@ -134,7 +143,7 @@ class ClockRib : public ClockNetwork { /* * Getters */ - ClockType get_network_type() const; + ClockType get_network_type() const override; /* * Setters @@ -152,15 +161,18 @@ class ClockRib : public ClockNetwork { /* * Member functions */ - void create_segments(std::vector& segment_inf); + void create_segments(std::vector& segment_inf) override; void create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, - int num_segments); + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, + int num_segments) override; + size_t estimate_additional_nodes(const DeviceGrid& grid) override; int create_chanx_wire(int x_start, int x_end, int y, int ptc_num, e_direction direction, - std::vector& rr_nodes); + std::vector* rr_nodes); void record_tap_locations(unsigned x_start, unsigned x_end, unsigned y, @@ -190,7 +202,7 @@ class ClockSpine : public ClockNetwork { /* * Getters */ - ClockType get_network_type() const; + ClockType get_network_type() const override; /* * Setters @@ -208,15 +220,18 @@ class ClockSpine : public ClockNetwork { /* * Member functions */ - void create_segments(std::vector& segment_inf); + void create_segments(std::vector& segment_inf) override; void create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, - int num_segments); + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, + int num_segments) override; + size_t estimate_additional_nodes(const DeviceGrid& grid) override; int create_chany_wire(int y_start, int y_end, int x, int ptc_num, e_direction direction, - std::vector& rr_nodes, + std::vector* rr_nodes, int num_segments); void record_tap_locations(unsigned y_start, unsigned y_end, @@ -238,11 +253,14 @@ class ClockHTree : private ClockNetwork { HtreeTaps tap; public: - ClockType get_network_type() const { return ClockType::H_TREE; } + ClockType get_network_type() const override { return ClockType::H_TREE; } // TODO: Unimplemented member function - void create_segments(std::vector& segment_inf); + void create_segments(std::vector& segment_inf) override; void create_rr_nodes_and_internal_edges_for_one_instance(ClockRRGraphBuilder& clock_graph, - int num_segments); + std::vector* rr_nodes, + t_rr_edge_info_set* rr_edges_to_create, + int num_segments) override; + size_t estimate_additional_nodes(const DeviceGrid& grid) override; }; #endif diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index df1bb8b0967..d5cf2ac8e41 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -148,32 +148,32 @@ static int get_opin_direct_connecions(int x, const int num_directs, const t_clb_to_clb_directs* clb_to_clb_directs); -static void alloc_and_load_rr_graph(const int num_nodes, - std::vector& L_rr_node, - const int num_seg_types, - const t_chan_details& chan_details_x, - const t_chan_details& chan_details_y, - const t_track_to_pin_lookup& track_to_pin_lookup, - const t_pin_to_track_lookup& opin_to_track_map, - const vtr::NdMatrix, 3>& switch_block_conn, - t_sb_connection_map* sb_conn_map, - const DeviceGrid& grid, - const int Fs, - t_sblock_pattern& sblock_pattern, - const std::vector>& Fc_out, - vtr::NdMatrix& Fc_xofs, - vtr::NdMatrix& Fc_yofs, - const t_rr_node_indices& L_rr_node_indices, - const int max_chan_width, - const t_chan_width& chan_width, - const int wire_to_ipin_switch, - const int delayless_switch, - const enum e_directionality directionality, - bool* Fc_clipped, - const t_direct_inf* directs, - const int num_directs, - const t_clb_to_clb_directs* clb_to_clb_directs, - bool is_global_graph); +static std::function alloc_and_load_rr_graph(std::vector& L_rr_node, + const int num_seg_types, + const t_chan_details& chan_details_x, + const t_chan_details& chan_details_y, + const t_track_to_pin_lookup& track_to_pin_lookup, + const t_pin_to_track_lookup& opin_to_track_map, + const vtr::NdMatrix, 3>& switch_block_conn, + t_sb_connection_map* sb_conn_map, + const DeviceGrid& grid, + const int Fs, + t_sblock_pattern& sblock_pattern, + const std::vector>& Fc_out, + vtr::NdMatrix& Fc_xofs, + vtr::NdMatrix& Fc_yofs, + const t_rr_node_indices& L_rr_node_indices, + const int max_chan_width, + const t_chan_width& chan_width, + const int wire_to_ipin_switch, + const int delayless_switch, + const enum e_directionality directionality, + bool* Fc_clipped, + const t_direct_inf* directs, + const int num_directs, + const t_clb_to_clb_directs* clb_to_clb_directs, + bool is_global_graph, + const enum e_clock_modeling clock_modeling); static float pattern_fmod(float a, float b); static void load_uniform_connection_block_pattern(vtr::NdMatrix& tracks_connected_to_pin, @@ -296,6 +296,7 @@ static void build_rr_graph(const t_graph_type graph_type, const float R_minW_nmos, const float R_minW_pmos, const enum e_base_cost_type base_cost_type, + const enum e_clock_modeling clock_modeling, const bool trim_empty_channels, const bool trim_obs_channels, const t_direct_inf* directs, @@ -356,19 +357,12 @@ void create_rr_graph(const t_graph_type graph_type, det_routing_arch->R_minW_nmos, det_routing_arch->R_minW_pmos, base_cost_type, + clock_modeling, trim_empty_channels, trim_obs_channels, directs, num_directs, &det_routing_arch->wire_to_rr_ipin_switch, Warnings); - - if (clock_modeling == DEDICATED_NETWORK) { - ClockRRGraphBuilder::create_and_append_clock_rr_graph(segment_inf, - det_routing_arch->R_minW_nmos, - det_routing_arch->R_minW_pmos, - det_routing_arch->wire_to_rr_ipin_switch, - base_cost_type); - } } process_non_config_sets(); @@ -422,6 +416,7 @@ static void build_rr_graph(const t_graph_type graph_type, const float R_minW_nmos, const float R_minW_pmos, const enum e_base_cost_type base_cost_type, + const enum e_clock_modeling clock_modeling, const bool trim_empty_channels, const bool trim_obs_channels, const t_direct_inf* directs, @@ -579,6 +574,11 @@ static void build_rr_graph(const t_graph_type graph_type, device_ctx.rr_node_indices = alloc_and_load_rr_node_indices(max_chan_width, grid, &num_rr_nodes, chan_details_x, chan_details_y); + size_t expected_node_count = num_rr_nodes; + if (clock_modeling == DEDICATED_NETWORK) { + expected_node_count += ClockRRGraphBuilder::estimate_additional_nodes(grid); + device_ctx.rr_nodes.reserve(expected_node_count); + } device_ctx.rr_nodes.resize(num_rr_nodes); /* These are data structures used by the the unidir opin mapping. They are used @@ -678,23 +678,34 @@ static void build_rr_graph(const t_graph_type graph_type, /* END OPIN MAP */ bool Fc_clipped = false; - alloc_and_load_rr_graph(device_ctx.rr_nodes.size(), device_ctx.rr_nodes, segment_inf.size(), - chan_details_x, chan_details_y, - track_to_pin_lookup, opin_to_track_map, - switch_block_conn, sb_conn_map, grid, Fs, unidir_sb_pattern, - Fc_out, Fc_xofs, Fc_yofs, device_ctx.rr_node_indices, - max_chan_width, - nodes_per_chan, - wire_to_arch_ipin_switch, - delayless_switch, - directionality, - &Fc_clipped, - directs, num_directs, clb_to_clb_directs, - is_global_graph); + auto update_chan_width = alloc_and_load_rr_graph( + device_ctx.rr_nodes, segment_inf.size(), + chan_details_x, chan_details_y, + track_to_pin_lookup, opin_to_track_map, + switch_block_conn, sb_conn_map, grid, Fs, unidir_sb_pattern, + Fc_out, Fc_xofs, Fc_yofs, device_ctx.rr_node_indices, + max_chan_width, + nodes_per_chan, + wire_to_arch_ipin_switch, + delayless_switch, + directionality, + &Fc_clipped, + directs, num_directs, clb_to_clb_directs, + is_global_graph, + clock_modeling); + + // Verify no incremental node allocation. + if (device_ctx.rr_nodes.size() > expected_node_count) { + VTR_LOG_ERROR("Expected no more than %zu nodes, have %zu nodes", + expected_node_count, device_ctx.rr_nodes.size()); + } /* Update rr_nodes capacities if global routing */ if (graph_type == GRAPH_GLOBAL) { - for (size_t i = 0; i < device_ctx.rr_nodes.size(); i++) { + // Using num_rr_nodes here over device_ctx.rr_nodes.size() because + // clock_modeling::DEDICATED_NETWORK will append some rr nodes after + // the regular graph. + for (int i = 0; i < num_rr_nodes; i++) { if (device_ctx.rr_nodes[i].type() == CHANX) { int ylow = device_ctx.rr_nodes[i].ylow(); device_ctx.rr_nodes[i].set_capacity(nodes_per_chan.x_list[ylow]); @@ -706,6 +717,8 @@ static void build_rr_graph(const t_graph_type graph_type, } } + update_chan_width(&nodes_per_chan); + /* Allocate and load routing resource switches, which are derived from the switches from the architecture file, * based on their fanin in the rr graph. This routine also adjusts the rr nodes to point to these new rr switches */ alloc_and_load_rr_switch_inf(num_arch_switches, R_minW_nmos, R_minW_pmos, wire_to_arch_ipin_switch, wire_to_rr_ipin_switch); @@ -1172,32 +1185,32 @@ static void free_type_track_to_pin_map(t_track_to_pin_lookup& track_to_pin_map, /* Does the actual work of allocating the rr_graph and filling all the * * appropriate values. Everything up to this was just a prelude! */ -static void alloc_and_load_rr_graph(const int num_nodes, - std::vector& L_rr_node, - const int num_seg_types, - const t_chan_details& chan_details_x, - const t_chan_details& chan_details_y, - const t_track_to_pin_lookup& track_to_pin_lookup, - const t_pin_to_track_lookup& opin_to_track_map, - const vtr::NdMatrix, 3>& switch_block_conn, - t_sb_connection_map* sb_conn_map, - const DeviceGrid& grid, - const int Fs, - t_sblock_pattern& sblock_pattern, - const std::vector>& Fc_out, - vtr::NdMatrix& Fc_xofs, - vtr::NdMatrix& Fc_yofs, - const t_rr_node_indices& L_rr_node_indices, - const int max_chan_width, - const t_chan_width& chan_width, - const int wire_to_ipin_switch, - const int delayless_switch, - const enum e_directionality directionality, - bool* Fc_clipped, - const t_direct_inf* directs, - const int num_directs, - const t_clb_to_clb_directs* clb_to_clb_directs, - bool is_global_graph) { +static std::function alloc_and_load_rr_graph(std::vector& L_rr_node, + const int num_seg_types, + const t_chan_details& chan_details_x, + const t_chan_details& chan_details_y, + const t_track_to_pin_lookup& track_to_pin_lookup, + const t_pin_to_track_lookup& opin_to_track_map, + const vtr::NdMatrix, 3>& switch_block_conn, + t_sb_connection_map* sb_conn_map, + const DeviceGrid& grid, + const int Fs, + t_sblock_pattern& sblock_pattern, + const std::vector>& Fc_out, + vtr::NdMatrix& Fc_xofs, + vtr::NdMatrix& Fc_yofs, + const t_rr_node_indices& L_rr_node_indices, + const int max_chan_width, + const t_chan_width& chan_width, + const int wire_to_ipin_switch, + const int delayless_switch, + const enum e_directionality directionality, + bool* Fc_clipped, + const t_direct_inf* directs, + const int num_directs, + const t_clb_to_clb_directs* clb_to_clb_directs, + bool is_global_graph, + const enum e_clock_modeling clock_modeling) { //We take special care when creating RR graph edges (there are typically many more //edges than nodes in an RR graph). // @@ -1295,7 +1308,25 @@ static void alloc_and_load_rr_graph(const int num_nodes, } } - init_fan_in(L_rr_node, num_nodes); + std::function update_chan_width = [](t_chan_width*) { + }; + if (clock_modeling == DEDICATED_NETWORK) { + ClockRRGraphBuilder builder( + chan_width, grid, &L_rr_node); + builder.create_and_append_clock_rr_graph( + num_seg_types, + &rr_edges_to_create); + uniquify_edges(rr_edges_to_create); + alloc_and_load_edges(L_rr_node, rr_edges_to_create); + rr_edges_to_create.clear(); + update_chan_width = [builder](t_chan_width* c) { + builder.update_chan_width(c); + }; + } + + init_fan_in(L_rr_node, L_rr_node.size()); + + return update_chan_width; } static void build_bidir_rr_opins(const int i, diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 617730a0df8..e195d13278a 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -235,6 +235,7 @@ void dump_sblock_pattern(const t_sblock_pattern& sblock_pattern, const char* fname); //Partitions RR graph edges to allow fast access to configurable/non-configurabe edge subsets +struct DeviceContext; void partition_rr_graph_edges(DeviceContext& device_ctx); #endif diff --git a/vpr/src/route/rr_graph_clock.cpp b/vpr/src/route/rr_graph_clock.cpp index 816c6a521c4..4dbb93a070f 100644 --- a/vpr/src/route/rr_graph_clock.cpp +++ b/vpr/src/route/rr_graph_clock.cpp @@ -9,119 +9,42 @@ #include "vtr_assert.h" #include "vtr_log.h" +#include "vtr_time.h" #include "vpr_error.h" -void ClockRRGraphBuilder:: - create_and_append_clock_rr_graph(std::vector& segment_inf, - const float R_minW_nmos, - const float R_minW_pmos, - int wire_to_rr_ipin_switch, - const enum e_base_cost_type base_cost_type) { - vtr::printf_info("Starting clock network routing resource graph generation...\n"); - clock_t begin = clock(); - - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto* chan_width = &device_ctx.chan_width; +void ClockRRGraphBuilder::create_and_append_clock_rr_graph(int num_seg_types, + t_rr_edge_info_set* rr_edges_to_create) { + vtr::ScopedStartFinishTimer timer("Build clock network routing resource graph"); + + const auto& device_ctx = g_vpr_ctx.device(); auto& clock_networks = device_ctx.clock_networks; auto& clock_routing = device_ctx.clock_connections; - size_t clock_nodes_start_idx = device_ctx.rr_nodes.size(); - - ClockRRGraphBuilder clock_graph = ClockRRGraphBuilder(); - clock_graph.create_clock_networks_wires(clock_networks, segment_inf.size()); - clock_graph.create_clock_networks_switches(clock_routing); - - // Reset fanin to account for newly added clock rr_nodes - init_fan_in(device_ctx.rr_nodes, device_ctx.rr_nodes.size()); - - clock_graph.add_rr_switches_and_map_to_nodes(clock_nodes_start_idx, R_minW_nmos, R_minW_pmos); - - // "Partition the rr graph edges for efficient access to configurable/non-configurable - // edge subsets. Must be done after RR switches have been allocated" - partition_rr_graph_edges(device_ctx); - - alloc_and_load_rr_indexed_data(segment_inf, device_ctx.rr_node_indices, - chan_width->max, wire_to_rr_ipin_switch, base_cost_type); - - float elapsed_time = (float)(clock() - begin) / CLOCKS_PER_SEC; - vtr::printf_info("Building clock network resource graph took %g seconds\n", elapsed_time); + create_clock_networks_wires(clock_networks, num_seg_types, rr_edges_to_create); + create_clock_networks_switches(clock_routing, rr_edges_to_create); } // Clock network information comes from the arch file -void ClockRRGraphBuilder::create_clock_networks_wires(std::vector>& clock_networks, - int num_segments) { +void ClockRRGraphBuilder::create_clock_networks_wires(const std::vector>& clock_networks, + int num_segments, + t_rr_edge_info_set* rr_edges_to_create) { // Add rr_nodes for each clock network wire for (auto& clock_network : clock_networks) { - clock_network->create_rr_nodes_for_clock_network_wires(*this, num_segments); + clock_network->create_rr_nodes_for_clock_network_wires(*this, rr_nodes_, rr_edges_to_create, num_segments); } // Reduce the capacity of rr_nodes for performance - auto& rr_nodes = g_vpr_ctx.mutable_device().rr_nodes; - rr_nodes.shrink_to_fit(); + rr_nodes_->shrink_to_fit(); } // Clock switch information comes from the arch file -void ClockRRGraphBuilder::create_clock_networks_switches(std::vector>& clock_connections) { +void ClockRRGraphBuilder::create_clock_networks_switches(const std::vector>& clock_connections, + t_rr_edge_info_set* rr_edges_to_create) { for (auto& clock_connection : clock_connections) { - clock_connection->create_switches(*this); + clock_connection->create_switches(*this, rr_edges_to_create); } } -void ClockRRGraphBuilder::add_rr_switches_and_map_to_nodes(size_t node_start_idx, - const float R_minW_nmos, - const float R_minW_pmos) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_nodes = device_ctx.rr_nodes; - - // Check to see that clock nodes were sucessfully appended to rr_nodes - VTR_ASSERT(rr_nodes.size() > node_start_idx); - - std::unordered_map arch_switch_to_rr_switch; - - // The following assumes that arch_switch was specified earlier when the edges where added - for (size_t node_idx = node_start_idx; node_idx < rr_nodes.size(); node_idx++) { - auto& from_node = rr_nodes[node_idx]; - for (t_edge_size edge_idx = 0; edge_idx < from_node.num_edges(); edge_idx++) { - int arch_switch_idx = from_node.edge_switch(edge_idx); - - int rr_switch_idx; - auto itter = arch_switch_to_rr_switch.find(arch_switch_idx); - if (itter == arch_switch_to_rr_switch.end()) { - rr_switch_idx = add_rr_switch_from_arch_switch_inf(arch_switch_idx, - R_minW_nmos, - R_minW_pmos); - arch_switch_to_rr_switch[arch_switch_idx] = rr_switch_idx; - } else { - rr_switch_idx = itter->second; - } - - from_node.set_edge_switch(edge_idx, rr_switch_idx); - } - } - - device_ctx.rr_switch_inf.shrink_to_fit(); -} - -int ClockRRGraphBuilder::add_rr_switch_from_arch_switch_inf(int arch_switch_idx, - const float R_minW_nmos, - const float R_minW_pmos) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& rr_switch_inf = device_ctx.rr_switch_inf; - auto& arch_switch_inf = device_ctx.arch_switch_inf; - - rr_switch_inf.emplace_back(); - int rr_switch_idx = rr_switch_inf.size() - 1; - - // TODO: Add support for non fixed Tdel based on fanin information - // and move assigning Tdel into add_rr_switch - VTR_ASSERT(arch_switch_inf[arch_switch_idx].fixed_Tdel()); - int fanin = UNDEFINED; - - load_rr_switch_from_arch_switch(arch_switch_idx, rr_switch_idx, fanin, R_minW_nmos, R_minW_pmos); - - return rr_switch_idx; -} - void ClockRRGraphBuilder::add_switch_location(std::string clock_name, std::string switch_point_name, int x, @@ -213,39 +136,61 @@ std::set> SwitchPoint::get_switch_locations() const { } int ClockRRGraphBuilder::get_and_increment_chanx_ptc_num() { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& grid = device_ctx.grid; - auto* channel_width = &device_ctx.chan_width; - // ptc_num is determined by the channel width // The channel width lets the drawing engine how much to space the LBs appart - int ptc_num = channel_width->x_max++; - if (channel_width->x_max > channel_width->max) { - channel_width->max = channel_width->x_max; - } - - for (size_t i = 0; i < grid.height(); ++i) { - device_ctx.chan_width.x_list[i]++; - } - + int ptc_num = chan_width_.x_max + (chanx_ptc_idx_++); return ptc_num; } int ClockRRGraphBuilder::get_and_increment_chany_ptc_num() { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto& grid = device_ctx.grid; - auto* channel_width = &device_ctx.chan_width; - // ptc_num is determined by the channel width // The channel width lets the drawing engine how much to space the LBs appart - int ptc_num = channel_width->y_max++; - if (channel_width->y_max > channel_width->max) { - channel_width->max = channel_width->y_max; + int ptc_num = chan_width_.y_max + (chany_ptc_idx_++); + return ptc_num; +} + +void ClockRRGraphBuilder::update_chan_width(t_chan_width* chan_width) const { + chan_width->x_max += chanx_ptc_idx_; + chan_width->y_max += chany_ptc_idx_; + chan_width->max = std::max(chan_width->max, chan_width->x_max); + chan_width->max = std::max(chan_width->max, chan_width->y_max); + + for (size_t i = 0; i < grid_.height(); ++i) { + chan_width->x_list[i] += chanx_ptc_idx_; + } + for (size_t i = 0; i < grid_.width(); ++i) { + chan_width->y_list[i] += chany_ptc_idx_; } +} - for (size_t i = 0; i < grid.width(); ++i) { - device_ctx.chan_width.y_list[i]++; +size_t ClockRRGraphBuilder::estimate_additional_nodes(const DeviceGrid& grid) { + size_t num_additional_nodes = 0; + + const auto& device_ctx = g_vpr_ctx.device(); + auto& clock_networks = device_ctx.clock_networks; + auto& clock_routing = device_ctx.clock_connections; + + for (auto& clock_network : clock_networks) { + num_additional_nodes += clock_network->estimate_additional_nodes(grid); + } + for (auto& clock_connection : clock_routing) { + num_additional_nodes += clock_connection->estimate_additional_nodes(); } - return ptc_num; + return num_additional_nodes; +} + +void ClockRRGraphBuilder::add_edge(t_rr_edge_info_set* rr_edges_to_create, + int src_node, + int sink_node, + int arch_switch_idx) const { + const auto& device_ctx = g_vpr_ctx.device(); + VTR_ASSERT(arch_switch_idx < device_ctx.num_arch_switches); + rr_edges_to_create->emplace_back(src_node, sink_node, arch_switch_idx); + + const auto& sw = device_ctx.arch_switch_inf[arch_switch_idx]; + if (!sw.buffered() && !sw.configurable()) { + // This is short, create a reverse edge. + rr_edges_to_create->emplace_back(sink_node, src_node, arch_switch_idx); + } } diff --git a/vpr/src/route/rr_graph_clock.h b/vpr/src/route/rr_graph_clock.h index ccab33d8bf4..3ee3a18ee00 100644 --- a/vpr/src/route/rr_graph_clock.h +++ b/vpr/src/route/rr_graph_clock.h @@ -68,11 +68,26 @@ class ClockRRGraphBuilder { int get_and_increment_chanx_ptc_num(); int get_and_increment_chany_ptc_num(); - public: /* Reverse lookup for to find the clock source and tap locations for each clock_network * The map key is the the clock network name and value are all the switch points*/ std::unordered_map clock_name_to_switch_points; + public: + ClockRRGraphBuilder( + const t_chan_width& chan_width, + const DeviceGrid& grid, + std::vector* rr_nodes) + : chan_width_(chan_width) + , grid_(grid) + , rr_nodes_(rr_nodes) + , chanx_ptc_idx_(0) + , chany_ptc_idx_(0) { + } + + const DeviceGrid& grid() const { + return grid_; + } + /* Saves a map from switch rr_node idx -> {x, y} location */ void add_switch_location(std::string clock_name, std::string switch_point_name, @@ -90,41 +105,37 @@ class ClockRRGraphBuilder { std::set> get_switch_locations(std::string clock_name, std::string switch_point_name) const; + void update_chan_width(t_chan_width* chan_width) const; + + static size_t estimate_additional_nodes(const DeviceGrid& grid); + + void add_edge(t_rr_edge_info_set* rr_edges_to_create, + int src_node, + int sink_node, + int arch_switch_idx) const; + public: /* Creates the routing resourse (rr) graph of the clock network and appends it to the * existing rr graph created in build_rr_graph for inter-block and intra-block routing. */ - static void create_and_append_clock_rr_graph(std::vector& segment_inf, - const float R_minW_nmos, - const float R_minW_pmos, - int wire_to_rr_ipin_switch, - const enum e_base_cost_type base_cost_type); + void create_and_append_clock_rr_graph(int num_seg_types, + t_rr_edge_info_set* rr_edges_to_create); private: /* loop over all of the clock networks and create their wires */ - void create_clock_networks_wires(std::vector>& clock_networks, - int num_segments); + void create_clock_networks_wires(const std::vector>& clock_networks, + int num_segments, + t_rr_edge_info_set* rr_edges_to_create); /* loop over all clock routing connections and create the switches and connections */ - void create_clock_networks_switches(std::vector>& clock_connections); - - /* Adds the architecture switches that the clock rr_nodes use to the rr switches and - * maps the newly added rr_switches to the nodes. - * The input nodes_start_idx ~ corresponds to the rr_node index of the first node - * used to create the clock network. Every node from node_start_idx..rr_nodes.size-1 - * is a node in the clock network.*/ - // TODO: Change to account for swtich fanin. Note: this function is simular to - // remap_rr_node_switch_indices but does not take into account node fanin. - void add_rr_switches_and_map_to_nodes(size_t nodes_start_idx, - const float R_minW_nmos, - const float R_minW_pmos); - - /* Returns the index of the newly added rr_switch. The rr_switch information is coppied - * in from the arch_switch information */ - // TODO: Does not account for fanin information when copping Tdel. Note: this function - // is simular to load_rr_switch_inf but does not take into account node fanin. - int add_rr_switch_from_arch_switch_inf(int arch_switch_idx, - const float R_minW_nmos, - const float R_minW_pmos); + void create_clock_networks_switches(const std::vector>& clock_connections, + t_rr_edge_info_set* rr_edges_to_create); + + const t_chan_width& chan_width_; + const DeviceGrid& grid_; + std::vector* rr_nodes_; + + int chanx_ptc_idx_; + int chany_ptc_idx_; }; #endif diff --git a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/config/golden_results.txt b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/config/golden_results.txt index 7308c682561..fdb69817a1f 100644 --- a/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/config/golden_results.txt +++ b/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/config/golden_results.txt @@ -1,4 +1,4 @@ -arch circuit script_params vtr_flow_elapsed_time error odin_synth_time max_odin_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_revision vpr_status max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_time placed_wirelength_est place_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile crit_path_route_time num_global_nets num_routed_nets -timing/k6_frac_N10_frac_chain_mem32K_htree0_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 12.79 0.11 16188 2 0.11 -1 -1 34240 -1 -1 29 311 15 0 v8.0.0-rc1-1194-g64d9b2790 success 65912 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.76 7926 2.69 3.71918 -3791.41 -3.71918 38 14664 22 4.25198e+07 9.78293e+06 2.06134e+06 2629.25 5.78 13215 12 2732 3118 2727378 877873 4.6565 -4338.38 -4.6565 -217.731 -0.937841 2.60756e+06 3325.97 1.23 15 950 -timing/k6_frac_N10_frac_chain_mem32K_htree0_routedCLK_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 13.71 0.10 16176 2 0.10 -1 -1 34268 -1 -1 29 311 15 0 v8.0.0-rc1-1194-g64d9b2790 success 65764 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.79 7855 2.67 4.29577 -3815.97 -4.29577 40 14565 31 4.25198e+07 9.78293e+06 2.18945e+06 2792.66 6.37 13336 16 3013 3384 3288699 970769 4.44197 -4744.42 -4.44197 -296.276 -1.26627 2.74222e+06 3497.72 1.46 15 950 -timing/k6_frac_N10_frac_chain_mem32K_htree0short_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 13.25 0.11 16296 2 0.10 -1 -1 34304 -1 -1 29 311 15 0 v8.0.0-rc1-1194-g64d9b2790 success 66468 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.76 7926 2.70 3.71918 -3791.41 -3.71918 38 15436 16 4.25198e+07 9.78293e+06 2.05675e+06 2623.40 6.15 14101 14 2682 3088 2566936 820999 4.6565 -4410.32 -4.6565 -156.683 -0.791471 2.60298e+06 3320.12 1.27 15 950 +arch circuit script_params vtr_flow_elapsed_time error odin_synth_time max_odin_mem abc_depth abc_synth_time abc_cec_time abc_sec_time max_abc_mem ace_time max_ace_mem num_clb num_io num_memories num_mult vpr_revision vpr_status hostname rundir max_vpr_mem num_primary_inputs num_primary_outputs num_pre_packed_nets num_pre_packed_blocks num_netlist_clocks num_post_packed_nets num_post_packed_blocks device_width device_height device_grid_tiles device_limiting_resources device_name pack_time placed_wirelength_est place_time placed_CPD_est placed_setup_TNS_est placed_setup_WNS_est min_chan_width routed_wirelength min_chan_width_route_success_iteration logic_block_area_total logic_block_area_used min_chan_width_routing_area_total min_chan_width_routing_area_per_tile min_chan_width_route_time crit_path_routed_wirelength crit_path_route_success_iteration crit_path_total_nets_routed crit_path_total_connections_routed crit_path_total_heap_pushes crit_path_total_heap_pops critical_path_delay setup_TNS setup_WNS hold_TNS hold_WNS crit_path_routing_area_total crit_path_routing_area_per_tile crit_path_route_time num_global_nets num_routed_nets +timing/k6_frac_N10_frac_chain_mem32K_htree0_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 11.39 0.11 15932 2 0.07 -1 -1 34240 -1 -1 29 311 15 0 v8.0.0-rc1-1253-g3599b84ff success pckevin /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/run159/timing/k6_frac_N10_frac_chain_mem32K_htree0_40nm.xml/verilog/mkPktMerge.v/common_--clock_modeling_dedicated_network 71668 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.49 8034 1.86 4.67761 -3422.54 -4.67761 44 13800 13 4.25198e+07 9.78293e+06 2.32482e+06 2965.34 6.46 12712 15 2416 2757 3101448 1072423 5.28384 -4223.84 -5.28384 -558.987 -1.62141 3.01841e+06 3850.01 0.87 15 950 +timing/k6_frac_N10_frac_chain_mem32K_htree0_routedCLK_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 12.92 0.10 16036 2 0.08 -1 -1 34272 -1 -1 29 311 15 0 v8.0.0-rc1-1253-g3599b84ff success pckevin /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/run159/timing/k6_frac_N10_frac_chain_mem32K_htree0_routedCLK_40nm.xml/verilog/mkPktMerge.v/common_--clock_modeling_dedicated_network 67220 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.50 8349 1.86 4.46249 -3766.69 -4.46249 36 15475 25 4.25198e+07 9.78293e+06 2.00615e+06 2558.86 8.24 13920 13 3067 3534 3057326 934903 5.30223 -3590.14 -5.30223 -841.067 -2.43312 2.47846e+06 3161.31 0.70 15 950 +timing/k6_frac_N10_frac_chain_mem32K_htree0short_40nm.xml verilog/mkPktMerge.v common_--clock_modeling_dedicated_network 10.20 0.07 16036 2 0.08 -1 -1 34328 -1 -1 29 311 15 0 v8.0.0-rc1-1253-g3599b84ff success pckevin /project/trees/vtr/vtr_flow/tasks/regression_tests/vtr_reg_strong/strong_dedicated_clock/run159/timing/k6_frac_N10_frac_chain_mem32K_htree0short_40nm.xml/verilog/mkPktMerge.v/common_--clock_modeling_dedicated_network 67096 311 156 1019 1160 1 965 511 28 28 784 memory auto 0.52 8047 1.86 4.20379 -3312.04 -4.20379 38 15873 29 4.25198e+07 9.78293e+06 2.05725e+06 2624.05 4.97 14350 15 3285 3698 4346113 2300071 5.46838 -4347.56 -5.46838 -1672.29 -3.37758 2.60363e+06 3320.95 1.26 15 950