From e785f1c97130ddea4ffae003a71864e0824ec1e8 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 18 Jul 2022 10:24:10 -0700 Subject: [PATCH 01/19] Files moved to Librrgraph and Files added to Libarchfpga --- libs/libarchfpga/src/base_cost_type.h | 14 +++ libs/libarchfpga/src/chan_width.h | 16 +++ libs/libarchfpga/src/cost_indices.h | 13 +++ .../libarchfpga/src}/device_grid.cpp | 2 +- .../libarchfpga/src}/device_grid.h | 0 libs/libarchfpga/src/graph_type.h | 13 +++ libs/libarchfpga/src/route_type.h | 9 ++ .../src/unified_to_parallel_seg_index.h | 8 ++ .../src/base/alloc_and_load_rr_indexed_data.h | 11 +++ .../librrgraph/src/base}/check_rr_graph.cpp | 97 +++++++++++-------- libs/librrgraph/src/base/check_rr_graph.h | 29 ++++++ libs/librrgraph/src/base/describe_rr_node.h | 9 ++ .../librrgraph/src/base}/gen/README.gen.md | 0 .../src/base}/gen/rr_graph_uxsdcxx.h | 0 .../src/base}/gen/rr_graph_uxsdcxx_capnp.h | 0 .../base}/gen/rr_graph_uxsdcxx_interface.h | 0 libs/librrgraph/src/base/get_parallel_segs.h | 11 +++ .../librrgraph/src/base}/rr_graph_reader.cpp | 63 +++++++----- libs/librrgraph/src/base/rr_graph_reader.h | 37 +++++++ .../src/base}/rr_graph_uxsdcxx_serializer.h | 64 +++++++++--- .../librrgraph/src/base}/rr_graph_writer.cpp | 52 ++++++---- libs/librrgraph/src/base/rr_graph_writer.h | 31 ++++++ libs/librrgraph/src/base/rr_metadata.cpp | 52 ++++++++++ libs/librrgraph/src/base/rr_metadata.h | 19 ++++ libs/librrgraph/src/base/rr_rc_data.cpp | 29 ++++++ .../librrgraph/src/base}/rr_rc_data.h | 2 +- .../libvtrutil/src}/vpr_error.cpp | 0 .../util => libs/libvtrutil/src}/vpr_error.h | 0 vpr/src/base/vpr_types.h | 67 +++++++------ vpr/src/route/check_rr_graph.h | 13 --- vpr/src/route/clock_connection_builders.cpp | 3 +- vpr/src/route/clock_network_builders.cpp | 4 +- vpr/src/route/rr_graph.h | 26 ++--- vpr/src/route/rr_graph2.h | 10 +- vpr/src/route/rr_graph_indexed_data.h | 11 ++- vpr/src/route/rr_graph_reader.h | 18 ---- vpr/src/route/rr_graph_timing_params.cpp | 2 +- vpr/src/route/rr_graph_writer.h | 13 --- vpr/src/route/rr_metadata.cpp | 59 ----------- vpr/src/route/rr_metadata.h | 18 ---- vpr/src/route/rr_rc_data.cpp | 29 ------ 41 files changed, 550 insertions(+), 304 deletions(-) create mode 100644 libs/libarchfpga/src/base_cost_type.h create mode 100644 libs/libarchfpga/src/chan_width.h create mode 100644 libs/libarchfpga/src/cost_indices.h rename {vpr/src/base => libs/libarchfpga/src}/device_grid.cpp (97%) rename {vpr/src/base => libs/libarchfpga/src}/device_grid.h (100%) create mode 100644 libs/libarchfpga/src/graph_type.h create mode 100644 libs/libarchfpga/src/route_type.h create mode 100644 libs/libarchfpga/src/unified_to_parallel_seg_index.h create mode 100644 libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h rename {vpr/src/route => libs/librrgraph/src/base}/check_rr_graph.cpp (89%) create mode 100644 libs/librrgraph/src/base/check_rr_graph.h create mode 100644 libs/librrgraph/src/base/describe_rr_node.h rename {vpr/src/route => libs/librrgraph/src/base}/gen/README.gen.md (100%) rename {vpr/src/route => libs/librrgraph/src/base}/gen/rr_graph_uxsdcxx.h (100%) rename {vpr/src/route => libs/librrgraph/src/base}/gen/rr_graph_uxsdcxx_capnp.h (100%) rename {vpr/src/route => libs/librrgraph/src/base}/gen/rr_graph_uxsdcxx_interface.h (100%) create mode 100644 libs/librrgraph/src/base/get_parallel_segs.h rename {vpr/src/route => libs/librrgraph/src/base}/rr_graph_reader.cpp (64%) create mode 100644 libs/librrgraph/src/base/rr_graph_reader.h rename {vpr/src/route => libs/librrgraph/src/base}/rr_graph_uxsdcxx_serializer.h (97%) rename {vpr/src/route => libs/librrgraph/src/base}/rr_graph_writer.cpp (57%) create mode 100644 libs/librrgraph/src/base/rr_graph_writer.h create mode 100644 libs/librrgraph/src/base/rr_metadata.cpp create mode 100644 libs/librrgraph/src/base/rr_metadata.h create mode 100644 libs/librrgraph/src/base/rr_rc_data.cpp rename {vpr/src/route => libs/librrgraph/src/base}/rr_rc_data.h (78%) rename {vpr/src/util => libs/libvtrutil/src}/vpr_error.cpp (100%) rename {vpr/src/util => libs/libvtrutil/src}/vpr_error.h (100%) delete mode 100644 vpr/src/route/check_rr_graph.h delete mode 100644 vpr/src/route/rr_graph_reader.h delete mode 100644 vpr/src/route/rr_graph_writer.h delete mode 100644 vpr/src/route/rr_metadata.cpp delete mode 100644 vpr/src/route/rr_metadata.h delete mode 100644 vpr/src/route/rr_rc_data.cpp diff --git a/libs/libarchfpga/src/base_cost_type.h b/libs/libarchfpga/src/base_cost_type.h new file mode 100644 index 00000000000..8112b97bb37 --- /dev/null +++ b/libs/libarchfpga/src/base_cost_type.h @@ -0,0 +1,14 @@ +#ifndef BASE_COST_TYPE_H +#define BASE_COST_TYPE_H + +enum e_base_cost_type { + DELAY_NORMALIZED, + DELAY_NORMALIZED_LENGTH, + DELAY_NORMALIZED_FREQUENCY, + DELAY_NORMALIZED_LENGTH_FREQUENCY, + DELAY_NORMALIZED_LENGTH_BOUNDED, + DEMAND_ONLY, + DEMAND_ONLY_NORMALIZED_LENGTH +}; + +#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/chan_width.h b/libs/libarchfpga/src/chan_width.h new file mode 100644 index 00000000000..eae2e08701b --- /dev/null +++ b/libs/libarchfpga/src/chan_width.h @@ -0,0 +1,16 @@ +#ifndef CHAN_WIDTH_H +#define CHAN_WIDTH_H + +#include + +struct t_chan_width { + int max = 0; + int x_max = 0; + int y_max = 0; + int x_min = 0; + int y_min = 0; + std::vector x_list; + std::vector y_list; +}; + +#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/cost_indices.h b/libs/libarchfpga/src/cost_indices.h new file mode 100644 index 00000000000..e3cff80b1aa --- /dev/null +++ b/libs/libarchfpga/src/cost_indices.h @@ -0,0 +1,13 @@ +#ifndef COST_INDICES_H +#define COST_INDICES_H + +///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. +enum e_cost_indices { + SOURCE_COST_INDEX = 0, + SINK_COST_INDEX, + OPIN_COST_INDEX, + IPIN_COST_INDEX, + CHANX_COST_INDEX_START +}; + +#endif \ No newline at end of file diff --git a/vpr/src/base/device_grid.cpp b/libs/libarchfpga/src/device_grid.cpp similarity index 97% rename from vpr/src/base/device_grid.cpp rename to libs/libarchfpga/src/device_grid.cpp index e4e05a7241c..9fc8c0afca9 100644 --- a/vpr/src/base/device_grid.cpp +++ b/libs/libarchfpga/src/device_grid.cpp @@ -1,5 +1,5 @@ #include "device_grid.h" -#include "vpr_utils.h" +//#include "vpr_utils.h" DeviceGrid::DeviceGrid(std::string grid_name, vtr::Matrix grid) : name_(grid_name) diff --git a/vpr/src/base/device_grid.h b/libs/libarchfpga/src/device_grid.h similarity index 100% rename from vpr/src/base/device_grid.h rename to libs/libarchfpga/src/device_grid.h diff --git a/libs/libarchfpga/src/graph_type.h b/libs/libarchfpga/src/graph_type.h new file mode 100644 index 00000000000..c7875a1e573 --- /dev/null +++ b/libs/libarchfpga/src/graph_type.h @@ -0,0 +1,13 @@ +#ifndef GRAPH_TYPE_H +#define GRAPH_TYPE_H + +enum e_graph_type { + GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */ + GRAPH_BIDIR, /* Detailed bidirectional graph */ + GRAPH_UNIDIR, /* Detailed unidir graph, untilable */ + /* RESEARCH TODO: Get this option debugged */ + GRAPH_UNIDIR_TILEABLE /* Detail unidir graph with wire groups multiples of 2*L */ +}; +typedef enum e_graph_type t_graph_type; + +#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/route_type.h b/libs/libarchfpga/src/route_type.h new file mode 100644 index 00000000000..a01adffba6c --- /dev/null +++ b/libs/libarchfpga/src/route_type.h @@ -0,0 +1,9 @@ +#ifndef ROUTE_TYPE_H +#define ROUTE_TYPE_H + +enum e_route_type { + GLOBAL, + DETAILED +}; + +#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/unified_to_parallel_seg_index.h b/libs/libarchfpga/src/unified_to_parallel_seg_index.h new file mode 100644 index 00000000000..55fabd4bd33 --- /dev/null +++ b/libs/libarchfpga/src/unified_to_parallel_seg_index.h @@ -0,0 +1,8 @@ +#ifndef UNIFIED_TO_PARALLEL_SEG_INDEX_H +#define UNIFIED_TO_PARALLEL_SEG_INDEX_H + +#include "physical_types.h" + +typedef std::unordered_multimap> t_unified_to_parallel_seg_index; + +#endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h new file mode 100644 index 00000000000..70fb5c85ccd --- /dev/null +++ b/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h @@ -0,0 +1,11 @@ +#ifndef ALLOC_AND_LOAD_RR_INDEXED_DATA_H +#define ALLOC_AND_LOAD_RR_INDEXED_DATA_H + +#include "physical_types.h" +void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, + const std::vector& segment_inf_x, + const std::vector& segment_inf_y, + int wire_to_ipin_switch, + enum e_base_cost_type base_cost_type); + +#endif \ No newline at end of file diff --git a/vpr/src/route/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp similarity index 89% rename from vpr/src/route/check_rr_graph.cpp rename to libs/librrgraph/src/base/check_rr_graph.cpp index 838791c5878..e0f4c5a678a 100644 --- a/vpr/src/route/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -1,22 +1,27 @@ #include "vtr_log.h" #include "vtr_memory.h" +#include "vtr_util.h" -#include "vpr_types.h" #include "vpr_error.h" -#include "globals.h" -#include "rr_graph.h" +//#include "globals.h" +//#include "rr_graph.h" #include "check_rr_graph.h" +#include "rr_node.h" +#include "physical_types_util.h" + +#include "describe_rr_node.h" + /*********************** Subroutines local to this module *******************/ -static bool rr_node_is_global_clb_ipin(RRNodeId inode); +static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode); -static void check_unbuffered_edges(int from_node); +static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node); -static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid); +static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_rr_node& node); -static void check_rr_edge(int from_node, int from_edge, int to_node); +static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int from_edge, int to_node); /************************ Subroutine definitions ****************************/ @@ -41,14 +46,18 @@ class node_edge_sorter { void check_rr_graph(const t_graph_type graph_type, const DeviceGrid& grid, - const std::vector& types) { + const std::vector& types, + const RRGraphView& rr_graph, + const vtr::vector rr_indexed_data, + const t_chan_width& chan_width, + int virtual_clock_network_root_idx) { e_route_type route_type = DETAILED; if (graph_type == GRAPH_GLOBAL) { route_type = GLOBAL; } - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; + //auto& device_ctx = g_vpr_ctx.device(); + //const auto& rr_graph = device_ctx.rr_graph; auto total_edges_to_node = std::vector(rr_graph.num_nodes()); auto switch_types_from_current_to_node = std::vector(rr_graph.num_nodes()); @@ -66,14 +75,14 @@ void check_rr_graph(const t_graph_type graph_type, } // Virtual clock network sink is special, ignore. - if (device_ctx.virtual_clock_network_root_idx == int(inode)) { + if (virtual_clock_network_root_idx == int(inode)) { continue; } t_rr_type rr_type = rr_graph.node_type(rr_node); int num_edges = rr_graph.num_edges(RRNodeId(inode)); - check_rr_node(inode, route_type, device_ctx); + check_rr_node(inode, route_type, rr_graph, grid, rr_indexed_data, chan_width); /* Check all the connectivity (edges, etc.) information. */ edges.resize(0); @@ -89,7 +98,7 @@ void check_rr_graph(const t_graph_type graph_type, inode, to_node); } - check_rr_edge(inode, iedge, to_node); + check_rr_edge(rr_graph, inode, iedge, to_node); edges.emplace_back(to_node, iedge); total_edges_to_node[to_node]++; @@ -181,7 +190,7 @@ void check_rr_graph(const t_graph_type graph_type, } /* Slow test could leave commented out most of the time. */ - check_unbuffered_edges(inode); + check_unbuffered_edges(rr_graph, inode); //Check that all config/non-config edges are appropriately organized for (auto edge : rr_graph.configurable_edges(RRNodeId(inode))) { @@ -204,19 +213,19 @@ void check_rr_graph(const t_graph_type graph_type, * now I check that everything is reachable. */ bool is_fringe_warning_sent = false; - for (const RRNodeId& rr_node : device_ctx.rr_graph.nodes()) { + for (const RRNodeId& rr_node : rr_graph.nodes()) { size_t inode = (size_t)rr_node; t_rr_type rr_type = rr_graph.node_type(rr_node); if (rr_type != SOURCE) { - if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(rr_node)) { + if (total_edges_to_node[inode] < 1 && !rr_node_is_global_clb_ipin(rr_graph, grid, rr_node)) { /* A global CLB input pin will not have any edges, and neither will * * a SOURCE or the start of a carry-chain. Anything else is an error. * For simplicity, carry-chain input pin are entirely ignored in this test */ bool is_chain = false; if (rr_type == IPIN) { - t_physical_tile_type_ptr type = device_ctx.grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type; + t_physical_tile_type_ptr type = grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type; for (const t_fc_specification& fc_spec : types[type->index].fc_specs) { if (fc_spec.fc_value == 0 && fc_spec.seg_index == 0) { is_chain = true; @@ -235,8 +244,8 @@ void check_rr_graph(const t_graph_type graph_type, if (!is_chain && !is_fringe && !is_wire) { if (rr_graph.node_type(rr_node) == IPIN || rr_graph.node_type(rr_node) == OPIN) { - if (has_adjacent_channel(node, device_ctx.grid)) { - auto block_type = device_ctx.grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type; + if (has_adjacent_channel(rr_graph, grid, node)) { + auto block_type = grid[rr_graph.node_xlow(rr_node)][rr_graph.node_ylow(rr_node)].type; std::string pin_name = block_type_pin_index_to_name(block_type, rr_graph.node_pin_num(rr_node)); /* Print error messages for all the sides that a node may appear */ for (const e_side& node_side : SIDES) { @@ -268,16 +277,16 @@ void check_rr_graph(const t_graph_type graph_type, } } -static bool rr_node_is_global_clb_ipin(RRNodeId inode) { +static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const DeviceGrid& grid, RRNodeId inode) { /* Returns true if inode refers to a global CLB input pin node. */ int ipin; t_physical_tile_type_ptr type; - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; + // auto& device_ctx = g_vpr_ctx.device(); + // const auto& rr_graph = device_ctx.rr_graph; - type = device_ctx.grid[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)].type; + type = grid[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)].type; if (rr_graph.node_type(inode) != IPIN) return (false); @@ -287,7 +296,12 @@ static bool rr_node_is_global_clb_ipin(RRNodeId inode) { return type->is_ignored_pin[ipin]; } -void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& device_ctx) { +void check_rr_node(int inode, + enum e_route_type route_type, + const RRGraphView& rr_graph, + const DeviceGrid& grid, + const vtr::vector rr_indexed_data, + const t_chan_width& chan_width) { /* This routine checks that the rr_node is inside the grid and has a valid * pin number, etc. */ @@ -298,7 +312,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& int nodes_per_chan, tracks_per_node, num_edges; RRIndexedDataId cost_index; float C, R; - const auto& rr_graph = device_ctx.rr_graph; + //const auto& rr_graph = device_ctx.rr_graph; RRNodeId rr_node = RRNodeId(inode); rr_type = rr_graph.node_type(rr_node); @@ -311,7 +325,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& cost_index = rr_graph.node_cost_index(rr_node); type = nullptr; - const auto& grid = device_ctx.grid; + //const auto& grid = device_ctx.grid; if (xlow > xhigh || ylow > yhigh) { VPR_ERROR(VPR_ERROR_ROUTE, "in check_rr_node: rr endpoints are (%d,%d) and (%d,%d).\n", xlow, ylow, xhigh, yhigh); @@ -327,13 +341,14 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& "in check_rr_node: inode %d (type %d) had a ptc_num of %d.\n", inode, rr_type, ptc_num); } - if (!cost_index || (size_t)cost_index >= (size_t)device_ctx.rr_indexed_data.size()) { + if (!cost_index || (size_t)cost_index >= (size_t)rr_indexed_data.size()) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "in check_rr_node: node %d cost index (%d) is out of range.\n", inode, cost_index); } /* Check that the segment is within the array and such. */ - type = device_ctx.grid[xlow][ylow].type; + // type = device_ctx.grid[xlow][ylow].type; + type = grid[xlow][ylow].type; switch (rr_type) { case SOURCE: @@ -439,11 +454,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& case CHANX: if (route_type == DETAILED) { - nodes_per_chan = device_ctx.chan_width.max; + nodes_per_chan = chan_width.max; tracks_per_node = 1; } else { nodes_per_chan = 1; - tracks_per_node = device_ctx.chan_width.x_list[ylow]; + tracks_per_node = chan_width.x_list[ylow]; } if (ptc_num >= nodes_per_chan) { @@ -459,11 +474,11 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& case CHANY: if (route_type == DETAILED) { - nodes_per_chan = device_ctx.chan_width.max; + nodes_per_chan = chan_width.max; tracks_per_node = 1; } else { nodes_per_chan = 1; - tracks_per_node = device_ctx.chan_width.y_list[xlow]; + tracks_per_node = chan_width.y_list[xlow]; } if (ptc_num >= nodes_per_chan) { @@ -494,7 +509,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& //Don't worry about disconnect PINs which have no adjacent channels (i.e. on the device perimeter) bool check_for_out_edges = true; if (rr_type == IPIN || rr_type == OPIN) { - if (!has_adjacent_channel(rr_graph.rr_nodes()[inode], device_ctx.grid)) { + if (!has_adjacent_channel(rr_graph, grid, rr_graph.rr_nodes()[inode])) { check_for_out_edges = false; } } @@ -528,7 +543,7 @@ void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& } } -static void check_unbuffered_edges(int from_node) { +static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node) { /* This routine checks that all pass transistors in the routing truly are * * bidirectional. It may be a slow check, so don't use it all the time. */ @@ -537,8 +552,8 @@ static void check_unbuffered_edges(int from_node) { short from_switch_type; bool trans_matched; - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; + // auto& device_ctx = g_vpr_ctx.device(); + // const auto& rr_graph = device_ctx.rr_graph; from_rr_type = rr_graph.node_type(RRNodeId(from_node)); if (from_rr_type != CHANX && from_rr_type != CHANY) @@ -584,11 +599,11 @@ static void check_unbuffered_edges(int from_node) { } /* End for all from_node edges */ } -static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid) { +static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_rr_node& node) { /* TODO: this function should be reworked later to adapt RRGraphView interface * once xlow(), ylow(), side() APIs are implemented */ - const auto& rr_graph = g_vpr_ctx.device().rr_graph; + //const auto& rr_graph = g_vpr_ctx.device().rr_graph; VTR_ASSERT(rr_graph.node_type(node.id()) == IPIN || rr_graph.node_type(node.id()) == OPIN); if ((rr_graph.node_xlow(node.id()) == 0 && !rr_graph.is_node_on_specific_side(node.id(), RIGHT)) //left device edge connects only along block's right side @@ -601,9 +616,9 @@ static bool has_adjacent_channel(const t_rr_node& node, const DeviceGrid& grid) return true; //All other blocks will be surrounded on all sides by channels } -static void check_rr_edge(int from_node, int iedge, int to_node) { - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; +static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int iedge, int to_node) { + // auto& device_ctx = g_vpr_ctx.device(); + // const auto& rr_graph = device_ctx.rr_graph; //Check that to to_node's fan-in is correct, given the switch type int iswitch = rr_graph.edge_switch(RRNodeId(from_node), iedge); diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h new file mode 100644 index 00000000000..3f3f52af3e8 --- /dev/null +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -0,0 +1,29 @@ +#ifndef CHECK_RR_GRAPH_H +#define CHECK_RR_GRAPH_H + +#include "physical_types.h" +//#include "vpr_context.h" + +#include "graph_type.h" +#include "device_grid.h" +#include "route_type.h" +#include "rr_graph_view.h" +#include "chan_width.h" + + +void check_rr_graph(const t_graph_type graph_type, + const DeviceGrid& grid, + const std::vector& types, + const RRGraphView& rr_graph, + const vtr::vector rr_indexed_data, + const t_chan_width& chan_width, + int virtual_clock_network_root_idx); + +void check_rr_node(int inode, + enum e_route_type route_type, + const RRGraphView& rr_graph, + const DeviceGrid& grid, + const vtr::vector rr_indexed_data, + const t_chan_width& chan_width); + +#endif diff --git a/libs/librrgraph/src/base/describe_rr_node.h b/libs/librrgraph/src/base/describe_rr_node.h new file mode 100644 index 00000000000..9b4b8dee18f --- /dev/null +++ b/libs/librrgraph/src/base/describe_rr_node.h @@ -0,0 +1,9 @@ +#ifndef DESCRIBE_RR_NODE +#define DESCRIBE_RR_NODE + +#include + +//Returns a brief one-line summary of an RR node +std::string describe_rr_node(int inode); + +#endif \ No newline at end of file diff --git a/vpr/src/route/gen/README.gen.md b/libs/librrgraph/src/base/gen/README.gen.md similarity index 100% rename from vpr/src/route/gen/README.gen.md rename to libs/librrgraph/src/base/gen/README.gen.md diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h similarity index 100% rename from vpr/src/route/gen/rr_graph_uxsdcxx.h rename to libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h similarity index 100% rename from vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h rename to libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h diff --git a/vpr/src/route/gen/rr_graph_uxsdcxx_interface.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h similarity index 100% rename from vpr/src/route/gen/rr_graph_uxsdcxx_interface.h rename to libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h diff --git a/libs/librrgraph/src/base/get_parallel_segs.h b/libs/librrgraph/src/base/get_parallel_segs.h new file mode 100644 index 00000000000..938702e7aef --- /dev/null +++ b/libs/librrgraph/src/base/get_parallel_segs.h @@ -0,0 +1,11 @@ +#ifndef GET_PARALLEL_SEGS_H +#define GET_PARALLEL_SEGS_H + +#include "unified_to_parallel_seg_index.h" +#include "physical_types.h" + +std::vector get_parallel_segs(const std::vector& segment_inf, + t_unified_to_parallel_seg_index& seg_index_map, + enum e_parallel_axis parallel_axis); + +#endif \ No newline at end of file diff --git a/vpr/src/route/rr_graph_reader.cpp b/libs/librrgraph/src/base/rr_graph_reader.cpp similarity index 64% rename from vpr/src/route/rr_graph_reader.cpp rename to libs/librrgraph/src/base/rr_graph_reader.cpp index 20cd6ca8a40..95579f8a8fe 100644 --- a/vpr/src/route/rr_graph_reader.cpp +++ b/libs/librrgraph/src/base/rr_graph_reader.cpp @@ -21,8 +21,8 @@ #include #include "vtr_time.h" -#include "vpr_types.h" -#include "globals.h" +//#include "vpr_types.h" +//#include "globals.h" #include "pugixml.hpp" #include "pugixml_util.hpp" @@ -32,26 +32,41 @@ #endif /************************ Subroutine definitions ****************************/ - -/*loads the given RR_graph file into the appropriate data structures +/* loads the given RR_graph file into the appropriate data structures * as specified by read_rr_graph_name. Set up correct routing data * structures as well*/ -void load_rr_file(const t_graph_type graph_type, - const DeviceGrid& grid, + +/**FIXME: To make rr_graph_reader independent of vpr_context, the below + * parameters are a workaround to passing the data structures of DeviceContext. + * Needs a solution to reduce the number of parameters passed in.*/ + +void load_rr_file(RRGraphBuilder* rr_graph_builder, + RRGraphView* rr_graph, + const std::vector& physical_tile_types, const std::vector& segment_inf, + vtr::vector* rr_indexed_data, + std::vector& rr_rc_data, + const DeviceGrid& grid, + const t_arch_switch_inf* arch_switch_inf, + const t_graph_type graph_type, + t_arch* arch, + t_chan_width* chan_width, const enum e_base_cost_type base_cost_type, + const size_t num_arch_switches, + const int virtual_clock_network_root_idx, int* wire_to_rr_ipin_switch, const char* read_rr_graph_name, + std::string* read_rr_graph_filename, bool read_edge_metadata, bool do_check_rr_graph) { vtr::ScopedStartFinishTimer timer("Loading routing resource graph"); - auto& device_ctx = g_vpr_ctx.mutable_device(); + // auto& device_ctx = g_vpr_ctx.mutable_device(); size_t num_segments = segment_inf.size(); - device_ctx.rr_graph_builder.reserve_segments(num_segments); + rr_graph_builder->reserve_segments(num_segments); for (size_t iseg = 0; iseg < num_segments; ++iseg) { - device_ctx.rr_graph_builder.add_rr_segment(segment_inf[(iseg)]); + rr_graph_builder->add_rr_segment(segment_inf[(iseg)]); } RrGraphSerializer reader( @@ -60,22 +75,24 @@ void load_rr_file(const t_graph_type graph_type, wire_to_rr_ipin_switch, do_check_rr_graph, read_rr_graph_name, - &device_ctx.read_rr_graph_filename, + read_rr_graph_filename, read_edge_metadata, - &device_ctx.chan_width, - &device_ctx.rr_graph_builder.rr_nodes(), - &device_ctx.rr_graph_builder, - &device_ctx.rr_graph, - &device_ctx.rr_graph_builder.rr_switch(), - &device_ctx.rr_indexed_data, - device_ctx.num_arch_switches, - device_ctx.arch_switch_inf, - device_ctx.rr_graph.rr_segments(), - device_ctx.physical_tile_types, + chan_width, + &rr_graph_builder->rr_nodes(), + rr_graph_builder, + rr_graph, + &rr_graph_builder->rr_switch(), + rr_indexed_data, + rr_rc_data, + virtual_clock_network_root_idx, + num_arch_switches, + arch_switch_inf, + rr_graph->rr_segments(), + physical_tile_types, grid, - &device_ctx.rr_graph_builder.rr_node_metadata(), - &device_ctx.rr_graph_builder.rr_edge_metadata(), - &device_ctx.arch->strings); + &rr_graph_builder->rr_node_metadata(), + &rr_graph_builder->rr_edge_metadata(), + &arch->strings); if (vtr::check_file_name_extension(read_rr_graph_name, ".xml")) { try { diff --git a/libs/librrgraph/src/base/rr_graph_reader.h b/libs/librrgraph/src/base/rr_graph_reader.h new file mode 100644 index 00000000000..3084868dfad --- /dev/null +++ b/libs/librrgraph/src/base/rr_graph_reader.h @@ -0,0 +1,37 @@ +/* Defines the function used to load an rr graph written in xml format into vpr*/ + +#ifndef RR_GRAPH_READER_H +#define RR_GRAPH_READER_H + +#include "graph_type.h" +#include "device_grid.h" +#include "physical_types.h" +#include "base_cost_type.h" +#include "chan_width.h" +#include "rr_node.h" +#include "rr_graph_builder.h" +#include "rr_graph_view.h" +#include "rr_graph_fwd.h" + + +void load_rr_file(RRGraphBuilder* rr_graph_builder, + RRGraphView* rr_graph, + const std::vector& physical_tile_types, + const std::vector& segment_inf, + vtr::vector* rr_indexed_data, + std::vector& rr_rc_data, + const DeviceGrid& grid, + const t_arch_switch_inf* arch_switch_inf, + const t_graph_type graph_type, + t_arch* arch, + t_chan_width* chan_width, + const enum e_base_cost_type base_cost_type, + const size_t num_arch_switches, + const int virtual_clock_network_root_idx, + int* wire_to_rr_ipin_switch, + const char* read_rr_graph_name, + std::string* read_rr_graph_filename, + bool read_edge_metadata, + bool do_check_rr_graph); + +#endif /* RR_GRAPH_READER_H */ diff --git a/vpr/src/route/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h similarity index 97% rename from vpr/src/route/rr_graph_uxsdcxx_serializer.h rename to libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h index 40608d52b73..093d40e5dba 100644 --- a/vpr/src/route/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h @@ -4,21 +4,41 @@ #include #include -#include "rr_graph.h" -#include "rr_graph_uxsdcxx_interface.h" #include "rr_node.h" -#include "vpr_error.h" #include "rr_metadata.h" +#include "rr_graph_uxsdcxx_interface.h" + +#include "check_rr_graph.h" #include "read_xml_arch_file.h" + #include "vtr_log.h" #include "vtr_version.h" -#include "vpr_utils.h" -#include "check_rr_graph.h" -#include "rr_graph2.h" -#include "rr_graph_indexed_data.h" + +#include "vpr_error.h" +//#include "vpr_utils.h" + +#include "device_grid.h" +#include "chan_width.h" +#include "base_cost_type.h" +#include "unified_to_parallel_seg_index.h" +#include "graph_type.h" +#include "cost_indices.h" +#include "alloc_and_load_rr_indexed_data.h" +#include "get_parallel_segs.h" + +#include "rr_graph_view.h" +#include "rr_graph_builder.h" +#include "rr_rc_data.h" + +#include "vtr_util.h" +#include "arch_util.h" +#include "physical_types_util.h" + + class MetadataBind { public: - MetadataBind(vtr::string_internment* strings, vtr::interned_string empty) + MetadataBind(MetadataStorage* rr_node_metadata, MetadataStorage>* rr_edge_metadata, + vtr::string_internment* strings, vtr::interned_string empty) : is_node_(false) , is_edge_(false) , ignore_(false) @@ -27,7 +47,9 @@ class MetadataBind { , switch_id_(OPEN) , strings_(strings) , name_(empty) - , value_(empty) {} + , value_(empty) + , rr_node_metadata_(rr_node_metadata) + , rr_edge_metadata_(rr_edge_metadata) {} ~MetadataBind() { assert_clear(); @@ -69,9 +91,9 @@ class MetadataBind { void bind() { if (is_node_) { - vpr::add_rr_node_metadata(inode_, name_, value_); + vpr::add_rr_node_metadata(*rr_node_metadata_, inode_, name_, value_); } else if (is_edge_) { - vpr::add_rr_edge_metadata(inode_, sink_node_, switch_id_, + vpr::add_rr_edge_metadata(*rr_edge_metadata_,inode_, sink_node_, switch_id_, name_, value_); } else if (ignore_) { @@ -103,6 +125,8 @@ class MetadataBind { vtr::string_internment* strings_; vtr::interned_string name_; vtr::interned_string value_; + MetadataStorage* rr_node_metadata_; + MetadataStorage>* rr_edge_metadata_; }; // Context for walking metadata. @@ -265,6 +289,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphView* rr_graph, vtr::vector* rr_switch_inf, vtr::vector* rr_indexed_data, + std::vector& rr_rc_data, + const int virtual_clock_network_root_idx, const size_t num_arch_switches, const t_arch_switch_inf* arch_switch_inf, const vtr::vector& segment_inf, @@ -281,6 +307,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { , rr_switch_inf_(rr_switch_inf) , rr_indexed_data_(rr_indexed_data) , read_rr_graph_filename_(read_rr_graph_filename) + , rr_rc_data_(rr_rc_data) + , virtual_clock_network_root_idx_(virtual_clock_network_root_idx) , graph_type_(graph_type) , base_cost_type_(base_cost_type) , do_check_rr_graph_(do_check_rr_graph) @@ -675,7 +703,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inline int init_node_timing(int& inode, float C, float R) final { auto node = (*rr_nodes_)[inode]; RRNodeId node_id = node.id(); - rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(R, C))); + rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(R, C, rr_rc_data_))); return inode; } inline void finish_node_timing(int& /*inode*/) final {} @@ -733,7 +761,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { } inline MetadataBind init_node_metadata(int& inode) final { - MetadataBind bind(strings_, empty_); + MetadataBind bind(rr_node_metadata_, rr_edge_metadata_, strings_, empty_); bind.set_node_target(inode); return bind; } @@ -795,7 +823,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { type); } - rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(0, 0))); + rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(0, 0, rr_rc_data_))); return id; } @@ -886,7 +914,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { src_node, rr_nodes_->size()); } - MetadataBind bind(strings_, empty_); + MetadataBind bind(rr_node_metadata_, rr_edge_metadata_, strings_, empty_); if (read_edge_metadata_) { bind.set_edge_target(src_node, sink_node, switch_id); } else { @@ -1585,7 +1613,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { read_rr_graph_filename_->assign(read_rr_graph_name_); if (do_check_rr_graph_) { - check_rr_graph(graph_type_, grid_, physical_tile_types_); + check_rr_graph(graph_type_, grid_, physical_tile_types_, *rr_graph_, *rr_indexed_data_, *chan_width_, virtual_clock_network_root_idx_); } } @@ -1883,6 +1911,10 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { t_rr_node_indices* rr_node_indices_; std::string* read_rr_graph_filename_; + //Newly Added + std::vector& rr_rc_data_; + const int virtual_clock_network_root_idx_; + // Constant data for loads and writes. const t_graph_type graph_type_; const enum e_base_cost_type base_cost_type_; diff --git a/vpr/src/route/rr_graph_writer.cpp b/libs/librrgraph/src/base/rr_graph_writer.cpp similarity index 57% rename from vpr/src/route/rr_graph_writer.cpp rename to libs/librrgraph/src/base/rr_graph_writer.cpp index d06d24c5c45..c05b74ba8d8 100644 --- a/vpr/src/route/rr_graph_writer.cpp +++ b/libs/librrgraph/src/base/rr_graph_writer.cpp @@ -19,13 +19,29 @@ # include "rr_graph_uxsdcxx_capnp.h" #endif -#include "globals.h" +//#include "globals.h" /************************ Subroutine definitions ****************************/ /* This function is used to write the rr_graph into xml format into a a file with name: file_name */ -void write_rr_graph(const char* file_name) { - auto& device_ctx = g_vpr_ctx.mutable_device(); + +/**FIXME: To make rr_graph_reader independent of vpr_context, the below + * parameters are a workaround to passing the data structures of DeviceContext. + * Needs a solution to reduce the number of parameters passed in.*/ + +void write_rr_graph(RRGraphBuilder* rr_graph_builder, + RRGraphView* rr_graph, + const std::vector& physical_tile_types, + vtr::vector* rr_indexed_data, + std::vector& rr_rc_data, + const DeviceGrid& grid, + const t_arch_switch_inf* arch_switch_inf, + t_arch* arch, + t_chan_width* chan_width, + const size_t num_arch_switches, + const char* file_name, + const int virtual_clock_network_root_idx) { + //auto& device_ctx = g_vpr_ctx.mutable_device(); RrGraphSerializer reader( /*graph_type=*/t_graph_type(), /*base_cost_type=*/e_base_cost_type(), @@ -34,20 +50,22 @@ void write_rr_graph(const char* file_name) { /*read_rr_graph_name=*/nullptr, /*read_rr_graph_filename=*/nullptr, /*read_edge_metadata=*/false, - &device_ctx.chan_width, - &device_ctx.rr_graph_builder.rr_nodes(), - &device_ctx.rr_graph_builder, - &device_ctx.rr_graph, - &device_ctx.rr_graph_builder.rr_switch(), - &device_ctx.rr_indexed_data, - device_ctx.num_arch_switches, - device_ctx.arch_switch_inf, - device_ctx.rr_graph.rr_segments(), - device_ctx.physical_tile_types, - device_ctx.grid, - &device_ctx.rr_graph_builder.rr_node_metadata(), - &device_ctx.rr_graph_builder.rr_edge_metadata(), - &device_ctx.arch->strings); + chan_width, + &rr_graph_builder->rr_nodes(), + rr_graph_builder, + rr_graph, + &rr_graph_builder->rr_switch(), + rr_indexed_data, + rr_rc_data, + virtual_clock_network_root_idx, + num_arch_switches, + arch_switch_inf, + rr_graph->rr_segments(), + physical_tile_types, + grid, + &rr_graph_builder->rr_node_metadata(), + &rr_graph_builder->rr_edge_metadata(), + &arch->strings); if (vtr::check_file_name_extension(file_name, ".xml")) { std::fstream fp; diff --git a/libs/librrgraph/src/base/rr_graph_writer.h b/libs/librrgraph/src/base/rr_graph_writer.h new file mode 100644 index 00000000000..1e34f8755ff --- /dev/null +++ b/libs/librrgraph/src/base/rr_graph_writer.h @@ -0,0 +1,31 @@ +/* + * This function writes the RR_graph generated by VPR into a file in XML format + * Information included in the file includes rr nodes, rr switches, the grid, block info, node indices + */ + +#ifndef RR_GRAPH_WRITER_H +#define RR_GRAPH_WRITER_H + +#include "physical_types.h" +#include "chan_width.h" +#include "rr_node.h" +#include "rr_graph_builder.h" +#include "rr_graph_view.h" +#include "rr_graph_fwd.h" +#include "chan_width.h" +#include "device_grid.h" + +void write_rr_graph(RRGraphBuilder* rr_graph_builder, + RRGraphView* rr_graph, + const std::vector& physical_tile_types, + vtr::vector* rr_indexed_data, + std::vector& rr_rc_data, + const DeviceGrid& grid, + const t_arch_switch_inf* arch_switch_inf, + t_arch* arch, + t_chan_width* chan_width, + const size_t num_arch_switches, + const char* file_name, + const int virtual_clock_network_root_idx); + +#endif diff --git a/libs/librrgraph/src/base/rr_metadata.cpp b/libs/librrgraph/src/base/rr_metadata.cpp new file mode 100644 index 00000000000..9ddd13decc3 --- /dev/null +++ b/libs/librrgraph/src/base/rr_metadata.cpp @@ -0,0 +1,52 @@ +#include "rr_metadata.h" + +//#include "globals.h" + +namespace vpr { + +const t_metadata_value* rr_node_metadata(const RRGraphBuilder& rr_graph_builder, int src_node, vtr::interned_string key) { + auto iter = rr_graph_builder.find_rr_node_metadata(src_node); + if (iter == rr_graph_builder.end_rr_node_metadata()) { + return nullptr; + } + return iter->second.one(key); +} + +void add_rr_node_metadata(MetadataStorage& rr_node_metadata, int src_node, vtr::interned_string key, vtr::interned_string value) { + rr_node_metadata.add_metadata(src_node, + key, + value); +} + +void add_rr_node_metadata(MetadataStorage& rr_node_metadata, int src_node, vtr::string_view key, vtr::string_view value, const t_arch* arch) { + rr_node_metadata.add_metadata(src_node, + arch->strings.intern_string(key), + arch->strings.intern_string(value)); +} + +const t_metadata_value* rr_edge_metadata(const RRGraphBuilder& rr_graph_builder, int src_node, int sink_id, short switch_id, vtr::interned_string key) { + auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); + + auto iter = rr_graph_builder.find_rr_edge_metadata(rr_edge); + if (iter == rr_graph_builder.end_rr_edge_metadata()) { + return nullptr; + } + + return iter->second.one(key); +} + +void add_rr_edge_metadata(MetadataStorage>& rr_edge_metadata, int src_node, int sink_id, short switch_id, vtr::string_view key, vtr::string_view value, const t_arch* arch) { + auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); + rr_edge_metadata.add_metadata(rr_edge, + arch->strings.intern_string(key), + arch->strings.intern_string(value)); +} + +void add_rr_edge_metadata(MetadataStorage>& rr_edge_metadata, int src_node, int sink_id, short switch_id, vtr::interned_string key, vtr::interned_string value) { + auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); + rr_edge_metadata.add_metadata(rr_edge, + key, + value); +} + +} // namespace vpr diff --git a/libs/librrgraph/src/base/rr_metadata.h b/libs/librrgraph/src/base/rr_metadata.h new file mode 100644 index 00000000000..8bc1577cd08 --- /dev/null +++ b/libs/librrgraph/src/base/rr_metadata.h @@ -0,0 +1,19 @@ +#ifndef RR_METADATA_H_ +#define RR_METADATA_H_ + +#include "physical_types.h" +#include "rr_graph_builder.h" + +namespace vpr { + +const t_metadata_value* rr_node_metadata(const RRGraphBuilder& rr_graph_builder, int src_node, vtr::interned_string key); +void add_rr_node_metadata(MetadataStorage& rr_node_metadata, int src_node, vtr::interned_string key, vtr::interned_string value); +void add_rr_node_metadata(MetadataStorage& rr_node_metadata, int src_node, vtr::string_view key, vtr::string_view value, const t_arch* arch); + +const t_metadata_value* rr_edge_metadata(const RRGraphBuilder& rr_graph_builder, int src_node, int sink_node, short switch_id, vtr::interned_string key); +void add_rr_edge_metadata(MetadataStorage>& rr_edge_metadata, int src_node, int sink_node, short switch_id, vtr::interned_string key, vtr::interned_string value); +void add_rr_edge_metadata(MetadataStorage>& rr_edge_metadata, int src_node, int sink_node, short switch_id, vtr::string_view key, vtr::string_view value, const t_arch* arch); + +} // namespace vpr + +#endif // RR_METADATA_H_ diff --git a/libs/librrgraph/src/base/rr_rc_data.cpp b/libs/librrgraph/src/base/rr_rc_data.cpp new file mode 100644 index 00000000000..899e714e938 --- /dev/null +++ b/libs/librrgraph/src/base/rr_rc_data.cpp @@ -0,0 +1,29 @@ +#include "rr_rc_data.h" +//#include "globals.h" + +t_rr_rc_data::t_rr_rc_data(float Rval, float Cval) noexcept + : R(Rval) + , C(Cval) {} + +short find_create_rr_rc_data(const float R, const float C, std::vector& rr_rc_data) { + //auto& device_ctx = g_vpr_ctx.mutable_device(); + + auto match = [&](const t_rr_rc_data& val) { + return val.R == R + && val.C == C; + }; + + //Just a linear search for now + auto itr = std::find_if(rr_rc_data.begin(), + rr_rc_data.end(), + match); + + if (itr == rr_rc_data.end()) { + //Note found -> create it + rr_rc_data.emplace_back(R, C); + + itr = --rr_rc_data.end(); //Iterator to inserted value + } + + return std::distance(rr_rc_data.begin(), itr); +} diff --git a/vpr/src/route/rr_rc_data.h b/libs/librrgraph/src/base/rr_rc_data.h similarity index 78% rename from vpr/src/route/rr_rc_data.h rename to libs/librrgraph/src/base/rr_rc_data.h index a710607e9cd..5c2009dc810 100644 --- a/vpr/src/route/rr_rc_data.h +++ b/libs/librrgraph/src/base/rr_rc_data.h @@ -11,6 +11,6 @@ * * The returned indicies index into DeviceContext.rr_rc_data. */ -short find_create_rr_rc_data(const float R, const float C); +short find_create_rr_rc_data(const float R, const float C, std::vector& rr_rc_data); #endif /* _RR_RC_DATA_H_ */ diff --git a/vpr/src/util/vpr_error.cpp b/libs/libvtrutil/src/vpr_error.cpp similarity index 100% rename from vpr/src/util/vpr_error.cpp rename to libs/libvtrutil/src/vpr_error.cpp diff --git a/vpr/src/util/vpr_error.h b/libs/libvtrutil/src/vpr_error.h similarity index 100% rename from vpr/src/util/vpr_error.h rename to libs/libvtrutil/src/vpr_error.h diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index 1f0db609fa4..e3ef5b74659 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -35,6 +35,11 @@ #include "clock_modeling.h" #include "heap_type.h" +#include "base_cost_type.h" +#include "chan_width.h" +#include "cost_indices.h" +#include "route_type.h" + #include "vtr_assert.h" #include "vtr_ndmatrix.h" #include "vtr_vector.h" @@ -1114,25 +1119,27 @@ struct t_placer_opts { * and abort routings deemed unroutable * * write_rr_graph_name: stores the file name of the output rr graph * * read_rr_graph_name: stores the file name of the rr graph to be read by vpr */ -enum e_route_type { - GLOBAL, - DETAILED -}; + +// enum e_route_type { +// GLOBAL, +// DETAILED +// }; enum e_router_algorithm { BREADTH_FIRST, TIMING_DRIVEN, }; -enum e_base_cost_type { - DELAY_NORMALIZED, - DELAY_NORMALIZED_LENGTH, - DELAY_NORMALIZED_FREQUENCY, - DELAY_NORMALIZED_LENGTH_FREQUENCY, - DELAY_NORMALIZED_LENGTH_BOUNDED, - DEMAND_ONLY, - DEMAND_ONLY_NORMALIZED_LENGTH -}; +// enum e_base_cost_type { +// DELAY_NORMALIZED, +// DELAY_NORMALIZED_LENGTH, +// DELAY_NORMALIZED_FREQUENCY, +// DELAY_NORMALIZED_LENGTH_FREQUENCY, +// DELAY_NORMALIZED_LENGTH_BOUNDED, +// DEMAND_ONLY, +// DEMAND_ONLY_NORMALIZED_LENGTH +// }; + enum e_routing_failure_predictor { OFF, SAFE, @@ -1594,14 +1601,14 @@ struct t_non_configurable_rr_sets { #define NO_PREVIOUS -1 -///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. -enum e_cost_indices { - SOURCE_COST_INDEX = 0, - SINK_COST_INDEX, - OPIN_COST_INDEX, - IPIN_COST_INDEX, - CHANX_COST_INDEX_START -}; +// ///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. +// enum e_cost_indices { +// SOURCE_COST_INDEX = 0, +// SINK_COST_INDEX, +// OPIN_COST_INDEX, +// IPIN_COST_INDEX, +// CHANX_COST_INDEX_START +// }; ///@brief Power estimation options struct t_power_opts { @@ -1619,15 +1626,15 @@ struct t_power_opts { * @param y_list= Stores the channel width of all verical channels and thus goes from [0..grid.width()] * (imagine a 2D Cartesian grid with vertical lines starting at every grid point on a line parallel to the x-axis) */ -struct t_chan_width { - int max = 0; - int x_max = 0; - int y_max = 0; - int x_min = 0; - int y_min = 0; - std::vector x_list; - std::vector y_list; -}; +// struct t_chan_width { +// int max = 0; +// int x_max = 0; +// int y_max = 0; +// int x_min = 0; +// int y_min = 0; +// std::vector x_list; +// std::vector y_list; +// }; ///@brief Type to store our list of token to enum pairings struct t_TokenPair { diff --git a/vpr/src/route/check_rr_graph.h b/vpr/src/route/check_rr_graph.h deleted file mode 100644 index d03cd22fcc7..00000000000 --- a/vpr/src/route/check_rr_graph.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CHECK_RR_GRAPH_H -#define CHECK_RR_GRAPH_H - -#include "physical_types.h" -#include "vpr_context.h" - -void check_rr_graph(const t_graph_type graph_type, - const DeviceGrid& grid, - const std::vector& types); - -void check_rr_node(int inode, enum e_route_type route_type, const DeviceContext& device_ctx); - -#endif diff --git a/vpr/src/route/clock_connection_builders.cpp b/vpr/src/route/clock_connection_builders.cpp index b47fe782d7a..dd5fa9d5fe1 100644 --- a/vpr/src/route/clock_connection_builders.cpp +++ b/vpr/src/route/clock_connection_builders.cpp @@ -94,6 +94,7 @@ RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, auto& rr_graph = device_ctx.rr_graph; auto& rr_graph_builder = device_ctx.rr_graph_builder; auto& node_lookup = device_ctx.rr_graph_builder.node_lookup(); + auto& rr_rc_data = device_ctx.rr_rc_data; rr_graph_builder.emplace_back(); RRNodeId node_index = RRNodeId(rr_graph.num_nodes() - 1); @@ -114,7 +115,7 @@ RRNodeId RoutingToClockConnection::create_virtual_clock_network_sink_node(int x, float R = 0.; float C = 0.; - rr_graph_builder.set_node_rc_index(node_index, NodeRCIndex(find_create_rr_rc_data(R, C))); + rr_graph_builder.set_node_rc_index(node_index, NodeRCIndex(find_create_rr_rc_data(R, C, rr_rc_data))); // Use a generic way when adding nodes to lookup. // However, since the SINK node has the same xhigh/xlow as well as yhigh/ylow, we can probably use a shortcut diff --git a/vpr/src/route/clock_network_builders.cpp b/vpr/src/route/clock_network_builders.cpp index 5f4a84722aa..1db5796f47d 100644 --- a/vpr/src/route/clock_network_builders.cpp +++ b/vpr/src/route/clock_network_builders.cpp @@ -336,7 +336,7 @@ int ClockRib::create_chanx_wire(int x_start, rr_graph_builder.set_node_capacity(chanx_node, 1); rr_graph_builder.set_node_track_num(chanx_node, ptc_num); rr_graph_builder.set_node_rc_index(chanx_node, NodeRCIndex(find_create_rr_rc_data( - x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal))); + x_chan_wire.layer.r_metal, x_chan_wire.layer.c_metal, g_vpr_ctx.mutable_device().rr_rc_data))); rr_graph_builder.set_node_direction(chanx_node, direction); short seg_index = 0; @@ -671,7 +671,7 @@ int ClockSpine::create_chany_wire(int y_start, rr_graph_builder.set_node_capacity(chany_node, 1); rr_graph_builder.set_node_track_num(chany_node, ptc_num); rr_graph_builder.set_node_rc_index(chany_node, NodeRCIndex(find_create_rr_rc_data( - y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal))); + y_chan_wire.layer.r_metal, y_chan_wire.layer.c_metal, g_vpr_ctx.mutable_device().rr_rc_data))); rr_graph_builder.set_node_direction(chany_node, direction); short seg_index = 0; diff --git a/vpr/src/route/rr_graph.h b/vpr/src/route/rr_graph.h index e4f29959207..526406180a4 100644 --- a/vpr/src/route/rr_graph.h +++ b/vpr/src/route/rr_graph.h @@ -8,15 +8,17 @@ #include "device_grid.h" #include "vpr_types.h" - -enum e_graph_type { - GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */ - GRAPH_BIDIR, /* Detailed bidirectional graph */ - GRAPH_UNIDIR, /* Detailed unidir graph, untilable */ - /* RESEARCH TODO: Get this option debugged */ - GRAPH_UNIDIR_TILEABLE /* Detail unidir graph with wire groups multiples of 2*L */ -}; -typedef enum e_graph_type t_graph_type; +#include "graph_type.h" +#include "describe_rr_node.h" + +// enum e_graph_type { +// GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */ +// GRAPH_BIDIR, /* Detailed bidirectional graph */ +// GRAPH_UNIDIR, /* Detailed unidir graph, untilable */ +// /* RESEARCH TODO: Get this option debugged */ +// GRAPH_UNIDIR_TILEABLE /* Detail unidir graph with wire groups multiples of 2*L */ +// }; +// typedef enum e_graph_type t_graph_type; /* Warnings about the routing graph that can be returned. * This is to avoid output messages during a value sweep */ @@ -41,8 +43,8 @@ void create_rr_graph(const t_graph_type graph_type, void free_rr_graph(); -//Returns a brief one-line summary of an RR node -std::string describe_rr_node(int inode); +// //Returns a brief one-line summary of an RR node +// std::string describe_rr_node(int inode); t_rr_switch_inf create_rr_switch_from_arch_switch(int arch_switch_idx, const float R_minW_nmos, @@ -56,4 +58,4 @@ void load_rr_switch_from_arch_switch(int arch_switch_idx, t_non_configurable_rr_sets identify_non_configurable_rr_sets(); -#endif +#endif \ No newline at end of file diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 2fec910a7a9..913ebc64078 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -9,6 +9,8 @@ #include "rr_graph_builder.h" #include "rr_types.h" #include "device_grid.h" +#include "unified_to_parallel_seg_index.h" +#include "get_parallel_segs.h" /******************* Types shared by rr_graph2 functions *********************/ @@ -20,7 +22,7 @@ typedef vtr::NdMatrix t_sblock_pattern; /* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment, * from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments * regardless of their axis. (see get_parallel_segs for more details)*/ -typedef std::unordered_multimap> t_unified_to_parallel_seg_index; +//typedef std::unordered_multimap> t_unified_to_parallel_seg_index; /******************* Subroutines exported by rr_graph2.c *********************/ @@ -184,9 +186,9 @@ void load_sblock_pattern_lookup(const int i, const enum e_switch_block_type switch_block_type, t_sblock_pattern& sblock_pattern); -std::vector get_parallel_segs(const std::vector& segment_inf, - t_unified_to_parallel_seg_index& seg_index_map, - enum e_parallel_axis parallel_axis); +// std::vector get_parallel_segs(const std::vector& segment_inf, +// t_unified_to_parallel_seg_index& seg_index_map, +// enum e_parallel_axis parallel_axis); int get_parallel_seg_index(const int abs, const t_unified_to_parallel_seg_index& index_map, diff --git a/vpr/src/route/rr_graph_indexed_data.h b/vpr/src/route/rr_graph_indexed_data.h index bd25949e644..41d1624109b 100644 --- a/vpr/src/route/rr_graph_indexed_data.h +++ b/vpr/src/route/rr_graph_indexed_data.h @@ -1,12 +1,13 @@ #ifndef RR_GRAPH_INDEXED_DATA_H #define RR_GRAPH_INDEXED_DATA_H #include "physical_types.h" +#include "alloc_and_load_rr_indexed_data.h" -void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, - const std::vector& segment_inf_x, - const std::vector& segment_inf_y, - int wire_to_ipin_switch, - enum e_base_cost_type base_cost_type); +// void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, +// const std::vector& segment_inf_x, +// const std::vector& segment_inf_y, +// int wire_to_ipin_switch, +// enum e_base_cost_type base_cost_type); void load_rr_index_segments(const int num_segment); diff --git a/vpr/src/route/rr_graph_reader.h b/vpr/src/route/rr_graph_reader.h deleted file mode 100644 index 7376bcc1d81..00000000000 --- a/vpr/src/route/rr_graph_reader.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Defines the function used to load an rr graph written in xml format into vpr*/ - -#ifndef RR_GRAPH_READER_H -#define RR_GRAPH_READER_H - -#include "rr_graph.h" -#include "device_grid.h" - -void load_rr_file(const t_graph_type graph_type, - const DeviceGrid& grid, - const std::vector& segment_inf, - const enum e_base_cost_type base_cost_type, - int* wire_to_rr_ipin_switch, - const char* read_rr_graph_name, - bool read_edge_metadata, - bool do_check_rr_graph); - -#endif /* RR_GRAPH_READER_H */ diff --git a/vpr/src/route/rr_graph_timing_params.cpp b/vpr/src/route/rr_graph_timing_params.cpp index 6ab190bd03e..b65ce58db9f 100644 --- a/vpr/src/route/rr_graph_timing_params.cpp +++ b/vpr/src/route/rr_graph_timing_params.cpp @@ -198,7 +198,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { //Create the final flywieghted t_rr_rc_data for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { - mutable_device_ctx.rr_graph_builder.set_node_rc_index(rr_id, NodeRCIndex(find_create_rr_rc_data(rr_graph.node_R(rr_id), rr_node_C[(size_t)rr_id]))); + mutable_device_ctx.rr_graph_builder.set_node_rc_index(rr_id, NodeRCIndex(find_create_rr_rc_data(rr_graph.node_R(rr_id), rr_node_C[(size_t)rr_id], mutable_device_ctx.rr_rc_data))); } delete[](Couts_to_add); diff --git a/vpr/src/route/rr_graph_writer.h b/vpr/src/route/rr_graph_writer.h deleted file mode 100644 index 1ab0d2e186a..00000000000 --- a/vpr/src/route/rr_graph_writer.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This function writes the RR_graph generated by VPR into a file in XML format - * Information included in the file includes rr nodes, rr switches, the grid, block info, node indices - */ - -#ifndef RR_GRAPH_WRITER_H -#define RR_GRAPH_WRITER_H - -#include "physical_types.h" - -void write_rr_graph(const char* file_name); - -#endif diff --git a/vpr/src/route/rr_metadata.cpp b/vpr/src/route/rr_metadata.cpp deleted file mode 100644 index 86f64b725ce..00000000000 --- a/vpr/src/route/rr_metadata.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "rr_metadata.h" - -#include "globals.h" - -namespace vpr { - -const t_metadata_value* rr_node_metadata(int src_node, vtr::interned_string key) { - auto& device_ctx = g_vpr_ctx.device(); - - auto iter = device_ctx.rr_graph_builder.find_rr_node_metadata(src_node); - if (iter == device_ctx.rr_graph_builder.end_rr_node_metadata()) { - return nullptr; - } - return iter->second.one(key); -} - -void add_rr_node_metadata(int src_node, vtr::interned_string key, vtr::interned_string value) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - device_ctx.rr_graph_builder.rr_node_metadata().add_metadata(src_node, - key, - value); -} - -void add_rr_node_metadata(int src_node, vtr::string_view key, vtr::string_view value) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - device_ctx.rr_graph_builder.rr_node_metadata().add_metadata(src_node, - device_ctx.arch->strings.intern_string(key), - device_ctx.arch->strings.intern_string(value)); -} - -const t_metadata_value* rr_edge_metadata(int src_node, int sink_id, short switch_id, vtr::interned_string key) { - const auto& device_ctx = g_vpr_ctx.device(); - auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); - - auto iter = device_ctx.rr_graph_builder.find_rr_edge_metadata(rr_edge); - if (iter == device_ctx.rr_graph_builder.end_rr_edge_metadata()) { - return nullptr; - } - - return iter->second.one(key); -} - -void add_rr_edge_metadata(int src_node, int sink_id, short switch_id, vtr::string_view key, vtr::string_view value) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); - device_ctx.rr_graph_builder.rr_edge_metadata().add_metadata(rr_edge, - device_ctx.arch->strings.intern_string(key), - device_ctx.arch->strings.intern_string(value)); -} - -void add_rr_edge_metadata(int src_node, int sink_id, short switch_id, vtr::interned_string key, vtr::interned_string value) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - auto rr_edge = std::make_tuple(src_node, sink_id, switch_id); - device_ctx.rr_graph_builder.rr_edge_metadata().add_metadata(rr_edge, - key, - value); -} - -} // namespace vpr diff --git a/vpr/src/route/rr_metadata.h b/vpr/src/route/rr_metadata.h deleted file mode 100644 index b13ca876b90..00000000000 --- a/vpr/src/route/rr_metadata.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef RR_METADATA_H_ -#define RR_METADATA_H_ - -#include "physical_types.h" - -namespace vpr { - -const t_metadata_value* rr_node_metadata(int src_node, vtr::interned_string key); -void add_rr_node_metadata(int src_node, vtr::interned_string key, vtr::interned_string value); -void add_rr_node_metadata(int src_node, vtr::string_view key, vtr::string_view value); - -const t_metadata_value* rr_edge_metadata(int src_node, int sink_node, short switch_id, vtr::interned_string key); -void add_rr_edge_metadata(int src_node, int sink_node, short switch_id, vtr::interned_string key, vtr::interned_string value); -void add_rr_edge_metadata(int src_node, int sink_node, short switch_id, vtr::string_view key, vtr::string_view value); - -} // namespace vpr - -#endif // RR_METADATA_H_ diff --git a/vpr/src/route/rr_rc_data.cpp b/vpr/src/route/rr_rc_data.cpp deleted file mode 100644 index 50b8e44f802..00000000000 --- a/vpr/src/route/rr_rc_data.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "rr_rc_data.h" -#include "globals.h" - -t_rr_rc_data::t_rr_rc_data(float Rval, float Cval) noexcept - : R(Rval) - , C(Cval) {} - -short find_create_rr_rc_data(const float R, const float C) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - - auto match = [&](const t_rr_rc_data& val) { - return val.R == R - && val.C == C; - }; - - //Just a linear search for now - auto itr = std::find_if(device_ctx.rr_rc_data.begin(), - device_ctx.rr_rc_data.end(), - match); - - if (itr == device_ctx.rr_rc_data.end()) { - //Note found -> create it - device_ctx.rr_rc_data.emplace_back(R, C); - - itr = --device_ctx.rr_rc_data.end(); //Iterator to inserted value - } - - return std::distance(device_ctx.rr_rc_data.begin(), itr); -} From 93a7dc6a46c7291ed5d70842bd231720c1fce373 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 18 Jul 2022 11:49:29 -0700 Subject: [PATCH 02/19] Fix input parameters for load_rr_graph(), write_rr_graph(), check_rr_graph(), and check_rr_node(). --- libs/librrgraph/src/base/check_rr_graph.cpp | 18 ++++----- libs/librrgraph/src/base/check_rr_graph.h | 16 ++++---- libs/librrgraph/src/base/rr_graph_reader.cpp | 2 +- libs/librrgraph/src/base/rr_graph_reader.h | 2 +- .../src/base/rr_graph_uxsdcxx_serializer.h | 2 +- libs/librrgraph/src/base/rr_graph_writer.cpp | 2 +- libs/librrgraph/src/base/rr_graph_writer.h | 2 +- vpr/src/route/check_route.cpp | 7 +++- vpr/src/route/rr_graph.cpp | 37 +++++++++++++++++-- 9 files changed, 61 insertions(+), 27 deletions(-) diff --git a/libs/librrgraph/src/base/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp index e0f4c5a678a..ae9287f28ea 100644 --- a/libs/librrgraph/src/base/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -44,12 +44,12 @@ class node_edge_sorter { } }; -void check_rr_graph(const t_graph_type graph_type, - const DeviceGrid& grid, +void check_rr_graph(const RRGraphView& rr_graph, const std::vector& types, - const RRGraphView& rr_graph, const vtr::vector rr_indexed_data, + const DeviceGrid& grid, const t_chan_width& chan_width, + const t_graph_type graph_type, int virtual_clock_network_root_idx) { e_route_type route_type = DETAILED; if (graph_type == GRAPH_GLOBAL) { @@ -82,7 +82,7 @@ void check_rr_graph(const t_graph_type graph_type, t_rr_type rr_type = rr_graph.node_type(rr_node); int num_edges = rr_graph.num_edges(RRNodeId(inode)); - check_rr_node(inode, route_type, rr_graph, grid, rr_indexed_data, chan_width); + check_rr_node(rr_graph, rr_indexed_data, grid, chan_width, route_type, inode); /* Check all the connectivity (edges, etc.) information. */ edges.resize(0); @@ -296,12 +296,12 @@ static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const Device return type->is_ignored_pin[ipin]; } -void check_rr_node(int inode, - enum e_route_type route_type, - const RRGraphView& rr_graph, - const DeviceGrid& grid, +void check_rr_node(const RRGraphView& rr_graph, const vtr::vector rr_indexed_data, - const t_chan_width& chan_width) { + const DeviceGrid& grid, + const t_chan_width& chan_width, + enum e_route_type route_type, + int inode) { /* This routine checks that the rr_node is inside the grid and has a valid * pin number, etc. */ diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index 3f3f52af3e8..e5761941fec 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -11,19 +11,19 @@ #include "chan_width.h" -void check_rr_graph(const t_graph_type graph_type, - const DeviceGrid& grid, +void check_rr_graph(const RRGraphView& rr_graph, const std::vector& types, - const RRGraphView& rr_graph, const vtr::vector rr_indexed_data, + const DeviceGrid& grid, const t_chan_width& chan_width, + const t_graph_type graph_type, int virtual_clock_network_root_idx); -void check_rr_node(int inode, - enum e_route_type route_type, - const RRGraphView& rr_graph, - const DeviceGrid& grid, +void check_rr_node(const RRGraphView& rr_graph, const vtr::vector rr_indexed_data, - const t_chan_width& chan_width); + const DeviceGrid& grid, + const t_chan_width& chan_width, + enum e_route_type route_type, + int inode); #endif diff --git a/libs/librrgraph/src/base/rr_graph_reader.cpp b/libs/librrgraph/src/base/rr_graph_reader.cpp index 95579f8a8fe..47ab78fd84c 100644 --- a/libs/librrgraph/src/base/rr_graph_reader.cpp +++ b/libs/librrgraph/src/base/rr_graph_reader.cpp @@ -49,7 +49,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_graph_type graph_type, - t_arch* arch, + const t_arch* arch, t_chan_width* chan_width, const enum e_base_cost_type base_cost_type, const size_t num_arch_switches, diff --git a/libs/librrgraph/src/base/rr_graph_reader.h b/libs/librrgraph/src/base/rr_graph_reader.h index 3084868dfad..199ec460f9e 100644 --- a/libs/librrgraph/src/base/rr_graph_reader.h +++ b/libs/librrgraph/src/base/rr_graph_reader.h @@ -23,7 +23,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_graph_type graph_type, - t_arch* arch, + const t_arch* arch, t_chan_width* chan_width, const enum e_base_cost_type base_cost_type, const size_t num_arch_switches, diff --git a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h index 093d40e5dba..734e1a810b3 100644 --- a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h @@ -1613,7 +1613,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { read_rr_graph_filename_->assign(read_rr_graph_name_); if (do_check_rr_graph_) { - check_rr_graph(graph_type_, grid_, physical_tile_types_, *rr_graph_, *rr_indexed_data_, *chan_width_, virtual_clock_network_root_idx_); + check_rr_graph(*rr_graph_, physical_tile_types_, *rr_indexed_data_, grid_, *chan_width_, graph_type_, virtual_clock_network_root_idx_); } } diff --git a/libs/librrgraph/src/base/rr_graph_writer.cpp b/libs/librrgraph/src/base/rr_graph_writer.cpp index c05b74ba8d8..55513331f59 100644 --- a/libs/librrgraph/src/base/rr_graph_writer.cpp +++ b/libs/librrgraph/src/base/rr_graph_writer.cpp @@ -36,7 +36,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, std::vector& rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, - t_arch* arch, + const t_arch* arch, t_chan_width* chan_width, const size_t num_arch_switches, const char* file_name, diff --git a/libs/librrgraph/src/base/rr_graph_writer.h b/libs/librrgraph/src/base/rr_graph_writer.h index 1e34f8755ff..90259f17b72 100644 --- a/libs/librrgraph/src/base/rr_graph_writer.h +++ b/libs/librrgraph/src/base/rr_graph_writer.h @@ -22,7 +22,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, std::vector& rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, - t_arch* arch, + const t_arch* arch, t_chan_width* chan_width, const size_t num_arch_switches, const char* file_name, diff --git a/vpr/src/route/check_route.cpp b/vpr/src/route/check_route.cpp index d3e6d3c10a2..ac0095a7ad2 100644 --- a/vpr/src/route/check_route.cpp +++ b/vpr/src/route/check_route.cpp @@ -596,7 +596,12 @@ static void check_node_and_range(int inode, enum e_route_type route_type) { VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "in check_node_and_range: rr_node #%d is out of legal, range (0 to %d).\n", inode, device_ctx.rr_graph.num_nodes() - 1); } - check_rr_node(inode, route_type, device_ctx); + check_rr_node(device_ctx.rr_graph, + device_ctx.rr_indexed_data, + device_ctx.grid, + device_ctx.chan_width, + route_type, + inode); } //Checks that all non-configurable edges are in a legal configuration diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 711187fbce8..e86f0b143df 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -322,14 +322,26 @@ void create_rr_graph(const t_graph_type graph_type, if (device_ctx.read_rr_graph_filename != det_routing_arch->read_rr_graph_filename) { free_rr_graph(); - load_rr_file(graph_type, - grid, + load_rr_file(&mutable_device_ctx.rr_graph_builder, + &mutable_device_ctx.rr_graph, + device_ctx.physical_tile_types, segment_inf, + &mutable_device_ctx.rr_indexed_data, + mutable_device_ctx.rr_rc_data, + grid, + device_ctx.arch_switch_inf, + graph_type, + device_ctx.arch, + &mutable_device_ctx.chan_width, router_opts.base_cost_type, + num_arch_switches, + device_ctx.virtual_clock_network_root_idx, &det_routing_arch->wire_to_rr_ipin_switch, det_routing_arch->read_rr_graph_filename.c_str(), + &det_routing_arch->read_rr_graph_filename, router_opts.read_rr_edge_metadata, router_opts.do_check_rr_graph); + if (router_opts.reorder_rr_graph_nodes_algorithm != DONT_REORDER) { mutable_device_ctx.rr_graph_builder.reorder_nodes(router_opts.reorder_rr_graph_nodes_algorithm, router_opts.reorder_rr_graph_nodes_threshold, @@ -378,7 +390,18 @@ void create_rr_graph(const t_graph_type graph_type, //Write out rr graph file if needed if (!det_routing_arch->write_rr_graph_filename.empty()) { - write_rr_graph(det_routing_arch->write_rr_graph_filename.c_str()); + write_rr_graph(&mutable_device_ctx.rr_graph_builder, + &mutable_device_ctx.rr_graph, + device_ctx.physical_tile_types, + &mutable_device_ctx.rr_indexed_data, + mutable_device_ctx.rr_rc_data, + grid, + device_ctx.arch_switch_inf, + device_ctx.arch, + &mutable_device_ctx.chan_width, + num_arch_switches, + det_routing_arch->write_rr_graph_filename.c_str(), + device_ctx.virtual_clock_network_root_idx); } } @@ -832,7 +855,13 @@ static void build_rr_graph(const t_graph_type graph_type, rr_graph_externals(segment_inf, segment_inf_x, segment_inf_y, *wire_to_rr_ipin_switch, base_cost_type); - check_rr_graph(graph_type, grid, types); + check_rr_graph(device_ctx.rr_graph, + types, + device_ctx.rr_indexed_data, + grid, + device_ctx.chan_width, + graph_type, + device_ctx.virtual_clock_network_root_idx); /* Free all temp structs */ delete[] seg_details_x; From b42102ac14f224846dcb635d9b0760ee1141f3ed Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 18 Jul 2022 14:47:42 -0700 Subject: [PATCH 03/19] Fix input parameters of add_rr_edge_metadata(), add_rr_node_metadata(), write_rr_graph(), and find_create_rr_rc_data(). --- utils/fasm/src/fasm.cpp | 9 +++++---- utils/fasm/src/fasm.h | 2 +- utils/fasm/test/test_fasm.cpp | 22 +++++++++++++++++++--- vpr/src/route/rr_graph.cpp | 8 +++++--- vpr/test/test_vpr.cpp | 21 +++++++++++++++++---- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/utils/fasm/src/fasm.cpp b/utils/fasm/src/fasm.cpp index 2b1ebdb7c5f..df800ad3c2c 100644 --- a/utils/fasm/src/fasm.cpp +++ b/utils/fasm/src/fasm.cpp @@ -622,25 +622,26 @@ void FasmWriterVisitor::visit_atom_impl(const t_pb* atom) { check_for_param(atom); } -void FasmWriterVisitor::walk_route_tree(const t_rt_node *root) { +void FasmWriterVisitor::walk_route_tree(const RRGraphBuilder& rr_graph_builder, const t_rt_node *root) { for (t_linked_rt_edge* edge = root->u.child_list; edge != nullptr; edge = edge->next) { - auto *meta = vpr::rr_edge_metadata(root->inode, edge->child->inode, edge->iswitch, fasm_features); + auto *meta = vpr::rr_edge_metadata(rr_graph_builder, root->inode, edge->child->inode, edge->iswitch, fasm_features); if(meta != nullptr) { output_fasm_features(meta->as_string().get(strings_), "", ""); } - walk_route_tree(edge->child); + walk_route_tree(rr_graph_builder, edge->child); } } void FasmWriterVisitor::walk_routing() { auto& route_ctx = g_vpr_ctx.mutable_routing(); + auto& device_ctx = g_vpr_ctx.mutable_device(); for(const auto &trace : route_ctx.trace) { t_trace *head = trace.head; if (!head) continue; t_rt_node* root = traceback_to_route_tree(head); - walk_route_tree(root); + walk_route_tree(device_ctx.rr_graph_builder, root); free_route_tree(root); } } diff --git a/utils/fasm/src/fasm.h b/utils/fasm/src/fasm.h index 438525abc58..6e0b89067ae 100644 --- a/utils/fasm/src/fasm.h +++ b/utils/fasm/src/fasm.h @@ -73,7 +73,7 @@ class FasmWriterVisitor : public NetlistVisitor { void check_for_lut(const t_pb* atom); void output_fasm_mux(std::string fasm_mux, t_interconnect *interconnect, const t_pb_graph_pin *mux_input_pin); void walk_routing(); - void walk_route_tree(const t_rt_node *root); + void walk_route_tree(const RRGraphBuilder& rr_graph_builder, const t_rt_node *root); std::string build_clb_prefix(const t_pb *pb, const t_pb_graph_node* pb_graph_node, bool* is_parent_pb_null) const; const LutOutputDefinition* find_lut(const t_pb_graph_node* pb_graph_node); void check_for_param(const t_pb *atom); diff --git a/utils/fasm/test/test_fasm.cpp b/utils/fasm/test/test_fasm.cpp index e211dbb741f..9c5066c100c 100644 --- a/utils/fasm/test/test_fasm.cpp +++ b/utils/fasm/test/test_fasm.cpp @@ -269,12 +269,28 @@ TEST_CASE("fasm_integration_test", "[fasm]") { value = value + "\n" + pin_feature; } - vpr::add_rr_edge_metadata((size_t)inode, sink_inode, switch_id, - vtr::string_view("fasm_features"), vtr::string_view(value.data(), value.size())); + vpr::add_rr_edge_metadata(device_ctx.rr_graph_builder.rr_edge_metadata(), + (size_t)inode, + sink_inode, + switch_id, + vtr::string_view("fasm_features"), + vtr::string_view(value.data(), value.size()), + device_ctx.arch); } } - write_rr_graph(kRrGraphFile); + write_rr_graph(&device_ctx.rr_graph_builder, + &device_ctx.rr_graph, + device_ctx.physical_tile_types, + &device_ctx.rr_indexed_data, + device_ctx.rr_rc_data, + device_ctx.grid, + device_ctx.arch_switch_inf, + device_ctx.arch, + &device_ctx.chan_width, + device_ctx.num_arch_switches, + kRrGraphFile, + device_ctx.virtual_clock_network_root_idx); vpr_free_all(arch, vpr_setup); } diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index e86f0b143df..4d6d333c204 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -1538,6 +1538,7 @@ static void build_rr_sinks_sources(RRGraphBuilder& rr_graph_builder, const std::vector& pin_class = type->pin_class; auto& device_ctx = g_vpr_ctx.device(); + auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; /* SINK and SOURCE-to-OPIN edges */ @@ -1594,7 +1595,7 @@ static void build_rr_sinks_sources(RRGraphBuilder& rr_graph_builder, rr_graph_builder.set_node_coordinates(inode, i, j, i + type->width - 1, j + type->height - 1); float R = 0.; float C = 0.; - rr_graph_builder.set_node_rc_index(inode, NodeRCIndex(find_create_rr_rc_data(R, C))); + rr_graph_builder.set_node_rc_index(inode, NodeRCIndex(find_create_rr_rc_data(R, C, mutable_device_ctx.rr_rc_data))); rr_graph_builder.set_node_class_num(inode, iclass); } @@ -1645,7 +1646,7 @@ static void build_rr_sinks_sources(RRGraphBuilder& rr_graph_builder, rr_graph_builder.set_node_capacity(inode, 1); float R = 0.; float C = 0.; - rr_graph_builder.set_node_rc_index(inode, NodeRCIndex(find_create_rr_rc_data(R, C))); + rr_graph_builder.set_node_rc_index(inode, NodeRCIndex(find_create_rr_rc_data(R, C, mutable_device_ctx.rr_rc_data))); rr_graph_builder.set_node_pin_num(inode, ipin); //Note that we store the grid tile location and side where the pin is located, @@ -1694,6 +1695,7 @@ static void build_rr_chan(RRGraphBuilder& rr_graph_builder, * coordinates based on channel type */ auto& device_ctx = g_vpr_ctx.device(); + auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); //Initally a assumes CHANX int seg_coord = x_coord; //The absolute coordinate of this segment within the channel @@ -1849,7 +1851,7 @@ static void build_rr_chan(RRGraphBuilder& rr_graph_builder, int length = end - start + 1; float R = length * seg_details[track].Rmetal(); float C = length * seg_details[track].Cmetal(); - rr_graph_builder.set_node_rc_index(node, NodeRCIndex(find_create_rr_rc_data(R, C))); + rr_graph_builder.set_node_rc_index(node, NodeRCIndex(find_create_rr_rc_data(R, C, mutable_device_ctx.rr_rc_data))); rr_graph_builder.set_node_type(node, chan_type); rr_graph_builder.set_node_track_num(node, track); diff --git a/vpr/test/test_vpr.cpp b/vpr/test/test_vpr.cpp index b57d593c83f..b37bd0837c4 100644 --- a/vpr/test/test_vpr.cpp +++ b/vpr/test/test_vpr.cpp @@ -134,7 +134,9 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { vpr_create_device(vpr_setup, arch); const auto& device_ctx = g_vpr_ctx.device(); + auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; + auto& rr_graph_builder = mutable_device_ctx.rr_graph_builder; for (const RRNodeId& inode : device_ctx.rr_graph.nodes()) { if ((rr_graph.node_type(inode) == CHANX || rr_graph.node_type(inode) == CHANY) && rr_graph.num_edges(inode) > 0) { @@ -147,10 +149,21 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { sink_inode = size_t(rr_graph.edge_sink_node(RRNodeId(src_inode), 0)); switch_id = rr_graph.edge_switch(RRNodeId(src_inode), 0); - vpr::add_rr_node_metadata(src_inode, vtr::string_view("node"), vtr::string_view("test node")); - vpr::add_rr_edge_metadata(src_inode, sink_inode, switch_id, vtr::string_view("edge"), vtr::string_view("test edge")); - - write_rr_graph(kRrGraphFile); + vpr::add_rr_node_metadata(rr_graph_builder.rr_node_metadata(), src_inode, vtr::string_view("node"), vtr::string_view("test node"), device_ctx.arch); + vpr::add_rr_edge_metadata(rr_graph_builder.rr_edge_metadata(), src_inode, sink_inode, switch_id, vtr::string_view("edge"), vtr::string_view("test edge"), device_ctx.arch); + + write_rr_graph(&mutable_device_ctx.rr_graph_builder, + &mutable_device_ctx.rr_graph, + device_ctx.physical_tile_types, + &mutable_device_ctx.rr_indexed_data, + mutable_device_ctx.rr_rc_data, + device_ctx.grid, + device_ctx.arch_switch_inf, + device_ctx.arch, + &mutable_device_ctx.chan_width, + device_ctx.num_arch_switches, + kRrGraphFile, + device_ctx.virtual_clock_network_root_idx); vpr_free_all(arch, vpr_setup); auto& atom_ctx = g_vpr_ctx.mutable_atom(); From 5db79886b12f06de8b108b7894efc33e2022a472 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Tue, 19 Jul 2022 15:56:51 -0700 Subject: [PATCH 04/19] [vpr] move VTR_ENABLE_CAPNPROTO to librrgraph CMakeList.txt --- libs/librrgraph/CMakeLists.txt | 30 ++++++++++++++ libs/librrgraph/src/base/rr_graph_writer.cpp | 6 +-- vpr/CMakeLists.txt | 42 ++++++++++---------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/libs/librrgraph/CMakeLists.txt b/libs/librrgraph/CMakeLists.txt index fdd8f4351fe..644b05de956 100644 --- a/libs/librrgraph/CMakeLists.txt +++ b/libs/librrgraph/CMakeLists.txt @@ -7,6 +7,10 @@ file(GLOB_RECURSE LIB_SOURCES src/*/*.cpp) file(GLOB_RECURSE LIB_HEADERS src/*/*.h) files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS) +if(${VTR_ENABLE_CAPNPROTO}) + add_definitions("-DVTR_ENABLE_CAPNPROTO") +endif() + #Create the library add_library(librrgraph STATIC ${LIB_HEADERS} @@ -23,6 +27,10 @@ target_link_libraries(librrgraph libarchfpga ) +if(${VTR_ENABLE_CAPNPROTO}) + target_link_libraries(librrgraph libvtrcapnproto) +endif() + target_compile_definitions(librrgraph PUBLIC ${INTERCHANGE_SCHEMA_HEADERS}) # Unit tests @@ -33,3 +41,25 @@ target_compile_definitions(librrgraph PUBLIC ${INTERCHANGE_SCHEMA_HEADERS}) # Run unit tests: comment out for now #add_test(NAME test_rr_graph COMMAND test_rr_graph --use-colour=yes) + +add_custom_target( + generate_rr_graph_serializers + COMMAND ${CMAKE_COMMAND} -E remove_directory rr_graph_generate + COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate + COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx + COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt + COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd + COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd + COMMAND ${CMAKE_COMMAND} -E copy + rr_graph_generate/rr_graph_uxsdcxx.h + rr_graph_generate/rr_graph_uxsdcxx_capnp.h + rr_graph_generate/rr_graph_uxsdcxx_interface.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/route/gen + COMMAND ${CMAKE_COMMAND} -E copy + rr_graph_generate/rr_graph_uxsdcxx.capnp + ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libvtrcapnproto/gen + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR} + ) \ No newline at end of file diff --git a/libs/librrgraph/src/base/rr_graph_writer.cpp b/libs/librrgraph/src/base/rr_graph_writer.cpp index 55513331f59..4d09460dbce 100644 --- a/libs/librrgraph/src/base/rr_graph_writer.cpp +++ b/libs/librrgraph/src/base/rr_graph_writer.cpp @@ -30,7 +30,7 @@ * Needs a solution to reduce the number of parameters passed in.*/ void write_rr_graph(RRGraphBuilder* rr_graph_builder, - RRGraphView* rr_graph, + RRGraphView* rr_graph_view, const std::vector& physical_tile_types, vtr::vector* rr_indexed_data, std::vector& rr_rc_data, @@ -53,14 +53,14 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, chan_width, &rr_graph_builder->rr_nodes(), rr_graph_builder, - rr_graph, + rr_graph_view, &rr_graph_builder->rr_switch(), rr_indexed_data, rr_rc_data, virtual_clock_network_root_idx, num_arch_switches, arch_switch_inf, - rr_graph->rr_segments(), + rr_graph_view->rr_segments(), physical_tile_types, grid, &rr_graph_builder->rr_node_metadata(), diff --git a/vpr/CMakeLists.txt b/vpr/CMakeLists.txt index f43da412c74..04321effc03 100644 --- a/vpr/CMakeLists.txt +++ b/vpr/CMakeLists.txt @@ -274,24 +274,24 @@ add_test(NAME test_vpr WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) -add_custom_target( - generate_rr_graph_serializers - COMMAND ${CMAKE_COMMAND} -E remove_directory rr_graph_generate - COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate - COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx - COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt - COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd - COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd - COMMAND ${CMAKE_COMMAND} -E copy - rr_graph_generate/rr_graph_uxsdcxx.h - rr_graph_generate/rr_graph_uxsdcxx_capnp.h - rr_graph_generate/rr_graph_uxsdcxx_interface.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/route/gen - COMMAND ${CMAKE_COMMAND} -E copy - rr_graph_generate/rr_graph_uxsdcxx.capnp - ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libvtrcapnproto/gen - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd - WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR} - ) +# add_custom_target( +# generate_rr_graph_serializers +# COMMAND ${CMAKE_COMMAND} -E remove_directory rr_graph_generate +# COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate +# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx +# COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt +# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd +# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd +# COMMAND ${CMAKE_COMMAND} -E copy +# rr_graph_generate/rr_graph_uxsdcxx.h +# rr_graph_generate/rr_graph_uxsdcxx_capnp.h +# rr_graph_generate/rr_graph_uxsdcxx_interface.h +# ${CMAKE_CURRENT_SOURCE_DIR}/src/route/gen +# COMMAND ${CMAKE_COMMAND} -E copy +# rr_graph_generate/rr_graph_uxsdcxx.capnp +# ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libvtrcapnproto/gen +# DEPENDS +# ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd +# WORKING_DIRECTORY +# ${CMAKE_CURRENT_BINARY_DIR} +# ) From 0bb613f95afd851ad355acb1bf1c5f27fa196bc4 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Wed, 20 Jul 2022 13:11:45 -0700 Subject: [PATCH 05/19] [vpr] move cmake dependencies in vpr/src/route to librrgraph/src/base/ --- libs/librrgraph/CMakeLists.txt | 18 +- .../librrgraph/src/base}/SCHEMA_GENERATOR.md | 18 +- .../src/base/gen/rr_graph_uxsdcxx.h | 7901 ++++++++--------- .../src/base/gen/rr_graph_uxsdcxx_capnp.h | 2169 ++--- .../src/base/gen/rr_graph_uxsdcxx_interface.h | 1063 ++- .../librrgraph/src/base}/rr_graph.xsd | 0 vpr/CMakeLists.txt | 21 - 7 files changed, 5429 insertions(+), 5761 deletions(-) rename {vpr/src/route => libs/librrgraph/src/base}/SCHEMA_GENERATOR.md (94%) rename {vpr/src/route => libs/librrgraph/src/base}/rr_graph.xsd (100%) diff --git a/libs/librrgraph/CMakeLists.txt b/libs/librrgraph/CMakeLists.txt index 644b05de956..949bb02790a 100644 --- a/libs/librrgraph/CMakeLists.txt +++ b/libs/librrgraph/CMakeLists.txt @@ -48,18 +48,14 @@ add_custom_target( COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt - COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd - COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd + COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd + COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd COMMAND ${CMAKE_COMMAND} -E copy rr_graph_generate/rr_graph_uxsdcxx.h rr_graph_generate/rr_graph_uxsdcxx_capnp.h rr_graph_generate/rr_graph_uxsdcxx_interface.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/route/gen - COMMAND ${CMAKE_COMMAND} -E copy - rr_graph_generate/rr_graph_uxsdcxx.capnp - ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libvtrcapnproto/gen - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd - WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR} - ) \ No newline at end of file + ${CMAKE_CURRENT_SOURCE_DIR}/src/base/gen + COMMAND ${CMAKE_COMMAND} -E copy rr_graph_generate/rr_graph_uxsdcxx.capnp ${CMAKE_CURRENT_SOURCE_DIR}/../libvtrcapnproto/gen + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/base/rr_graph.xsd + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) \ No newline at end of file diff --git a/vpr/src/route/SCHEMA_GENERATOR.md b/libs/librrgraph/src/base/SCHEMA_GENERATOR.md similarity index 94% rename from vpr/src/route/SCHEMA_GENERATOR.md rename to libs/librrgraph/src/base/SCHEMA_GENERATOR.md index bbbc6aa68ff..6ac74dd122c 100644 --- a/vpr/src/route/SCHEMA_GENERATOR.md +++ b/libs/librrgraph/src/base/SCHEMA_GENERATOR.md @@ -6,16 +6,16 @@ mediated via RrGraphBase located in `rr_graph_uxsdcxx_interface.h`. If `rr_graph.xsd` is modified, then the following files must be updated: - - `vpr/src/route/gen/rr_graph_uxsdcxx.h` - - `vpr/src/route/gen/rr_graph_uxsdcxx_capnp.h` - - `vpr/src/route/gen/rr_graph_uxsdcxx_interface.h` + - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h` + - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h` + - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h` - `libs/libvtrcapnproto/rr_graph_uxsdcxx.capnp` ### Instructions to update generated files (using CMake) 1. Run target `generate_rr_graph_serializers`, e.g. run `make generate_rr_graph_serializers`. 2. Run target `format`, e.g. run `make format`. -3. Update `vpr/src/route/rr_graph_uxsdcxx_interface_impl.h`, implement or +3. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or update interfaces that are new or are changed. The compiler will complain that virtual methods are missing if the schema has changed. @@ -23,13 +23,13 @@ If `rr_graph.xsd` is modified, then the following files must be updated: 1. Clone https://github.com/duck2/uxsdcxx/ 2. Run `python3 -mpip install --user -r requirements.txt` -3. Run `python3 uxsdcxx.py vpr/src/route/rr_graph.xsd` -3. Run `python3 uxsdcap.py vpr/src/route/rr_graph.xsd` +3. Run `python3 uxsdcxx.py libs/librrgraph/src/base/rr_graph.xsd` +3. Run `python3 uxsdcap.py libs/librrgraph/src/base/rr_graph.xsd` 4. Copy `rr_graph_uxsdcxx.h`, `rr_graph_uxsdcxx_capnp.h`, - `rr_graph_uxsdcxx_interface.h` to `vpr/src/route/` -5. Copy `rr_graph_uxsdcxx.capnp` to `libs/libvtrcapnproto/` + `rr_graph_uxsdcxx_interface.h` to `libs/librrgraph/src/base/` +5. Copy `rr_graph_uxsdcxx.capnp` to `../libvtrcapnproto/` 6. Run `make format` -7. Update `vpr/src/route/rr_graph_uxsdcxx_interface_impl.h`, implement or +7. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or update interfaces that are new or are changed. The compiler will complain that virtual methods are missing if the schema has changed. diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h index b9ce441ae76..086b99cc243 100644 --- a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h +++ b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h @@ -4,13 +4,14 @@ * https://github.com/duck2/uxsdcxx * Modify only if your build process doesn't involve regenerating this file. * - * Cmdline: uxsdcxx/uxsdcxx.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * md5sum of input file: cd57d47fc9dfa62c7030397ca759217e + * Cmdline: uxsdcxx/uxsdcxx.py /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * Input file: /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * md5sum of input file: 41df83ecf127a53590711ddec605742a */ #include + #include #include #include @@ -32,4434 +33,4146 @@ namespace uxsd { * Internal function for getting line and column number from file based on * byte offset. */ -inline void get_line_number(const char* filename, std::ptrdiff_t offset, int* line, int* col); +inline void get_line_number(const char *filename, std::ptrdiff_t offset, int * line, int * col); -[[noreturn]] inline void noreturn_report(const std::function* report_error, const char* msg) { +[[noreturn]] inline void noreturn_report(const std::function * report_error, const char *msg) { (*report_error)(msg); throw std::runtime_error("Unreachable!"); } /* Declarations for internal load functions for the complex types. */ -template -inline void load_channel(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_channel_required_attributes(const pugi::xml_node& root, int* chan_width_max, int* x_max, int* x_min, int* y_max, int* y_min, const std::function* report_error); -template -inline void load_x_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_x_list_required_attributes(const pugi::xml_node& root, unsigned int* index, int* info, const std::function* report_error); -template -inline void load_y_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_y_list_required_attributes(const pugi::xml_node& root, unsigned int* index, int* info, const std::function* report_error); -template -inline void load_channels(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_sizing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_sizing_required_attributes(const pugi::xml_node& root, float* buf_size, float* mux_trans_size, const std::function* report_error); -template -inline void load_switch(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_switch_required_attributes(const pugi::xml_node& root, int* id, const std::function* report_error); -template -inline void load_switches(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_segment_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_segment(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_segment_required_attributes(const pugi::xml_node& root, int* id, const std::function* report_error); -template -inline void load_segments(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_pin(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_pin_required_attributes(const pugi::xml_node& root, int* ptc, const std::function* report_error); -template -inline void load_pin_class(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_pin_class_required_attributes(const pugi::xml_node& root, enum_pin_type* type, const std::function* report_error); -template -inline void load_block_type(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_block_type_required_attributes(const pugi::xml_node& root, int* height, int* id, int* width, const std::function* report_error); -template -inline void load_block_types(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_grid_loc(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_grid_loc_required_attributes(const pugi::xml_node& root, int* block_type_id, int* height_offset, int* width_offset, int* x, int* y, const std::function* report_error); -template -inline void load_grid_locs(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_node_loc(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_node_loc_required_attributes(const pugi::xml_node& root, int* ptc, int* xhigh, int* xlow, int* yhigh, int* ylow, const std::function* report_error); -template -inline void load_node_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_node_timing_required_attributes(const pugi::xml_node& root, float* C, float* R, const std::function* report_error); -template -inline void load_node_segment(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_node_segment_required_attributes(const pugi::xml_node& root, int* segment_id, const std::function* report_error); -template -inline void load_meta(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_metadata(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_node(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_node_required_attributes(const pugi::xml_node& root, unsigned int* capacity, unsigned int* id, enum_node_type* type, const std::function* report_error); -template -inline void load_rr_nodes(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_edge(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -inline void load_edge_required_attributes(const pugi::xml_node& root, unsigned int* sink_node, unsigned int* src_node, unsigned int* switch_id, const std::function* report_error); -template -inline void load_rr_edges(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); -template -inline void load_rr_graph(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug); +template +inline void load_channel(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_channel_required_attributes(const pugi::xml_node &root, int * chan_width_max, int * x_max, int * x_min, int * y_max, int * y_min, const std::function * report_error); +template +inline void load_x_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_x_list_required_attributes(const pugi::xml_node &root, unsigned int * index, int * info, const std::function * report_error); +template +inline void load_y_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_y_list_required_attributes(const pugi::xml_node &root, unsigned int * index, int * info, const std::function * report_error); +template +inline void load_channels(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_sizing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_sizing_required_attributes(const pugi::xml_node &root, float * buf_size, float * mux_trans_size, const std::function * report_error); +template +inline void load_switch(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_switch_required_attributes(const pugi::xml_node &root, int * id, const std::function * report_error); +template +inline void load_switches(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_segment_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_segment(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_segment_required_attributes(const pugi::xml_node &root, int * id, const std::function * report_error); +template +inline void load_segments(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_pin(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_pin_required_attributes(const pugi::xml_node &root, int * ptc, const std::function * report_error); +template +inline void load_pin_class(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_pin_class_required_attributes(const pugi::xml_node &root, enum_pin_type * type, const std::function * report_error); +template +inline void load_block_type(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_block_type_required_attributes(const pugi::xml_node &root, int * height, int * id, int * width, const std::function * report_error); +template +inline void load_block_types(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_grid_loc(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_grid_loc_required_attributes(const pugi::xml_node &root, int * block_type_id, int * height_offset, int * width_offset, int * x, int * y, const std::function * report_error); +template +inline void load_grid_locs(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_node_loc(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_node_loc_required_attributes(const pugi::xml_node &root, int * ptc, int * xhigh, int * xlow, int * yhigh, int * ylow, const std::function * report_error); +template +inline void load_node_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_node_timing_required_attributes(const pugi::xml_node &root, float * C, float * R, const std::function * report_error); +template +inline void load_node_segment(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_node_segment_required_attributes(const pugi::xml_node &root, int * segment_id, const std::function * report_error); +template +inline void load_meta(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_metadata(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_node(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_node_required_attributes(const pugi::xml_node &root, unsigned int * capacity, unsigned int * id, enum_node_type * type, const std::function * report_error); +template +inline void load_rr_nodes(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_edge(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +inline void load_edge_required_attributes(const pugi::xml_node &root, unsigned int * sink_node, unsigned int * src_node, unsigned int * switch_id, const std::function * report_error); +template +inline void load_rr_edges(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); +template +inline void load_rr_graph(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug); /* Declarations for internal write functions for the complex types. */ -template -inline void write_channels(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_switch(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_switches(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_segment(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_segments(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_pin(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_pin_class(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_block_type(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_block_types(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_grid_locs(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_meta(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_metadata(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_node(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_rr_nodes(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_edge(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_rr_edges(T& in, std::ostream& os, const void* data, void* iter); -template -inline void write_rr_graph(T& in, std::ostream& os, const void* data, void* iter); +template +inline void write_channels(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_switch(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_switches(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_segment(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_segments(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_pin(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_pin_class(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_block_type(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_block_types(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_grid_locs(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_meta(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_metadata(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_node(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_rr_nodes(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_edge(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_rr_edges(T &in, std::ostream &os, const void *data, void *iter); +template +inline void write_rr_graph(T &in, std::ostream &os, const void *data, void *iter); /* Load function for the root element. */ -template -inline void load_rr_graph_xml(T& out, Context& context, const char* filename, std::istream& is) { - pugi::xml_document doc; - pugi::xml_parse_result result = doc.load(is); - if (!result) { - int line, col; - get_line_number(filename, result.offset, &line, &col); - std::stringstream msg; - msg << "Unable to load XML file '" << filename << "', "; - msg << result.description() << " (line: " << line; - msg << " col: " << col << ")"; - out.error_encountered(filename, line, msg.str().c_str()); - } - ptrdiff_t offset_debug = 0; - std::function report_error = [filename, &out, &offset_debug](const char* message) { - int line, col; - get_line_number(filename, offset_debug, &line, &col); - out.error_encountered(filename, line, message); - // If error_encountered didn't throw, throw now to unwind. - throw std::runtime_error(message); - }; - out.start_load(&report_error); - - for (pugi::xml_node node = doc.first_child(); node; node = node.next_sibling()) { - if (std::strcmp(node.name(), "rr_graph") == 0) { - /* If errno is set up to this point, it messes with strtol errno checking. */ - errno = 0; - load_rr_graph(node, out, context, &report_error, &offset_debug); - } else { - offset_debug = node.offset_debug(); - report_error(("Invalid root-level element " + std::string(node.name())).c_str()); - } - } - out.finish_load(); +template +inline void load_rr_graph_xml(T &out, Context &context, const char * filename, std::istream &is){ + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load(is); + if(!result) { + int line, col; + get_line_number(filename, result.offset, &line, &col); + std::stringstream msg; + msg << "Unable to load XML file '" << filename << "', "; + msg << result.description() << " (line: " << line; + msg << " col: " << col << ")"; out.error_encountered(filename, line, msg.str().c_str()); + } + ptrdiff_t offset_debug = 0; + std::function report_error = [filename, &out, &offset_debug](const char * message) { + int line, col; + get_line_number(filename, offset_debug, &line, &col); + out.error_encountered(filename, line, message); + // If error_encountered didn't throw, throw now to unwind. + throw std::runtime_error(message); + }; + out.start_load(&report_error); + + for(pugi::xml_node node= doc.first_child(); node; node = node.next_sibling()){ + if(std::strcmp(node.name(), "rr_graph") == 0){ + /* If errno is set up to this point, it messes with strtol errno checking. */ + errno = 0; + load_rr_graph(node, out, context, &report_error, &offset_debug); + } else { + offset_debug = node.offset_debug(); + report_error(("Invalid root-level element " + std::string(node.name())).c_str()); + } + } + out.finish_load(); } /* Write function for the root element. */ -template -inline void write_rr_graph_xml(T& in, Context& context, std::ostream& os) { - in.start_write(); - os << "\n"; - write_rr_graph(in, os, context); - os << "\n"; - in.finish_write(); +template +inline void write_rr_graph_xml(T &in, Context &context, std::ostream &os){ + in.start_write(); + os << "\n"; + write_rr_graph(in, os, context); + os << "\n"; + in.finish_write(); } + typedef const uint32_t __attribute__((aligned(1))) triehash_uu32; typedef const uint64_t __attribute__((aligned(1))) triehash_uu64; static_assert(alignof(triehash_uu32) == 1, "Unaligned 32-bit access not found."); static_assert(alignof(triehash_uu64) == 1, "Unaligned 64-bit access not found."); #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define onechar(c, s, l) (((uint64_t)(c)) << (s)) +#define onechar(c, s, l) (((uint64_t)(c)) << (s)) #else -# define onechar(c, s, l) (((uint64_t)(c)) << (l - 8 - s)) +#define onechar(c, s, l) (((uint64_t)(c)) << (l-8-s)) #endif /* Tokens for attribute and node names. */ -enum class atok_t_channel { CHAN_WIDTH_MAX, - X_MAX, - X_MIN, - Y_MAX, - Y_MIN }; -constexpr const char* atok_lookup_t_channel[] = {"chan_width_max", "x_max", "x_min", "y_max", "y_min"}; - -enum class atok_t_x_list { INDEX, - INFO }; -constexpr const char* atok_lookup_t_x_list[] = {"index", "info"}; - -enum class atok_t_y_list { INDEX, - INFO }; -constexpr const char* atok_lookup_t_y_list[] = {"index", "info"}; - -enum class gtok_t_channels { CHANNEL, - X_LIST, - Y_LIST }; -constexpr const char* gtok_lookup_t_channels[] = {"channel", "x_list", "y_list"}; - -enum class atok_t_timing { CIN, - CINTERNAL, - COUT, - R, - TDEL }; -constexpr const char* atok_lookup_t_timing[] = {"Cin", "Cinternal", "Cout", "R", "Tdel"}; - -enum class atok_t_sizing { BUF_SIZE, - MUX_TRANS_SIZE }; -constexpr const char* atok_lookup_t_sizing[] = {"buf_size", "mux_trans_size"}; - -enum class gtok_t_switch { TIMING, - SIZING }; -constexpr const char* gtok_lookup_t_switch[] = {"timing", "sizing"}; -enum class atok_t_switch { ID, - NAME, - TYPE }; -constexpr const char* atok_lookup_t_switch[] = {"id", "name", "type"}; - -enum class gtok_t_switches { SWITCH }; -constexpr const char* gtok_lookup_t_switches[] = {"switch"}; - -enum class atok_t_segment_timing { C_PER_METER, - R_PER_METER }; -constexpr const char* atok_lookup_t_segment_timing[] = {"C_per_meter", "R_per_meter"}; - -enum class gtok_t_segment { TIMING }; -constexpr const char* gtok_lookup_t_segment[] = {"timing"}; -enum class atok_t_segment { ID, - NAME }; -constexpr const char* atok_lookup_t_segment[] = {"id", "name"}; - -enum class gtok_t_segments { SEGMENT }; -constexpr const char* gtok_lookup_t_segments[] = {"segment"}; - -enum class atok_t_pin { PTC }; -constexpr const char* atok_lookup_t_pin[] = {"ptc"}; - -enum class gtok_t_pin_class { PIN }; -constexpr const char* gtok_lookup_t_pin_class[] = {"pin"}; -enum class atok_t_pin_class { TYPE }; -constexpr const char* atok_lookup_t_pin_class[] = {"type"}; - -enum class gtok_t_block_type { PIN_CLASS }; -constexpr const char* gtok_lookup_t_block_type[] = {"pin_class"}; -enum class atok_t_block_type { HEIGHT, - ID, - NAME, - WIDTH }; -constexpr const char* atok_lookup_t_block_type[] = {"height", "id", "name", "width"}; - -enum class gtok_t_block_types { BLOCK_TYPE }; -constexpr const char* gtok_lookup_t_block_types[] = {"block_type"}; - -enum class atok_t_grid_loc { BLOCK_TYPE_ID, - HEIGHT_OFFSET, - WIDTH_OFFSET, - X, - Y }; -constexpr const char* atok_lookup_t_grid_loc[] = {"block_type_id", "height_offset", "width_offset", "x", "y"}; - -enum class gtok_t_grid_locs { GRID_LOC }; -constexpr const char* gtok_lookup_t_grid_locs[] = {"grid_loc"}; - -enum class atok_t_node_loc { PTC, - SIDE, - XHIGH, - XLOW, - YHIGH, - YLOW }; -constexpr const char* atok_lookup_t_node_loc[] = {"ptc", "side", "xhigh", "xlow", "yhigh", "ylow"}; - -enum class atok_t_node_timing { C, - R }; -constexpr const char* atok_lookup_t_node_timing[] = {"C", "R"}; - -enum class atok_t_node_segment { SEGMENT_ID }; -constexpr const char* atok_lookup_t_node_segment[] = {"segment_id"}; - -enum class atok_t_meta { NAME }; -constexpr const char* atok_lookup_t_meta[] = {"name"}; - -enum class gtok_t_metadata { META }; -constexpr const char* gtok_lookup_t_metadata[] = {"meta"}; -enum class gtok_t_node { LOC, - TIMING, - SEGMENT, - METADATA }; -constexpr const char* gtok_lookup_t_node[] = {"loc", "timing", "segment", "metadata"}; -enum class atok_t_node { CAPACITY, - DIRECTION, - ID, - TYPE }; -constexpr const char* atok_lookup_t_node[] = {"capacity", "direction", "id", "type"}; - -enum class gtok_t_rr_nodes { NODE }; -constexpr const char* gtok_lookup_t_rr_nodes[] = {"node"}; -enum class gtok_t_edge { METADATA }; -constexpr const char* gtok_lookup_t_edge[] = {"metadata"}; -enum class atok_t_edge { SINK_NODE, - SRC_NODE, - SWITCH_ID }; -constexpr const char* atok_lookup_t_edge[] = {"sink_node", "src_node", "switch_id"}; - -enum class gtok_t_rr_edges { EDGE }; -constexpr const char* gtok_lookup_t_rr_edges[] = {"edge"}; -enum class gtok_t_rr_graph { CHANNELS, - SWITCHES, - SEGMENTS, - BLOCK_TYPES, - GRID, - RR_NODES, - RR_EDGES }; -constexpr const char* gtok_lookup_t_rr_graph[] = {"channels", "switches", "segments", "block_types", "grid", "rr_nodes", "rr_edges"}; -enum class atok_t_rr_graph { TOOL_COMMENT, - TOOL_NAME, - TOOL_VERSION }; -constexpr const char* atok_lookup_t_rr_graph[] = {"tool_comment", "tool_name", "tool_version"}; +enum class atok_t_channel {CHAN_WIDTH_MAX, X_MAX, X_MIN, Y_MAX, Y_MIN}; +constexpr const char *atok_lookup_t_channel[] = {"chan_width_max", "x_max", "x_min", "y_max", "y_min"}; + + +enum class atok_t_x_list {INDEX, INFO}; +constexpr const char *atok_lookup_t_x_list[] = {"index", "info"}; + + +enum class atok_t_y_list {INDEX, INFO}; +constexpr const char *atok_lookup_t_y_list[] = {"index", "info"}; + +enum class gtok_t_channels {CHANNEL, X_LIST, Y_LIST}; +constexpr const char *gtok_lookup_t_channels[] = {"channel", "x_list", "y_list"}; + +enum class atok_t_timing {CIN, CINTERNAL, COUT, R, TDEL}; +constexpr const char *atok_lookup_t_timing[] = {"Cin", "Cinternal", "Cout", "R", "Tdel"}; + + +enum class atok_t_sizing {BUF_SIZE, MUX_TRANS_SIZE}; +constexpr const char *atok_lookup_t_sizing[] = {"buf_size", "mux_trans_size"}; + +enum class gtok_t_switch {TIMING, SIZING}; +constexpr const char *gtok_lookup_t_switch[] = {"timing", "sizing"}; +enum class atok_t_switch {ID, NAME, TYPE}; +constexpr const char *atok_lookup_t_switch[] = {"id", "name", "type"}; + +enum class gtok_t_switches {SWITCH}; +constexpr const char *gtok_lookup_t_switches[] = {"switch"}; + +enum class atok_t_segment_timing {C_PER_METER, R_PER_METER}; +constexpr const char *atok_lookup_t_segment_timing[] = {"C_per_meter", "R_per_meter"}; + +enum class gtok_t_segment {TIMING}; +constexpr const char *gtok_lookup_t_segment[] = {"timing"}; +enum class atok_t_segment {ID, NAME}; +constexpr const char *atok_lookup_t_segment[] = {"id", "name"}; + +enum class gtok_t_segments {SEGMENT}; +constexpr const char *gtok_lookup_t_segments[] = {"segment"}; + +enum class atok_t_pin {PTC}; +constexpr const char *atok_lookup_t_pin[] = {"ptc"}; + +enum class gtok_t_pin_class {PIN}; +constexpr const char *gtok_lookup_t_pin_class[] = {"pin"}; +enum class atok_t_pin_class {TYPE}; +constexpr const char *atok_lookup_t_pin_class[] = {"type"}; + +enum class gtok_t_block_type {PIN_CLASS}; +constexpr const char *gtok_lookup_t_block_type[] = {"pin_class"}; +enum class atok_t_block_type {HEIGHT, ID, NAME, WIDTH}; +constexpr const char *atok_lookup_t_block_type[] = {"height", "id", "name", "width"}; + +enum class gtok_t_block_types {BLOCK_TYPE}; +constexpr const char *gtok_lookup_t_block_types[] = {"block_type"}; + +enum class atok_t_grid_loc {BLOCK_TYPE_ID, HEIGHT_OFFSET, WIDTH_OFFSET, X, Y}; +constexpr const char *atok_lookup_t_grid_loc[] = {"block_type_id", "height_offset", "width_offset", "x", "y"}; + +enum class gtok_t_grid_locs {GRID_LOC}; +constexpr const char *gtok_lookup_t_grid_locs[] = {"grid_loc"}; + +enum class atok_t_node_loc {PTC, SIDE, XHIGH, XLOW, YHIGH, YLOW}; +constexpr const char *atok_lookup_t_node_loc[] = {"ptc", "side", "xhigh", "xlow", "yhigh", "ylow"}; + + +enum class atok_t_node_timing {C, R}; +constexpr const char *atok_lookup_t_node_timing[] = {"C", "R"}; + + +enum class atok_t_node_segment {SEGMENT_ID}; +constexpr const char *atok_lookup_t_node_segment[] = {"segment_id"}; + + +enum class atok_t_meta {NAME}; +constexpr const char *atok_lookup_t_meta[] = {"name"}; + +enum class gtok_t_metadata {META}; +constexpr const char *gtok_lookup_t_metadata[] = {"meta"}; +enum class gtok_t_node {LOC, TIMING, SEGMENT, METADATA}; +constexpr const char *gtok_lookup_t_node[] = {"loc", "timing", "segment", "metadata"}; +enum class atok_t_node {CAPACITY, DIRECTION, ID, TYPE}; +constexpr const char *atok_lookup_t_node[] = {"capacity", "direction", "id", "type"}; + +enum class gtok_t_rr_nodes {NODE}; +constexpr const char *gtok_lookup_t_rr_nodes[] = {"node"}; +enum class gtok_t_edge {METADATA}; +constexpr const char *gtok_lookup_t_edge[] = {"metadata"}; +enum class atok_t_edge {SINK_NODE, SRC_NODE, SWITCH_ID}; +constexpr const char *atok_lookup_t_edge[] = {"sink_node", "src_node", "switch_id"}; + +enum class gtok_t_rr_edges {EDGE}; +constexpr const char *gtok_lookup_t_rr_edges[] = {"edge"}; +enum class gtok_t_rr_graph {CHANNELS, SWITCHES, SEGMENTS, BLOCK_TYPES, GRID, RR_NODES, RR_EDGES}; +constexpr const char *gtok_lookup_t_rr_graph[] = {"channels", "switches", "segments", "block_types", "grid", "rr_nodes", "rr_edges"}; +enum class atok_t_rr_graph {TOOL_COMMENT, TOOL_NAME, TOOL_VERSION}; +constexpr const char *atok_lookup_t_rr_graph[] = {"tool_comment", "tool_name", "tool_version"}; + /* Internal lexers. These convert the PugiXML node names to input tokens. */ -inline atok_t_channel lex_attr_t_channel(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): - switch (in[4]) { - case onechar('x', 0, 8): - return atok_t_channel::X_MAX; - break; - default: - break; - } - break; - case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - return atok_t_channel::X_MIN; - break; - default: - break; - } - break; - case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): - switch (in[4]) { - case onechar('x', 0, 8): - return atok_t_channel::Y_MAX; - break; - default: - break; - } - break; - case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - return atok_t_channel::Y_MIN; - break; - default: - break; - } - break; - default: - break; - } - break; - case 14: - switch (*((triehash_uu64*)&in[0])) { - case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('_', 32, 64) | onechar('w', 40, 64) | onechar('i', 48, 64) | onechar('d', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('t', 0, 32) | onechar('h', 8, 32) | onechar('_', 16, 32) | onechar('m', 24, 32): - switch (in[12]) { - case onechar('a', 0, 8): - switch (in[13]) { - case onechar('x', 0, 8): - return atok_t_channel::CHAN_WIDTH_MAX; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_channel lex_attr_t_channel(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): + switch(in[4]){ + case onechar('x', 0, 8): + return atok_t_channel::X_MAX; + break; + default: break; + } + break; + case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + return atok_t_channel::X_MIN; + break; + default: break; + } + break; + case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): + switch(in[4]){ + case onechar('x', 0, 8): + return atok_t_channel::Y_MAX; + break; + default: break; + } + break; + case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + return atok_t_channel::Y_MIN; + break; + default: break; + } + break; + default: break; + } + break; + case 14: + switch(*((triehash_uu64*)&in[0])){ + case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('_', 32, 64) | onechar('w', 40, 64) | onechar('i', 48, 64) | onechar('d', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('t', 0, 32) | onechar('h', 8, 32) | onechar('_', 16, 32) | onechar('m', 24, 32): + switch(in[12]){ + case onechar('a', 0, 8): + switch(in[13]){ + case onechar('x', 0, 8): + return atok_t_channel::CHAN_WIDTH_MAX; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_x_list lex_attr_t_x_list(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): - return atok_t_x_list::INFO; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): - switch (in[4]) { - case onechar('x', 0, 8): - return atok_t_x_list::INDEX; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_x_list lex_attr_t_x_list(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): + return atok_t_x_list::INFO; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): + switch(in[4]){ + case onechar('x', 0, 8): + return atok_t_x_list::INDEX; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_y_list lex_attr_t_y_list(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): - return atok_t_y_list::INFO; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): - switch (in[4]) { - case onechar('x', 0, 8): - return atok_t_y_list::INDEX; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_y_list lex_attr_t_y_list(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): + return atok_t_y_list::INFO; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): + switch(in[4]){ + case onechar('x', 0, 8): + return atok_t_y_list::INDEX; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_channels lex_node_t_channels(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('s', 0, 8): - switch (in[5]) { - case onechar('t', 0, 8): - return gtok_t_channels::X_LIST; - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('s', 0, 8): - switch (in[5]) { - case onechar('t', 0, 8): - return gtok_t_channels::Y_LIST; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 7: - switch (*((triehash_uu32*)&in[0])) { - case onechar('c', 0, 32) | onechar('h', 8, 32) | onechar('a', 16, 32) | onechar('n', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - switch (in[5]) { - case onechar('e', 0, 8): - switch (in[6]) { - case onechar('l', 0, 8): - return gtok_t_channels::CHANNEL; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_channels lex_node_t_channels(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('s', 0, 8): + switch(in[5]){ + case onechar('t', 0, 8): + return gtok_t_channels::X_LIST; + break; + default: break; + } + break; + default: break; + } + break; + case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('s', 0, 8): + switch(in[5]){ + case onechar('t', 0, 8): + return gtok_t_channels::Y_LIST; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 7: + switch(*((triehash_uu32*)&in[0])){ + case onechar('c', 0, 32) | onechar('h', 8, 32) | onechar('a', 16, 32) | onechar('n', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + switch(in[5]){ + case onechar('e', 0, 8): + switch(in[6]){ + case onechar('l', 0, 8): + return gtok_t_channels::CHANNEL; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_timing lex_attr_t_timing(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 1: - switch (in[0]) { - case onechar('R', 0, 8): - return atok_t_timing::R; - break; - default: - break; - } - break; - case 3: - switch (in[0]) { - case onechar('C', 0, 8): - switch (in[1]) { - case onechar('i', 0, 8): - switch (in[2]) { - case onechar('n', 0, 8): - return atok_t_timing::CIN; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('C', 0, 32) | onechar('o', 8, 32) | onechar('u', 16, 32) | onechar('t', 24, 32): - return atok_t_timing::COUT; - break; - case onechar('T', 0, 32) | onechar('d', 8, 32) | onechar('e', 16, 32) | onechar('l', 24, 32): - return atok_t_timing::TDEL; - break; - default: - break; - } - break; - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('C', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('t', 24, 64) | onechar('e', 32, 64) | onechar('r', 40, 64) | onechar('n', 48, 64) | onechar('a', 56, 64): - switch (in[8]) { - case onechar('l', 0, 8): - return atok_t_timing::CINTERNAL; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_timing lex_attr_t_timing(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 1: + switch(in[0]){ + case onechar('R', 0, 8): + return atok_t_timing::R; + break; + default: break; + } + break; + case 3: + switch(in[0]){ + case onechar('C', 0, 8): + switch(in[1]){ + case onechar('i', 0, 8): + switch(in[2]){ + case onechar('n', 0, 8): + return atok_t_timing::CIN; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('C', 0, 32) | onechar('o', 8, 32) | onechar('u', 16, 32) | onechar('t', 24, 32): + return atok_t_timing::COUT; + break; + case onechar('T', 0, 32) | onechar('d', 8, 32) | onechar('e', 16, 32) | onechar('l', 24, 32): + return atok_t_timing::TDEL; + break; + default: break; + } + break; + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('C', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('t', 24, 64) | onechar('e', 32, 64) | onechar('r', 40, 64) | onechar('n', 48, 64) | onechar('a', 56, 64): + switch(in[8]){ + case onechar('l', 0, 8): + return atok_t_timing::CINTERNAL; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_sizing lex_attr_t_sizing(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('b', 0, 64) | onechar('u', 8, 64) | onechar('f', 16, 64) | onechar('_', 24, 64) | onechar('s', 32, 64) | onechar('i', 40, 64) | onechar('z', 48, 64) | onechar('e', 56, 64): - return atok_t_sizing::BUF_SIZE; - break; - default: - break; - } - break; - case 14: - switch (*((triehash_uu64*)&in[0])) { - case onechar('m', 0, 64) | onechar('u', 8, 64) | onechar('x', 16, 64) | onechar('_', 24, 64) | onechar('t', 32, 64) | onechar('r', 40, 64) | onechar('a', 48, 64) | onechar('n', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('s', 0, 32) | onechar('_', 8, 32) | onechar('s', 16, 32) | onechar('i', 24, 32): - switch (in[12]) { - case onechar('z', 0, 8): - switch (in[13]) { - case onechar('e', 0, 8): - return atok_t_sizing::MUX_TRANS_SIZE; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_sizing lex_attr_t_sizing(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('b', 0, 64) | onechar('u', 8, 64) | onechar('f', 16, 64) | onechar('_', 24, 64) | onechar('s', 32, 64) | onechar('i', 40, 64) | onechar('z', 48, 64) | onechar('e', 56, 64): + return atok_t_sizing::BUF_SIZE; + break; + default: break; + } + break; + case 14: + switch(*((triehash_uu64*)&in[0])){ + case onechar('m', 0, 64) | onechar('u', 8, 64) | onechar('x', 16, 64) | onechar('_', 24, 64) | onechar('t', 32, 64) | onechar('r', 40, 64) | onechar('a', 48, 64) | onechar('n', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('s', 0, 32) | onechar('_', 8, 32) | onechar('s', 16, 32) | onechar('i', 24, 32): + switch(in[12]){ + case onechar('z', 0, 8): + switch(in[13]){ + case onechar('e', 0, 8): + return atok_t_sizing::MUX_TRANS_SIZE; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_switch lex_node_t_switch(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('z', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - switch (in[5]) { - case onechar('g', 0, 8): - return gtok_t_switch::SIZING; - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - switch (in[5]) { - case onechar('g', 0, 8): - return gtok_t_switch::TIMING; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_switch lex_node_t_switch(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('z', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + switch(in[5]){ + case onechar('g', 0, 8): + return gtok_t_switch::SIZING; + break; + default: break; + } + break; + default: break; + } + break; + case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + switch(in[5]){ + case onechar('g', 0, 8): + return gtok_t_switch::TIMING; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_switch lex_attr_t_switch(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 2: - switch (in[0]) { - case onechar('i', 0, 8): - switch (in[1]) { - case onechar('d', 0, 8): - return atok_t_switch::ID; - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): - return atok_t_switch::NAME; - break; - case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): - return atok_t_switch::TYPE; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_switch lex_attr_t_switch(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 2: + switch(in[0]){ + case onechar('i', 0, 8): + switch(in[1]){ + case onechar('d', 0, 8): + return atok_t_switch::ID; + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): + return atok_t_switch::NAME; + break; + case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): + return atok_t_switch::TYPE; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_switches lex_node_t_switches(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('w', 8, 32) | onechar('i', 16, 32) | onechar('t', 24, 32): - switch (in[4]) { - case onechar('c', 0, 8): - switch (in[5]) { - case onechar('h', 0, 8): - return gtok_t_switches::SWITCH; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_switches lex_node_t_switches(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('w', 8, 32) | onechar('i', 16, 32) | onechar('t', 24, 32): + switch(in[4]){ + case onechar('c', 0, 8): + switch(in[5]){ + case onechar('h', 0, 8): + return gtok_t_switches::SWITCH; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_segment_timing lex_attr_t_segment_timing(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 11: - switch (*((triehash_uu64*)&in[0])) { - case onechar('C', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): - switch (in[8]) { - case onechar('t', 0, 8): - switch (in[9]) { - case onechar('e', 0, 8): - switch (in[10]) { - case onechar('r', 0, 8): - return atok_t_segment_timing::C_PER_METER; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('R', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): - switch (in[8]) { - case onechar('t', 0, 8): - switch (in[9]) { - case onechar('e', 0, 8): - switch (in[10]) { - case onechar('r', 0, 8): - return atok_t_segment_timing::R_PER_METER; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_segment_timing lex_attr_t_segment_timing(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 11: + switch(*((triehash_uu64*)&in[0])){ + case onechar('C', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): + switch(in[8]){ + case onechar('t', 0, 8): + switch(in[9]){ + case onechar('e', 0, 8): + switch(in[10]){ + case onechar('r', 0, 8): + return atok_t_segment_timing::C_PER_METER; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case onechar('R', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): + switch(in[8]){ + case onechar('t', 0, 8): + switch(in[9]){ + case onechar('e', 0, 8): + switch(in[10]){ + case onechar('r', 0, 8): + return atok_t_segment_timing::R_PER_METER; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_segment lex_node_t_segment(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - switch (in[5]) { - case onechar('g', 0, 8): - return gtok_t_segment::TIMING; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_segment lex_node_t_segment(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + switch(in[5]){ + case onechar('g', 0, 8): + return gtok_t_segment::TIMING; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_segment lex_attr_t_segment(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 2: - switch (in[0]) { - case onechar('i', 0, 8): - switch (in[1]) { - case onechar('d', 0, 8): - return atok_t_segment::ID; - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): - return atok_t_segment::NAME; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_segment lex_attr_t_segment(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 2: + switch(in[0]){ + case onechar('i', 0, 8): + switch(in[1]){ + case onechar('d', 0, 8): + return atok_t_segment::ID; + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): + return atok_t_segment::NAME; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_segments lex_node_t_segments(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 7: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): - switch (in[4]) { - case onechar('e', 0, 8): - switch (in[5]) { - case onechar('n', 0, 8): - switch (in[6]) { - case onechar('t', 0, 8): - return gtok_t_segments::SEGMENT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_segments lex_node_t_segments(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 7: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): + switch(in[4]){ + case onechar('e', 0, 8): + switch(in[5]){ + case onechar('n', 0, 8): + switch(in[6]){ + case onechar('t', 0, 8): + return gtok_t_segments::SEGMENT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_pin lex_attr_t_pin(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('p', 0, 8): - switch (in[1]) { - case onechar('t', 0, 8): - switch (in[2]) { - case onechar('c', 0, 8): - return atok_t_pin::PTC; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_pin lex_attr_t_pin(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('p', 0, 8): + switch(in[1]){ + case onechar('t', 0, 8): + switch(in[2]){ + case onechar('c', 0, 8): + return atok_t_pin::PTC; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_pin_class lex_node_t_pin_class(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('p', 0, 8): - switch (in[1]) { - case onechar('i', 0, 8): - switch (in[2]) { - case onechar('n', 0, 8): - return gtok_t_pin_class::PIN; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_pin_class lex_node_t_pin_class(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('p', 0, 8): + switch(in[1]){ + case onechar('i', 0, 8): + switch(in[2]){ + case onechar('n', 0, 8): + return gtok_t_pin_class::PIN; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_pin_class lex_attr_t_pin_class(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): - return atok_t_pin_class::TYPE; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_pin_class lex_attr_t_pin_class(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): + return atok_t_pin_class::TYPE; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_block_type lex_node_t_block_type(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('p', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('_', 24, 64) | onechar('c', 32, 64) | onechar('l', 40, 64) | onechar('a', 48, 64) | onechar('s', 56, 64): - switch (in[8]) { - case onechar('s', 0, 8): - return gtok_t_block_type::PIN_CLASS; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_block_type lex_node_t_block_type(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('p', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('_', 24, 64) | onechar('c', 32, 64) | onechar('l', 40, 64) | onechar('a', 48, 64) | onechar('s', 56, 64): + switch(in[8]){ + case onechar('s', 0, 8): + return gtok_t_block_type::PIN_CLASS; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_block_type lex_attr_t_block_type(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 2: - switch (in[0]) { - case onechar('i', 0, 8): - switch (in[1]) { - case onechar('d', 0, 8): - return atok_t_block_type::ID; - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): - return atok_t_block_type::NAME; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('w', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('t', 24, 32): - switch (in[4]) { - case onechar('h', 0, 8): - return atok_t_block_type::WIDTH; - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('h', 0, 32) | onechar('e', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): - switch (in[4]) { - case onechar('h', 0, 8): - switch (in[5]) { - case onechar('t', 0, 8): - return atok_t_block_type::HEIGHT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_block_type lex_attr_t_block_type(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 2: + switch(in[0]){ + case onechar('i', 0, 8): + switch(in[1]){ + case onechar('d', 0, 8): + return atok_t_block_type::ID; + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): + return atok_t_block_type::NAME; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('w', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('t', 24, 32): + switch(in[4]){ + case onechar('h', 0, 8): + return atok_t_block_type::WIDTH; + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('h', 0, 32) | onechar('e', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): + switch(in[4]){ + case onechar('h', 0, 8): + switch(in[5]){ + case onechar('t', 0, 8): + return atok_t_block_type::HEIGHT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_block_types lex_node_t_block_types(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 10: - switch (*((triehash_uu64*)&in[0])) { - case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): - switch (in[8]) { - case onechar('p', 0, 8): - switch (in[9]) { - case onechar('e', 0, 8): - return gtok_t_block_types::BLOCK_TYPE; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_block_types lex_node_t_block_types(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 10: + switch(*((triehash_uu64*)&in[0])){ + case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): + switch(in[8]){ + case onechar('p', 0, 8): + switch(in[9]){ + case onechar('e', 0, 8): + return gtok_t_block_types::BLOCK_TYPE; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_grid_loc lex_attr_t_grid_loc(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 1: - switch (in[0]) { - case onechar('x', 0, 8): - return atok_t_grid_loc::X; - break; - case onechar('y', 0, 8): - return atok_t_grid_loc::Y; - break; - default: - break; - } - break; - case 12: - switch (*((triehash_uu64*)&in[0])) { - case onechar('w', 0, 64) | onechar('i', 8, 64) | onechar('d', 16, 64) | onechar('t', 24, 64) | onechar('h', 32, 64) | onechar('_', 40, 64) | onechar('o', 48, 64) | onechar('f', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('f', 0, 32) | onechar('s', 8, 32) | onechar('e', 16, 32) | onechar('t', 24, 32): - return atok_t_grid_loc::WIDTH_OFFSET; - break; - default: - break; - } - break; - default: - break; - } - break; - case 13: - switch (*((triehash_uu64*)&in[0])) { - case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('p', 0, 32) | onechar('e', 8, 32) | onechar('_', 16, 32) | onechar('i', 24, 32): - switch (in[12]) { - case onechar('d', 0, 8): - return atok_t_grid_loc::BLOCK_TYPE_ID; - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('h', 0, 64) | onechar('e', 8, 64) | onechar('i', 16, 64) | onechar('g', 24, 64) | onechar('h', 32, 64) | onechar('t', 40, 64) | onechar('_', 48, 64) | onechar('o', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('f', 0, 32) | onechar('f', 8, 32) | onechar('s', 16, 32) | onechar('e', 24, 32): - switch (in[12]) { - case onechar('t', 0, 8): - return atok_t_grid_loc::HEIGHT_OFFSET; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_grid_loc lex_attr_t_grid_loc(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 1: + switch(in[0]){ + case onechar('x', 0, 8): + return atok_t_grid_loc::X; + break; + case onechar('y', 0, 8): + return atok_t_grid_loc::Y; + break; + default: break; + } + break; + case 12: + switch(*((triehash_uu64*)&in[0])){ + case onechar('w', 0, 64) | onechar('i', 8, 64) | onechar('d', 16, 64) | onechar('t', 24, 64) | onechar('h', 32, 64) | onechar('_', 40, 64) | onechar('o', 48, 64) | onechar('f', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('f', 0, 32) | onechar('s', 8, 32) | onechar('e', 16, 32) | onechar('t', 24, 32): + return atok_t_grid_loc::WIDTH_OFFSET; + break; + default: break; + } + break; + default: break; + } + break; + case 13: + switch(*((triehash_uu64*)&in[0])){ + case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('p', 0, 32) | onechar('e', 8, 32) | onechar('_', 16, 32) | onechar('i', 24, 32): + switch(in[12]){ + case onechar('d', 0, 8): + return atok_t_grid_loc::BLOCK_TYPE_ID; + break; + default: break; + } + break; + default: break; + } + break; + case onechar('h', 0, 64) | onechar('e', 8, 64) | onechar('i', 16, 64) | onechar('g', 24, 64) | onechar('h', 32, 64) | onechar('t', 40, 64) | onechar('_', 48, 64) | onechar('o', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('f', 0, 32) | onechar('f', 8, 32) | onechar('s', 16, 32) | onechar('e', 24, 32): + switch(in[12]){ + case onechar('t', 0, 8): + return atok_t_grid_loc::HEIGHT_OFFSET; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_grid_locs lex_node_t_grid_locs(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('g', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('d', 24, 64) | onechar('_', 32, 64) | onechar('l', 40, 64) | onechar('o', 48, 64) | onechar('c', 56, 64): - return gtok_t_grid_locs::GRID_LOC; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_grid_locs lex_node_t_grid_locs(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('g', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('d', 24, 64) | onechar('_', 32, 64) | onechar('l', 40, 64) | onechar('o', 48, 64) | onechar('c', 56, 64): + return gtok_t_grid_locs::GRID_LOC; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_node_loc lex_attr_t_node_loc(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('p', 0, 8): - switch (in[1]) { - case onechar('t', 0, 8): - switch (in[2]) { - case onechar('c', 0, 8): - return atok_t_node_loc::PTC; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): - return atok_t_node_loc::SIDE; - break; - case onechar('x', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): - return atok_t_node_loc::XLOW; - break; - case onechar('y', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): - return atok_t_node_loc::YLOW; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('x', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): - switch (in[4]) { - case onechar('h', 0, 8): - return atok_t_node_loc::XHIGH; - break; - default: - break; - } - break; - case onechar('y', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): - switch (in[4]) { - case onechar('h', 0, 8): - return atok_t_node_loc::YHIGH; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_node_loc lex_attr_t_node_loc(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('p', 0, 8): + switch(in[1]){ + case onechar('t', 0, 8): + switch(in[2]){ + case onechar('c', 0, 8): + return atok_t_node_loc::PTC; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): + return atok_t_node_loc::SIDE; + break; + case onechar('x', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): + return atok_t_node_loc::XLOW; + break; + case onechar('y', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): + return atok_t_node_loc::YLOW; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('x', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): + switch(in[4]){ + case onechar('h', 0, 8): + return atok_t_node_loc::XHIGH; + break; + default: break; + } + break; + case onechar('y', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): + switch(in[4]){ + case onechar('h', 0, 8): + return atok_t_node_loc::YHIGH; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_node_timing lex_attr_t_node_timing(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 1: - switch (in[0]) { - case onechar('C', 0, 8): - return atok_t_node_timing::C; - break; - case onechar('R', 0, 8): - return atok_t_node_timing::R; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_node_timing lex_attr_t_node_timing(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 1: + switch(in[0]){ + case onechar('C', 0, 8): + return atok_t_node_timing::C; + break; + case onechar('R', 0, 8): + return atok_t_node_timing::R; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_node_segment lex_attr_t_node_segment(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 10: - switch (*((triehash_uu64*)&in[0])) { - case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('_', 56, 64): - switch (in[8]) { - case onechar('i', 0, 8): - switch (in[9]) { - case onechar('d', 0, 8): - return atok_t_node_segment::SEGMENT_ID; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_node_segment lex_attr_t_node_segment(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 10: + switch(*((triehash_uu64*)&in[0])){ + case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('_', 56, 64): + switch(in[8]){ + case onechar('i', 0, 8): + switch(in[9]){ + case onechar('d', 0, 8): + return atok_t_node_segment::SEGMENT_ID; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline atok_t_meta lex_attr_t_meta(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): - return atok_t_meta::NAME; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_meta lex_attr_t_meta(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): + return atok_t_meta::NAME; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_metadata lex_node_t_metadata(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('t', 16, 32) | onechar('a', 24, 32): - return gtok_t_metadata::META; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_metadata lex_node_t_metadata(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('t', 16, 32) | onechar('a', 24, 32): + return gtok_t_metadata::META; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline gtok_t_node lex_node_t_node(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('l', 0, 8): - switch (in[1]) { - case onechar('o', 0, 8): - switch (in[2]) { - case onechar('c', 0, 8): - return gtok_t_node::LOC; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): - switch (in[4]) { - case onechar('n', 0, 8): - switch (in[5]) { - case onechar('g', 0, 8): - return gtok_t_node::TIMING; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 7: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): - switch (in[4]) { - case onechar('e', 0, 8): - switch (in[5]) { - case onechar('n', 0, 8): - switch (in[6]) { - case onechar('t', 0, 8): - return gtok_t_node::SEGMENT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): - return gtok_t_node::METADATA; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_node lex_node_t_node(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('l', 0, 8): + switch(in[1]){ + case onechar('o', 0, 8): + switch(in[2]){ + case onechar('c', 0, 8): + return gtok_t_node::LOC; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): + switch(in[4]){ + case onechar('n', 0, 8): + switch(in[5]){ + case onechar('g', 0, 8): + return gtok_t_node::TIMING; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 7: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): + switch(in[4]){ + case onechar('e', 0, 8): + switch(in[5]){ + case onechar('n', 0, 8): + switch(in[6]){ + case onechar('t', 0, 8): + return gtok_t_node::SEGMENT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): + return gtok_t_node::METADATA; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_node lex_attr_t_node(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 2: - switch (in[0]) { - case onechar('i', 0, 8): - switch (in[1]) { - case onechar('d', 0, 8): - return atok_t_node::ID; - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): - return atok_t_node::TYPE; - break; - default: - break; - } - break; - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('c', 0, 64) | onechar('a', 8, 64) | onechar('p', 16, 64) | onechar('a', 24, 64) | onechar('c', 32, 64) | onechar('i', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): - return atok_t_node::CAPACITY; - break; - default: - break; - } - break; - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('d', 0, 64) | onechar('i', 8, 64) | onechar('r', 16, 64) | onechar('e', 24, 64) | onechar('c', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64): - switch (in[8]) { - case onechar('n', 0, 8): - return atok_t_node::DIRECTION; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_node lex_attr_t_node(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 2: + switch(in[0]){ + case onechar('i', 0, 8): + switch(in[1]){ + case onechar('d', 0, 8): + return atok_t_node::ID; + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): + return atok_t_node::TYPE; + break; + default: break; + } + break; + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('c', 0, 64) | onechar('a', 8, 64) | onechar('p', 16, 64) | onechar('a', 24, 64) | onechar('c', 32, 64) | onechar('i', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): + return atok_t_node::CAPACITY; + break; + default: break; + } + break; + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('d', 0, 64) | onechar('i', 8, 64) | onechar('r', 16, 64) | onechar('e', 24, 64) | onechar('c', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64): + switch(in[8]){ + case onechar('n', 0, 8): + return atok_t_node::DIRECTION; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_rr_nodes lex_node_t_rr_nodes(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('n', 0, 32) | onechar('o', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): - return gtok_t_rr_nodes::NODE; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_rr_nodes lex_node_t_rr_nodes(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('n', 0, 32) | onechar('o', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): + return gtok_t_rr_nodes::NODE; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline gtok_t_edge lex_node_t_edge(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): - return gtok_t_edge::METADATA; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_edge lex_node_t_edge(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): + return gtok_t_edge::METADATA; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_edge lex_attr_t_edge(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('s', 0, 64) | onechar('r', 8, 64) | onechar('c', 16, 64) | onechar('_', 24, 64) | onechar('n', 32, 64) | onechar('o', 40, 64) | onechar('d', 48, 64) | onechar('e', 56, 64): - return atok_t_edge::SRC_NODE; - break; - default: - break; - } - break; - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('s', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('k', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('o', 48, 64) | onechar('d', 56, 64): - switch (in[8]) { - case onechar('e', 0, 8): - return atok_t_edge::SINK_NODE; - break; - default: - break; - } - break; - case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('_', 48, 64) | onechar('i', 56, 64): - switch (in[8]) { - case onechar('d', 0, 8): - return atok_t_edge::SWITCH_ID; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_edge lex_attr_t_edge(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('s', 0, 64) | onechar('r', 8, 64) | onechar('c', 16, 64) | onechar('_', 24, 64) | onechar('n', 32, 64) | onechar('o', 40, 64) | onechar('d', 48, 64) | onechar('e', 56, 64): + return atok_t_edge::SRC_NODE; + break; + default: break; + } + break; + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('s', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('k', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('o', 48, 64) | onechar('d', 56, 64): + switch(in[8]){ + case onechar('e', 0, 8): + return atok_t_edge::SINK_NODE; + break; + default: break; + } + break; + case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('_', 48, 64) | onechar('i', 56, 64): + switch(in[8]){ + case onechar('d', 0, 8): + return atok_t_edge::SWITCH_ID; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } -inline gtok_t_rr_edges lex_node_t_rr_edges(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('e', 0, 32) | onechar('d', 8, 32) | onechar('g', 16, 32) | onechar('e', 24, 32): - return gtok_t_rr_edges::EDGE; - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_rr_edges lex_node_t_rr_edges(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('e', 0, 32) | onechar('d', 8, 32) | onechar('g', 16, 32) | onechar('e', 24, 32): + return gtok_t_rr_edges::EDGE; + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline gtok_t_rr_graph lex_node_t_rr_graph(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('g', 0, 32) | onechar('r', 8, 32) | onechar('i', 16, 32) | onechar('d', 24, 32): - return gtok_t_rr_graph::GRID; - break; - default: - break; - } - break; - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('n', 32, 64) | onechar('e', 40, 64) | onechar('l', 48, 64) | onechar('s', 56, 64): - return gtok_t_rr_graph::CHANNELS; - break; - case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('e', 24, 64) | onechar('d', 32, 64) | onechar('g', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): - return gtok_t_rr_graph::RR_EDGES; - break; - case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('n', 24, 64) | onechar('o', 32, 64) | onechar('d', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): - return gtok_t_rr_graph::RR_NODES; - break; - case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('s', 56, 64): - return gtok_t_rr_graph::SEGMENTS; - break; - case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): - return gtok_t_rr_graph::SWITCHES; - break; - default: - break; - } - break; - case 11: - switch (*((triehash_uu64*)&in[0])) { - case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): - switch (in[8]) { - case onechar('p', 0, 8): - switch (in[9]) { - case onechar('e', 0, 8): - switch (in[10]) { - case onechar('s', 0, 8): - return gtok_t_rr_graph::BLOCK_TYPES; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); +inline gtok_t_rr_graph lex_node_t_rr_graph(const char *in, const std::function *report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('g', 0, 32) | onechar('r', 8, 32) | onechar('i', 16, 32) | onechar('d', 24, 32): + return gtok_t_rr_graph::GRID; + break; + default: break; + } + break; + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('n', 32, 64) | onechar('e', 40, 64) | onechar('l', 48, 64) | onechar('s', 56, 64): + return gtok_t_rr_graph::CHANNELS; + break; + case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('e', 24, 64) | onechar('d', 32, 64) | onechar('g', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): + return gtok_t_rr_graph::RR_EDGES; + break; + case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('n', 24, 64) | onechar('o', 32, 64) | onechar('d', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): + return gtok_t_rr_graph::RR_NODES; + break; + case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('s', 56, 64): + return gtok_t_rr_graph::SEGMENTS; + break; + case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): + return gtok_t_rr_graph::SWITCHES; + break; + default: break; + } + break; + case 11: + switch(*((triehash_uu64*)&in[0])){ + case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): + switch(in[8]){ + case onechar('p', 0, 8): + switch(in[9]){ + case onechar('e', 0, 8): + switch(in[10]){ + case onechar('s', 0, 8): + return gtok_t_rr_graph::BLOCK_TYPES; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized child " + std::string(in) + " of .").c_str()); } -inline atok_t_rr_graph lex_attr_t_rr_graph(const char* in, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('a', 48, 64) | onechar('m', 56, 64): - switch (in[8]) { - case onechar('e', 0, 8): - return atok_t_rr_graph::TOOL_NAME; - break; - default: - break; - } - break; - default: - break; - } - break; - case 12: - switch (*((triehash_uu64*)&in[0])) { - case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('c', 40, 64) | onechar('o', 48, 64) | onechar('m', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('n', 16, 32) | onechar('t', 24, 32): - return atok_t_rr_graph::TOOL_COMMENT; - break; - default: - break; - } - break; - case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('v', 40, 64) | onechar('e', 48, 64) | onechar('r', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('o', 16, 32) | onechar('n', 24, 32): - return atok_t_rr_graph::TOOL_VERSION; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); +inline atok_t_rr_graph lex_attr_t_rr_graph(const char *in, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('a', 48, 64) | onechar('m', 56, 64): + switch(in[8]){ + case onechar('e', 0, 8): + return atok_t_rr_graph::TOOL_NAME; + break; + default: break; + } + break; + default: break; + } + break; + case 12: + switch(*((triehash_uu64*)&in[0])){ + case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('c', 40, 64) | onechar('o', 48, 64) | onechar('m', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('n', 16, 32) | onechar('t', 24, 32): + return atok_t_rr_graph::TOOL_COMMENT; + break; + default: break; + } + break; + case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('v', 40, 64) | onechar('e', 48, 64) | onechar('r', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('o', 16, 32) | onechar('n', 24, 32): + return atok_t_rr_graph::TOOL_VERSION; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + noreturn_report(report_error, ("Found unrecognized attribute " + std::string(in) + " of .").c_str()); } /** * Internal error function for xs:choice and xs:sequence validators. */ -[[noreturn]] inline void dfa_error(const char* wrong, const int* states, const char* const* lookup, int len, const std::function* report_error); +[[noreturn]] inline void dfa_error(const char *wrong, const int *states, const char * const *lookup, int len, const std::function * report_error); /** * Internal error function for xs:all validators. */ template -[[noreturn]] inline void all_error(std::bitset gstate, const char* const* lookup, const std::function* report_error); +[[noreturn]] inline void all_error(std::bitset gstate, const char * const *lookup, const std::function * report_error); /** * Internal error function for attribute validators. */ template -[[noreturn]] inline void attr_error(std::bitset astate, const char* const* lookup, const std::function* report_error); +[[noreturn]] inline void attr_error(std::bitset astate, const char * const *lookup, const std::function * report_error); + /* Lookup tables for enums. */ -constexpr const char* lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", "pass_gate", "short", "buffer"}; -constexpr const char* lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; -constexpr const char* lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; -constexpr const char* lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; -constexpr const char* lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM", "RIGHT_LEFT", "RIGHT_BOTTOM", "RIGHT_BOTTOM_LEFT", "TOP_RIGHT", "TOP_BOTTOM", "TOP_LEFT", "TOP_RIGHT_BOTTOM", "TOP_RIGHT_LEFT", "TOP_BOTTOM_LEFT", "TOP_RIGHT_BOTTOM_LEFT", "BOTTOM_LEFT"}; +constexpr const char *lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", "pass_gate", "short", "buffer"}; +constexpr const char *lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; +constexpr const char *lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; +constexpr const char *lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; +constexpr const char *lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM", "RIGHT_LEFT", "RIGHT_BOTTOM", "RIGHT_BOTTOM_LEFT", "TOP_RIGHT", "TOP_BOTTOM", "TOP_LEFT", "TOP_RIGHT_BOTTOM", "TOP_RIGHT_LEFT", "TOP_BOTTOM_LEFT", "TOP_RIGHT_BOTTOM_LEFT", "BOTTOM_LEFT"}; /* Lexers(string->token functions) for enums. */ -inline enum_switch_type lex_enum_switch_type(const char* in, bool throw_on_invalid, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('m', 0, 8): - switch (in[1]) { - case onechar('u', 0, 8): - switch (in[2]) { - case onechar('x', 0, 8): - return enum_switch_type::MUX; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('s', 0, 32) | onechar('h', 8, 32) | onechar('o', 16, 32) | onechar('r', 24, 32): - switch (in[4]) { - case onechar('t', 0, 8): - return enum_switch_type::SHORT; - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('b', 0, 32) | onechar('u', 8, 32) | onechar('f', 16, 32) | onechar('f', 24, 32): - switch (in[4]) { - case onechar('e', 0, 8): - switch (in[5]) { - case onechar('r', 0, 8): - return enum_switch_type::BUFFER; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('t', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('s', 24, 64) | onechar('t', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64): - return enum_switch_type::TRISTATE; - break; - default: - break; - } - break; - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('s', 16, 64) | onechar('s', 24, 64) | onechar('_', 32, 64) | onechar('g', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64): - switch (in[8]) { - case onechar('e', 0, 8): - return enum_switch_type::PASS_GATE; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - if (throw_on_invalid) - noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_switch_type.").c_str()); - return enum_switch_type::UXSD_INVALID; +inline enum_switch_type lex_enum_switch_type(const char *in, bool throw_on_invalid, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('m', 0, 8): + switch(in[1]){ + case onechar('u', 0, 8): + switch(in[2]){ + case onechar('x', 0, 8): + return enum_switch_type::MUX; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('s', 0, 32) | onechar('h', 8, 32) | onechar('o', 16, 32) | onechar('r', 24, 32): + switch(in[4]){ + case onechar('t', 0, 8): + return enum_switch_type::SHORT; + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('b', 0, 32) | onechar('u', 8, 32) | onechar('f', 16, 32) | onechar('f', 24, 32): + switch(in[4]){ + case onechar('e', 0, 8): + switch(in[5]){ + case onechar('r', 0, 8): + return enum_switch_type::BUFFER; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('t', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('s', 24, 64) | onechar('t', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64): + return enum_switch_type::TRISTATE; + break; + default: break; + } + break; + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('s', 16, 64) | onechar('s', 24, 64) | onechar('_', 32, 64) | onechar('g', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64): + switch(in[8]){ + case onechar('e', 0, 8): + return enum_switch_type::PASS_GATE; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + if(throw_on_invalid) + noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_switch_type.").c_str()); + return enum_switch_type::UXSD_INVALID; } -inline enum_pin_type lex_enum_pin_type(const char* in, bool throw_on_invalid, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('E', 16, 32) | onechar('N', 24, 32): - return enum_pin_type::OPEN; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('P', 16, 32) | onechar('U', 24, 32): - switch (in[4]) { - case onechar('T', 0, 8): - return enum_pin_type::INPUT; - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('O', 0, 32) | onechar('U', 8, 32) | onechar('T', 16, 32) | onechar('P', 24, 32): - switch (in[4]) { - case onechar('U', 0, 8): - switch (in[5]) { - case onechar('T', 0, 8): - return enum_pin_type::OUTPUT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - if (throw_on_invalid) - noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_pin_type.").c_str()); - return enum_pin_type::UXSD_INVALID; +inline enum_pin_type lex_enum_pin_type(const char *in, bool throw_on_invalid, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('E', 16, 32) | onechar('N', 24, 32): + return enum_pin_type::OPEN; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('P', 16, 32) | onechar('U', 24, 32): + switch(in[4]){ + case onechar('T', 0, 8): + return enum_pin_type::INPUT; + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('O', 0, 32) | onechar('U', 8, 32) | onechar('T', 16, 32) | onechar('P', 24, 32): + switch(in[4]){ + case onechar('U', 0, 8): + switch(in[5]){ + case onechar('T', 0, 8): + return enum_pin_type::OUTPUT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + if(throw_on_invalid) + noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_pin_type.").c_str()); + return enum_pin_type::UXSD_INVALID; } -inline enum_node_type lex_enum_node_type(const char* in, bool throw_on_invalid, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('I', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): - return enum_node_type::IPIN; - break; - case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): - return enum_node_type::OPIN; - break; - case onechar('S', 0, 32) | onechar('I', 8, 32) | onechar('N', 16, 32) | onechar('K', 24, 32): - return enum_node_type::SINK; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('C', 0, 32) | onechar('H', 8, 32) | onechar('A', 16, 32) | onechar('N', 24, 32): - switch (in[4]) { - case onechar('X', 0, 8): - return enum_node_type::CHANX; - break; - case onechar('Y', 0, 8): - return enum_node_type::CHANY; - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('S', 0, 32) | onechar('O', 8, 32) | onechar('U', 16, 32) | onechar('R', 24, 32): - switch (in[4]) { - case onechar('C', 0, 8): - switch (in[5]) { - case onechar('E', 0, 8): - return enum_node_type::SOURCE; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - if (throw_on_invalid) - noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_node_type.").c_str()); - return enum_node_type::UXSD_INVALID; +inline enum_node_type lex_enum_node_type(const char *in, bool throw_on_invalid, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('I', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): + return enum_node_type::IPIN; + break; + case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): + return enum_node_type::OPIN; + break; + case onechar('S', 0, 32) | onechar('I', 8, 32) | onechar('N', 16, 32) | onechar('K', 24, 32): + return enum_node_type::SINK; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('C', 0, 32) | onechar('H', 8, 32) | onechar('A', 16, 32) | onechar('N', 24, 32): + switch(in[4]){ + case onechar('X', 0, 8): + return enum_node_type::CHANX; + break; + case onechar('Y', 0, 8): + return enum_node_type::CHANY; + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('S', 0, 32) | onechar('O', 8, 32) | onechar('U', 16, 32) | onechar('R', 24, 32): + switch(in[4]){ + case onechar('C', 0, 8): + switch(in[5]){ + case onechar('E', 0, 8): + return enum_node_type::SOURCE; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + if(throw_on_invalid) + noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_node_type.").c_str()); + return enum_node_type::UXSD_INVALID; } -inline enum_node_direction lex_enum_node_direction(const char* in, bool throw_on_invalid, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('B', 0, 32) | onechar('I', 8, 32) | onechar('_', 16, 32) | onechar('D', 24, 32): - switch (in[4]) { - case onechar('I', 0, 8): - switch (in[5]) { - case onechar('R', 0, 8): - return enum_node_direction::BI_DIR; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 7: - switch (*((triehash_uu32*)&in[0])) { - case onechar('D', 0, 32) | onechar('E', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): - switch (in[4]) { - case onechar('D', 0, 8): - switch (in[5]) { - case onechar('I', 0, 8): - switch (in[6]) { - case onechar('R', 0, 8): - return enum_node_direction::DEC_DIR; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): - switch (in[4]) { - case onechar('D', 0, 8): - switch (in[5]) { - case onechar('I', 0, 8): - switch (in[6]) { - case onechar('R', 0, 8): - return enum_node_direction::INC_DIR; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - if (throw_on_invalid) - noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_node_direction.").c_str()); - return enum_node_direction::UXSD_INVALID; +inline enum_node_direction lex_enum_node_direction(const char *in, bool throw_on_invalid, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('B', 0, 32) | onechar('I', 8, 32) | onechar('_', 16, 32) | onechar('D', 24, 32): + switch(in[4]){ + case onechar('I', 0, 8): + switch(in[5]){ + case onechar('R', 0, 8): + return enum_node_direction::BI_DIR; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 7: + switch(*((triehash_uu32*)&in[0])){ + case onechar('D', 0, 32) | onechar('E', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): + switch(in[4]){ + case onechar('D', 0, 8): + switch(in[5]){ + case onechar('I', 0, 8): + switch(in[6]){ + case onechar('R', 0, 8): + return enum_node_direction::DEC_DIR; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): + switch(in[4]){ + case onechar('D', 0, 8): + switch(in[5]){ + case onechar('I', 0, 8): + switch(in[6]){ + case onechar('R', 0, 8): + return enum_node_direction::INC_DIR; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + if(throw_on_invalid) + noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_node_direction.").c_str()); + return enum_node_direction::UXSD_INVALID; } -inline enum_loc_side lex_enum_loc_side(const char* in, bool throw_on_invalid, const std::function* report_error) { - unsigned int len = strlen(in); - switch (len) { - case 3: - switch (in[0]) { - case onechar('T', 0, 8): - switch (in[1]) { - case onechar('O', 0, 8): - switch (in[2]) { - case onechar('P', 0, 8): - return enum_loc_side::TOP; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 4: - switch (*((triehash_uu32*)&in[0])) { - case onechar('L', 0, 32) | onechar('E', 8, 32) | onechar('F', 16, 32) | onechar('T', 24, 32): - return enum_loc_side::LEFT; - break; - default: - break; - } - break; - case 5: - switch (*((triehash_uu32*)&in[0])) { - case onechar('R', 0, 32) | onechar('I', 8, 32) | onechar('G', 16, 32) | onechar('H', 24, 32): - switch (in[4]) { - case onechar('T', 0, 8): - return enum_loc_side::RIGHT; - break; - default: - break; - } - break; - default: - break; - } - break; - case 6: - switch (*((triehash_uu32*)&in[0])) { - case onechar('B', 0, 32) | onechar('O', 8, 32) | onechar('T', 16, 32) | onechar('T', 24, 32): - switch (in[4]) { - case onechar('O', 0, 8): - switch (in[5]) { - case onechar('M', 0, 8): - return enum_loc_side::BOTTOM; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 8: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('L', 32, 64) | onechar('E', 40, 64) | onechar('F', 48, 64) | onechar('T', 56, 64): - return enum_loc_side::TOP_LEFT; - break; - default: - break; - } - break; - case 9: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): - switch (in[8]) { - case onechar('T', 0, 8): - return enum_loc_side::TOP_RIGHT; - break; - default: - break; - } - break; - default: - break; - } - break; - case 10: - switch (*((triehash_uu64*)&in[0])) { - case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('L', 48, 64) | onechar('E', 56, 64): - switch (in[8]) { - case onechar('F', 0, 8): - switch (in[9]) { - case onechar('T', 0, 8): - return enum_loc_side::RIGHT_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): - switch (in[8]) { - case onechar('O', 0, 8): - switch (in[9]) { - case onechar('M', 0, 8): - return enum_loc_side::TOP_BOTTOM; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 11: - switch (*((triehash_uu64*)&in[0])) { - case onechar('B', 0, 64) | onechar('O', 8, 64) | onechar('T', 16, 64) | onechar('T', 24, 64) | onechar('O', 32, 64) | onechar('M', 40, 64) | onechar('_', 48, 64) | onechar('L', 56, 64): - switch (in[8]) { - case onechar('E', 0, 8): - switch (in[9]) { - case onechar('F', 0, 8): - switch (in[10]) { - case onechar('T', 0, 8): - return enum_loc_side::BOTTOM_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 12: - switch (*((triehash_uu64*)&in[0])) { - case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('T', 0, 32) | onechar('T', 8, 32) | onechar('O', 16, 32) | onechar('M', 24, 32): - return enum_loc_side::RIGHT_BOTTOM; - break; - default: - break; - } - break; - default: - break; - } - break; - case 14: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('T', 0, 32) | onechar('_', 8, 32) | onechar('L', 16, 32) | onechar('E', 24, 32): - switch (in[12]) { - case onechar('F', 0, 8): - switch (in[13]) { - case onechar('T', 0, 8): - return enum_loc_side::TOP_RIGHT_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 15: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): - switch (*((triehash_uu32*)&in[8])) { - case onechar('O', 0, 32) | onechar('M', 8, 32) | onechar('_', 16, 32) | onechar('L', 24, 32): - switch (in[12]) { - case onechar('E', 0, 8): - switch (in[13]) { - case onechar('F', 0, 8): - switch (in[14]) { - case onechar('T', 0, 8): - return enum_loc_side::TOP_BOTTOM_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 16: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): - switch (*((triehash_uu64*)&in[8])) { - case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): - return enum_loc_side::TOP_RIGHT_BOTTOM; - break; - default: - break; - } - break; - default: - break; - } - break; - case 17: - switch (*((triehash_uu64*)&in[0])) { - case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): - switch (*((triehash_uu64*)&in[8])) { - case onechar('T', 0, 64) | onechar('T', 8, 64) | onechar('O', 16, 64) | onechar('M', 24, 64) | onechar('_', 32, 64) | onechar('L', 40, 64) | onechar('E', 48, 64) | onechar('F', 56, 64): - switch (in[16]) { - case onechar('T', 0, 8): - return enum_loc_side::RIGHT_BOTTOM_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - case 21: - switch (*((triehash_uu64*)&in[0])) { - case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): - switch (*((triehash_uu64*)&in[8])) { - case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): - switch (*((triehash_uu32*)&in[16])) { - case onechar('_', 0, 32) | onechar('L', 8, 32) | onechar('E', 16, 32) | onechar('F', 24, 32): - switch (in[20]) { - case onechar('T', 0, 8): - return enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - break; - default: - break; - } - if (throw_on_invalid) - noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_loc_side.").c_str()); - return enum_loc_side::UXSD_INVALID; +inline enum_loc_side lex_enum_loc_side(const char *in, bool throw_on_invalid, const std::function * report_error){ + unsigned int len = strlen(in); + switch(len){ + case 3: + switch(in[0]){ + case onechar('T', 0, 8): + switch(in[1]){ + case onechar('O', 0, 8): + switch(in[2]){ + case onechar('P', 0, 8): + return enum_loc_side::TOP; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 4: + switch(*((triehash_uu32*)&in[0])){ + case onechar('L', 0, 32) | onechar('E', 8, 32) | onechar('F', 16, 32) | onechar('T', 24, 32): + return enum_loc_side::LEFT; + break; + default: break; + } + break; + case 5: + switch(*((triehash_uu32*)&in[0])){ + case onechar('R', 0, 32) | onechar('I', 8, 32) | onechar('G', 16, 32) | onechar('H', 24, 32): + switch(in[4]){ + case onechar('T', 0, 8): + return enum_loc_side::RIGHT; + break; + default: break; + } + break; + default: break; + } + break; + case 6: + switch(*((triehash_uu32*)&in[0])){ + case onechar('B', 0, 32) | onechar('O', 8, 32) | onechar('T', 16, 32) | onechar('T', 24, 32): + switch(in[4]){ + case onechar('O', 0, 8): + switch(in[5]){ + case onechar('M', 0, 8): + return enum_loc_side::BOTTOM; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 8: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('L', 32, 64) | onechar('E', 40, 64) | onechar('F', 48, 64) | onechar('T', 56, 64): + return enum_loc_side::TOP_LEFT; + break; + default: break; + } + break; + case 9: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch(in[8]){ + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT; + break; + default: break; + } + break; + default: break; + } + break; + case 10: + switch(*((triehash_uu64*)&in[0])){ + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('L', 48, 64) | onechar('E', 56, 64): + switch(in[8]){ + case onechar('F', 0, 8): + switch(in[9]){ + case onechar('T', 0, 8): + return enum_loc_side::RIGHT_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): + switch(in[8]){ + case onechar('O', 0, 8): + switch(in[9]){ + case onechar('M', 0, 8): + return enum_loc_side::TOP_BOTTOM; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 11: + switch(*((triehash_uu64*)&in[0])){ + case onechar('B', 0, 64) | onechar('O', 8, 64) | onechar('T', 16, 64) | onechar('T', 24, 64) | onechar('O', 32, 64) | onechar('M', 40, 64) | onechar('_', 48, 64) | onechar('L', 56, 64): + switch(in[8]){ + case onechar('E', 0, 8): + switch(in[9]){ + case onechar('F', 0, 8): + switch(in[10]){ + case onechar('T', 0, 8): + return enum_loc_side::BOTTOM_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 12: + switch(*((triehash_uu64*)&in[0])){ + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('T', 0, 32) | onechar('T', 8, 32) | onechar('O', 16, 32) | onechar('M', 24, 32): + return enum_loc_side::RIGHT_BOTTOM; + break; + default: break; + } + break; + default: break; + } + break; + case 14: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('T', 0, 32) | onechar('_', 8, 32) | onechar('L', 16, 32) | onechar('E', 24, 32): + switch(in[12]){ + case onechar('F', 0, 8): + switch(in[13]){ + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 15: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('B', 32, 64) | onechar('O', 40, 64) | onechar('T', 48, 64) | onechar('T', 56, 64): + switch(*((triehash_uu32*)&in[8])){ + case onechar('O', 0, 32) | onechar('M', 8, 32) | onechar('_', 16, 32) | onechar('L', 24, 32): + switch(in[12]){ + case onechar('E', 0, 8): + switch(in[13]){ + case onechar('F', 0, 8): + switch(in[14]){ + case onechar('T', 0, 8): + return enum_loc_side::TOP_BOTTOM_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 16: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch(*((triehash_uu64*)&in[8])){ + case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): + return enum_loc_side::TOP_RIGHT_BOTTOM; + break; + default: break; + } + break; + default: break; + } + break; + case 17: + switch(*((triehash_uu64*)&in[0])){ + case onechar('R', 0, 64) | onechar('I', 8, 64) | onechar('G', 16, 64) | onechar('H', 24, 64) | onechar('T', 32, 64) | onechar('_', 40, 64) | onechar('B', 48, 64) | onechar('O', 56, 64): + switch(*((triehash_uu64*)&in[8])){ + case onechar('T', 0, 64) | onechar('T', 8, 64) | onechar('O', 16, 64) | onechar('M', 24, 64) | onechar('_', 32, 64) | onechar('L', 40, 64) | onechar('E', 48, 64) | onechar('F', 56, 64): + switch(in[16]){ + case onechar('T', 0, 8): + return enum_loc_side::RIGHT_BOTTOM_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + case 21: + switch(*((triehash_uu64*)&in[0])){ + case onechar('T', 0, 64) | onechar('O', 8, 64) | onechar('P', 16, 64) | onechar('_', 24, 64) | onechar('R', 32, 64) | onechar('I', 40, 64) | onechar('G', 48, 64) | onechar('H', 56, 64): + switch(*((triehash_uu64*)&in[8])){ + case onechar('T', 0, 64) | onechar('_', 8, 64) | onechar('B', 16, 64) | onechar('O', 24, 64) | onechar('T', 32, 64) | onechar('T', 40, 64) | onechar('O', 48, 64) | onechar('M', 56, 64): + switch(*((triehash_uu32*)&in[16])){ + case onechar('_', 0, 32) | onechar('L', 8, 32) | onechar('E', 16, 32) | onechar('F', 24, 32): + switch(in[20]){ + case onechar('T', 0, 8): + return enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + break; + default: break; + } + if(throw_on_invalid) + noreturn_report(report_error, ("Found unrecognized enum value " + std::string(in) + " of enum_loc_side.").c_str()); + return enum_loc_side::UXSD_INVALID; } + /* Internal loading functions, which validate and load a PugiXML DOM tree into memory. */ -inline int load_int(const char* in, const std::function* report_error) { - int out; - out = std::strtol(in, NULL, 10); - if (errno != 0) - noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a int.").c_str()); - return out; +inline int load_int(const char *in, const std::function * report_error){ + int out; + out = std::strtol(in, NULL, 10); + if(errno != 0) + noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a int.").c_str()); + return out; } -inline unsigned int load_unsigned_int(const char* in, const std::function* report_error) { - unsigned int out; - out = std::strtoul(in, NULL, 10); - if (errno != 0) - noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a unsigned int.").c_str()); - return out; +inline unsigned int load_unsigned_int(const char *in, const std::function * report_error){ + unsigned int out; + out = std::strtoul(in, NULL, 10); + if(errno != 0) + noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a unsigned int.").c_str()); + return out; } -inline float load_float(const char* in, const std::function* report_error) { - float out; - out = std::strtof(in, NULL); - if (errno != 0) - noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a float.").c_str()); - return out; +inline float load_float(const char *in, const std::function * report_error){ + float out; + out = std::strtof(in, NULL); + if(errno != 0) + noreturn_report(report_error, ("Invalid value `" + std::string(in) + "` when loading into a float.").c_str()); + return out; } -inline void load_channel_required_attributes(const pugi::xml_node& root, int* chan_width_max, int* x_max, int* x_min, int* y_max, int* y_min, const std::function* report_error) { - std::bitset<5> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_channel in = lex_attr_t_channel(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_channel::CHAN_WIDTH_MAX: - *chan_width_max = load_int(attr.value(), report_error); - break; - case atok_t_channel::X_MAX: - *x_max = load_int(attr.value(), report_error); - break; - case atok_t_channel::X_MIN: - *x_min = load_int(attr.value(), report_error); - break; - case atok_t_channel::Y_MAX: - *y_max = load_int(attr.value(), report_error); - break; - case atok_t_channel::Y_MIN: - *y_min = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_channel, report_error); +inline void load_channel_required_attributes(const pugi::xml_node &root, int * chan_width_max, int * x_max, int * x_min, int * y_max, int * y_min, const std::function * report_error){ + std::bitset<5> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_channel in = lex_attr_t_channel(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_channel::CHAN_WIDTH_MAX: + *chan_width_max = load_int(attr.value(), report_error); + break; + case atok_t_channel::X_MAX: + *x_max = load_int(attr.value(), report_error); + break; + case atok_t_channel::X_MIN: + *x_min = load_int(attr.value(), report_error); + break; + case atok_t_channel::Y_MAX: + *y_max = load_int(attr.value(), report_error); + break; + case atok_t_channel::Y_MIN: + *y_min = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_channel, report_error); } -inline void load_x_list_required_attributes(const pugi::xml_node& root, unsigned int* index, int* info, const std::function* report_error) { - std::bitset<2> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_x_list in = lex_attr_t_x_list(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_x_list::INDEX: - *index = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_x_list::INFO: - *info = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_astate = astate | std::bitset<2>(0b00); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_x_list, report_error); +inline void load_x_list_required_attributes(const pugi::xml_node &root, unsigned int * index, int * info, const std::function * report_error){ + std::bitset<2> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_x_list in = lex_attr_t_x_list(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_x_list::INDEX: + *index = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_x_list::INFO: + *info = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_astate = astate | std::bitset<2>(0b00); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_x_list, report_error); } -inline void load_y_list_required_attributes(const pugi::xml_node& root, unsigned int* index, int* info, const std::function* report_error) { - std::bitset<2> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_y_list in = lex_attr_t_y_list(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_y_list::INDEX: - *index = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_y_list::INFO: - *info = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_astate = astate | std::bitset<2>(0b00); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_y_list, report_error); +inline void load_y_list_required_attributes(const pugi::xml_node &root, unsigned int * index, int * info, const std::function * report_error){ + std::bitset<2> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_y_list in = lex_attr_t_y_list(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_y_list::INDEX: + *index = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_y_list::INFO: + *info = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_astate = astate | std::bitset<2>(0b00); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_y_list, report_error); } -inline void load_sizing_required_attributes(const pugi::xml_node& root, float* buf_size, float* mux_trans_size, const std::function* report_error) { - std::bitset<2> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_sizing in = lex_attr_t_sizing(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_sizing::BUF_SIZE: - *buf_size = load_float(attr.value(), report_error); - break; - case atok_t_sizing::MUX_TRANS_SIZE: - *mux_trans_size = load_float(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_astate = astate | std::bitset<2>(0b00); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_sizing, report_error); +inline void load_sizing_required_attributes(const pugi::xml_node &root, float * buf_size, float * mux_trans_size, const std::function * report_error){ + std::bitset<2> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_sizing in = lex_attr_t_sizing(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_sizing::BUF_SIZE: + *buf_size = load_float(attr.value(), report_error); + break; + case atok_t_sizing::MUX_TRANS_SIZE: + *mux_trans_size = load_float(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_astate = astate | std::bitset<2>(0b00); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_sizing, report_error); } -inline void load_switch_required_attributes(const pugi::xml_node& root, int* id, const std::function* report_error) { - std::bitset<3> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_switch in = lex_attr_t_switch(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_switch::ID: - *id = load_int(attr.value(), report_error); - break; - case atok_t_switch::NAME: - /* Attribute name set after element init */ - break; - case atok_t_switch::TYPE: - /* Attribute type set after element init */ - break; - default: - break; /* Not possible. */ - } - } - std::bitset<3> test_astate = astate | std::bitset<3>(0b100); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_switch, report_error); +inline void load_switch_required_attributes(const pugi::xml_node &root, int * id, const std::function * report_error){ + std::bitset<3> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_switch in = lex_attr_t_switch(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_switch::ID: + *id = load_int(attr.value(), report_error); + break; + case atok_t_switch::NAME: + /* Attribute name set after element init */ + break; + case atok_t_switch::TYPE: + /* Attribute type set after element init */ + break; + default: break; /* Not possible. */ + } + } + std::bitset<3> test_astate = astate | std::bitset<3>(0b100); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_switch, report_error); } -inline void load_segment_required_attributes(const pugi::xml_node& root, int* id, const std::function* report_error) { - std::bitset<2> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_segment in = lex_attr_t_segment(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_segment::ID: - *id = load_int(attr.value(), report_error); - break; - case atok_t_segment::NAME: - /* Attribute name set after element init */ - break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_astate = astate | std::bitset<2>(0b00); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_segment, report_error); +inline void load_segment_required_attributes(const pugi::xml_node &root, int * id, const std::function * report_error){ + std::bitset<2> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_segment in = lex_attr_t_segment(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_segment::ID: + *id = load_int(attr.value(), report_error); + break; + case atok_t_segment::NAME: + /* Attribute name set after element init */ + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_astate = astate | std::bitset<2>(0b00); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_segment, report_error); } -inline void load_pin_required_attributes(const pugi::xml_node& root, int* ptc, const std::function* report_error) { - std::bitset<1> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_pin in = lex_attr_t_pin(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_pin::PTC: - *ptc = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<1> test_astate = astate | std::bitset<1>(0b0); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin, report_error); +inline void load_pin_required_attributes(const pugi::xml_node &root, int * ptc, const std::function * report_error){ + std::bitset<1> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_pin in = lex_attr_t_pin(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_pin::PTC: + *ptc = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<1> test_astate = astate | std::bitset<1>(0b0); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin, report_error); } -inline void load_pin_class_required_attributes(const pugi::xml_node& root, enum_pin_type* type, const std::function* report_error) { - std::bitset<1> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_pin_class in = lex_attr_t_pin_class(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_pin_class::TYPE: - *type = lex_enum_pin_type(attr.value(), true, report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<1> test_astate = astate | std::bitset<1>(0b0); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin_class, report_error); +inline void load_pin_class_required_attributes(const pugi::xml_node &root, enum_pin_type * type, const std::function * report_error){ + std::bitset<1> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_pin_class in = lex_attr_t_pin_class(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_pin_class::TYPE: + *type = lex_enum_pin_type(attr.value(), true, report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<1> test_astate = astate | std::bitset<1>(0b0); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin_class, report_error); } -inline void load_block_type_required_attributes(const pugi::xml_node& root, int* height, int* id, int* width, const std::function* report_error) { - std::bitset<4> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_block_type in = lex_attr_t_block_type(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_block_type::HEIGHT: - *height = load_int(attr.value(), report_error); - break; - case atok_t_block_type::ID: - *id = load_int(attr.value(), report_error); - break; - case atok_t_block_type::NAME: - /* Attribute name set after element init */ - break; - case atok_t_block_type::WIDTH: - *width = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<4> test_astate = astate | std::bitset<4>(0b0000); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_block_type, report_error); +inline void load_block_type_required_attributes(const pugi::xml_node &root, int * height, int * id, int * width, const std::function * report_error){ + std::bitset<4> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_block_type in = lex_attr_t_block_type(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_block_type::HEIGHT: + *height = load_int(attr.value(), report_error); + break; + case atok_t_block_type::ID: + *id = load_int(attr.value(), report_error); + break; + case atok_t_block_type::NAME: + /* Attribute name set after element init */ + break; + case atok_t_block_type::WIDTH: + *width = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<4> test_astate = astate | std::bitset<4>(0b0000); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_block_type, report_error); } -inline void load_grid_loc_required_attributes(const pugi::xml_node& root, int* block_type_id, int* height_offset, int* width_offset, int* x, int* y, const std::function* report_error) { - std::bitset<5> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_grid_loc in = lex_attr_t_grid_loc(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_grid_loc::BLOCK_TYPE_ID: - *block_type_id = load_int(attr.value(), report_error); - break; - case atok_t_grid_loc::HEIGHT_OFFSET: - *height_offset = load_int(attr.value(), report_error); - break; - case atok_t_grid_loc::WIDTH_OFFSET: - *width_offset = load_int(attr.value(), report_error); - break; - case atok_t_grid_loc::X: - *x = load_int(attr.value(), report_error); - break; - case atok_t_grid_loc::Y: - *y = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_grid_loc, report_error); +inline void load_grid_loc_required_attributes(const pugi::xml_node &root, int * block_type_id, int * height_offset, int * width_offset, int * x, int * y, const std::function * report_error){ + std::bitset<5> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_grid_loc in = lex_attr_t_grid_loc(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_grid_loc::BLOCK_TYPE_ID: + *block_type_id = load_int(attr.value(), report_error); + break; + case atok_t_grid_loc::HEIGHT_OFFSET: + *height_offset = load_int(attr.value(), report_error); + break; + case atok_t_grid_loc::WIDTH_OFFSET: + *width_offset = load_int(attr.value(), report_error); + break; + case atok_t_grid_loc::X: + *x = load_int(attr.value(), report_error); + break; + case atok_t_grid_loc::Y: + *y = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_grid_loc, report_error); } -inline void load_node_loc_required_attributes(const pugi::xml_node& root, int* ptc, int* xhigh, int* xlow, int* yhigh, int* ylow, const std::function* report_error) { - std::bitset<6> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node_loc in = lex_attr_t_node_loc(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_node_loc::PTC: - *ptc = load_int(attr.value(), report_error); - break; - case atok_t_node_loc::SIDE: - /* Attribute side set after element init */ - break; - case atok_t_node_loc::XHIGH: - *xhigh = load_int(attr.value(), report_error); - break; - case atok_t_node_loc::XLOW: - *xlow = load_int(attr.value(), report_error); - break; - case atok_t_node_loc::YHIGH: - *yhigh = load_int(attr.value(), report_error); - break; - case atok_t_node_loc::YLOW: - *ylow = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<6> test_astate = astate | std::bitset<6>(0b000010); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_loc, report_error); +inline void load_node_loc_required_attributes(const pugi::xml_node &root, int * ptc, int * xhigh, int * xlow, int * yhigh, int * ylow, const std::function * report_error){ + std::bitset<6> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node_loc in = lex_attr_t_node_loc(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_node_loc::PTC: + *ptc = load_int(attr.value(), report_error); + break; + case atok_t_node_loc::SIDE: + /* Attribute side set after element init */ + break; + case atok_t_node_loc::XHIGH: + *xhigh = load_int(attr.value(), report_error); + break; + case atok_t_node_loc::XLOW: + *xlow = load_int(attr.value(), report_error); + break; + case atok_t_node_loc::YHIGH: + *yhigh = load_int(attr.value(), report_error); + break; + case atok_t_node_loc::YLOW: + *ylow = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<6> test_astate = astate | std::bitset<6>(0b000010); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_loc, report_error); } -inline void load_node_timing_required_attributes(const pugi::xml_node& root, float* C, float* R, const std::function* report_error) { - std::bitset<2> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node_timing in = lex_attr_t_node_timing(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_node_timing::C: - *C = load_float(attr.value(), report_error); - break; - case atok_t_node_timing::R: - *R = load_float(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_astate = astate | std::bitset<2>(0b00); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_timing, report_error); +inline void load_node_timing_required_attributes(const pugi::xml_node &root, float * C, float * R, const std::function * report_error){ + std::bitset<2> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node_timing in = lex_attr_t_node_timing(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_node_timing::C: + *C = load_float(attr.value(), report_error); + break; + case atok_t_node_timing::R: + *R = load_float(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_astate = astate | std::bitset<2>(0b00); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_timing, report_error); } -inline void load_node_segment_required_attributes(const pugi::xml_node& root, int* segment_id, const std::function* report_error) { - std::bitset<1> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node_segment in = lex_attr_t_node_segment(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_node_segment::SEGMENT_ID: - *segment_id = load_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<1> test_astate = astate | std::bitset<1>(0b0); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_segment, report_error); +inline void load_node_segment_required_attributes(const pugi::xml_node &root, int * segment_id, const std::function * report_error){ + std::bitset<1> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node_segment in = lex_attr_t_node_segment(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_node_segment::SEGMENT_ID: + *segment_id = load_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<1> test_astate = astate | std::bitset<1>(0b0); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_segment, report_error); } -inline void load_node_required_attributes(const pugi::xml_node& root, unsigned int* capacity, unsigned int* id, enum_node_type* type, const std::function* report_error) { - std::bitset<4> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node in = lex_attr_t_node(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_node::CAPACITY: - *capacity = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_node::DIRECTION: - /* Attribute direction set after element init */ - break; - case atok_t_node::ID: - *id = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_node::TYPE: - *type = lex_enum_node_type(attr.value(), true, report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<4> test_astate = astate | std::bitset<4>(0b0010); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_node, report_error); +inline void load_node_required_attributes(const pugi::xml_node &root, unsigned int * capacity, unsigned int * id, enum_node_type * type, const std::function * report_error){ + std::bitset<4> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node in = lex_attr_t_node(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_node::CAPACITY: + *capacity = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_node::DIRECTION: + /* Attribute direction set after element init */ + break; + case atok_t_node::ID: + *id = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_node::TYPE: + *type = lex_enum_node_type(attr.value(), true, report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<4> test_astate = astate | std::bitset<4>(0b0010); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node, report_error); } -inline void load_edge_required_attributes(const pugi::xml_node& root, unsigned int* sink_node, unsigned int* src_node, unsigned int* switch_id, const std::function* report_error) { - std::bitset<3> astate = 0; - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_edge in = lex_attr_t_edge(attr.name(), report_error); - if (astate[(int)in] == 0) - astate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); - switch (in) { - case atok_t_edge::SINK_NODE: - *sink_node = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_edge::SRC_NODE: - *src_node = load_unsigned_int(attr.value(), report_error); - break; - case atok_t_edge::SWITCH_ID: - *switch_id = load_unsigned_int(attr.value(), report_error); - break; - default: - break; /* Not possible. */ - } - } - std::bitset<3> test_astate = astate | std::bitset<3>(0b000); - if (!test_astate.all()) attr_error(test_astate, atok_lookup_t_edge, report_error); +inline void load_edge_required_attributes(const pugi::xml_node &root, unsigned int * sink_node, unsigned int * src_node, unsigned int * switch_id, const std::function * report_error){ + std::bitset<3> astate = 0; + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_edge in = lex_attr_t_edge(attr.name(), report_error); + if(astate[(int)in] == 0) astate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate attribute " + std::string(attr.name()) + " in .").c_str()); + switch(in){ + case atok_t_edge::SINK_NODE: + *sink_node = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_edge::SRC_NODE: + *src_node = load_unsigned_int(attr.value(), report_error); + break; + case atok_t_edge::SWITCH_ID: + *switch_id = load_unsigned_int(attr.value(), report_error); + break; + default: break; /* Not possible. */ + } + } + std::bitset<3> test_astate = astate | std::bitset<3>(0b000); + if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_edge, report_error); } template -inline void load_channel(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_channel(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_x_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_x_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_y_list(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_y_list(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } constexpr int NUM_T_CHANNELS_STATES = 4; constexpr const int NUM_T_CHANNELS_INPUTS = 3; constexpr int gstate_t_channels[NUM_T_CHANNELS_STATES][NUM_T_CHANNELS_INPUTS] = { - {-1, -1, 0}, - {-1, 1, 0}, - {-1, 1, -1}, - {2, -1, -1}, + {-1, -1, 0}, + {-1, 1, 0}, + {-1, 1, -1}, + {2, -1, -1}, }; template -inline void load_channels(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t x_list_count = 0; - size_t y_list_count = 0; - { - int next, state = 3; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_channels in = lex_node_t_channels(node.name(), report_error); - next = gstate_t_channels[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_channels[(int)in], gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); - state = next; - switch (in) { - case gtok_t_channels::CHANNEL: - break; - case gtok_t_channels::X_LIST: - x_list_count += 1; - break; - case gtok_t_channels::Y_LIST: - y_list_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_channels_x_list(context, x_list_count); - out.preallocate_channels_y_list(context, y_list_count); - } - int next, state = 3; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_channels in = lex_node_t_channels(node.name(), report_error); - next = gstate_t_channels[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_channels[(int)in], gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); - state = next; - switch (in) { - case gtok_t_channels::CHANNEL: { - int channel_chan_width_max; - memset(&channel_chan_width_max, 0, sizeof(channel_chan_width_max)); - int channel_x_max; - memset(&channel_x_max, 0, sizeof(channel_x_max)); - int channel_x_min; - memset(&channel_x_min, 0, sizeof(channel_x_min)); - int channel_y_max; - memset(&channel_y_max, 0, sizeof(channel_y_max)); - int channel_y_min; - memset(&channel_y_min, 0, sizeof(channel_y_min)); - load_channel_required_attributes(node, &channel_chan_width_max, &channel_x_max, &channel_x_min, &channel_y_max, &channel_y_min, report_error); - auto child_context = out.init_channels_channel(context, channel_chan_width_max, channel_x_max, channel_x_min, channel_y_max, channel_y_min); - load_channel(node, out, child_context, report_error, offset_debug); - out.finish_channels_channel(child_context); - } break; - case gtok_t_channels::X_LIST: { - unsigned int x_list_index; - memset(&x_list_index, 0, sizeof(x_list_index)); - int x_list_info; - memset(&x_list_info, 0, sizeof(x_list_info)); - load_x_list_required_attributes(node, &x_list_index, &x_list_info, report_error); - auto child_context = out.add_channels_x_list(context, x_list_index, x_list_info); - load_x_list(node, out, child_context, report_error, offset_debug); - out.finish_channels_x_list(child_context); - } break; - case gtok_t_channels::Y_LIST: { - unsigned int y_list_index; - memset(&y_list_index, 0, sizeof(y_list_index)); - int y_list_info; - memset(&y_list_info, 0, sizeof(y_list_info)); - load_y_list_required_attributes(node, &y_list_index, &y_list_info, report_error); - auto child_context = out.add_channels_y_list(context, y_list_index, y_list_info); - load_y_list(node, out, child_context, report_error, offset_debug); - out.finish_channels_y_list(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); +inline void load_channels(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t x_list_count = 0; + size_t y_list_count = 0; + { + int next, state=3; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_channels in = lex_node_t_channels(node.name(), report_error); + next = gstate_t_channels[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_channels[(int)in], gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); + state = next; + switch(in) { + case gtok_t_channels::CHANNEL: + break; + case gtok_t_channels::X_LIST: + x_list_count += 1; + break; + case gtok_t_channels::Y_LIST: + y_list_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_channels_x_list(context, x_list_count); + out.preallocate_channels_y_list(context, y_list_count); + } + int next, state=3; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_channels in = lex_node_t_channels(node.name(), report_error); + next = gstate_t_channels[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_channels[(int)in], gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); + state = next; + switch(in){ + case gtok_t_channels::CHANNEL: + { + int channel_chan_width_max; + memset(&channel_chan_width_max, 0, sizeof(channel_chan_width_max)); + int channel_x_max; + memset(&channel_x_max, 0, sizeof(channel_x_max)); + int channel_x_min; + memset(&channel_x_min, 0, sizeof(channel_x_min)); + int channel_y_max; + memset(&channel_y_max, 0, sizeof(channel_y_max)); + int channel_y_min; + memset(&channel_y_min, 0, sizeof(channel_y_min)); + load_channel_required_attributes(node, &channel_chan_width_max, &channel_x_max, &channel_x_min, &channel_y_max, &channel_y_min, report_error); + auto child_context = out.init_channels_channel(context, channel_chan_width_max, channel_x_max, channel_x_min, channel_y_max, channel_y_min); + load_channel(node, out, child_context, report_error, offset_debug); + out.finish_channels_channel(child_context); + } + break; + case gtok_t_channels::X_LIST: + { + unsigned int x_list_index; + memset(&x_list_index, 0, sizeof(x_list_index)); + int x_list_info; + memset(&x_list_info, 0, sizeof(x_list_info)); + load_x_list_required_attributes(node, &x_list_index, &x_list_info, report_error); + auto child_context = out.add_channels_x_list(context, x_list_index, x_list_info); + load_x_list(node, out, child_context, report_error, offset_debug); + out.finish_channels_x_list(child_context); + } + break; + case gtok_t_channels::Y_LIST: + { + unsigned int y_list_index; + memset(&y_list_index, 0, sizeof(y_list_index)); + int y_list_info; + memset(&y_list_info, 0, sizeof(y_list_info)); + load_y_list_required_attributes(node, &y_list_index, &y_list_info, report_error); + auto child_context = out.add_channels_y_list(context, y_list_index, y_list_info); + load_y_list(node, out, child_context, report_error, offset_debug); + out.finish_channels_y_list(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_channels[state], gtok_lookup_t_channels, 3, report_error); + } template -inline void load_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_timing in = lex_attr_t_timing(attr.name(), report_error); - switch (in) { - case atok_t_timing::CIN: - out.set_timing_Cin(load_float(attr.value(), report_error), context); - break; - case atok_t_timing::CINTERNAL: - out.set_timing_Cinternal(load_float(attr.value(), report_error), context); - break; - case atok_t_timing::COUT: - out.set_timing_Cout(load_float(attr.value(), report_error), context); - break; - case atok_t_timing::R: - out.set_timing_R(load_float(attr.value(), report_error), context); - break; - case atok_t_timing::TDEL: - out.set_timing_Tdel(load_float(attr.value(), report_error), context); - break; - default: - break; /* Not possible. */ - } - } - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_timing in = lex_attr_t_timing(attr.name(), report_error); + switch(in){ + case atok_t_timing::CIN: + out.set_timing_Cin(load_float(attr.value(), report_error), context); + break; + case atok_t_timing::CINTERNAL: + out.set_timing_Cinternal(load_float(attr.value(), report_error), context); + break; + case atok_t_timing::COUT: + out.set_timing_Cout(load_float(attr.value(), report_error), context); + break; + case atok_t_timing::R: + out.set_timing_R(load_float(attr.value(), report_error), context); + break; + case atok_t_timing::TDEL: + out.set_timing_Tdel(load_float(attr.value(), report_error), context); + break; + default: break; /* Not possible. */ + } + } + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_sizing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_sizing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_switch(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_switch in = lex_attr_t_switch(attr.name(), report_error); - switch (in) { - case atok_t_switch::ID: - /* Attribute id is already set */ - break; - case atok_t_switch::NAME: - out.set_switch_name(attr.value(), context); - break; - case atok_t_switch::TYPE: - out.set_switch_type(lex_enum_switch_type(attr.value(), true, report_error), context); - break; - default: - break; /* Not possible. */ - } - } - - std::bitset<2> gstate = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_switch in = lex_node_t_switch(node.name(), report_error); - if (gstate[(int)in] == 0) - gstate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); - switch (in) { - case gtok_t_switch::TIMING: { - auto child_context = out.init_switch_timing(context); - load_timing(node, out, child_context, report_error, offset_debug); - out.finish_switch_timing(child_context); - } break; - case gtok_t_switch::SIZING: { - float sizing_buf_size; - memset(&sizing_buf_size, 0, sizeof(sizing_buf_size)); - float sizing_mux_trans_size; - memset(&sizing_mux_trans_size, 0, sizeof(sizing_mux_trans_size)); - load_sizing_required_attributes(node, &sizing_buf_size, &sizing_mux_trans_size, report_error); - auto child_context = out.init_switch_sizing(context, sizing_buf_size, sizing_mux_trans_size); - load_sizing(node, out, child_context, report_error, offset_debug); - out.finish_switch_sizing(child_context); - } break; - default: - break; /* Not possible. */ - } - } - std::bitset<2> test_gstate = gstate | std::bitset<2>(0b01); - if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_switch, report_error); +inline void load_switch(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_switch in = lex_attr_t_switch(attr.name(), report_error); + switch(in){ + case atok_t_switch::ID: + /* Attribute id is already set */ + break; + case atok_t_switch::NAME: + out.set_switch_name(attr.value(), context); + break; + case atok_t_switch::TYPE: + out.set_switch_type(lex_enum_switch_type(attr.value(), true, report_error), context); + break; + default: break; /* Not possible. */ + } + } + + std::bitset<2> gstate = 0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_switch in = lex_node_t_switch(node.name(), report_error); + if(gstate[(int)in] == 0) gstate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); + switch(in){ + case gtok_t_switch::TIMING: + { + auto child_context = out.init_switch_timing(context); + load_timing(node, out, child_context, report_error, offset_debug); + out.finish_switch_timing(child_context); + } + break; + case gtok_t_switch::SIZING: + { + float sizing_buf_size; + memset(&sizing_buf_size, 0, sizeof(sizing_buf_size)); + float sizing_mux_trans_size; + memset(&sizing_mux_trans_size, 0, sizeof(sizing_mux_trans_size)); + load_sizing_required_attributes(node, &sizing_buf_size, &sizing_mux_trans_size, report_error); + auto child_context = out.init_switch_sizing(context, sizing_buf_size, sizing_mux_trans_size); + load_sizing(node, out, child_context, report_error, offset_debug); + out.finish_switch_sizing(child_context); + } + break; + default: break; /* Not possible. */ + } + } + std::bitset<2> test_gstate = gstate | std::bitset<2>(0b01); + if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_switch, report_error); + } constexpr int NUM_T_SWITCHES_STATES = 2; constexpr const int NUM_T_SWITCHES_INPUTS = 1; constexpr int gstate_t_switches[NUM_T_SWITCHES_STATES][NUM_T_SWITCHES_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_switches(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t switch_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_switches in = lex_node_t_switches(node.name(), report_error); - next = gstate_t_switches[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_switches[(int)in], gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); - state = next; - switch (in) { - case gtok_t_switches::SWITCH: - switch_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_switches_switch(context, switch_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_switches in = lex_node_t_switches(node.name(), report_error); - next = gstate_t_switches[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_switches[(int)in], gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); - state = next; - switch (in) { - case gtok_t_switches::SWITCH: { - int switch_id; - memset(&switch_id, 0, sizeof(switch_id)); - load_switch_required_attributes(node, &switch_id, report_error); - auto child_context = out.add_switches_switch(context, switch_id); - load_switch(node, out, child_context, report_error, offset_debug); - out.finish_switches_switch(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); +inline void load_switches(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t switch_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_switches in = lex_node_t_switches(node.name(), report_error); + next = gstate_t_switches[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_switches[(int)in], gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); + state = next; + switch(in) { + case gtok_t_switches::SWITCH: + switch_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_switches_switch(context, switch_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_switches in = lex_node_t_switches(node.name(), report_error); + next = gstate_t_switches[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_switches[(int)in], gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); + state = next; + switch(in){ + case gtok_t_switches::SWITCH: + { + int switch_id; + memset(&switch_id, 0, sizeof(switch_id)); + load_switch_required_attributes(node, &switch_id, report_error); + auto child_context = out.add_switches_switch(context, switch_id); + load_switch(node, out, child_context, report_error, offset_debug); + out.finish_switches_switch(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_switches[state], gtok_lookup_t_switches, 1, report_error); + } template -inline void load_segment_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_segment_timing in = lex_attr_t_segment_timing(attr.name(), report_error); - switch (in) { - case atok_t_segment_timing::C_PER_METER: - out.set_segment_timing_C_per_meter(load_float(attr.value(), report_error), context); - break; - case atok_t_segment_timing::R_PER_METER: - out.set_segment_timing_R_per_meter(load_float(attr.value(), report_error), context); - break; - default: - break; /* Not possible. */ - } - } - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_segment_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_segment_timing in = lex_attr_t_segment_timing(attr.name(), report_error); + switch(in){ + case atok_t_segment_timing::C_PER_METER: + out.set_segment_timing_C_per_meter(load_float(attr.value(), report_error), context); + break; + case atok_t_segment_timing::R_PER_METER: + out.set_segment_timing_R_per_meter(load_float(attr.value(), report_error), context); + break; + default: break; /* Not possible. */ + } + } + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_segment(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_segment in = lex_attr_t_segment(attr.name(), report_error); - switch (in) { - case atok_t_segment::ID: - /* Attribute id is already set */ - break; - case atok_t_segment::NAME: - out.set_segment_name(attr.value(), context); - break; - default: - break; /* Not possible. */ - } - } - - std::bitset<1> gstate = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_segment in = lex_node_t_segment(node.name(), report_error); - if (gstate[(int)in] == 0) - gstate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); - switch (in) { - case gtok_t_segment::TIMING: { - auto child_context = out.init_segment_timing(context); - load_segment_timing(node, out, child_context, report_error, offset_debug); - out.finish_segment_timing(child_context); - } break; - default: - break; /* Not possible. */ - } - } - std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); - if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_segment, report_error); +inline void load_segment(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_segment in = lex_attr_t_segment(attr.name(), report_error); + switch(in){ + case atok_t_segment::ID: + /* Attribute id is already set */ + break; + case atok_t_segment::NAME: + out.set_segment_name(attr.value(), context); + break; + default: break; /* Not possible. */ + } + } + + std::bitset<1> gstate = 0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_segment in = lex_node_t_segment(node.name(), report_error); + if(gstate[(int)in] == 0) gstate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); + switch(in){ + case gtok_t_segment::TIMING: + { + auto child_context = out.init_segment_timing(context); + load_segment_timing(node, out, child_context, report_error, offset_debug); + out.finish_segment_timing(child_context); + } + break; + default: break; /* Not possible. */ + } + } + std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); + if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_segment, report_error); + } constexpr int NUM_T_SEGMENTS_STATES = 2; constexpr const int NUM_T_SEGMENTS_INPUTS = 1; constexpr int gstate_t_segments[NUM_T_SEGMENTS_STATES][NUM_T_SEGMENTS_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_segments(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t segment_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_segments in = lex_node_t_segments(node.name(), report_error); - next = gstate_t_segments[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_segments[(int)in], gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); - state = next; - switch (in) { - case gtok_t_segments::SEGMENT: - segment_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_segments_segment(context, segment_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_segments in = lex_node_t_segments(node.name(), report_error); - next = gstate_t_segments[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_segments[(int)in], gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); - state = next; - switch (in) { - case gtok_t_segments::SEGMENT: { - int segment_id; - memset(&segment_id, 0, sizeof(segment_id)); - load_segment_required_attributes(node, &segment_id, report_error); - auto child_context = out.add_segments_segment(context, segment_id); - load_segment(node, out, child_context, report_error, offset_debug); - out.finish_segments_segment(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); +inline void load_segments(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t segment_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_segments in = lex_node_t_segments(node.name(), report_error); + next = gstate_t_segments[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_segments[(int)in], gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); + state = next; + switch(in) { + case gtok_t_segments::SEGMENT: + segment_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_segments_segment(context, segment_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_segments in = lex_node_t_segments(node.name(), report_error); + next = gstate_t_segments[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_segments[(int)in], gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); + state = next; + switch(in){ + case gtok_t_segments::SEGMENT: + { + int segment_id; + memset(&segment_id, 0, sizeof(segment_id)); + load_segment_required_attributes(node, &segment_id, report_error); + auto child_context = out.add_segments_segment(context, segment_id); + load_segment(node, out, child_context, report_error, offset_debug); + out.finish_segments_segment(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_segments[state], gtok_lookup_t_segments, 1, report_error); + } template -inline void load_pin(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - out.set_pin_value(root.child_value(), context); - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_pin(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + out.set_pin_value(root.child_value(), context); + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } constexpr int NUM_T_PIN_CLASS_STATES = 2; constexpr const int NUM_T_PIN_CLASS_INPUTS = 1; constexpr int gstate_t_pin_class[NUM_T_PIN_CLASS_STATES][NUM_T_PIN_CLASS_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_pin_class(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - // Preallocate arrays by counting child nodes (if any) - size_t pin_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_pin_class in = lex_node_t_pin_class(node.name(), report_error); - next = gstate_t_pin_class[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_pin_class[(int)in], gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); - state = next; - switch (in) { - case gtok_t_pin_class::PIN: - pin_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_pin_class_pin(context, pin_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_pin_class in = lex_node_t_pin_class(node.name(), report_error); - next = gstate_t_pin_class[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_pin_class[(int)in], gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); - state = next; - switch (in) { - case gtok_t_pin_class::PIN: { - int pin_ptc; - memset(&pin_ptc, 0, sizeof(pin_ptc)); - load_pin_required_attributes(node, &pin_ptc, report_error); - auto child_context = out.add_pin_class_pin(context, pin_ptc); - load_pin(node, out, child_context, report_error, offset_debug); - out.finish_pin_class_pin(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); +inline void load_pin_class(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + // Preallocate arrays by counting child nodes (if any) + size_t pin_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_pin_class in = lex_node_t_pin_class(node.name(), report_error); + next = gstate_t_pin_class[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_pin_class[(int)in], gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); + state = next; + switch(in) { + case gtok_t_pin_class::PIN: + pin_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_pin_class_pin(context, pin_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_pin_class in = lex_node_t_pin_class(node.name(), report_error); + next = gstate_t_pin_class[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_pin_class[(int)in], gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); + state = next; + switch(in){ + case gtok_t_pin_class::PIN: + { + int pin_ptc; + memset(&pin_ptc, 0, sizeof(pin_ptc)); + load_pin_required_attributes(node, &pin_ptc, report_error); + auto child_context = out.add_pin_class_pin(context, pin_ptc); + load_pin(node, out, child_context, report_error, offset_debug); + out.finish_pin_class_pin(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1, report_error); + } constexpr int NUM_T_BLOCK_TYPE_STATES = 1; constexpr const int NUM_T_BLOCK_TYPE_INPUTS = 1; constexpr int gstate_t_block_type[NUM_T_BLOCK_TYPE_STATES][NUM_T_BLOCK_TYPE_INPUTS] = { - {0}, + {0}, }; template -inline void load_block_type(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_block_type in = lex_attr_t_block_type(attr.name(), report_error); - switch (in) { - case atok_t_block_type::HEIGHT: - /* Attribute height is already set */ - break; - case atok_t_block_type::ID: - /* Attribute id is already set */ - break; - case atok_t_block_type::NAME: - out.set_block_type_name(attr.value(), context); - break; - case atok_t_block_type::WIDTH: - /* Attribute width is already set */ - break; - default: - break; /* Not possible. */ - } - } - - // Preallocate arrays by counting child nodes (if any) - size_t pin_class_count = 0; - { - int next, state = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_block_type in = lex_node_t_block_type(node.name(), report_error); - next = gstate_t_block_type[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_block_type[(int)in], gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); - state = next; - switch (in) { - case gtok_t_block_type::PIN_CLASS: - pin_class_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_block_type_pin_class(context, pin_class_count); - } - int next, state = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_block_type in = lex_node_t_block_type(node.name(), report_error); - next = gstate_t_block_type[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_block_type[(int)in], gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); - state = next; - switch (in) { - case gtok_t_block_type::PIN_CLASS: { - enum_pin_type pin_class_type; - memset(&pin_class_type, 0, sizeof(pin_class_type)); - load_pin_class_required_attributes(node, &pin_class_type, report_error); - auto child_context = out.add_block_type_pin_class(context, pin_class_type); - load_pin_class(node, out, child_context, report_error, offset_debug); - out.finish_block_type_pin_class(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); +inline void load_block_type(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_block_type in = lex_attr_t_block_type(attr.name(), report_error); + switch(in){ + case atok_t_block_type::HEIGHT: + /* Attribute height is already set */ + break; + case atok_t_block_type::ID: + /* Attribute id is already set */ + break; + case atok_t_block_type::NAME: + out.set_block_type_name(attr.value(), context); + break; + case atok_t_block_type::WIDTH: + /* Attribute width is already set */ + break; + default: break; /* Not possible. */ + } + } + + // Preallocate arrays by counting child nodes (if any) + size_t pin_class_count = 0; + { + int next, state=0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_block_type in = lex_node_t_block_type(node.name(), report_error); + next = gstate_t_block_type[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_block_type[(int)in], gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); + state = next; + switch(in) { + case gtok_t_block_type::PIN_CLASS: + pin_class_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_block_type_pin_class(context, pin_class_count); + } + int next, state=0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_block_type in = lex_node_t_block_type(node.name(), report_error); + next = gstate_t_block_type[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_block_type[(int)in], gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); + state = next; + switch(in){ + case gtok_t_block_type::PIN_CLASS: + { + enum_pin_type pin_class_type; + memset(&pin_class_type, 0, sizeof(pin_class_type)); + load_pin_class_required_attributes(node, &pin_class_type, report_error); + auto child_context = out.add_block_type_pin_class(context, pin_class_type); + load_pin_class(node, out, child_context, report_error, offset_debug); + out.finish_block_type_pin_class(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_block_type[state], gtok_lookup_t_block_type, 1, report_error); + } constexpr int NUM_T_BLOCK_TYPES_STATES = 2; constexpr const int NUM_T_BLOCK_TYPES_INPUTS = 1; constexpr int gstate_t_block_types[NUM_T_BLOCK_TYPES_STATES][NUM_T_BLOCK_TYPES_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_block_types(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t block_type_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_block_types in = lex_node_t_block_types(node.name(), report_error); - next = gstate_t_block_types[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_block_types[(int)in], gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); - state = next; - switch (in) { - case gtok_t_block_types::BLOCK_TYPE: - block_type_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_block_types_block_type(context, block_type_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_block_types in = lex_node_t_block_types(node.name(), report_error); - next = gstate_t_block_types[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_block_types[(int)in], gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); - state = next; - switch (in) { - case gtok_t_block_types::BLOCK_TYPE: { - int block_type_height; - memset(&block_type_height, 0, sizeof(block_type_height)); - int block_type_id; - memset(&block_type_id, 0, sizeof(block_type_id)); - int block_type_width; - memset(&block_type_width, 0, sizeof(block_type_width)); - load_block_type_required_attributes(node, &block_type_height, &block_type_id, &block_type_width, report_error); - auto child_context = out.add_block_types_block_type(context, block_type_height, block_type_id, block_type_width); - load_block_type(node, out, child_context, report_error, offset_debug); - out.finish_block_types_block_type(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); +inline void load_block_types(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t block_type_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_block_types in = lex_node_t_block_types(node.name(), report_error); + next = gstate_t_block_types[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_block_types[(int)in], gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); + state = next; + switch(in) { + case gtok_t_block_types::BLOCK_TYPE: + block_type_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_block_types_block_type(context, block_type_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_block_types in = lex_node_t_block_types(node.name(), report_error); + next = gstate_t_block_types[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_block_types[(int)in], gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); + state = next; + switch(in){ + case gtok_t_block_types::BLOCK_TYPE: + { + int block_type_height; + memset(&block_type_height, 0, sizeof(block_type_height)); + int block_type_id; + memset(&block_type_id, 0, sizeof(block_type_id)); + int block_type_width; + memset(&block_type_width, 0, sizeof(block_type_width)); + load_block_type_required_attributes(node, &block_type_height, &block_type_id, &block_type_width, report_error); + auto child_context = out.add_block_types_block_type(context, block_type_height, block_type_id, block_type_width); + load_block_type(node, out, child_context, report_error, offset_debug); + out.finish_block_types_block_type(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_block_types[state], gtok_lookup_t_block_types, 1, report_error); + } template -inline void load_grid_loc(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_grid_loc(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } constexpr int NUM_T_GRID_LOCS_STATES = 2; constexpr const int NUM_T_GRID_LOCS_INPUTS = 1; constexpr int gstate_t_grid_locs[NUM_T_GRID_LOCS_STATES][NUM_T_GRID_LOCS_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_grid_locs(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t grid_loc_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_grid_locs in = lex_node_t_grid_locs(node.name(), report_error); - next = gstate_t_grid_locs[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_grid_locs[(int)in], gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); - state = next; - switch (in) { - case gtok_t_grid_locs::GRID_LOC: - grid_loc_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_grid_locs_grid_loc(context, grid_loc_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_grid_locs in = lex_node_t_grid_locs(node.name(), report_error); - next = gstate_t_grid_locs[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_grid_locs[(int)in], gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); - state = next; - switch (in) { - case gtok_t_grid_locs::GRID_LOC: { - int grid_loc_block_type_id; - memset(&grid_loc_block_type_id, 0, sizeof(grid_loc_block_type_id)); - int grid_loc_height_offset; - memset(&grid_loc_height_offset, 0, sizeof(grid_loc_height_offset)); - int grid_loc_width_offset; - memset(&grid_loc_width_offset, 0, sizeof(grid_loc_width_offset)); - int grid_loc_x; - memset(&grid_loc_x, 0, sizeof(grid_loc_x)); - int grid_loc_y; - memset(&grid_loc_y, 0, sizeof(grid_loc_y)); - load_grid_loc_required_attributes(node, &grid_loc_block_type_id, &grid_loc_height_offset, &grid_loc_width_offset, &grid_loc_x, &grid_loc_y, report_error); - auto child_context = out.add_grid_locs_grid_loc(context, grid_loc_block_type_id, grid_loc_height_offset, grid_loc_width_offset, grid_loc_x, grid_loc_y); - load_grid_loc(node, out, child_context, report_error, offset_debug); - out.finish_grid_locs_grid_loc(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); +inline void load_grid_locs(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t grid_loc_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_grid_locs in = lex_node_t_grid_locs(node.name(), report_error); + next = gstate_t_grid_locs[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_grid_locs[(int)in], gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); + state = next; + switch(in) { + case gtok_t_grid_locs::GRID_LOC: + grid_loc_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_grid_locs_grid_loc(context, grid_loc_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_grid_locs in = lex_node_t_grid_locs(node.name(), report_error); + next = gstate_t_grid_locs[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_grid_locs[(int)in], gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); + state = next; + switch(in){ + case gtok_t_grid_locs::GRID_LOC: + { + int grid_loc_block_type_id; + memset(&grid_loc_block_type_id, 0, sizeof(grid_loc_block_type_id)); + int grid_loc_height_offset; + memset(&grid_loc_height_offset, 0, sizeof(grid_loc_height_offset)); + int grid_loc_width_offset; + memset(&grid_loc_width_offset, 0, sizeof(grid_loc_width_offset)); + int grid_loc_x; + memset(&grid_loc_x, 0, sizeof(grid_loc_x)); + int grid_loc_y; + memset(&grid_loc_y, 0, sizeof(grid_loc_y)); + load_grid_loc_required_attributes(node, &grid_loc_block_type_id, &grid_loc_height_offset, &grid_loc_width_offset, &grid_loc_x, &grid_loc_y, report_error); + auto child_context = out.add_grid_locs_grid_loc(context, grid_loc_block_type_id, grid_loc_height_offset, grid_loc_width_offset, grid_loc_x, grid_loc_y); + load_grid_loc(node, out, child_context, report_error, offset_debug); + out.finish_grid_locs_grid_loc(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1, report_error); + } template -inline void load_node_loc(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node_loc in = lex_attr_t_node_loc(attr.name(), report_error); - switch (in) { - case atok_t_node_loc::PTC: - /* Attribute ptc is already set */ - break; - case atok_t_node_loc::SIDE: - out.set_node_loc_side(lex_enum_loc_side(attr.value(), true, report_error), context); - break; - case atok_t_node_loc::XHIGH: - /* Attribute xhigh is already set */ - break; - case atok_t_node_loc::XLOW: - /* Attribute xlow is already set */ - break; - case atok_t_node_loc::YHIGH: - /* Attribute yhigh is already set */ - break; - case atok_t_node_loc::YLOW: - /* Attribute ylow is already set */ - break; - default: - break; /* Not possible. */ - } - } - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_node_loc(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node_loc in = lex_attr_t_node_loc(attr.name(), report_error); + switch(in){ + case atok_t_node_loc::PTC: + /* Attribute ptc is already set */ + break; + case atok_t_node_loc::SIDE: + out.set_node_loc_side(lex_enum_loc_side(attr.value(), true, report_error), context); + break; + case atok_t_node_loc::XHIGH: + /* Attribute xhigh is already set */ + break; + case atok_t_node_loc::XLOW: + /* Attribute xlow is already set */ + break; + case atok_t_node_loc::YHIGH: + /* Attribute yhigh is already set */ + break; + case atok_t_node_loc::YLOW: + /* Attribute ylow is already set */ + break; + default: break; /* Not possible. */ + } + } + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_node_timing(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_node_timing(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_node_segment(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_node_segment(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } template -inline void load_meta(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_meta in = lex_attr_t_meta(attr.name(), report_error); - switch (in) { - case atok_t_meta::NAME: - out.set_meta_name(attr.value(), context); - break; - default: - break; /* Not possible. */ - } - } - - out.set_meta_value(root.child_value(), context); - if (root.first_child().type() == pugi::node_element) - noreturn_report(report_error, "Unexpected child element in ."); +inline void load_meta(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_meta in = lex_attr_t_meta(attr.name(), report_error); + switch(in){ + case atok_t_meta::NAME: + out.set_meta_name(attr.value(), context); + break; + default: break; /* Not possible. */ + } + } + + out.set_meta_value(root.child_value(), context); + if(root.first_child().type() == pugi::node_element) + noreturn_report(report_error, "Unexpected child element in ."); + } constexpr int NUM_T_METADATA_STATES = 2; constexpr const int NUM_T_METADATA_INPUTS = 1; constexpr int gstate_t_metadata[NUM_T_METADATA_STATES][NUM_T_METADATA_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_metadata(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t meta_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_metadata in = lex_node_t_metadata(node.name(), report_error); - next = gstate_t_metadata[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_metadata[(int)in], gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); - state = next; - switch (in) { - case gtok_t_metadata::META: - meta_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_metadata_meta(context, meta_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_metadata in = lex_node_t_metadata(node.name(), report_error); - next = gstate_t_metadata[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_metadata[(int)in], gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); - state = next; - switch (in) { - case gtok_t_metadata::META: { - auto child_context = out.add_metadata_meta(context); - load_meta(node, out, child_context, report_error, offset_debug); - out.finish_metadata_meta(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); +inline void load_metadata(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t meta_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_metadata in = lex_node_t_metadata(node.name(), report_error); + next = gstate_t_metadata[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_metadata[(int)in], gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); + state = next; + switch(in) { + case gtok_t_metadata::META: + meta_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_metadata_meta(context, meta_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_metadata in = lex_node_t_metadata(node.name(), report_error); + next = gstate_t_metadata[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_metadata[(int)in], gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); + state = next; + switch(in){ + case gtok_t_metadata::META: + { + auto child_context = out.add_metadata_meta(context); + load_meta(node, out, child_context, report_error, offset_debug); + out.finish_metadata_meta(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_metadata[state], gtok_lookup_t_metadata, 1, report_error); + } template -inline void load_node(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_node in = lex_attr_t_node(attr.name(), report_error); - switch (in) { - case atok_t_node::CAPACITY: - /* Attribute capacity is already set */ - break; - case atok_t_node::DIRECTION: - out.set_node_direction(lex_enum_node_direction(attr.value(), true, report_error), context); - break; - case atok_t_node::ID: - /* Attribute id is already set */ - break; - case atok_t_node::TYPE: - /* Attribute type is already set */ - break; - default: - break; /* Not possible. */ - } - } - - std::bitset<4> gstate = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_node in = lex_node_t_node(node.name(), report_error); - if (gstate[(int)in] == 0) - gstate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); - switch (in) { - case gtok_t_node::LOC: { - int node_loc_ptc; - memset(&node_loc_ptc, 0, sizeof(node_loc_ptc)); - int node_loc_xhigh; - memset(&node_loc_xhigh, 0, sizeof(node_loc_xhigh)); - int node_loc_xlow; - memset(&node_loc_xlow, 0, sizeof(node_loc_xlow)); - int node_loc_yhigh; - memset(&node_loc_yhigh, 0, sizeof(node_loc_yhigh)); - int node_loc_ylow; - memset(&node_loc_ylow, 0, sizeof(node_loc_ylow)); - load_node_loc_required_attributes(node, &node_loc_ptc, &node_loc_xhigh, &node_loc_xlow, &node_loc_yhigh, &node_loc_ylow, report_error); - auto child_context = out.init_node_loc(context, node_loc_ptc, node_loc_xhigh, node_loc_xlow, node_loc_yhigh, node_loc_ylow); - load_node_loc(node, out, child_context, report_error, offset_debug); - out.finish_node_loc(child_context); - } break; - case gtok_t_node::TIMING: { - float node_timing_C; - memset(&node_timing_C, 0, sizeof(node_timing_C)); - float node_timing_R; - memset(&node_timing_R, 0, sizeof(node_timing_R)); - load_node_timing_required_attributes(node, &node_timing_C, &node_timing_R, report_error); - auto child_context = out.init_node_timing(context, node_timing_C, node_timing_R); - load_node_timing(node, out, child_context, report_error, offset_debug); - out.finish_node_timing(child_context); - } break; - case gtok_t_node::SEGMENT: { - int node_segment_segment_id; - memset(&node_segment_segment_id, 0, sizeof(node_segment_segment_id)); - load_node_segment_required_attributes(node, &node_segment_segment_id, report_error); - auto child_context = out.init_node_segment(context, node_segment_segment_id); - load_node_segment(node, out, child_context, report_error, offset_debug); - out.finish_node_segment(child_context); - } break; - case gtok_t_node::METADATA: { - auto child_context = out.init_node_metadata(context); - load_metadata(node, out, child_context, report_error, offset_debug); - out.finish_node_metadata(child_context); - } break; - default: - break; /* Not possible. */ - } - } - std::bitset<4> test_gstate = gstate | std::bitset<4>(0b1110); - if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_node, report_error); +inline void load_node(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_node in = lex_attr_t_node(attr.name(), report_error); + switch(in){ + case atok_t_node::CAPACITY: + /* Attribute capacity is already set */ + break; + case atok_t_node::DIRECTION: + out.set_node_direction(lex_enum_node_direction(attr.value(), true, report_error), context); + break; + case atok_t_node::ID: + /* Attribute id is already set */ + break; + case atok_t_node::TYPE: + /* Attribute type is already set */ + break; + default: break; /* Not possible. */ + } + } + + std::bitset<4> gstate = 0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_node in = lex_node_t_node(node.name(), report_error); + if(gstate[(int)in] == 0) gstate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); + switch(in){ + case gtok_t_node::LOC: + { + int node_loc_ptc; + memset(&node_loc_ptc, 0, sizeof(node_loc_ptc)); + int node_loc_xhigh; + memset(&node_loc_xhigh, 0, sizeof(node_loc_xhigh)); + int node_loc_xlow; + memset(&node_loc_xlow, 0, sizeof(node_loc_xlow)); + int node_loc_yhigh; + memset(&node_loc_yhigh, 0, sizeof(node_loc_yhigh)); + int node_loc_ylow; + memset(&node_loc_ylow, 0, sizeof(node_loc_ylow)); + load_node_loc_required_attributes(node, &node_loc_ptc, &node_loc_xhigh, &node_loc_xlow, &node_loc_yhigh, &node_loc_ylow, report_error); + auto child_context = out.init_node_loc(context, node_loc_ptc, node_loc_xhigh, node_loc_xlow, node_loc_yhigh, node_loc_ylow); + load_node_loc(node, out, child_context, report_error, offset_debug); + out.finish_node_loc(child_context); + } + break; + case gtok_t_node::TIMING: + { + float node_timing_C; + memset(&node_timing_C, 0, sizeof(node_timing_C)); + float node_timing_R; + memset(&node_timing_R, 0, sizeof(node_timing_R)); + load_node_timing_required_attributes(node, &node_timing_C, &node_timing_R, report_error); + auto child_context = out.init_node_timing(context, node_timing_C, node_timing_R); + load_node_timing(node, out, child_context, report_error, offset_debug); + out.finish_node_timing(child_context); + } + break; + case gtok_t_node::SEGMENT: + { + int node_segment_segment_id; + memset(&node_segment_segment_id, 0, sizeof(node_segment_segment_id)); + load_node_segment_required_attributes(node, &node_segment_segment_id, report_error); + auto child_context = out.init_node_segment(context, node_segment_segment_id); + load_node_segment(node, out, child_context, report_error, offset_debug); + out.finish_node_segment(child_context); + } + break; + case gtok_t_node::METADATA: + { + auto child_context = out.init_node_metadata(context); + load_metadata(node, out, child_context, report_error, offset_debug); + out.finish_node_metadata(child_context); + } + break; + default: break; /* Not possible. */ + } + } + std::bitset<4> test_gstate = gstate | std::bitset<4>(0b1110); + if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_node, report_error); + } constexpr int NUM_T_RR_NODES_STATES = 2; constexpr const int NUM_T_RR_NODES_INPUTS = 1; constexpr int gstate_t_rr_nodes[NUM_T_RR_NODES_STATES][NUM_T_RR_NODES_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_rr_nodes(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t node_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_rr_nodes in = lex_node_t_rr_nodes(node.name(), report_error); - next = gstate_t_rr_nodes[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_rr_nodes[(int)in], gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); - state = next; - switch (in) { - case gtok_t_rr_nodes::NODE: - node_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_rr_nodes_node(context, node_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_rr_nodes in = lex_node_t_rr_nodes(node.name(), report_error); - next = gstate_t_rr_nodes[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_rr_nodes[(int)in], gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); - state = next; - switch (in) { - case gtok_t_rr_nodes::NODE: { - unsigned int node_capacity; - memset(&node_capacity, 0, sizeof(node_capacity)); - unsigned int node_id; - memset(&node_id, 0, sizeof(node_id)); - enum_node_type node_type; - memset(&node_type, 0, sizeof(node_type)); - load_node_required_attributes(node, &node_capacity, &node_id, &node_type, report_error); - auto child_context = out.add_rr_nodes_node(context, node_capacity, node_id, node_type); - load_node(node, out, child_context, report_error, offset_debug); - out.finish_rr_nodes_node(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); +inline void load_rr_nodes(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t node_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_rr_nodes in = lex_node_t_rr_nodes(node.name(), report_error); + next = gstate_t_rr_nodes[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_rr_nodes[(int)in], gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); + state = next; + switch(in) { + case gtok_t_rr_nodes::NODE: + node_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_rr_nodes_node(context, node_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_rr_nodes in = lex_node_t_rr_nodes(node.name(), report_error); + next = gstate_t_rr_nodes[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_rr_nodes[(int)in], gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); + state = next; + switch(in){ + case gtok_t_rr_nodes::NODE: + { + unsigned int node_capacity; + memset(&node_capacity, 0, sizeof(node_capacity)); + unsigned int node_id; + memset(&node_id, 0, sizeof(node_id)); + enum_node_type node_type; + memset(&node_type, 0, sizeof(node_type)); + load_node_required_attributes(node, &node_capacity, &node_id, &node_type, report_error); + auto child_context = out.add_rr_nodes_node(context, node_capacity, node_id, node_type); + load_node(node, out, child_context, report_error, offset_debug); + out.finish_rr_nodes_node(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1, report_error); + } template -inline void load_edge(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - std::bitset<1> gstate = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_edge in = lex_node_t_edge(node.name(), report_error); - if (gstate[(int)in] == 0) - gstate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); - switch (in) { - case gtok_t_edge::METADATA: { - auto child_context = out.init_edge_metadata(context); - load_metadata(node, out, child_context, report_error, offset_debug); - out.finish_edge_metadata(child_context); - } break; - default: - break; /* Not possible. */ - } - } - std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); - if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_edge, report_error); +inline void load_edge(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + + std::bitset<1> gstate = 0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_edge in = lex_node_t_edge(node.name(), report_error); + if(gstate[(int)in] == 0) gstate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); + switch(in){ + case gtok_t_edge::METADATA: + { + auto child_context = out.init_edge_metadata(context); + load_metadata(node, out, child_context, report_error, offset_debug); + out.finish_edge_metadata(child_context); + } + break; + default: break; /* Not possible. */ + } + } + std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); + if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_edge, report_error); + } constexpr int NUM_T_RR_EDGES_STATES = 2; constexpr const int NUM_T_RR_EDGES_INPUTS = 1; constexpr int gstate_t_rr_edges[NUM_T_RR_EDGES_STATES][NUM_T_RR_EDGES_INPUTS] = { - {0}, - {0}, + {0}, + {0}, }; template -inline void load_rr_edges(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - if (root.first_attribute()) - noreturn_report(report_error, "Unexpected attribute in ."); - - // Preallocate arrays by counting child nodes (if any) - size_t edge_count = 0; - { - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_rr_edges in = lex_node_t_rr_edges(node.name(), report_error); - next = gstate_t_rr_edges[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_rr_edges[(int)in], gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); - state = next; - switch (in) { - case gtok_t_rr_edges::EDGE: - edge_count += 1; - break; - default: - break; /* Not possible. */ - } - } - - out.preallocate_rr_edges_edge(context, edge_count); - } - int next, state = 1; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_rr_edges in = lex_node_t_rr_edges(node.name(), report_error); - next = gstate_t_rr_edges[state][(int)in]; - if (next == -1) - dfa_error(gtok_lookup_t_rr_edges[(int)in], gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); - state = next; - switch (in) { - case gtok_t_rr_edges::EDGE: { - unsigned int edge_sink_node; - memset(&edge_sink_node, 0, sizeof(edge_sink_node)); - unsigned int edge_src_node; - memset(&edge_src_node, 0, sizeof(edge_src_node)); - unsigned int edge_switch_id; - memset(&edge_switch_id, 0, sizeof(edge_switch_id)); - load_edge_required_attributes(node, &edge_sink_node, &edge_src_node, &edge_switch_id, report_error); - auto child_context = out.add_rr_edges_edge(context, edge_sink_node, edge_src_node, edge_switch_id); - load_edge(node, out, child_context, report_error, offset_debug); - out.finish_rr_edges_edge(child_context); - } break; - default: - break; /* Not possible. */ - } - } - if (state != 0) dfa_error("end of input", gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); +inline void load_rr_edges(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + if(root.first_attribute()) + noreturn_report(report_error, "Unexpected attribute in ."); + + // Preallocate arrays by counting child nodes (if any) + size_t edge_count = 0; + { + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { + *offset_debug = node.offset_debug(); + gtok_t_rr_edges in = lex_node_t_rr_edges(node.name(), report_error); + next = gstate_t_rr_edges[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_rr_edges[(int)in], gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); + state = next; + switch(in) { + case gtok_t_rr_edges::EDGE: + edge_count += 1; + break; + default: break; /* Not possible. */ + } + } + + out.preallocate_rr_edges_edge(context, edge_count); + } + int next, state=1; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_rr_edges in = lex_node_t_rr_edges(node.name(), report_error); + next = gstate_t_rr_edges[state][(int)in]; + if(next == -1) + dfa_error(gtok_lookup_t_rr_edges[(int)in], gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); + state = next; + switch(in){ + case gtok_t_rr_edges::EDGE: + { + unsigned int edge_sink_node; + memset(&edge_sink_node, 0, sizeof(edge_sink_node)); + unsigned int edge_src_node; + memset(&edge_src_node, 0, sizeof(edge_src_node)); + unsigned int edge_switch_id; + memset(&edge_switch_id, 0, sizeof(edge_switch_id)); + load_edge_required_attributes(node, &edge_sink_node, &edge_src_node, &edge_switch_id, report_error); + auto child_context = out.add_rr_edges_edge(context, edge_sink_node, edge_src_node, edge_switch_id); + load_edge(node, out, child_context, report_error, offset_debug); + out.finish_rr_edges_edge(child_context); + } + break; + default: break; /* Not possible. */ + } + } + if(state != 0) dfa_error("end of input", gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1, report_error); + } template -inline void load_rr_graph(const pugi::xml_node& root, T& out, Context& context, const std::function* report_error, ptrdiff_t* offset_debug) { - (void)root; - (void)out; - (void)context; - (void)report_error; - // Update current file offset in case an error is encountered. - *offset_debug = root.offset_debug(); - - for (pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()) { - atok_t_rr_graph in = lex_attr_t_rr_graph(attr.name(), report_error); - switch (in) { - case atok_t_rr_graph::TOOL_COMMENT: - out.set_rr_graph_tool_comment(attr.value(), context); - break; - case atok_t_rr_graph::TOOL_NAME: - out.set_rr_graph_tool_name(attr.value(), context); - break; - case atok_t_rr_graph::TOOL_VERSION: - out.set_rr_graph_tool_version(attr.value(), context); - break; - default: - break; /* Not possible. */ - } - } - - std::bitset<7> gstate = 0; - for (pugi::xml_node node = root.first_child(); node; node = node.next_sibling()) { - *offset_debug = node.offset_debug(); - gtok_t_rr_graph in = lex_node_t_rr_graph(node.name(), report_error); - if (gstate[(int)in] == 0) - gstate[(int)in] = 1; - else - noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); - switch (in) { - case gtok_t_rr_graph::CHANNELS: { - auto child_context = out.init_rr_graph_channels(context); - load_channels(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_channels(child_context); - } break; - case gtok_t_rr_graph::SWITCHES: { - auto child_context = out.init_rr_graph_switches(context); - load_switches(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_switches(child_context); - } break; - case gtok_t_rr_graph::SEGMENTS: { - auto child_context = out.init_rr_graph_segments(context); - load_segments(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_segments(child_context); - } break; - case gtok_t_rr_graph::BLOCK_TYPES: { - auto child_context = out.init_rr_graph_block_types(context); - load_block_types(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_block_types(child_context); - } break; - case gtok_t_rr_graph::GRID: { - auto child_context = out.init_rr_graph_grid(context); - load_grid_locs(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_grid(child_context); - } break; - case gtok_t_rr_graph::RR_NODES: { - auto child_context = out.init_rr_graph_rr_nodes(context); - load_rr_nodes(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_rr_nodes(child_context); - } break; - case gtok_t_rr_graph::RR_EDGES: { - auto child_context = out.init_rr_graph_rr_edges(context); - load_rr_edges(node, out, child_context, report_error, offset_debug); - out.finish_rr_graph_rr_edges(child_context); - } break; - default: - break; /* Not possible. */ - } - } - std::bitset<7> test_gstate = gstate | std::bitset<7>(0b0000000); - if (!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_rr_graph, report_error); +inline void load_rr_graph(const pugi::xml_node &root, T &out, Context &context, const std::function *report_error, ptrdiff_t *offset_debug){ + (void)root; + (void)out; + (void)context; + (void)report_error; + // Update current file offset in case an error is encountered. + *offset_debug = root.offset_debug(); + + for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ + atok_t_rr_graph in = lex_attr_t_rr_graph(attr.name(), report_error); + switch(in){ + case atok_t_rr_graph::TOOL_COMMENT: + out.set_rr_graph_tool_comment(attr.value(), context); + break; + case atok_t_rr_graph::TOOL_NAME: + out.set_rr_graph_tool_name(attr.value(), context); + break; + case atok_t_rr_graph::TOOL_VERSION: + out.set_rr_graph_tool_version(attr.value(), context); + break; + default: break; /* Not possible. */ + } + } + + std::bitset<7> gstate = 0; + for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ + *offset_debug = node.offset_debug(); + gtok_t_rr_graph in = lex_node_t_rr_graph(node.name(), report_error); + if(gstate[(int)in] == 0) gstate[(int)in] = 1; + else noreturn_report(report_error, ("Duplicate element " + std::string(node.name()) + " in .").c_str()); + switch(in){ + case gtok_t_rr_graph::CHANNELS: + { + auto child_context = out.init_rr_graph_channels(context); + load_channels(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_channels(child_context); + } + break; + case gtok_t_rr_graph::SWITCHES: + { + auto child_context = out.init_rr_graph_switches(context); + load_switches(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_switches(child_context); + } + break; + case gtok_t_rr_graph::SEGMENTS: + { + auto child_context = out.init_rr_graph_segments(context); + load_segments(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_segments(child_context); + } + break; + case gtok_t_rr_graph::BLOCK_TYPES: + { + auto child_context = out.init_rr_graph_block_types(context); + load_block_types(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_block_types(child_context); + } + break; + case gtok_t_rr_graph::GRID: + { + auto child_context = out.init_rr_graph_grid(context); + load_grid_locs(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_grid(child_context); + } + break; + case gtok_t_rr_graph::RR_NODES: + { + auto child_context = out.init_rr_graph_rr_nodes(context); + load_rr_nodes(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_rr_nodes(child_context); + } + break; + case gtok_t_rr_graph::RR_EDGES: + { + auto child_context = out.init_rr_graph_rr_edges(context); + load_rr_edges(node, out, child_context, report_error, offset_debug); + out.finish_rr_graph_rr_edges(child_context); + } + break; + default: break; /* Not possible. */ + } + } + std::bitset<7> test_gstate = gstate | std::bitset<7>(0b0000000); + if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_rr_graph, report_error); + } + /* Internal writing functions, which uxsdcxx uses to write out a class. */ template -inline void write_channels(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - auto child_context = in.get_channels_channel(context); - os << "\n"; - } - { - for (size_t i = 0, n = in.num_channels_x_list(context); i < n; i++) { - auto child_context = in.get_channels_x_list(i, context); - os << "\n"; - } - } - { - for (size_t i = 0, n = in.num_channels_y_list(context); i < n; i++) { - auto child_context = in.get_channels_y_list(i, context); - os << "\n"; - } - } +inline void write_channels(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + auto child_context = in.get_channels_channel(context); + os << "\n"; + } + { + for(size_t i=0, n=in.num_channels_x_list(context); i\n"; + } + } + { + for(size_t i=0, n=in.num_channels_y_list(context); i\n"; + } + } } template -inline void write_switch(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - if (in.has_switch_timing(context)) { - auto child_context = in.get_switch_timing(context); - os << "\n"; - } - } - { - auto child_context = in.get_switch_sizing(context); - os << "\n"; - } +inline void write_switch(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + if(in.has_switch_timing(context)){ + auto child_context = in.get_switch_timing(context); + os << "\n"; + } + } + { + auto child_context = in.get_switch_sizing(context); + os << "\n"; + } } template -inline void write_switches(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_switches_switch(context); i < n; i++) { - auto child_context = in.get_switches_switch(i, context); - os << ""; - write_switch(in, os, child_context); - os << "\n"; - } - } +inline void write_switches(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_switches_switch(context); i"; + write_switch(in, os, child_context); + os << "\n"; + } + } } template -inline void write_segment(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - if (in.has_segment_timing(context)) { - auto child_context = in.get_segment_timing(context); - os << "\n"; - } - } +inline void write_segment(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + if(in.has_segment_timing(context)){ + auto child_context = in.get_segment_timing(context); + os << "\n"; + } + } } template -inline void write_segments(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_segments_segment(context); i < n; i++) { - auto child_context = in.get_segments_segment(i, context); - os << ""; - write_segment(in, os, child_context); - os << "\n"; - } - } +inline void write_segments(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_segments_segment(context); i"; + write_segment(in, os, child_context); + os << "\n"; + } + } } template -inline void write_pin(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - os << in.get_pin_value(context); +inline void write_pin(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + os << in.get_pin_value(context); } template -inline void write_pin_class(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_pin_class_pin(context); i < n; i++) { - auto child_context = in.get_pin_class_pin(i, context); - os << ""; - write_pin(in, os, child_context); - os << "\n"; - } - } +inline void write_pin_class(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_pin_class_pin(context); i"; + write_pin(in, os, child_context); + os << "\n"; + } + } } template -inline void write_block_type(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_block_type_pin_class(context); i < n; i++) { - auto child_context = in.get_block_type_pin_class(i, context); - os << ""; - write_pin_class(in, os, child_context); - os << "\n"; - } - } +inline void write_block_type(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_block_type_pin_class(context); i"; + write_pin_class(in, os, child_context); + os << "\n"; + } + } } template -inline void write_block_types(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_block_types_block_type(context); i < n; i++) { - auto child_context = in.get_block_types_block_type(i, context); - os << ""; - write_block_type(in, os, child_context); - os << "\n"; - } - } +inline void write_block_types(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_block_types_block_type(context); i"; + write_block_type(in, os, child_context); + os << "\n"; + } + } } template -inline void write_grid_locs(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_grid_locs_grid_loc(context); i < n; i++) { - auto child_context = in.get_grid_locs_grid_loc(i, context); - os << "\n"; - } - } +inline void write_grid_locs(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_grid_locs_grid_loc(context); i\n"; + } + } } template -inline void write_meta(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - os << in.get_meta_value(context); +inline void write_meta(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + os << in.get_meta_value(context); } template -inline void write_metadata(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_metadata_meta(context); i < n; i++) { - auto child_context = in.get_metadata_meta(i, context); - os << ""; - write_meta(in, os, child_context); - os << "\n"; - } - } +inline void write_metadata(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_metadata_meta(context); i"; + write_meta(in, os, child_context); + os << "\n"; + } + } } template -inline void write_node(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - auto child_context = in.get_node_loc(context); - os << "\n"; - } - { - if (in.has_node_timing(context)) { - auto child_context = in.get_node_timing(context); - os << "\n"; - } - } - { - if (in.has_node_segment(context)) { - auto child_context = in.get_node_segment(context); - os << "\n"; - } - } - { - if (in.has_node_metadata(context)) { - auto child_context = in.get_node_metadata(context); - os << "\n"; - write_metadata(in, os, child_context); - os << "\n"; - } - } +inline void write_node(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + auto child_context = in.get_node_loc(context); + os << "\n"; + } + { + if(in.has_node_timing(context)){ + auto child_context = in.get_node_timing(context); + os << "\n"; + } + } + { + if(in.has_node_segment(context)){ + auto child_context = in.get_node_segment(context); + os << "\n"; + } + } + { + if(in.has_node_metadata(context)){ + auto child_context = in.get_node_metadata(context); + os << "\n"; + write_metadata(in, os, child_context); + os << "\n"; + } + } } template -inline void write_rr_nodes(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_rr_nodes_node(context); i < n; i++) { - auto child_context = in.get_rr_nodes_node(i, context); - os << ""; - write_node(in, os, child_context); - os << "\n"; - } - } +inline void write_rr_nodes(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_rr_nodes_node(context); i"; + write_node(in, os, child_context); + os << "\n"; + } + } } template -inline void write_edge(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - if (in.has_edge_metadata(context)) { - auto child_context = in.get_edge_metadata(context); - os << "\n"; - write_metadata(in, os, child_context); - os << "\n"; - } - } +inline void write_edge(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + if(in.has_edge_metadata(context)){ + auto child_context = in.get_edge_metadata(context); + os << "\n"; + write_metadata(in, os, child_context); + os << "\n"; + } + } } template -inline void write_rr_edges(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - for (size_t i = 0, n = in.num_rr_edges_edge(context); i < n; i++) { - auto child_context = in.get_rr_edges_edge(i, context); - os << ""; - write_edge(in, os, child_context); - os << "\n"; - } - } +inline void write_rr_edges(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + for(size_t i=0, n=in.num_rr_edges_edge(context); i"; + write_edge(in, os, child_context); + os << "\n"; + } + } } template -inline void write_rr_graph(T& in, std::ostream& os, Context& context) { - (void)in; - (void)os; - (void)context; - { - auto child_context = in.get_rr_graph_channels(context); - os << "\n"; - write_channels(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_switches(context); - os << "\n"; - write_switches(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_segments(context); - os << "\n"; - write_segments(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_block_types(context); - os << "\n"; - write_block_types(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_grid(context); - os << "\n"; - write_grid_locs(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_rr_nodes(context); - os << "\n"; - write_rr_nodes(in, os, child_context); - os << "\n"; - } - { - auto child_context = in.get_rr_graph_rr_edges(context); - os << "\n"; - write_rr_edges(in, os, child_context); - os << "\n"; - } +inline void write_rr_graph(T &in, std::ostream &os, Context &context){ + (void)in; + (void)os; + (void)context; + { + auto child_context = in.get_rr_graph_channels(context); + os << "\n"; + write_channels(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_switches(context); + os << "\n"; + write_switches(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_segments(context); + os << "\n"; + write_segments(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_block_types(context); + os << "\n"; + write_block_types(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_grid(context); + os << "\n"; + write_grid_locs(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_rr_nodes(context); + os << "\n"; + write_rr_nodes(in, os, child_context); + os << "\n"; + } + { + auto child_context = in.get_rr_graph_rr_edges(context); + os << "\n"; + write_rr_edges(in, os, child_context); + os << "\n"; + } } -inline void dfa_error(const char* wrong, const int* states, const char* const* lookup, int len, const std::function* report_error) { - std::vector expected; - for (int i = 0; i < len; i++) { - if (states[i] != -1) expected.push_back(lookup[i]); - } +inline void dfa_error(const char *wrong, const int *states, const char * const *lookup, int len, const std::function * report_error){ + std::vector expected; + for(int i=0; i -inline void all_error(std::bitset gstate, const char* const* lookup, const std::function* report_error) { - std::vector missing; - for (unsigned int i = 0; i < N; i++) { - if (gstate[i] == 0) missing.push_back(lookup[i]); - } +inline void all_error(std::bitset gstate, const char * const *lookup, const std::function * report_error){ + std::vector missing; + for(unsigned int i=0; i -inline void attr_error(std::bitset astate, const char* const* lookup, const std::function* report_error) { - std::vector missing; - for (unsigned int i = 0; i < N; i++) { - if (astate[i] == 0) missing.push_back(lookup[i]); - } +inline void attr_error(std::bitset astate, const char * const *lookup, const std::function * report_error){ + std::vector missing; + for(unsigned int i=0; i f(fopen(filename, "rb"), fclose); - - if (!f) { - throw std::runtime_error(std::string("Failed to open file") + filename); - } - - int current_line = 1; - std::ptrdiff_t offset = 0; - std::ptrdiff_t last_line_offset = 0; - std::ptrdiff_t current_line_offset = 0; - - char buffer[1024]; - std::size_t size; - - while ((size = fread(buffer, 1, sizeof(buffer), f.get())) > 0) { - for (std::size_t i = 0; i < size; ++i) { - if (buffer[i] == '\n') { - current_line += 1; - last_line_offset = current_line_offset; - current_line_offset = offset + i; - - if (target_offset < current_line_offset) { - if (target_offset < last_line_offset) { - throw std::runtime_error("Assertion violation"); - } - - *line = current_line - 1; - *col = target_offset - last_line_offset; - return; - } - } - } - - offset += size; - } - - *line = current_line; - *col = target_offset - current_line_offset; +inline void get_line_number(const char *filename, std::ptrdiff_t target_offset, int * line, int * col) { + std::unique_ptr f(fopen(filename, "rb"), fclose); + + if (!f) { + throw std::runtime_error(std::string("Failed to open file") + filename); + } + + int current_line = 1; + std::ptrdiff_t offset = 0; + std::ptrdiff_t last_line_offset = 0; + std::ptrdiff_t current_line_offset = 0; + + char buffer[1024]; + std::size_t size; + + while ((size = fread(buffer, 1, sizeof(buffer), f.get())) > 0) { + for (std::size_t i = 0; i < size; ++i) { + if (buffer[i] == '\n') { + current_line += 1; + last_line_offset = current_line_offset; + current_line_offset = offset + i; + + if(target_offset < current_line_offset) { + if(target_offset < last_line_offset) { + throw std::runtime_error("Assertion violation"); + } + + *line = current_line - 1; + *col = target_offset - last_line_offset; + return; + } + } + } + + offset += size; + } + + *line = current_line; + *col = target_offset - current_line_offset; } + } /* namespace uxsd */ diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h index 8474e458e00..c890e738696 100644 --- a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h +++ b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h @@ -4,9 +4,9 @@ * https://github.com/duck2/uxsdcxx * Modify only if your build process doesn't involve regenerating this file. * - * Cmdline: uxsdcxx/uxsdcap.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * md5sum of input file: cd57d47fc9dfa62c7030397ca759217e + * Cmdline: uxsdcxx/uxsdcap.py /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * Input file: /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * md5sum of input file: 41df83ecf127a53590711ddec605742a */ #include @@ -23,1249 +23,1260 @@ /* All uxsdcxx functions and structs live in this namespace. */ namespace uxsd { /* Declarations for internal load functions for the complex types. */ -template -void load_channel_capnp_type(const ucap::Channel::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_x_list_capnp_type(const ucap::XList::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_y_list_capnp_type(const ucap::YList::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_channels_capnp_type(const ucap::Channels::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_timing_capnp_type(const ucap::Timing::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_sizing_capnp_type(const ucap::Sizing::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_switch_capnp_type(const ucap::Switch::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_switches_capnp_type(const ucap::Switches::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_segment_timing_capnp_type(const ucap::SegmentTiming::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_segment_capnp_type(const ucap::Segment::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_segments_capnp_type(const ucap::Segments::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_pin_capnp_type(const ucap::Pin::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_pin_class_capnp_type(const ucap::PinClass::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_block_type_capnp_type(const ucap::BlockType::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_block_types_capnp_type(const ucap::BlockTypes::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_grid_loc_capnp_type(const ucap::GridLoc::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_grid_locs_capnp_type(const ucap::GridLocs::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_node_loc_capnp_type(const ucap::NodeLoc::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_node_timing_capnp_type(const ucap::NodeTiming::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_node_segment_capnp_type(const ucap::NodeSegment::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_meta_capnp_type(const ucap::Meta::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_metadata_capnp_type(const ucap::Metadata::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_node_capnp_type(const ucap::Node::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_rr_nodes_capnp_type(const ucap::RrNodes::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_edge_capnp_type(const ucap::Edge::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_rr_edges_capnp_type(const ucap::RrEdges::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); -template -void load_rr_graph_capnp_type(const ucap::RrGraph::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack); +template +void load_channel_capnp_type(const ucap::Channel::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_x_list_capnp_type(const ucap::XList::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_y_list_capnp_type(const ucap::YList::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_channels_capnp_type(const ucap::Channels::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_timing_capnp_type(const ucap::Timing::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_sizing_capnp_type(const ucap::Sizing::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_switch_capnp_type(const ucap::Switch::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_switches_capnp_type(const ucap::Switches::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_segment_timing_capnp_type(const ucap::SegmentTiming::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_segment_capnp_type(const ucap::Segment::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_segments_capnp_type(const ucap::Segments::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_pin_capnp_type(const ucap::Pin::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_pin_class_capnp_type(const ucap::PinClass::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_block_type_capnp_type(const ucap::BlockType::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_block_types_capnp_type(const ucap::BlockTypes::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_grid_loc_capnp_type(const ucap::GridLoc::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_grid_locs_capnp_type(const ucap::GridLocs::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_node_loc_capnp_type(const ucap::NodeLoc::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_node_timing_capnp_type(const ucap::NodeTiming::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_node_segment_capnp_type(const ucap::NodeSegment::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_meta_capnp_type(const ucap::Meta::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_metadata_capnp_type(const ucap::Metadata::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_node_capnp_type(const ucap::Node::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_rr_nodes_capnp_type(const ucap::RrNodes::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_edge_capnp_type(const ucap::Edge::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_rr_edges_capnp_type(const ucap::RrEdges::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); +template +void load_rr_graph_capnp_type(const ucap::RrGraph::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack); /* Declarations for internal write functions for the complex types. */ -template -inline void write_channels_capnp_type(T& in, ucap::Channels::Builder& root, Context& context); -template -inline void write_switch_capnp_type(T& in, ucap::Switch::Builder& root, Context& context); -template -inline void write_switches_capnp_type(T& in, ucap::Switches::Builder& root, Context& context); -template -inline void write_segment_capnp_type(T& in, ucap::Segment::Builder& root, Context& context); -template -inline void write_segments_capnp_type(T& in, ucap::Segments::Builder& root, Context& context); -template -inline void write_pin_capnp_type(T& in, ucap::Pin::Builder& root, Context& context); -template -inline void write_pin_class_capnp_type(T& in, ucap::PinClass::Builder& root, Context& context); -template -inline void write_block_type_capnp_type(T& in, ucap::BlockType::Builder& root, Context& context); -template -inline void write_block_types_capnp_type(T& in, ucap::BlockTypes::Builder& root, Context& context); -template -inline void write_grid_locs_capnp_type(T& in, ucap::GridLocs::Builder& root, Context& context); -template -inline void write_meta_capnp_type(T& in, ucap::Meta::Builder& root, Context& context); -template -inline void write_metadata_capnp_type(T& in, ucap::Metadata::Builder& root, Context& context); -template -inline void write_node_capnp_type(T& in, ucap::Node::Builder& root, Context& context); -template -inline void write_rr_nodes_capnp_type(T& in, ucap::RrNodes::Builder& root, Context& context); -template -inline void write_edge_capnp_type(T& in, ucap::Edge::Builder& root, Context& context); -template -inline void write_rr_edges_capnp_type(T& in, ucap::RrEdges::Builder& root, Context& context); -template -inline void write_rr_graph_capnp_type(T& in, ucap::RrGraph::Builder& root, Context& context); +template +inline void write_channels_capnp_type(T &in, ucap::Channels::Builder &root, Context &context); +template +inline void write_switch_capnp_type(T &in, ucap::Switch::Builder &root, Context &context); +template +inline void write_switches_capnp_type(T &in, ucap::Switches::Builder &root, Context &context); +template +inline void write_segment_capnp_type(T &in, ucap::Segment::Builder &root, Context &context); +template +inline void write_segments_capnp_type(T &in, ucap::Segments::Builder &root, Context &context); +template +inline void write_pin_capnp_type(T &in, ucap::Pin::Builder &root, Context &context); +template +inline void write_pin_class_capnp_type(T &in, ucap::PinClass::Builder &root, Context &context); +template +inline void write_block_type_capnp_type(T &in, ucap::BlockType::Builder &root, Context &context); +template +inline void write_block_types_capnp_type(T &in, ucap::BlockTypes::Builder &root, Context &context); +template +inline void write_grid_locs_capnp_type(T &in, ucap::GridLocs::Builder &root, Context &context); +template +inline void write_meta_capnp_type(T &in, ucap::Meta::Builder &root, Context &context); +template +inline void write_metadata_capnp_type(T &in, ucap::Metadata::Builder &root, Context &context); +template +inline void write_node_capnp_type(T &in, ucap::Node::Builder &root, Context &context); +template +inline void write_rr_nodes_capnp_type(T &in, ucap::RrNodes::Builder &root, Context &context); +template +inline void write_edge_capnp_type(T &in, ucap::Edge::Builder &root, Context &context); +template +inline void write_rr_edges_capnp_type(T &in, ucap::RrEdges::Builder &root, Context &context); +template +inline void write_rr_graph_capnp_type(T &in, ucap::RrGraph::Builder &root, Context &context); /* Enum conversions from uxsd to ucap */ -inline enum_switch_type conv_enum_switch_type(ucap::SwitchType e, const std::function* report_error) { - switch (e) { - case ucap::SwitchType::UXSD_INVALID: - return enum_switch_type::UXSD_INVALID; - case ucap::SwitchType::MUX: - return enum_switch_type::MUX; - case ucap::SwitchType::TRISTATE: - return enum_switch_type::TRISTATE; - case ucap::SwitchType::PASS_GATE: - return enum_switch_type::PASS_GATE; - case ucap::SwitchType::SHORT: - return enum_switch_type::SHORT; - case ucap::SwitchType::BUFFER: - return enum_switch_type::BUFFER; - default: - (*report_error)("Unknown enum_switch_type"); - throw std::runtime_error("Unreachable!"); - } +inline enum_switch_type conv_enum_switch_type(ucap::SwitchType e, const std::function * report_error) { + switch(e) { + case ucap::SwitchType::UXSD_INVALID: + return enum_switch_type::UXSD_INVALID; + case ucap::SwitchType::MUX: + return enum_switch_type::MUX; + case ucap::SwitchType::TRISTATE: + return enum_switch_type::TRISTATE; + case ucap::SwitchType::PASS_GATE: + return enum_switch_type::PASS_GATE; + case ucap::SwitchType::SHORT: + return enum_switch_type::SHORT; + case ucap::SwitchType::BUFFER: + return enum_switch_type::BUFFER; + default: + (*report_error)("Unknown enum_switch_type"); + throw std::runtime_error("Unreachable!"); + } } inline ucap::SwitchType conv_to_enum_switch_type(enum_switch_type e) { - switch (e) { - case enum_switch_type::UXSD_INVALID: - return ucap::SwitchType::UXSD_INVALID; - case enum_switch_type::MUX: - return ucap::SwitchType::MUX; - case enum_switch_type::TRISTATE: - return ucap::SwitchType::TRISTATE; - case enum_switch_type::PASS_GATE: - return ucap::SwitchType::PASS_GATE; - case enum_switch_type::SHORT: - return ucap::SwitchType::SHORT; - case enum_switch_type::BUFFER: - return ucap::SwitchType::BUFFER; - default: - throw std::runtime_error("Unknown enum_switch_type"); - } + switch(e) { + case enum_switch_type::UXSD_INVALID: + return ucap::SwitchType::UXSD_INVALID; + case enum_switch_type::MUX: + return ucap::SwitchType::MUX; + case enum_switch_type::TRISTATE: + return ucap::SwitchType::TRISTATE; + case enum_switch_type::PASS_GATE: + return ucap::SwitchType::PASS_GATE; + case enum_switch_type::SHORT: + return ucap::SwitchType::SHORT; + case enum_switch_type::BUFFER: + return ucap::SwitchType::BUFFER; + default: + throw std::runtime_error("Unknown enum_switch_type"); + } } -inline enum_pin_type conv_enum_pin_type(ucap::PinType e, const std::function* report_error) { - switch (e) { - case ucap::PinType::UXSD_INVALID: - return enum_pin_type::UXSD_INVALID; - case ucap::PinType::OPEN: - return enum_pin_type::OPEN; - case ucap::PinType::OUTPUT: - return enum_pin_type::OUTPUT; - case ucap::PinType::INPUT: - return enum_pin_type::INPUT; - default: - (*report_error)("Unknown enum_pin_type"); - throw std::runtime_error("Unreachable!"); - } +inline enum_pin_type conv_enum_pin_type(ucap::PinType e, const std::function * report_error) { + switch(e) { + case ucap::PinType::UXSD_INVALID: + return enum_pin_type::UXSD_INVALID; + case ucap::PinType::OPEN: + return enum_pin_type::OPEN; + case ucap::PinType::OUTPUT: + return enum_pin_type::OUTPUT; + case ucap::PinType::INPUT: + return enum_pin_type::INPUT; + default: + (*report_error)("Unknown enum_pin_type"); + throw std::runtime_error("Unreachable!"); + } } inline ucap::PinType conv_to_enum_pin_type(enum_pin_type e) { - switch (e) { - case enum_pin_type::UXSD_INVALID: - return ucap::PinType::UXSD_INVALID; - case enum_pin_type::OPEN: - return ucap::PinType::OPEN; - case enum_pin_type::OUTPUT: - return ucap::PinType::OUTPUT; - case enum_pin_type::INPUT: - return ucap::PinType::INPUT; - default: - throw std::runtime_error("Unknown enum_pin_type"); - } + switch(e) { + case enum_pin_type::UXSD_INVALID: + return ucap::PinType::UXSD_INVALID; + case enum_pin_type::OPEN: + return ucap::PinType::OPEN; + case enum_pin_type::OUTPUT: + return ucap::PinType::OUTPUT; + case enum_pin_type::INPUT: + return ucap::PinType::INPUT; + default: + throw std::runtime_error("Unknown enum_pin_type"); + } } -inline enum_node_type conv_enum_node_type(ucap::NodeType e, const std::function* report_error) { - switch (e) { - case ucap::NodeType::UXSD_INVALID: - return enum_node_type::UXSD_INVALID; - case ucap::NodeType::CHANX: - return enum_node_type::CHANX; - case ucap::NodeType::CHANY: - return enum_node_type::CHANY; - case ucap::NodeType::SOURCE: - return enum_node_type::SOURCE; - case ucap::NodeType::SINK: - return enum_node_type::SINK; - case ucap::NodeType::OPIN: - return enum_node_type::OPIN; - case ucap::NodeType::IPIN: - return enum_node_type::IPIN; - default: - (*report_error)("Unknown enum_node_type"); - throw std::runtime_error("Unreachable!"); - } +inline enum_node_type conv_enum_node_type(ucap::NodeType e, const std::function * report_error) { + switch(e) { + case ucap::NodeType::UXSD_INVALID: + return enum_node_type::UXSD_INVALID; + case ucap::NodeType::CHANX: + return enum_node_type::CHANX; + case ucap::NodeType::CHANY: + return enum_node_type::CHANY; + case ucap::NodeType::SOURCE: + return enum_node_type::SOURCE; + case ucap::NodeType::SINK: + return enum_node_type::SINK; + case ucap::NodeType::OPIN: + return enum_node_type::OPIN; + case ucap::NodeType::IPIN: + return enum_node_type::IPIN; + default: + (*report_error)("Unknown enum_node_type"); + throw std::runtime_error("Unreachable!"); + } } inline ucap::NodeType conv_to_enum_node_type(enum_node_type e) { - switch (e) { - case enum_node_type::UXSD_INVALID: - return ucap::NodeType::UXSD_INVALID; - case enum_node_type::CHANX: - return ucap::NodeType::CHANX; - case enum_node_type::CHANY: - return ucap::NodeType::CHANY; - case enum_node_type::SOURCE: - return ucap::NodeType::SOURCE; - case enum_node_type::SINK: - return ucap::NodeType::SINK; - case enum_node_type::OPIN: - return ucap::NodeType::OPIN; - case enum_node_type::IPIN: - return ucap::NodeType::IPIN; - default: - throw std::runtime_error("Unknown enum_node_type"); - } + switch(e) { + case enum_node_type::UXSD_INVALID: + return ucap::NodeType::UXSD_INVALID; + case enum_node_type::CHANX: + return ucap::NodeType::CHANX; + case enum_node_type::CHANY: + return ucap::NodeType::CHANY; + case enum_node_type::SOURCE: + return ucap::NodeType::SOURCE; + case enum_node_type::SINK: + return ucap::NodeType::SINK; + case enum_node_type::OPIN: + return ucap::NodeType::OPIN; + case enum_node_type::IPIN: + return ucap::NodeType::IPIN; + default: + throw std::runtime_error("Unknown enum_node_type"); + } } -inline enum_node_direction conv_enum_node_direction(ucap::NodeDirection e, const std::function* report_error) { - switch (e) { - case ucap::NodeDirection::UXSD_INVALID: - return enum_node_direction::UXSD_INVALID; - case ucap::NodeDirection::INC_DIR: - return enum_node_direction::INC_DIR; - case ucap::NodeDirection::DEC_DIR: - return enum_node_direction::DEC_DIR; - case ucap::NodeDirection::BI_DIR: - return enum_node_direction::BI_DIR; - default: - (*report_error)("Unknown enum_node_direction"); - throw std::runtime_error("Unreachable!"); - } +inline enum_node_direction conv_enum_node_direction(ucap::NodeDirection e, const std::function * report_error) { + switch(e) { + case ucap::NodeDirection::UXSD_INVALID: + return enum_node_direction::UXSD_INVALID; + case ucap::NodeDirection::INC_DIR: + return enum_node_direction::INC_DIR; + case ucap::NodeDirection::DEC_DIR: + return enum_node_direction::DEC_DIR; + case ucap::NodeDirection::BI_DIR: + return enum_node_direction::BI_DIR; + default: + (*report_error)("Unknown enum_node_direction"); + throw std::runtime_error("Unreachable!"); + } } inline ucap::NodeDirection conv_to_enum_node_direction(enum_node_direction e) { - switch (e) { - case enum_node_direction::UXSD_INVALID: - return ucap::NodeDirection::UXSD_INVALID; - case enum_node_direction::INC_DIR: - return ucap::NodeDirection::INC_DIR; - case enum_node_direction::DEC_DIR: - return ucap::NodeDirection::DEC_DIR; - case enum_node_direction::BI_DIR: - return ucap::NodeDirection::BI_DIR; - default: - throw std::runtime_error("Unknown enum_node_direction"); - } + switch(e) { + case enum_node_direction::UXSD_INVALID: + return ucap::NodeDirection::UXSD_INVALID; + case enum_node_direction::INC_DIR: + return ucap::NodeDirection::INC_DIR; + case enum_node_direction::DEC_DIR: + return ucap::NodeDirection::DEC_DIR; + case enum_node_direction::BI_DIR: + return ucap::NodeDirection::BI_DIR; + default: + throw std::runtime_error("Unknown enum_node_direction"); + } } -inline enum_loc_side conv_enum_loc_side(ucap::LocSide e, const std::function* report_error) { - switch (e) { - case ucap::LocSide::UXSD_INVALID: - return enum_loc_side::UXSD_INVALID; - case ucap::LocSide::LEFT: - return enum_loc_side::LEFT; - case ucap::LocSide::RIGHT: - return enum_loc_side::RIGHT; - case ucap::LocSide::TOP: - return enum_loc_side::TOP; - case ucap::LocSide::BOTTOM: - return enum_loc_side::BOTTOM; - case ucap::LocSide::RIGHT_LEFT: - return enum_loc_side::RIGHT_LEFT; - case ucap::LocSide::RIGHT_BOTTOM: - return enum_loc_side::RIGHT_BOTTOM; - case ucap::LocSide::RIGHT_BOTTOM_LEFT: - return enum_loc_side::RIGHT_BOTTOM_LEFT; - case ucap::LocSide::TOP_RIGHT: - return enum_loc_side::TOP_RIGHT; - case ucap::LocSide::TOP_BOTTOM: - return enum_loc_side::TOP_BOTTOM; - case ucap::LocSide::TOP_LEFT: - return enum_loc_side::TOP_LEFT; - case ucap::LocSide::TOP_RIGHT_BOTTOM: - return enum_loc_side::TOP_RIGHT_BOTTOM; - case ucap::LocSide::TOP_RIGHT_LEFT: - return enum_loc_side::TOP_RIGHT_LEFT; - case ucap::LocSide::TOP_BOTTOM_LEFT: - return enum_loc_side::TOP_BOTTOM_LEFT; - case ucap::LocSide::TOP_RIGHT_BOTTOM_LEFT: - return enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; - case ucap::LocSide::BOTTOM_LEFT: - return enum_loc_side::BOTTOM_LEFT; - default: - (*report_error)("Unknown enum_loc_side"); - throw std::runtime_error("Unreachable!"); - } +inline enum_loc_side conv_enum_loc_side(ucap::LocSide e, const std::function * report_error) { + switch(e) { + case ucap::LocSide::UXSD_INVALID: + return enum_loc_side::UXSD_INVALID; + case ucap::LocSide::LEFT: + return enum_loc_side::LEFT; + case ucap::LocSide::RIGHT: + return enum_loc_side::RIGHT; + case ucap::LocSide::TOP: + return enum_loc_side::TOP; + case ucap::LocSide::BOTTOM: + return enum_loc_side::BOTTOM; + case ucap::LocSide::RIGHT_LEFT: + return enum_loc_side::RIGHT_LEFT; + case ucap::LocSide::RIGHT_BOTTOM: + return enum_loc_side::RIGHT_BOTTOM; + case ucap::LocSide::RIGHT_BOTTOM_LEFT: + return enum_loc_side::RIGHT_BOTTOM_LEFT; + case ucap::LocSide::TOP_RIGHT: + return enum_loc_side::TOP_RIGHT; + case ucap::LocSide::TOP_BOTTOM: + return enum_loc_side::TOP_BOTTOM; + case ucap::LocSide::TOP_LEFT: + return enum_loc_side::TOP_LEFT; + case ucap::LocSide::TOP_RIGHT_BOTTOM: + return enum_loc_side::TOP_RIGHT_BOTTOM; + case ucap::LocSide::TOP_RIGHT_LEFT: + return enum_loc_side::TOP_RIGHT_LEFT; + case ucap::LocSide::TOP_BOTTOM_LEFT: + return enum_loc_side::TOP_BOTTOM_LEFT; + case ucap::LocSide::TOP_RIGHT_BOTTOM_LEFT: + return enum_loc_side::TOP_RIGHT_BOTTOM_LEFT; + case ucap::LocSide::BOTTOM_LEFT: + return enum_loc_side::BOTTOM_LEFT; + default: + (*report_error)("Unknown enum_loc_side"); + throw std::runtime_error("Unreachable!"); + } } inline ucap::LocSide conv_to_enum_loc_side(enum_loc_side e) { - switch (e) { - case enum_loc_side::UXSD_INVALID: - return ucap::LocSide::UXSD_INVALID; - case enum_loc_side::LEFT: - return ucap::LocSide::LEFT; - case enum_loc_side::RIGHT: - return ucap::LocSide::RIGHT; - case enum_loc_side::TOP: - return ucap::LocSide::TOP; - case enum_loc_side::BOTTOM: - return ucap::LocSide::BOTTOM; - case enum_loc_side::RIGHT_LEFT: - return ucap::LocSide::RIGHT_LEFT; - case enum_loc_side::RIGHT_BOTTOM: - return ucap::LocSide::RIGHT_BOTTOM; - case enum_loc_side::RIGHT_BOTTOM_LEFT: - return ucap::LocSide::RIGHT_BOTTOM_LEFT; - case enum_loc_side::TOP_RIGHT: - return ucap::LocSide::TOP_RIGHT; - case enum_loc_side::TOP_BOTTOM: - return ucap::LocSide::TOP_BOTTOM; - case enum_loc_side::TOP_LEFT: - return ucap::LocSide::TOP_LEFT; - case enum_loc_side::TOP_RIGHT_BOTTOM: - return ucap::LocSide::TOP_RIGHT_BOTTOM; - case enum_loc_side::TOP_RIGHT_LEFT: - return ucap::LocSide::TOP_RIGHT_LEFT; - case enum_loc_side::TOP_BOTTOM_LEFT: - return ucap::LocSide::TOP_BOTTOM_LEFT; - case enum_loc_side::TOP_RIGHT_BOTTOM_LEFT: - return ucap::LocSide::TOP_RIGHT_BOTTOM_LEFT; - case enum_loc_side::BOTTOM_LEFT: - return ucap::LocSide::BOTTOM_LEFT; - default: - throw std::runtime_error("Unknown enum_loc_side"); - } + switch(e) { + case enum_loc_side::UXSD_INVALID: + return ucap::LocSide::UXSD_INVALID; + case enum_loc_side::LEFT: + return ucap::LocSide::LEFT; + case enum_loc_side::RIGHT: + return ucap::LocSide::RIGHT; + case enum_loc_side::TOP: + return ucap::LocSide::TOP; + case enum_loc_side::BOTTOM: + return ucap::LocSide::BOTTOM; + case enum_loc_side::RIGHT_LEFT: + return ucap::LocSide::RIGHT_LEFT; + case enum_loc_side::RIGHT_BOTTOM: + return ucap::LocSide::RIGHT_BOTTOM; + case enum_loc_side::RIGHT_BOTTOM_LEFT: + return ucap::LocSide::RIGHT_BOTTOM_LEFT; + case enum_loc_side::TOP_RIGHT: + return ucap::LocSide::TOP_RIGHT; + case enum_loc_side::TOP_BOTTOM: + return ucap::LocSide::TOP_BOTTOM; + case enum_loc_side::TOP_LEFT: + return ucap::LocSide::TOP_LEFT; + case enum_loc_side::TOP_RIGHT_BOTTOM: + return ucap::LocSide::TOP_RIGHT_BOTTOM; + case enum_loc_side::TOP_RIGHT_LEFT: + return ucap::LocSide::TOP_RIGHT_LEFT; + case enum_loc_side::TOP_BOTTOM_LEFT: + return ucap::LocSide::TOP_BOTTOM_LEFT; + case enum_loc_side::TOP_RIGHT_BOTTOM_LEFT: + return ucap::LocSide::TOP_RIGHT_BOTTOM_LEFT; + case enum_loc_side::BOTTOM_LEFT: + return ucap::LocSide::BOTTOM_LEFT; + default: + throw std::runtime_error("Unknown enum_loc_side"); + } } + /* Load function for the root element. */ -template -inline void load_rr_graph_capnp(T& out, kj::ArrayPtr data, Context& context, const char* filename) { - /* Remove traversal limits. */ - ::capnp::ReaderOptions opts = ::capnp::ReaderOptions(); - opts.traversalLimitInWords = std::numeric_limits::max(); - ::capnp::FlatArrayMessageReader reader(data, opts); - auto root = reader.getRoot(); - std::vector> stack; - stack.reserve(20); - stack.push_back(std::make_pair("root", 0)); - - std::function report_error = [filename, &out, &stack](const char* message) { - std::stringstream msg; - msg << message << std::endl; - msg << "Error occured at "; - for (size_t i = 0; i < stack.size(); ++i) { - msg << stack[i].first << "[" << stack[i].second << "]"; - if (i + 1 < stack.size()) { - msg << " . "; - } - } - out.error_encountered(filename, -1, msg.str().c_str()); - }; - out.start_load(&report_error); - load_rr_graph_capnp_type(root, out, context, &report_error, &stack); - out.finish_load(); +template +inline void load_rr_graph_capnp(T &out, kj::ArrayPtr data, Context &context, const char * filename){ + /* Remove traversal limits. */ + ::capnp::ReaderOptions opts = ::capnp::ReaderOptions(); + opts.traversalLimitInWords = std::numeric_limits::max(); + ::capnp::FlatArrayMessageReader reader(data, opts); + auto root = reader.getRoot(); + std::vector> stack; + stack.reserve(20); + stack.push_back(std::make_pair("root", 0)); + + std::function report_error = [filename, &out, &stack](const char *message){ + std::stringstream msg; + msg << message << std::endl; + msg << "Error occured at "; + for(size_t i = 0; i < stack.size(); ++i) { + msg << stack[i].first << "[" << stack[i].second << "]"; + if(i+1 < stack.size()) { + msg << " . "; + } + } + out.error_encountered(filename, -1, msg.str().c_str()); + }; + out.start_load(&report_error); + load_rr_graph_capnp_type(root, out, context, &report_error, &stack); + out.finish_load(); } /* Write function for the root element. */ -template -inline void write_rr_graph_capnp(T& in, Context& context, ucap::RrGraph::Builder& root) { - in.start_write(); - if ((bool)in.get_rr_graph_tool_comment(context)) - root.setToolComment(in.get_rr_graph_tool_comment(context)); - if ((bool)in.get_rr_graph_tool_name(context)) - root.setToolName(in.get_rr_graph_tool_name(context)); - if ((bool)in.get_rr_graph_tool_version(context)) - root.setToolVersion(in.get_rr_graph_tool_version(context)); - write_rr_graph_capnp_type(in, root, context); - in.finish_write(); +template +inline void write_rr_graph_capnp(T &in, Context &context, ucap::RrGraph::Builder &root) { + in.start_write(); + if((bool)in.get_rr_graph_tool_comment(context)) + root.setToolComment(in.get_rr_graph_tool_comment(context)); + if((bool)in.get_rr_graph_tool_name(context)) + root.setToolName(in.get_rr_graph_tool_name(context)); + if((bool)in.get_rr_graph_tool_version(context)) + root.setToolVersion(in.get_rr_graph_tool_version(context)); + write_rr_graph_capnp_type(in, root, context); + in.finish_write(); } + /* Internal loading functions, which validate and load a PugiXML DOM tree into memory. */ template -inline void load_channel_capnp_type(const ucap::Channel::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_channel_capnp_type(const ucap::Channel::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_x_list_capnp_type(const ucap::XList::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_x_list_capnp_type(const ucap::XList::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_y_list_capnp_type(const ucap::YList::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_y_list_capnp_type(const ucap::YList::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_channels_capnp_type(const ucap::Channels::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getChannel", 0)); - if (root.hasChannel()) { - auto child_el = root.getChannel(); - auto child_context = out.init_channels_channel(context, child_el.getChanWidthMax(), child_el.getXMax(), child_el.getXMin(), child_el.getYMax(), child_el.getYMin()); - load_channel_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_channels_channel(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getXList", 0)); - { - auto data = root.getXLists(); - out.preallocate_channels_x_list(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_channels_x_list(context, el.getIndex(), el.getInfo()); - load_x_list_capnp_type(el, out, child_context, report_error, stack); - out.finish_channels_x_list(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); - stack->push_back(std::make_pair("getYList", 0)); - { - auto data = root.getYLists(); - out.preallocate_channels_y_list(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_channels_y_list(context, el.getIndex(), el.getInfo()); - load_y_list_capnp_type(el, out, child_context, report_error, stack); - out.finish_channels_y_list(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_channels_capnp_type(const ucap::Channels::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getChannel", 0)); + if (root.hasChannel()) { + auto child_el = root.getChannel(); + auto child_context = out.init_channels_channel(context, child_el.getChanWidthMax(), child_el.getXMax(), child_el.getXMin(), child_el.getYMax(), child_el.getYMin()); + load_channel_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_channels_channel(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getXList", 0)); + { + auto data = root.getXLists(); + out.preallocate_channels_x_list(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_channels_x_list(context, el.getIndex(), el.getInfo()); + load_x_list_capnp_type(el, out, child_context, report_error, stack); + out.finish_channels_x_list(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); + stack->push_back(std::make_pair("getYList", 0)); + { + auto data = root.getYLists(); + out.preallocate_channels_y_list(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_channels_y_list(context, el.getIndex(), el.getInfo()); + load_y_list_capnp_type(el, out, child_context, report_error, stack); + out.finish_channels_y_list(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_timing_capnp_type(const ucap::Timing::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_timing_Cin(root.getCin(), context); - out.set_timing_Cinternal(root.getCinternal(), context); - out.set_timing_Cout(root.getCout(), context); - out.set_timing_R(root.getR(), context); - out.set_timing_Tdel(root.getTdel(), context); +inline void load_timing_capnp_type(const ucap::Timing::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_timing_Cin(root.getCin(), context); + out.set_timing_Cinternal(root.getCinternal(), context); + out.set_timing_Cout(root.getCout(), context); + out.set_timing_R(root.getR(), context); + out.set_timing_Tdel(root.getTdel(), context); } template -inline void load_sizing_capnp_type(const ucap::Sizing::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_sizing_capnp_type(const ucap::Sizing::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_switch_capnp_type(const ucap::Switch::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_switch_name(root.getName().cStr(), context); - out.set_switch_type(conv_enum_switch_type(root.getType(), report_error), context); - stack->push_back(std::make_pair("getTiming", 0)); - if (root.hasTiming()) { - auto child_el = root.getTiming(); - auto child_context = out.init_switch_timing(context); - load_timing_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_switch_timing(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getSizing", 0)); - if (root.hasSizing()) { - auto child_el = root.getSizing(); - auto child_context = out.init_switch_sizing(context, child_el.getBufSize(), child_el.getMuxTransSize()); - load_sizing_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_switch_sizing(child_context); - } - stack->pop_back(); +inline void load_switch_capnp_type(const ucap::Switch::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_switch_name(root.getName().cStr(), context); + out.set_switch_type(conv_enum_switch_type(root.getType(), report_error), context); + stack->push_back(std::make_pair("getTiming", 0)); + if (root.hasTiming()) { + auto child_el = root.getTiming(); + auto child_context = out.init_switch_timing(context); + load_timing_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_switch_timing(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getSizing", 0)); + if (root.hasSizing()) { + auto child_el = root.getSizing(); + auto child_context = out.init_switch_sizing(context, child_el.getBufSize(), child_el.getMuxTransSize()); + load_sizing_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_switch_sizing(child_context); + } + stack->pop_back(); } template -inline void load_switches_capnp_type(const ucap::Switches::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getSwitch", 0)); - { - auto data = root.getSwitches(); - out.preallocate_switches_switch(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_switches_switch(context, el.getId()); - load_switch_capnp_type(el, out, child_context, report_error, stack); - out.finish_switches_switch(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_switches_capnp_type(const ucap::Switches::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getSwitch", 0)); + { + auto data = root.getSwitches(); + out.preallocate_switches_switch(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_switches_switch(context, el.getId()); + load_switch_capnp_type(el, out, child_context, report_error, stack); + out.finish_switches_switch(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_segment_timing_capnp_type(const ucap::SegmentTiming::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_segment_timing_C_per_meter(root.getCPerMeter(), context); - out.set_segment_timing_R_per_meter(root.getRPerMeter(), context); +inline void load_segment_timing_capnp_type(const ucap::SegmentTiming::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_segment_timing_C_per_meter(root.getCPerMeter(), context); + out.set_segment_timing_R_per_meter(root.getRPerMeter(), context); } template -inline void load_segment_capnp_type(const ucap::Segment::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_segment_name(root.getName().cStr(), context); - stack->push_back(std::make_pair("getTiming", 0)); - if (root.hasTiming()) { - auto child_el = root.getTiming(); - auto child_context = out.init_segment_timing(context); - load_segment_timing_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_segment_timing(child_context); - } - stack->pop_back(); +inline void load_segment_capnp_type(const ucap::Segment::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_segment_name(root.getName().cStr(), context); + stack->push_back(std::make_pair("getTiming", 0)); + if (root.hasTiming()) { + auto child_el = root.getTiming(); + auto child_context = out.init_segment_timing(context); + load_segment_timing_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_segment_timing(child_context); + } + stack->pop_back(); } template -inline void load_segments_capnp_type(const ucap::Segments::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getSegment", 0)); - { - auto data = root.getSegments(); - out.preallocate_segments_segment(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_segments_segment(context, el.getId()); - load_segment_capnp_type(el, out, child_context, report_error, stack); - out.finish_segments_segment(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_segments_capnp_type(const ucap::Segments::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getSegment", 0)); + { + auto data = root.getSegments(); + out.preallocate_segments_segment(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_segments_segment(context, el.getId()); + load_segment_capnp_type(el, out, child_context, report_error, stack); + out.finish_segments_segment(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_pin_capnp_type(const ucap::Pin::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getValue", 0)); - out.set_pin_value(root.getValue().cStr(), context); - stack->pop_back(); +inline void load_pin_capnp_type(const ucap::Pin::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getValue", 0)); + out.set_pin_value(root.getValue().cStr(), context); + stack->pop_back(); } template -inline void load_pin_class_capnp_type(const ucap::PinClass::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getPin", 0)); - { - auto data = root.getPins(); - out.preallocate_pin_class_pin(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_pin_class_pin(context, el.getPtc()); - load_pin_capnp_type(el, out, child_context, report_error, stack); - out.finish_pin_class_pin(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_pin_class_capnp_type(const ucap::PinClass::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getPin", 0)); + { + auto data = root.getPins(); + out.preallocate_pin_class_pin(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_pin_class_pin(context, el.getPtc()); + load_pin_capnp_type(el, out, child_context, report_error, stack); + out.finish_pin_class_pin(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_block_type_capnp_type(const ucap::BlockType::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_block_type_name(root.getName().cStr(), context); - stack->push_back(std::make_pair("getPinClass", 0)); - { - auto data = root.getPinClasses(); - out.preallocate_block_type_pin_class(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_block_type_pin_class(context, conv_enum_pin_type(el.getType(), report_error)); - load_pin_class_capnp_type(el, out, child_context, report_error, stack); - out.finish_block_type_pin_class(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_block_type_capnp_type(const ucap::BlockType::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_block_type_name(root.getName().cStr(), context); + stack->push_back(std::make_pair("getPinClass", 0)); + { + auto data = root.getPinClasses(); + out.preallocate_block_type_pin_class(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_block_type_pin_class(context, conv_enum_pin_type(el.getType(), report_error)); + load_pin_class_capnp_type(el, out, child_context, report_error, stack); + out.finish_block_type_pin_class(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_block_types_capnp_type(const ucap::BlockTypes::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getBlockType", 0)); - { - auto data = root.getBlockTypes(); - out.preallocate_block_types_block_type(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_block_types_block_type(context, el.getHeight(), el.getId(), el.getWidth()); - load_block_type_capnp_type(el, out, child_context, report_error, stack); - out.finish_block_types_block_type(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_block_types_capnp_type(const ucap::BlockTypes::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getBlockType", 0)); + { + auto data = root.getBlockTypes(); + out.preallocate_block_types_block_type(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_block_types_block_type(context, el.getHeight(), el.getId(), el.getWidth()); + load_block_type_capnp_type(el, out, child_context, report_error, stack); + out.finish_block_types_block_type(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_grid_loc_capnp_type(const ucap::GridLoc::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_grid_loc_capnp_type(const ucap::GridLoc::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_grid_locs_capnp_type(const ucap::GridLocs::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getGridLoc", 0)); - { - auto data = root.getGridLocs(); - out.preallocate_grid_locs_grid_loc(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_grid_locs_grid_loc(context, el.getBlockTypeId(), el.getHeightOffset(), el.getWidthOffset(), el.getX(), el.getY()); - load_grid_loc_capnp_type(el, out, child_context, report_error, stack); - out.finish_grid_locs_grid_loc(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_grid_locs_capnp_type(const ucap::GridLocs::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getGridLoc", 0)); + { + auto data = root.getGridLocs(); + out.preallocate_grid_locs_grid_loc(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_grid_locs_grid_loc(context, el.getBlockTypeId(), el.getHeightOffset(), el.getWidthOffset(), el.getX(), el.getY()); + load_grid_loc_capnp_type(el, out, child_context, report_error, stack); + out.finish_grid_locs_grid_loc(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_node_loc_capnp_type(const ucap::NodeLoc::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_node_loc_side(conv_enum_loc_side(root.getSide(), report_error), context); +inline void load_node_loc_capnp_type(const ucap::NodeLoc::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_node_loc_side(conv_enum_loc_side(root.getSide(), report_error), context); } template -inline void load_node_timing_capnp_type(const ucap::NodeTiming::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_node_timing_capnp_type(const ucap::NodeTiming::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_node_segment_capnp_type(const ucap::NodeSegment::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; +inline void load_node_segment_capnp_type(const ucap::NodeSegment::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + } template -inline void load_meta_capnp_type(const ucap::Meta::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_meta_name(root.getName().cStr(), context); - stack->push_back(std::make_pair("getValue", 0)); - out.set_meta_value(root.getValue().cStr(), context); - stack->pop_back(); +inline void load_meta_capnp_type(const ucap::Meta::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_meta_name(root.getName().cStr(), context); + stack->push_back(std::make_pair("getValue", 0)); + out.set_meta_value(root.getValue().cStr(), context); + stack->pop_back(); } template -inline void load_metadata_capnp_type(const ucap::Metadata::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getMeta", 0)); - { - auto data = root.getMetas(); - out.preallocate_metadata_meta(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_metadata_meta(context); - load_meta_capnp_type(el, out, child_context, report_error, stack); - out.finish_metadata_meta(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_metadata_capnp_type(const ucap::Metadata::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getMeta", 0)); + { + auto data = root.getMetas(); + out.preallocate_metadata_meta(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_metadata_meta(context); + load_meta_capnp_type(el, out, child_context, report_error, stack); + out.finish_metadata_meta(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_node_capnp_type(const ucap::Node::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_node_direction(conv_enum_node_direction(root.getDirection(), report_error), context); - stack->push_back(std::make_pair("getLoc", 0)); - if (root.hasLoc()) { - auto child_el = root.getLoc(); - auto child_context = out.init_node_loc(context, child_el.getPtc(), child_el.getXhigh(), child_el.getXlow(), child_el.getYhigh(), child_el.getYlow()); - load_node_loc_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_node_loc(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getTiming", 0)); - if (root.hasTiming()) { - auto child_el = root.getTiming(); - auto child_context = out.init_node_timing(context, child_el.getC(), child_el.getR()); - load_node_timing_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_node_timing(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getSegment", 0)); - if (root.hasSegment()) { - auto child_el = root.getSegment(); - auto child_context = out.init_node_segment(context, child_el.getSegmentId()); - load_node_segment_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_node_segment(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getMetadata", 0)); - if (root.hasMetadata()) { - auto child_el = root.getMetadata(); - auto child_context = out.init_node_metadata(context); - load_metadata_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_node_metadata(child_context); - } - stack->pop_back(); +inline void load_node_capnp_type(const ucap::Node::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_node_direction(conv_enum_node_direction(root.getDirection(), report_error), context); + stack->push_back(std::make_pair("getLoc", 0)); + if (root.hasLoc()) { + auto child_el = root.getLoc(); + auto child_context = out.init_node_loc(context, child_el.getPtc(), child_el.getXhigh(), child_el.getXlow(), child_el.getYhigh(), child_el.getYlow()); + load_node_loc_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_node_loc(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getTiming", 0)); + if (root.hasTiming()) { + auto child_el = root.getTiming(); + auto child_context = out.init_node_timing(context, child_el.getC(), child_el.getR()); + load_node_timing_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_node_timing(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getSegment", 0)); + if (root.hasSegment()) { + auto child_el = root.getSegment(); + auto child_context = out.init_node_segment(context, child_el.getSegmentId()); + load_node_segment_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_node_segment(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getMetadata", 0)); + if (root.hasMetadata()) { + auto child_el = root.getMetadata(); + auto child_context = out.init_node_metadata(context); + load_metadata_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_node_metadata(child_context); + } + stack->pop_back(); } template -inline void load_rr_nodes_capnp_type(const ucap::RrNodes::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getNode", 0)); - { - auto data = root.getNodes(); - out.preallocate_rr_nodes_node(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_rr_nodes_node(context, el.getCapacity(), el.getId(), conv_enum_node_type(el.getType(), report_error)); - load_node_capnp_type(el, out, child_context, report_error, stack); - out.finish_rr_nodes_node(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_rr_nodes_capnp_type(const ucap::RrNodes::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getNode", 0)); + { + auto data = root.getNodes(); + out.preallocate_rr_nodes_node(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_rr_nodes_node(context, el.getCapacity(), el.getId(), conv_enum_node_type(el.getType(), report_error)); + load_node_capnp_type(el, out, child_context, report_error, stack); + out.finish_rr_nodes_node(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_edge_capnp_type(const ucap::Edge::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getMetadata", 0)); - if (root.hasMetadata()) { - auto child_el = root.getMetadata(); - auto child_context = out.init_edge_metadata(context); - load_metadata_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_edge_metadata(child_context); - } - stack->pop_back(); +inline void load_edge_capnp_type(const ucap::Edge::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getMetadata", 0)); + if (root.hasMetadata()) { + auto child_el = root.getMetadata(); + auto child_context = out.init_edge_metadata(context); + load_metadata_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_edge_metadata(child_context); + } + stack->pop_back(); } template -inline void load_rr_edges_capnp_type(const ucap::RrEdges::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - stack->push_back(std::make_pair("getEdge", 0)); - { - auto data = root.getEdges(); - out.preallocate_rr_edges_edge(context, data.size()); - for (const auto& el : data) { - auto child_context = out.add_rr_edges_edge(context, el.getSinkNode(), el.getSrcNode(), el.getSwitchId()); - load_edge_capnp_type(el, out, child_context, report_error, stack); - out.finish_rr_edges_edge(child_context); - stack->back().second += 1; - } - } - stack->pop_back(); +inline void load_rr_edges_capnp_type(const ucap::RrEdges::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + stack->push_back(std::make_pair("getEdge", 0)); + { + auto data = root.getEdges(); + out.preallocate_rr_edges_edge(context, data.size()); + for(const auto & el : data) { + auto child_context = out.add_rr_edges_edge(context, el.getSinkNode(), el.getSrcNode(), el.getSwitchId()); + load_edge_capnp_type(el, out, child_context, report_error, stack); + out.finish_rr_edges_edge(child_context); + stack->back().second += 1; + } + } + stack->pop_back(); } template -inline void load_rr_graph_capnp_type(const ucap::RrGraph::Reader& root, T& out, Context& context, const std::function* report_error, std::vector>* stack) { - (void)root; - (void)out; - (void)context; - (void)report_error; - (void)stack; - - out.set_rr_graph_tool_comment(root.getToolComment().cStr(), context); - out.set_rr_graph_tool_name(root.getToolName().cStr(), context); - out.set_rr_graph_tool_version(root.getToolVersion().cStr(), context); - stack->push_back(std::make_pair("getChannels", 0)); - if (root.hasChannels()) { - auto child_el = root.getChannels(); - auto child_context = out.init_rr_graph_channels(context); - load_channels_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_channels(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getSwitches", 0)); - if (root.hasSwitches()) { - auto child_el = root.getSwitches(); - auto child_context = out.init_rr_graph_switches(context); - load_switches_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_switches(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getSegments", 0)); - if (root.hasSegments()) { - auto child_el = root.getSegments(); - auto child_context = out.init_rr_graph_segments(context); - load_segments_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_segments(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getBlockTypes", 0)); - if (root.hasBlockTypes()) { - auto child_el = root.getBlockTypes(); - auto child_context = out.init_rr_graph_block_types(context); - load_block_types_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_block_types(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getGrid", 0)); - if (root.hasGrid()) { - auto child_el = root.getGrid(); - auto child_context = out.init_rr_graph_grid(context); - load_grid_locs_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_grid(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getRrNodes", 0)); - if (root.hasRrNodes()) { - auto child_el = root.getRrNodes(); - auto child_context = out.init_rr_graph_rr_nodes(context); - load_rr_nodes_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_rr_nodes(child_context); - } - stack->pop_back(); - stack->push_back(std::make_pair("getRrEdges", 0)); - if (root.hasRrEdges()) { - auto child_el = root.getRrEdges(); - auto child_context = out.init_rr_graph_rr_edges(context); - load_rr_edges_capnp_type(child_el, out, child_context, report_error, stack); - out.finish_rr_graph_rr_edges(child_context); - } - stack->pop_back(); +inline void load_rr_graph_capnp_type(const ucap::RrGraph::Reader &root, T &out, Context &context, const std::function * report_error, std::vector> * stack){ + (void)root; + (void)out; + (void)context; + (void)report_error; + (void)stack; + + out.set_rr_graph_tool_comment(root.getToolComment().cStr(), context); + out.set_rr_graph_tool_name(root.getToolName().cStr(), context); + out.set_rr_graph_tool_version(root.getToolVersion().cStr(), context); + stack->push_back(std::make_pair("getChannels", 0)); + if (root.hasChannels()) { + auto child_el = root.getChannels(); + auto child_context = out.init_rr_graph_channels(context); + load_channels_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_channels(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getSwitches", 0)); + if (root.hasSwitches()) { + auto child_el = root.getSwitches(); + auto child_context = out.init_rr_graph_switches(context); + load_switches_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_switches(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getSegments", 0)); + if (root.hasSegments()) { + auto child_el = root.getSegments(); + auto child_context = out.init_rr_graph_segments(context); + load_segments_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_segments(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getBlockTypes", 0)); + if (root.hasBlockTypes()) { + auto child_el = root.getBlockTypes(); + auto child_context = out.init_rr_graph_block_types(context); + load_block_types_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_block_types(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getGrid", 0)); + if (root.hasGrid()) { + auto child_el = root.getGrid(); + auto child_context = out.init_rr_graph_grid(context); + load_grid_locs_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_grid(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getRrNodes", 0)); + if (root.hasRrNodes()) { + auto child_el = root.getRrNodes(); + auto child_context = out.init_rr_graph_rr_nodes(context); + load_rr_nodes_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_rr_nodes(child_context); + } + stack->pop_back(); + stack->push_back(std::make_pair("getRrEdges", 0)); + if (root.hasRrEdges()) { + auto child_el = root.getRrEdges(); + auto child_context = out.init_rr_graph_rr_edges(context); + load_rr_edges_capnp_type(child_el, out, child_context, report_error, stack); + out.finish_rr_graph_rr_edges(child_context); + } + stack->pop_back(); } + /* Internal writing functions, which uxsdcxx uses to write out a class. */ template -inline void write_channels_capnp_type(T& in, ucap::Channels::Builder& root, Context& context) { - (void)in; - (void)root; - - { - auto child_context = in.get_channels_channel(context); - auto channels_channel = root.initChannel(); - channels_channel.setChanWidthMax(in.get_channel_chan_width_max(child_context)); - channels_channel.setXMax(in.get_channel_x_max(child_context)); - channels_channel.setXMin(in.get_channel_x_min(child_context)); - channels_channel.setYMax(in.get_channel_y_max(child_context)); - channels_channel.setYMin(in.get_channel_y_min(child_context)); - } - - size_t num_channels_x_lists = in.num_channels_x_list(context); - auto channels_x_lists = root.initXLists(num_channels_x_lists); - for (size_t i = 0; i < num_channels_x_lists; i++) { - auto channels_x_list = channels_x_lists[i]; - auto child_context = in.get_channels_x_list(i, context); - channels_x_list.setIndex(in.get_x_list_index(child_context)); - channels_x_list.setInfo(in.get_x_list_info(child_context)); - } - - size_t num_channels_y_lists = in.num_channels_y_list(context); - auto channels_y_lists = root.initYLists(num_channels_y_lists); - for (size_t i = 0; i < num_channels_y_lists; i++) { - auto channels_y_list = channels_y_lists[i]; - auto child_context = in.get_channels_y_list(i, context); - channels_y_list.setIndex(in.get_y_list_index(child_context)); - channels_y_list.setInfo(in.get_y_list_info(child_context)); - } +inline void write_channels_capnp_type(T &in, ucap::Channels::Builder &root, Context &context) { + (void)in; + (void)root; + + { + auto child_context = in.get_channels_channel(context); + auto channels_channel = root.initChannel(); + channels_channel.setChanWidthMax(in.get_channel_chan_width_max(child_context)); + channels_channel.setXMax(in.get_channel_x_max(child_context)); + channels_channel.setXMin(in.get_channel_x_min(child_context)); + channels_channel.setYMax(in.get_channel_y_max(child_context)); + channels_channel.setYMin(in.get_channel_y_min(child_context)); + } + + size_t num_channels_x_lists = in.num_channels_x_list(context); + auto channels_x_lists = root.initXLists(num_channels_x_lists); + for(size_t i = 0; i < num_channels_x_lists; i++) { + auto channels_x_list = channels_x_lists[i]; + auto child_context = in.get_channels_x_list(i, context); + channels_x_list.setIndex(in.get_x_list_index(child_context)); + channels_x_list.setInfo(in.get_x_list_info(child_context)); + } + + size_t num_channels_y_lists = in.num_channels_y_list(context); + auto channels_y_lists = root.initYLists(num_channels_y_lists); + for(size_t i = 0; i < num_channels_y_lists; i++) { + auto channels_y_list = channels_y_lists[i]; + auto child_context = in.get_channels_y_list(i, context); + channels_y_list.setIndex(in.get_y_list_index(child_context)); + channels_y_list.setInfo(in.get_y_list_info(child_context)); + } } template -inline void write_switch_capnp_type(T& in, ucap::Switch::Builder& root, Context& context) { - (void)in; - (void)root; - - if (in.has_switch_timing(context)) { - auto switch_timing = root.initTiming(); - auto child_context = in.get_switch_timing(context); - if ((bool)in.get_timing_Cin(child_context)) - switch_timing.setCin(in.get_timing_Cin(child_context)); - if ((bool)in.get_timing_Cinternal(child_context)) - switch_timing.setCinternal(in.get_timing_Cinternal(child_context)); - if ((bool)in.get_timing_Cout(child_context)) - switch_timing.setCout(in.get_timing_Cout(child_context)); - if ((bool)in.get_timing_R(child_context)) - switch_timing.setR(in.get_timing_R(child_context)); - if ((bool)in.get_timing_Tdel(child_context)) - switch_timing.setTdel(in.get_timing_Tdel(child_context)); - } - - { - auto child_context = in.get_switch_sizing(context); - auto switch_sizing = root.initSizing(); - switch_sizing.setBufSize(in.get_sizing_buf_size(child_context)); - switch_sizing.setMuxTransSize(in.get_sizing_mux_trans_size(child_context)); - } +inline void write_switch_capnp_type(T &in, ucap::Switch::Builder &root, Context &context) { + (void)in; + (void)root; + + if(in.has_switch_timing(context)){ + auto switch_timing = root.initTiming(); + auto child_context = in.get_switch_timing(context); + if((bool)in.get_timing_Cin(child_context)) + switch_timing.setCin(in.get_timing_Cin(child_context)); + if((bool)in.get_timing_Cinternal(child_context)) + switch_timing.setCinternal(in.get_timing_Cinternal(child_context)); + if((bool)in.get_timing_Cout(child_context)) + switch_timing.setCout(in.get_timing_Cout(child_context)); + if((bool)in.get_timing_R(child_context)) + switch_timing.setR(in.get_timing_R(child_context)); + if((bool)in.get_timing_Tdel(child_context)) + switch_timing.setTdel(in.get_timing_Tdel(child_context)); + } + + { + auto child_context = in.get_switch_sizing(context); + auto switch_sizing = root.initSizing(); + switch_sizing.setBufSize(in.get_sizing_buf_size(child_context)); + switch_sizing.setMuxTransSize(in.get_sizing_mux_trans_size(child_context)); + } } template -inline void write_switches_capnp_type(T& in, ucap::Switches::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_switches_switches = in.num_switches_switch(context); - auto switches_switches = root.initSwitches(num_switches_switches); - for (size_t i = 0; i < num_switches_switches; i++) { - auto switches_switch = switches_switches[i]; - auto child_context = in.get_switches_switch(i, context); - switches_switch.setId(in.get_switch_id(child_context)); - switches_switch.setName(in.get_switch_name(child_context)); - if ((bool)in.get_switch_type(child_context)) - switches_switch.setType(conv_to_enum_switch_type(in.get_switch_type(child_context))); - write_switch_capnp_type(in, switches_switch, child_context); - } +inline void write_switches_capnp_type(T &in, ucap::Switches::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_switches_switches = in.num_switches_switch(context); + auto switches_switches = root.initSwitches(num_switches_switches); + for(size_t i = 0; i < num_switches_switches; i++) { + auto switches_switch = switches_switches[i]; + auto child_context = in.get_switches_switch(i, context); + switches_switch.setId(in.get_switch_id(child_context)); + switches_switch.setName(in.get_switch_name(child_context)); + if((bool)in.get_switch_type(child_context)) + switches_switch.setType(conv_to_enum_switch_type(in.get_switch_type(child_context))); + write_switch_capnp_type(in, switches_switch, child_context); + } } template -inline void write_segment_capnp_type(T& in, ucap::Segment::Builder& root, Context& context) { - (void)in; - (void)root; - - if (in.has_segment_timing(context)) { - auto segment_timing = root.initTiming(); - auto child_context = in.get_segment_timing(context); - if ((bool)in.get_segment_timing_C_per_meter(child_context)) - segment_timing.setCPerMeter(in.get_segment_timing_C_per_meter(child_context)); - if ((bool)in.get_segment_timing_R_per_meter(child_context)) - segment_timing.setRPerMeter(in.get_segment_timing_R_per_meter(child_context)); - } +inline void write_segment_capnp_type(T &in, ucap::Segment::Builder &root, Context &context) { + (void)in; + (void)root; + + if(in.has_segment_timing(context)){ + auto segment_timing = root.initTiming(); + auto child_context = in.get_segment_timing(context); + if((bool)in.get_segment_timing_C_per_meter(child_context)) + segment_timing.setCPerMeter(in.get_segment_timing_C_per_meter(child_context)); + if((bool)in.get_segment_timing_R_per_meter(child_context)) + segment_timing.setRPerMeter(in.get_segment_timing_R_per_meter(child_context)); + } } template -inline void write_segments_capnp_type(T& in, ucap::Segments::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_segments_segments = in.num_segments_segment(context); - auto segments_segments = root.initSegments(num_segments_segments); - for (size_t i = 0; i < num_segments_segments; i++) { - auto segments_segment = segments_segments[i]; - auto child_context = in.get_segments_segment(i, context); - segments_segment.setId(in.get_segment_id(child_context)); - segments_segment.setName(in.get_segment_name(child_context)); - write_segment_capnp_type(in, segments_segment, child_context); - } +inline void write_segments_capnp_type(T &in, ucap::Segments::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_segments_segments = in.num_segments_segment(context); + auto segments_segments = root.initSegments(num_segments_segments); + for(size_t i = 0; i < num_segments_segments; i++) { + auto segments_segment = segments_segments[i]; + auto child_context = in.get_segments_segment(i, context); + segments_segment.setId(in.get_segment_id(child_context)); + segments_segment.setName(in.get_segment_name(child_context)); + write_segment_capnp_type(in, segments_segment, child_context); + } } template -inline void write_pin_capnp_type(T& in, ucap::Pin::Builder& root, Context& context) { - (void)in; - (void)root; - root.setValue(in.get_pin_value(context)); +inline void write_pin_capnp_type(T &in, ucap::Pin::Builder &root, Context &context) { + (void)in; + (void)root; + root.setValue(in.get_pin_value(context)); } template -inline void write_pin_class_capnp_type(T& in, ucap::PinClass::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_pin_class_pins = in.num_pin_class_pin(context); - auto pin_class_pins = root.initPins(num_pin_class_pins); - for (size_t i = 0; i < num_pin_class_pins; i++) { - auto pin_class_pin = pin_class_pins[i]; - auto child_context = in.get_pin_class_pin(i, context); - pin_class_pin.setPtc(in.get_pin_ptc(child_context)); - write_pin_capnp_type(in, pin_class_pin, child_context); - } +inline void write_pin_class_capnp_type(T &in, ucap::PinClass::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_pin_class_pins = in.num_pin_class_pin(context); + auto pin_class_pins = root.initPins(num_pin_class_pins); + for(size_t i = 0; i < num_pin_class_pins; i++) { + auto pin_class_pin = pin_class_pins[i]; + auto child_context = in.get_pin_class_pin(i, context); + pin_class_pin.setPtc(in.get_pin_ptc(child_context)); + write_pin_capnp_type(in, pin_class_pin, child_context); + } } template -inline void write_block_type_capnp_type(T& in, ucap::BlockType::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_block_type_pin_classes = in.num_block_type_pin_class(context); - auto block_type_pin_classes = root.initPinClasses(num_block_type_pin_classes); - for (size_t i = 0; i < num_block_type_pin_classes; i++) { - auto block_type_pin_class = block_type_pin_classes[i]; - auto child_context = in.get_block_type_pin_class(i, context); - block_type_pin_class.setType(conv_to_enum_pin_type(in.get_pin_class_type(child_context))); - write_pin_class_capnp_type(in, block_type_pin_class, child_context); - } +inline void write_block_type_capnp_type(T &in, ucap::BlockType::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_block_type_pin_classes = in.num_block_type_pin_class(context); + auto block_type_pin_classes = root.initPinClasses(num_block_type_pin_classes); + for(size_t i = 0; i < num_block_type_pin_classes; i++) { + auto block_type_pin_class = block_type_pin_classes[i]; + auto child_context = in.get_block_type_pin_class(i, context); + block_type_pin_class.setType(conv_to_enum_pin_type(in.get_pin_class_type(child_context))); + write_pin_class_capnp_type(in, block_type_pin_class, child_context); + } } template -inline void write_block_types_capnp_type(T& in, ucap::BlockTypes::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_block_types_block_types = in.num_block_types_block_type(context); - auto block_types_block_types = root.initBlockTypes(num_block_types_block_types); - for (size_t i = 0; i < num_block_types_block_types; i++) { - auto block_types_block_type = block_types_block_types[i]; - auto child_context = in.get_block_types_block_type(i, context); - block_types_block_type.setHeight(in.get_block_type_height(child_context)); - block_types_block_type.setId(in.get_block_type_id(child_context)); - block_types_block_type.setName(in.get_block_type_name(child_context)); - block_types_block_type.setWidth(in.get_block_type_width(child_context)); - write_block_type_capnp_type(in, block_types_block_type, child_context); - } +inline void write_block_types_capnp_type(T &in, ucap::BlockTypes::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_block_types_block_types = in.num_block_types_block_type(context); + auto block_types_block_types = root.initBlockTypes(num_block_types_block_types); + for(size_t i = 0; i < num_block_types_block_types; i++) { + auto block_types_block_type = block_types_block_types[i]; + auto child_context = in.get_block_types_block_type(i, context); + block_types_block_type.setHeight(in.get_block_type_height(child_context)); + block_types_block_type.setId(in.get_block_type_id(child_context)); + block_types_block_type.setName(in.get_block_type_name(child_context)); + block_types_block_type.setWidth(in.get_block_type_width(child_context)); + write_block_type_capnp_type(in, block_types_block_type, child_context); + } } template -inline void write_grid_locs_capnp_type(T& in, ucap::GridLocs::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_grid_locs_grid_locs = in.num_grid_locs_grid_loc(context); - auto grid_locs_grid_locs = root.initGridLocs(num_grid_locs_grid_locs); - for (size_t i = 0; i < num_grid_locs_grid_locs; i++) { - auto grid_locs_grid_loc = grid_locs_grid_locs[i]; - auto child_context = in.get_grid_locs_grid_loc(i, context); - grid_locs_grid_loc.setBlockTypeId(in.get_grid_loc_block_type_id(child_context)); - grid_locs_grid_loc.setHeightOffset(in.get_grid_loc_height_offset(child_context)); - grid_locs_grid_loc.setWidthOffset(in.get_grid_loc_width_offset(child_context)); - grid_locs_grid_loc.setX(in.get_grid_loc_x(child_context)); - grid_locs_grid_loc.setY(in.get_grid_loc_y(child_context)); - } +inline void write_grid_locs_capnp_type(T &in, ucap::GridLocs::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_grid_locs_grid_locs = in.num_grid_locs_grid_loc(context); + auto grid_locs_grid_locs = root.initGridLocs(num_grid_locs_grid_locs); + for(size_t i = 0; i < num_grid_locs_grid_locs; i++) { + auto grid_locs_grid_loc = grid_locs_grid_locs[i]; + auto child_context = in.get_grid_locs_grid_loc(i, context); + grid_locs_grid_loc.setBlockTypeId(in.get_grid_loc_block_type_id(child_context)); + grid_locs_grid_loc.setHeightOffset(in.get_grid_loc_height_offset(child_context)); + grid_locs_grid_loc.setWidthOffset(in.get_grid_loc_width_offset(child_context)); + grid_locs_grid_loc.setX(in.get_grid_loc_x(child_context)); + grid_locs_grid_loc.setY(in.get_grid_loc_y(child_context)); + } } template -inline void write_meta_capnp_type(T& in, ucap::Meta::Builder& root, Context& context) { - (void)in; - (void)root; - root.setValue(in.get_meta_value(context)); +inline void write_meta_capnp_type(T &in, ucap::Meta::Builder &root, Context &context) { + (void)in; + (void)root; + root.setValue(in.get_meta_value(context)); } template -inline void write_metadata_capnp_type(T& in, ucap::Metadata::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_metadata_metas = in.num_metadata_meta(context); - auto metadata_metas = root.initMetas(num_metadata_metas); - for (size_t i = 0; i < num_metadata_metas; i++) { - auto metadata_meta = metadata_metas[i]; - auto child_context = in.get_metadata_meta(i, context); - metadata_meta.setName(in.get_meta_name(child_context)); - write_meta_capnp_type(in, metadata_meta, child_context); - } +inline void write_metadata_capnp_type(T &in, ucap::Metadata::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_metadata_metas = in.num_metadata_meta(context); + auto metadata_metas = root.initMetas(num_metadata_metas); + for(size_t i = 0; i < num_metadata_metas; i++) { + auto metadata_meta = metadata_metas[i]; + auto child_context = in.get_metadata_meta(i, context); + metadata_meta.setName(in.get_meta_name(child_context)); + write_meta_capnp_type(in, metadata_meta, child_context); + } } template -inline void write_node_capnp_type(T& in, ucap::Node::Builder& root, Context& context) { - (void)in; - (void)root; - - { - auto child_context = in.get_node_loc(context); - auto node_loc = root.initLoc(); - node_loc.setPtc(in.get_node_loc_ptc(child_context)); - if ((bool)in.get_node_loc_side(child_context)) - node_loc.setSide(conv_to_enum_loc_side(in.get_node_loc_side(child_context))); - node_loc.setXhigh(in.get_node_loc_xhigh(child_context)); - node_loc.setXlow(in.get_node_loc_xlow(child_context)); - node_loc.setYhigh(in.get_node_loc_yhigh(child_context)); - node_loc.setYlow(in.get_node_loc_ylow(child_context)); - } - - if (in.has_node_timing(context)) { - auto node_timing = root.initTiming(); - auto child_context = in.get_node_timing(context); - node_timing.setC(in.get_node_timing_C(child_context)); - node_timing.setR(in.get_node_timing_R(child_context)); - } - - if (in.has_node_segment(context)) { - auto node_segment = root.initSegment(); - auto child_context = in.get_node_segment(context); - node_segment.setSegmentId(in.get_node_segment_segment_id(child_context)); - } - - if (in.has_node_metadata(context)) { - auto node_metadata = root.initMetadata(); - auto child_context = in.get_node_metadata(context); - write_metadata_capnp_type(in, node_metadata, child_context); - } +inline void write_node_capnp_type(T &in, ucap::Node::Builder &root, Context &context) { + (void)in; + (void)root; + + { + auto child_context = in.get_node_loc(context); + auto node_loc = root.initLoc(); + node_loc.setPtc(in.get_node_loc_ptc(child_context)); + if((bool)in.get_node_loc_side(child_context)) + node_loc.setSide(conv_to_enum_loc_side(in.get_node_loc_side(child_context))); + node_loc.setXhigh(in.get_node_loc_xhigh(child_context)); + node_loc.setXlow(in.get_node_loc_xlow(child_context)); + node_loc.setYhigh(in.get_node_loc_yhigh(child_context)); + node_loc.setYlow(in.get_node_loc_ylow(child_context)); + } + + if(in.has_node_timing(context)){ + auto node_timing = root.initTiming(); + auto child_context = in.get_node_timing(context); + node_timing.setC(in.get_node_timing_C(child_context)); + node_timing.setR(in.get_node_timing_R(child_context)); + } + + if(in.has_node_segment(context)){ + auto node_segment = root.initSegment(); + auto child_context = in.get_node_segment(context); + node_segment.setSegmentId(in.get_node_segment_segment_id(child_context)); + } + + if(in.has_node_metadata(context)){ + auto node_metadata = root.initMetadata(); + auto child_context = in.get_node_metadata(context); + write_metadata_capnp_type(in, node_metadata, child_context); + } } template -inline void write_rr_nodes_capnp_type(T& in, ucap::RrNodes::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_rr_nodes_nodes = in.num_rr_nodes_node(context); - auto rr_nodes_nodes = root.initNodes(num_rr_nodes_nodes); - for (size_t i = 0; i < num_rr_nodes_nodes; i++) { - auto rr_nodes_node = rr_nodes_nodes[i]; - auto child_context = in.get_rr_nodes_node(i, context); - rr_nodes_node.setCapacity(in.get_node_capacity(child_context)); - if ((bool)in.get_node_direction(child_context)) - rr_nodes_node.setDirection(conv_to_enum_node_direction(in.get_node_direction(child_context))); - rr_nodes_node.setId(in.get_node_id(child_context)); - rr_nodes_node.setType(conv_to_enum_node_type(in.get_node_type(child_context))); - write_node_capnp_type(in, rr_nodes_node, child_context); - } +inline void write_rr_nodes_capnp_type(T &in, ucap::RrNodes::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_rr_nodes_nodes = in.num_rr_nodes_node(context); + auto rr_nodes_nodes = root.initNodes(num_rr_nodes_nodes); + for(size_t i = 0; i < num_rr_nodes_nodes; i++) { + auto rr_nodes_node = rr_nodes_nodes[i]; + auto child_context = in.get_rr_nodes_node(i, context); + rr_nodes_node.setCapacity(in.get_node_capacity(child_context)); + if((bool)in.get_node_direction(child_context)) + rr_nodes_node.setDirection(conv_to_enum_node_direction(in.get_node_direction(child_context))); + rr_nodes_node.setId(in.get_node_id(child_context)); + rr_nodes_node.setType(conv_to_enum_node_type(in.get_node_type(child_context))); + write_node_capnp_type(in, rr_nodes_node, child_context); + } } template -inline void write_edge_capnp_type(T& in, ucap::Edge::Builder& root, Context& context) { - (void)in; - (void)root; - - if (in.has_edge_metadata(context)) { - auto edge_metadata = root.initMetadata(); - auto child_context = in.get_edge_metadata(context); - write_metadata_capnp_type(in, edge_metadata, child_context); - } +inline void write_edge_capnp_type(T &in, ucap::Edge::Builder &root, Context &context) { + (void)in; + (void)root; + + if(in.has_edge_metadata(context)){ + auto edge_metadata = root.initMetadata(); + auto child_context = in.get_edge_metadata(context); + write_metadata_capnp_type(in, edge_metadata, child_context); + } } template -inline void write_rr_edges_capnp_type(T& in, ucap::RrEdges::Builder& root, Context& context) { - (void)in; - (void)root; - - size_t num_rr_edges_edges = in.num_rr_edges_edge(context); - auto rr_edges_edges = root.initEdges(num_rr_edges_edges); - for (size_t i = 0; i < num_rr_edges_edges; i++) { - auto rr_edges_edge = rr_edges_edges[i]; - auto child_context = in.get_rr_edges_edge(i, context); - rr_edges_edge.setSinkNode(in.get_edge_sink_node(child_context)); - rr_edges_edge.setSrcNode(in.get_edge_src_node(child_context)); - rr_edges_edge.setSwitchId(in.get_edge_switch_id(child_context)); - write_edge_capnp_type(in, rr_edges_edge, child_context); - } +inline void write_rr_edges_capnp_type(T &in, ucap::RrEdges::Builder &root, Context &context) { + (void)in; + (void)root; + + size_t num_rr_edges_edges = in.num_rr_edges_edge(context); + auto rr_edges_edges = root.initEdges(num_rr_edges_edges); + for(size_t i = 0; i < num_rr_edges_edges; i++) { + auto rr_edges_edge = rr_edges_edges[i]; + auto child_context = in.get_rr_edges_edge(i, context); + rr_edges_edge.setSinkNode(in.get_edge_sink_node(child_context)); + rr_edges_edge.setSrcNode(in.get_edge_src_node(child_context)); + rr_edges_edge.setSwitchId(in.get_edge_switch_id(child_context)); + write_edge_capnp_type(in, rr_edges_edge, child_context); + } } template -inline void write_rr_graph_capnp_type(T& in, ucap::RrGraph::Builder& root, Context& context) { - (void)in; - (void)root; - - { - auto child_context = in.get_rr_graph_channels(context); - auto rr_graph_channels = root.initChannels(); - write_channels_capnp_type(in, rr_graph_channels, child_context); - } - - { - auto child_context = in.get_rr_graph_switches(context); - auto rr_graph_switches = root.initSwitches(); - write_switches_capnp_type(in, rr_graph_switches, child_context); - } - - { - auto child_context = in.get_rr_graph_segments(context); - auto rr_graph_segments = root.initSegments(); - write_segments_capnp_type(in, rr_graph_segments, child_context); - } - - { - auto child_context = in.get_rr_graph_block_types(context); - auto rr_graph_block_types = root.initBlockTypes(); - write_block_types_capnp_type(in, rr_graph_block_types, child_context); - } - - { - auto child_context = in.get_rr_graph_grid(context); - auto rr_graph_grid = root.initGrid(); - write_grid_locs_capnp_type(in, rr_graph_grid, child_context); - } - - { - auto child_context = in.get_rr_graph_rr_nodes(context); - auto rr_graph_rr_nodes = root.initRrNodes(); - write_rr_nodes_capnp_type(in, rr_graph_rr_nodes, child_context); - } - - { - auto child_context = in.get_rr_graph_rr_edges(context); - auto rr_graph_rr_edges = root.initRrEdges(); - write_rr_edges_capnp_type(in, rr_graph_rr_edges, child_context); - } +inline void write_rr_graph_capnp_type(T &in, ucap::RrGraph::Builder &root, Context &context) { + (void)in; + (void)root; + + { + auto child_context = in.get_rr_graph_channels(context); + auto rr_graph_channels = root.initChannels(); + write_channels_capnp_type(in, rr_graph_channels, child_context); + } + + { + auto child_context = in.get_rr_graph_switches(context); + auto rr_graph_switches = root.initSwitches(); + write_switches_capnp_type(in, rr_graph_switches, child_context); + } + + { + auto child_context = in.get_rr_graph_segments(context); + auto rr_graph_segments = root.initSegments(); + write_segments_capnp_type(in, rr_graph_segments, child_context); + } + + { + auto child_context = in.get_rr_graph_block_types(context); + auto rr_graph_block_types = root.initBlockTypes(); + write_block_types_capnp_type(in, rr_graph_block_types, child_context); + } + + { + auto child_context = in.get_rr_graph_grid(context); + auto rr_graph_grid = root.initGrid(); + write_grid_locs_capnp_type(in, rr_graph_grid, child_context); + } + + { + auto child_context = in.get_rr_graph_rr_nodes(context); + auto rr_graph_rr_nodes = root.initRrNodes(); + write_rr_nodes_capnp_type(in, rr_graph_rr_nodes, child_context); + } + + { + auto child_context = in.get_rr_graph_rr_edges(context); + auto rr_graph_rr_edges = root.initRrEdges(); + write_rr_edges_capnp_type(in, rr_graph_rr_edges, child_context); + } } + } /* namespace uxsd */ diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h index 56f8aa8f56d..69795c800ca 100644 --- a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h +++ b/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h @@ -4,13 +4,14 @@ * https://github.com/duck2/uxsdcxx * Modify only if your build process doesn't involve regenerating this file. * - * Cmdline: uxsdcxx/uxsdcxx.py /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * Input file: /research/ece/lnis/USERS/tang/github/vtr-verilog-to-routing/vpr/src/route/rr_graph.xsd - * md5sum of input file: cd57d47fc9dfa62c7030397ca759217e + * Cmdline: uxsdcxx/uxsdcxx.py /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * Input file: /home/oscar/Desktop/vtr-new/libs/librrgraph/src/base/rr_graph.xsd + * md5sum of input file: 41df83ecf127a53590711ddec605742a */ #include + /* All uxsdcxx functions and structs live in this namespace. */ #include @@ -20,556 +21,524 @@ namespace uxsd { /* Enum tokens generated from XSD enumerations. */ -enum class enum_switch_type { UXSD_INVALID = 0, - MUX, - TRISTATE, - PASS_GATE, - SHORT, - BUFFER }; - -enum class enum_pin_type { UXSD_INVALID = 0, - OPEN, - OUTPUT, - INPUT }; - -enum class enum_node_type { UXSD_INVALID = 0, - CHANX, - CHANY, - SOURCE, - SINK, - OPIN, - IPIN }; - -enum class enum_node_direction { UXSD_INVALID = 0, - INC_DIR, - DEC_DIR, - BI_DIR }; - -enum class enum_loc_side { UXSD_INVALID = 0, - LEFT, - RIGHT, - TOP, - BOTTOM, - RIGHT_LEFT, - RIGHT_BOTTOM, - RIGHT_BOTTOM_LEFT, - TOP_RIGHT, - TOP_BOTTOM, - TOP_LEFT, - TOP_RIGHT_BOTTOM, - TOP_RIGHT_LEFT, - TOP_BOTTOM_LEFT, - TOP_RIGHT_BOTTOM_LEFT, - BOTTOM_LEFT }; +enum class enum_switch_type {UXSD_INVALID = 0, MUX, TRISTATE, PASS_GATE, SHORT, BUFFER}; + +enum class enum_pin_type {UXSD_INVALID = 0, OPEN, OUTPUT, INPUT}; + +enum class enum_node_type {UXSD_INVALID = 0, CHANX, CHANY, SOURCE, SINK, OPIN, IPIN}; + +enum class enum_node_direction {UXSD_INVALID = 0, INC_DIR, DEC_DIR, BI_DIR}; + +enum class enum_loc_side {UXSD_INVALID = 0, LEFT, RIGHT, TOP, BOTTOM, RIGHT_LEFT, RIGHT_BOTTOM, RIGHT_BOTTOM_LEFT, TOP_RIGHT, TOP_BOTTOM, TOP_LEFT, TOP_RIGHT_BOTTOM, TOP_RIGHT_LEFT, TOP_BOTTOM_LEFT, TOP_RIGHT_BOTTOM_LEFT, BOTTOM_LEFT}; /* Base class for the schema. */ struct DefaultRrGraphContextTypes { - using ChannelReadContext = void*; - using XListReadContext = void*; - using YListReadContext = void*; - using ChannelsReadContext = void*; - using TimingReadContext = void*; - using SizingReadContext = void*; - using SwitchReadContext = void*; - using SwitchesReadContext = void*; - using SegmentTimingReadContext = void*; - using SegmentReadContext = void*; - using SegmentsReadContext = void*; - using PinReadContext = void*; - using PinClassReadContext = void*; - using BlockTypeReadContext = void*; - using BlockTypesReadContext = void*; - using GridLocReadContext = void*; - using GridLocsReadContext = void*; - using NodeLocReadContext = void*; - using NodeTimingReadContext = void*; - using NodeSegmentReadContext = void*; - using MetaReadContext = void*; - using MetadataReadContext = void*; - using NodeReadContext = void*; - using RrNodesReadContext = void*; - using EdgeReadContext = void*; - using RrEdgesReadContext = void*; - using RrGraphReadContext = void*; - using ChannelWriteContext = void*; - using XListWriteContext = void*; - using YListWriteContext = void*; - using ChannelsWriteContext = void*; - using TimingWriteContext = void*; - using SizingWriteContext = void*; - using SwitchWriteContext = void*; - using SwitchesWriteContext = void*; - using SegmentTimingWriteContext = void*; - using SegmentWriteContext = void*; - using SegmentsWriteContext = void*; - using PinWriteContext = void*; - using PinClassWriteContext = void*; - using BlockTypeWriteContext = void*; - using BlockTypesWriteContext = void*; - using GridLocWriteContext = void*; - using GridLocsWriteContext = void*; - using NodeLocWriteContext = void*; - using NodeTimingWriteContext = void*; - using NodeSegmentWriteContext = void*; - using MetaWriteContext = void*; - using MetadataWriteContext = void*; - using NodeWriteContext = void*; - using RrNodesWriteContext = void*; - using EdgeWriteContext = void*; - using RrEdgesWriteContext = void*; - using RrGraphWriteContext = void*; +using ChannelReadContext = void *; + using XListReadContext = void *; + using YListReadContext = void *; + using ChannelsReadContext = void *; + using TimingReadContext = void *; + using SizingReadContext = void *; + using SwitchReadContext = void *; + using SwitchesReadContext = void *; + using SegmentTimingReadContext = void *; + using SegmentReadContext = void *; + using SegmentsReadContext = void *; + using PinReadContext = void *; + using PinClassReadContext = void *; + using BlockTypeReadContext = void *; + using BlockTypesReadContext = void *; + using GridLocReadContext = void *; + using GridLocsReadContext = void *; + using NodeLocReadContext = void *; + using NodeTimingReadContext = void *; + using NodeSegmentReadContext = void *; + using MetaReadContext = void *; + using MetadataReadContext = void *; + using NodeReadContext = void *; + using RrNodesReadContext = void *; + using EdgeReadContext = void *; + using RrEdgesReadContext = void *; + using RrGraphReadContext = void *; +using ChannelWriteContext = void *; + using XListWriteContext = void *; + using YListWriteContext = void *; + using ChannelsWriteContext = void *; + using TimingWriteContext = void *; + using SizingWriteContext = void *; + using SwitchWriteContext = void *; + using SwitchesWriteContext = void *; + using SegmentTimingWriteContext = void *; + using SegmentWriteContext = void *; + using SegmentsWriteContext = void *; + using PinWriteContext = void *; + using PinClassWriteContext = void *; + using BlockTypeWriteContext = void *; + using BlockTypesWriteContext = void *; + using GridLocWriteContext = void *; + using GridLocsWriteContext = void *; + using NodeLocWriteContext = void *; + using NodeTimingWriteContext = void *; + using NodeSegmentWriteContext = void *; + using MetaWriteContext = void *; + using MetadataWriteContext = void *; + using NodeWriteContext = void *; + using RrNodesWriteContext = void *; + using EdgeWriteContext = void *; + using RrEdgesWriteContext = void *; + using RrGraphWriteContext = void *; }; -template +template class RrGraphBase { - public: - virtual ~RrGraphBase() {} - virtual void start_load(const std::function* report_error) = 0; - virtual void finish_load() = 0; - virtual void start_write() = 0; - virtual void finish_write() = 0; - virtual void error_encountered(const char* file, int line, const char* message) = 0; - /** Generated for complex type "channel": - * - * - * - * - * - * - * - */ - virtual inline int get_channel_chan_width_max(typename ContextTypes::ChannelReadContext& ctx) = 0; - virtual inline int get_channel_x_max(typename ContextTypes::ChannelReadContext& ctx) = 0; - virtual inline int get_channel_x_min(typename ContextTypes::ChannelReadContext& ctx) = 0; - virtual inline int get_channel_y_max(typename ContextTypes::ChannelReadContext& ctx) = 0; - virtual inline int get_channel_y_min(typename ContextTypes::ChannelReadContext& ctx) = 0; - - /** Generated for complex type "x_list": - * - * - * - * - * - */ - virtual inline unsigned int get_x_list_index(typename ContextTypes::XListReadContext& ctx) = 0; - virtual inline int get_x_list_info(typename ContextTypes::XListReadContext& ctx) = 0; - - /** Generated for complex type "y_list": - * - * - * - * - */ - virtual inline unsigned int get_y_list_index(typename ContextTypes::YListReadContext& ctx) = 0; - virtual inline int get_y_list_info(typename ContextTypes::YListReadContext& ctx) = 0; - - /** Generated for complex type "channels": - * - * - * - * - * - * - * - */ - virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext& ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; - virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext& ctx) = 0; - virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext& ctx) = 0; - virtual inline void preallocate_channels_x_list(typename ContextTypes::ChannelsWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::XListWriteContext add_channels_x_list(typename ContextTypes::ChannelsWriteContext& ctx, unsigned int index, int info) = 0; - virtual inline void finish_channels_x_list(typename ContextTypes::XListWriteContext& ctx) = 0; - virtual inline size_t num_channels_x_list(typename ContextTypes::ChannelsReadContext& ctx) = 0; - virtual inline typename ContextTypes::XListReadContext get_channels_x_list(int n, typename ContextTypes::ChannelsReadContext& ctx) = 0; - virtual inline void preallocate_channels_y_list(typename ContextTypes::ChannelsWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::YListWriteContext add_channels_y_list(typename ContextTypes::ChannelsWriteContext& ctx, unsigned int index, int info) = 0; - virtual inline void finish_channels_y_list(typename ContextTypes::YListWriteContext& ctx) = 0; - virtual inline size_t num_channels_y_list(typename ContextTypes::ChannelsReadContext& ctx) = 0; - virtual inline typename ContextTypes::YListReadContext get_channels_y_list(int n, typename ContextTypes::ChannelsReadContext& ctx) = 0; - - /** Generated for complex type "timing": - * - * - * - * - * - * - * - * - */ - virtual inline float get_timing_Cin(typename ContextTypes::TimingReadContext& ctx) = 0; - virtual inline void set_timing_Cin(float Cin, typename ContextTypes::TimingWriteContext& ctx) = 0; - virtual inline float get_timing_Cinternal(typename ContextTypes::TimingReadContext& ctx) = 0; - virtual inline void set_timing_Cinternal(float Cinternal, typename ContextTypes::TimingWriteContext& ctx) = 0; - virtual inline float get_timing_Cout(typename ContextTypes::TimingReadContext& ctx) = 0; - virtual inline void set_timing_Cout(float Cout, typename ContextTypes::TimingWriteContext& ctx) = 0; - virtual inline float get_timing_R(typename ContextTypes::TimingReadContext& ctx) = 0; - virtual inline void set_timing_R(float R, typename ContextTypes::TimingWriteContext& ctx) = 0; - virtual inline float get_timing_Tdel(typename ContextTypes::TimingReadContext& ctx) = 0; - virtual inline void set_timing_Tdel(float Tdel, typename ContextTypes::TimingWriteContext& ctx) = 0; - - /** Generated for complex type "sizing": - * - * - * - * - */ - virtual inline float get_sizing_buf_size(typename ContextTypes::SizingReadContext& ctx) = 0; - virtual inline float get_sizing_mux_trans_size(typename ContextTypes::SizingReadContext& ctx) = 0; - - /** Generated for complex type "switch": - * - * - * - * - * - * - * - * - * - * - * - */ - virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext& ctx) = 0; - virtual inline const char* get_switch_name(typename ContextTypes::SwitchReadContext& ctx) = 0; - virtual inline void set_switch_name(const char* name, typename ContextTypes::SwitchWriteContext& ctx) = 0; - virtual inline enum_switch_type get_switch_type(typename ContextTypes::SwitchReadContext& ctx) = 0; - virtual inline void set_switch_type(enum_switch_type type, typename ContextTypes::SwitchWriteContext& ctx) = 0; - virtual inline typename ContextTypes::TimingWriteContext init_switch_timing(typename ContextTypes::SwitchWriteContext& ctx) = 0; - virtual inline void finish_switch_timing(typename ContextTypes::TimingWriteContext& ctx) = 0; - virtual inline typename ContextTypes::TimingReadContext get_switch_timing(typename ContextTypes::SwitchReadContext& ctx) = 0; - virtual inline bool has_switch_timing(typename ContextTypes::SwitchReadContext& ctx) = 0; - virtual inline typename ContextTypes::SizingWriteContext init_switch_sizing(typename ContextTypes::SwitchWriteContext& ctx, float buf_size, float mux_trans_size) = 0; - virtual inline void finish_switch_sizing(typename ContextTypes::SizingWriteContext& ctx) = 0; - virtual inline typename ContextTypes::SizingReadContext get_switch_sizing(typename ContextTypes::SwitchReadContext& ctx) = 0; - - /** Generated for complex type "switches": - * - * - * - * - * - */ - virtual inline void preallocate_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::SwitchWriteContext add_switches_switch(typename ContextTypes::SwitchesWriteContext& ctx, int id) = 0; - virtual inline void finish_switches_switch(typename ContextTypes::SwitchWriteContext& ctx) = 0; - virtual inline size_t num_switches_switch(typename ContextTypes::SwitchesReadContext& ctx) = 0; - virtual inline typename ContextTypes::SwitchReadContext get_switches_switch(int n, typename ContextTypes::SwitchesReadContext& ctx) = 0; - - /** Generated for complex type "segment_timing": - * - * - * - * - */ - virtual inline float get_segment_timing_C_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; - virtual inline void set_segment_timing_C_per_meter(float C_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; - virtual inline float get_segment_timing_R_per_meter(typename ContextTypes::SegmentTimingReadContext& ctx) = 0; - virtual inline void set_segment_timing_R_per_meter(float R_per_meter, typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; - - /** Generated for complex type "segment": - * - * - * - * - * - * - * - */ - virtual inline int get_segment_id(typename ContextTypes::SegmentReadContext& ctx) = 0; - virtual inline const char* get_segment_name(typename ContextTypes::SegmentReadContext& ctx) = 0; - virtual inline void set_segment_name(const char* name, typename ContextTypes::SegmentWriteContext& ctx) = 0; - virtual inline typename ContextTypes::SegmentTimingWriteContext init_segment_timing(typename ContextTypes::SegmentWriteContext& ctx) = 0; - virtual inline void finish_segment_timing(typename ContextTypes::SegmentTimingWriteContext& ctx) = 0; - virtual inline typename ContextTypes::SegmentTimingReadContext get_segment_timing(typename ContextTypes::SegmentReadContext& ctx) = 0; - virtual inline bool has_segment_timing(typename ContextTypes::SegmentReadContext& ctx) = 0; - - /** Generated for complex type "segments": - * - * - * - * - * - */ - virtual inline void preallocate_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::SegmentWriteContext add_segments_segment(typename ContextTypes::SegmentsWriteContext& ctx, int id) = 0; - virtual inline void finish_segments_segment(typename ContextTypes::SegmentWriteContext& ctx) = 0; - virtual inline size_t num_segments_segment(typename ContextTypes::SegmentsReadContext& ctx) = 0; - virtual inline typename ContextTypes::SegmentReadContext get_segments_segment(int n, typename ContextTypes::SegmentsReadContext& ctx) = 0; - - /** Generated for complex type "pin": - * - * - * - * - * - * - * - */ - virtual inline int get_pin_ptc(typename ContextTypes::PinReadContext& ctx) = 0; - virtual inline void set_pin_value(const char* value, typename ContextTypes::PinWriteContext& ctx) = 0; - virtual inline const char* get_pin_value(typename ContextTypes::PinReadContext& ctx) = 0; - - /** Generated for complex type "pin_class": - * - * - * - * - * - * - */ - virtual inline enum_pin_type get_pin_class_type(typename ContextTypes::PinClassReadContext& ctx) = 0; - virtual inline void preallocate_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::PinWriteContext add_pin_class_pin(typename ContextTypes::PinClassWriteContext& ctx, int ptc) = 0; - virtual inline void finish_pin_class_pin(typename ContextTypes::PinWriteContext& ctx) = 0; - virtual inline size_t num_pin_class_pin(typename ContextTypes::PinClassReadContext& ctx) = 0; - virtual inline typename ContextTypes::PinReadContext get_pin_class_pin(int n, typename ContextTypes::PinClassReadContext& ctx) = 0; - - /** Generated for complex type "block_type": - * - * - * - * - * - * - * - * - * - */ - virtual inline int get_block_type_height(typename ContextTypes::BlockTypeReadContext& ctx) = 0; - virtual inline int get_block_type_id(typename ContextTypes::BlockTypeReadContext& ctx) = 0; - virtual inline const char* get_block_type_name(typename ContextTypes::BlockTypeReadContext& ctx) = 0; - virtual inline void set_block_type_name(const char* name, typename ContextTypes::BlockTypeWriteContext& ctx) = 0; - virtual inline int get_block_type_width(typename ContextTypes::BlockTypeReadContext& ctx) = 0; - virtual inline void preallocate_block_type_pin_class(typename ContextTypes::BlockTypeWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::PinClassWriteContext add_block_type_pin_class(typename ContextTypes::BlockTypeWriteContext& ctx, enum_pin_type type) = 0; - virtual inline void finish_block_type_pin_class(typename ContextTypes::PinClassWriteContext& ctx) = 0; - virtual inline size_t num_block_type_pin_class(typename ContextTypes::BlockTypeReadContext& ctx) = 0; - virtual inline typename ContextTypes::PinClassReadContext get_block_type_pin_class(int n, typename ContextTypes::BlockTypeReadContext& ctx) = 0; - - /** Generated for complex type "block_types": - * - * - * - * - * - */ - virtual inline void preallocate_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::BlockTypeWriteContext add_block_types_block_type(typename ContextTypes::BlockTypesWriteContext& ctx, int height, int id, int width) = 0; - virtual inline void finish_block_types_block_type(typename ContextTypes::BlockTypeWriteContext& ctx) = 0; - virtual inline size_t num_block_types_block_type(typename ContextTypes::BlockTypesReadContext& ctx) = 0; - virtual inline typename ContextTypes::BlockTypeReadContext get_block_types_block_type(int n, typename ContextTypes::BlockTypesReadContext& ctx) = 0; - - /** Generated for complex type "grid_loc": - * - * - * - * - * - * - * - */ - virtual inline int get_grid_loc_block_type_id(typename ContextTypes::GridLocReadContext& ctx) = 0; - virtual inline int get_grid_loc_height_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; - virtual inline int get_grid_loc_width_offset(typename ContextTypes::GridLocReadContext& ctx) = 0; - virtual inline int get_grid_loc_x(typename ContextTypes::GridLocReadContext& ctx) = 0; - virtual inline int get_grid_loc_y(typename ContextTypes::GridLocReadContext& ctx) = 0; - - /** Generated for complex type "grid_locs": - * - * - * - * - * - */ - virtual inline void preallocate_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::GridLocWriteContext add_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext& ctx, int block_type_id, int height_offset, int width_offset, int x, int y) = 0; - virtual inline void finish_grid_locs_grid_loc(typename ContextTypes::GridLocWriteContext& ctx) = 0; - virtual inline size_t num_grid_locs_grid_loc(typename ContextTypes::GridLocsReadContext& ctx) = 0; - virtual inline typename ContextTypes::GridLocReadContext get_grid_locs_grid_loc(int n, typename ContextTypes::GridLocsReadContext& ctx) = 0; - - /** Generated for complex type "node_loc": - * - * - * - * - * - * - * - * - */ - virtual inline int get_node_loc_ptc(typename ContextTypes::NodeLocReadContext& ctx) = 0; - virtual inline enum_loc_side get_node_loc_side(typename ContextTypes::NodeLocReadContext& ctx) = 0; - virtual inline void set_node_loc_side(enum_loc_side side, typename ContextTypes::NodeLocWriteContext& ctx) = 0; - virtual inline int get_node_loc_xhigh(typename ContextTypes::NodeLocReadContext& ctx) = 0; - virtual inline int get_node_loc_xlow(typename ContextTypes::NodeLocReadContext& ctx) = 0; - virtual inline int get_node_loc_yhigh(typename ContextTypes::NodeLocReadContext& ctx) = 0; - virtual inline int get_node_loc_ylow(typename ContextTypes::NodeLocReadContext& ctx) = 0; - - /** Generated for complex type "node_timing": - * - * - * - * - */ - virtual inline float get_node_timing_C(typename ContextTypes::NodeTimingReadContext& ctx) = 0; - virtual inline float get_node_timing_R(typename ContextTypes::NodeTimingReadContext& ctx) = 0; - - /** Generated for complex type "node_segment": - * - * - * - */ - virtual inline int get_node_segment_segment_id(typename ContextTypes::NodeSegmentReadContext& ctx) = 0; - - /** Generated for complex type "meta": - * - * - * - * - * - * - * - */ - virtual inline const char* get_meta_name(typename ContextTypes::MetaReadContext& ctx) = 0; - virtual inline void set_meta_name(const char* name, typename ContextTypes::MetaWriteContext& ctx) = 0; - virtual inline void set_meta_value(const char* value, typename ContextTypes::MetaWriteContext& ctx) = 0; - virtual inline const char* get_meta_value(typename ContextTypes::MetaReadContext& ctx) = 0; - - /** Generated for complex type "metadata": - * - * - * - * - * - */ - virtual inline void preallocate_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::MetaWriteContext add_metadata_meta(typename ContextTypes::MetadataWriteContext& ctx) = 0; - virtual inline void finish_metadata_meta(typename ContextTypes::MetaWriteContext& ctx) = 0; - virtual inline size_t num_metadata_meta(typename ContextTypes::MetadataReadContext& ctx) = 0; - virtual inline typename ContextTypes::MetaReadContext get_metadata_meta(int n, typename ContextTypes::MetadataReadContext& ctx) = 0; - - /** Generated for complex type "node": - * - * - * - * - * - * - * - * - * - * - * - * - */ - virtual inline unsigned int get_node_capacity(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline enum_node_direction get_node_direction(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline void set_node_direction(enum_node_direction direction, typename ContextTypes::NodeWriteContext& ctx) = 0; - virtual inline unsigned int get_node_id(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline enum_node_type get_node_type(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline typename ContextTypes::NodeLocWriteContext init_node_loc(typename ContextTypes::NodeWriteContext& ctx, int ptc, int xhigh, int xlow, int yhigh, int ylow) = 0; - virtual inline void finish_node_loc(typename ContextTypes::NodeLocWriteContext& ctx) = 0; - virtual inline typename ContextTypes::NodeLocReadContext get_node_loc(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline typename ContextTypes::NodeTimingWriteContext init_node_timing(typename ContextTypes::NodeWriteContext& ctx, float C, float R) = 0; - virtual inline void finish_node_timing(typename ContextTypes::NodeTimingWriteContext& ctx) = 0; - virtual inline typename ContextTypes::NodeTimingReadContext get_node_timing(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline bool has_node_timing(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline typename ContextTypes::NodeSegmentWriteContext init_node_segment(typename ContextTypes::NodeWriteContext& ctx, int segment_id) = 0; - virtual inline void finish_node_segment(typename ContextTypes::NodeSegmentWriteContext& ctx) = 0; - virtual inline typename ContextTypes::NodeSegmentReadContext get_node_segment(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline bool has_node_segment(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline typename ContextTypes::MetadataWriteContext init_node_metadata(typename ContextTypes::NodeWriteContext& ctx) = 0; - virtual inline void finish_node_metadata(typename ContextTypes::MetadataWriteContext& ctx) = 0; - virtual inline typename ContextTypes::MetadataReadContext get_node_metadata(typename ContextTypes::NodeReadContext& ctx) = 0; - virtual inline bool has_node_metadata(typename ContextTypes::NodeReadContext& ctx) = 0; - - /** Generated for complex type "rr_nodes": - * - * - * - * - * - */ - virtual inline void preallocate_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::NodeWriteContext add_rr_nodes_node(typename ContextTypes::RrNodesWriteContext& ctx, unsigned int capacity, unsigned int id, enum_node_type type) = 0; - virtual inline void finish_rr_nodes_node(typename ContextTypes::NodeWriteContext& ctx) = 0; - virtual inline size_t num_rr_nodes_node(typename ContextTypes::RrNodesReadContext& ctx) = 0; - virtual inline typename ContextTypes::NodeReadContext get_rr_nodes_node(int n, typename ContextTypes::RrNodesReadContext& ctx) = 0; - - /** Generated for complex type "edge": - * - * - * - * - * - * - * - * - */ - virtual inline unsigned int get_edge_sink_node(typename ContextTypes::EdgeReadContext& ctx) = 0; - virtual inline unsigned int get_edge_src_node(typename ContextTypes::EdgeReadContext& ctx) = 0; - virtual inline unsigned int get_edge_switch_id(typename ContextTypes::EdgeReadContext& ctx) = 0; - virtual inline typename ContextTypes::MetadataWriteContext init_edge_metadata(typename ContextTypes::EdgeWriteContext& ctx) = 0; - virtual inline void finish_edge_metadata(typename ContextTypes::MetadataWriteContext& ctx) = 0; - virtual inline typename ContextTypes::MetadataReadContext get_edge_metadata(typename ContextTypes::EdgeReadContext& ctx) = 0; - virtual inline bool has_edge_metadata(typename ContextTypes::EdgeReadContext& ctx) = 0; - - /** Generated for complex type "rr_edges": - * - * - * - * - * - */ - virtual inline void preallocate_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, size_t size) = 0; - virtual inline typename ContextTypes::EdgeWriteContext add_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext& ctx, unsigned int sink_node, unsigned int src_node, unsigned int switch_id) = 0; - virtual inline void finish_rr_edges_edge(typename ContextTypes::EdgeWriteContext& ctx) = 0; - virtual inline size_t num_rr_edges_edge(typename ContextTypes::RrEdgesReadContext& ctx) = 0; - virtual inline typename ContextTypes::EdgeReadContext get_rr_edges_edge(int n, typename ContextTypes::RrEdgesReadContext& ctx) = 0; - - /** Generated for complex type "rr_graph": - * - * - * - * - * - * - * - * - * - * - * - * - * - * - */ - virtual inline const char* get_rr_graph_tool_comment(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline void set_rr_graph_tool_comment(const char* tool_comment, typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline const char* get_rr_graph_tool_name(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline void set_rr_graph_tool_name(const char* tool_name, typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline const char* get_rr_graph_tool_version(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline void set_rr_graph_tool_version(const char* tool_version, typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline typename ContextTypes::ChannelsWriteContext init_rr_graph_channels(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_channels(typename ContextTypes::ChannelsWriteContext& ctx) = 0; - virtual inline typename ContextTypes::ChannelsReadContext get_rr_graph_channels(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::SwitchesWriteContext init_rr_graph_switches(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_switches(typename ContextTypes::SwitchesWriteContext& ctx) = 0; - virtual inline typename ContextTypes::SwitchesReadContext get_rr_graph_switches(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::SegmentsWriteContext init_rr_graph_segments(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_segments(typename ContextTypes::SegmentsWriteContext& ctx) = 0; - virtual inline typename ContextTypes::SegmentsReadContext get_rr_graph_segments(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::BlockTypesWriteContext init_rr_graph_block_types(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_block_types(typename ContextTypes::BlockTypesWriteContext& ctx) = 0; - virtual inline typename ContextTypes::BlockTypesReadContext get_rr_graph_block_types(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::GridLocsWriteContext init_rr_graph_grid(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_grid(typename ContextTypes::GridLocsWriteContext& ctx) = 0; - virtual inline typename ContextTypes::GridLocsReadContext get_rr_graph_grid(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::RrNodesWriteContext init_rr_graph_rr_nodes(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_rr_nodes(typename ContextTypes::RrNodesWriteContext& ctx) = 0; - virtual inline typename ContextTypes::RrNodesReadContext get_rr_graph_rr_nodes(typename ContextTypes::RrGraphReadContext& ctx) = 0; - virtual inline typename ContextTypes::RrEdgesWriteContext init_rr_graph_rr_edges(typename ContextTypes::RrGraphWriteContext& ctx) = 0; - virtual inline void finish_rr_graph_rr_edges(typename ContextTypes::RrEdgesWriteContext& ctx) = 0; - virtual inline typename ContextTypes::RrEdgesReadContext get_rr_graph_rr_edges(typename ContextTypes::RrGraphReadContext& ctx) = 0; +public: + virtual ~RrGraphBase() {} + virtual void start_load(const std::function *report_error) = 0; + virtual void finish_load() = 0; + virtual void start_write() = 0; + virtual void finish_write() = 0; + virtual void error_encountered(const char * file, int line, const char *message) = 0; + /** Generated for complex type "channel": + * + * + * + * + * + * + * + */ + virtual inline int get_channel_chan_width_max(typename ContextTypes::ChannelReadContext &ctx) = 0; + virtual inline int get_channel_x_max(typename ContextTypes::ChannelReadContext &ctx) = 0; + virtual inline int get_channel_x_min(typename ContextTypes::ChannelReadContext &ctx) = 0; + virtual inline int get_channel_y_max(typename ContextTypes::ChannelReadContext &ctx) = 0; + virtual inline int get_channel_y_min(typename ContextTypes::ChannelReadContext &ctx) = 0; + + /** Generated for complex type "x_list": + * + * + * + * + * + */ + virtual inline unsigned int get_x_list_index(typename ContextTypes::XListReadContext &ctx) = 0; + virtual inline int get_x_list_info(typename ContextTypes::XListReadContext &ctx) = 0; + + /** Generated for complex type "y_list": + * + * + * + * + */ + virtual inline unsigned int get_y_list_index(typename ContextTypes::YListReadContext &ctx) = 0; + virtual inline int get_y_list_info(typename ContextTypes::YListReadContext &ctx) = 0; + + /** Generated for complex type "channels": + * + * + * + * + * + * + * + */ + virtual inline typename ContextTypes::ChannelWriteContext init_channels_channel(typename ContextTypes::ChannelsWriteContext &ctx, int chan_width_max, int x_max, int x_min, int y_max, int y_min) = 0; + virtual inline void finish_channels_channel(typename ContextTypes::ChannelWriteContext &ctx) = 0; + virtual inline typename ContextTypes::ChannelReadContext get_channels_channel(typename ContextTypes::ChannelsReadContext &ctx) = 0; + virtual inline void preallocate_channels_x_list(typename ContextTypes::ChannelsWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::XListWriteContext add_channels_x_list(typename ContextTypes::ChannelsWriteContext &ctx, unsigned int index, int info) = 0; + virtual inline void finish_channels_x_list(typename ContextTypes::XListWriteContext &ctx) = 0; + virtual inline size_t num_channels_x_list(typename ContextTypes::ChannelsReadContext &ctx) = 0; + virtual inline typename ContextTypes::XListReadContext get_channels_x_list(int n, typename ContextTypes::ChannelsReadContext &ctx) = 0; + virtual inline void preallocate_channels_y_list(typename ContextTypes::ChannelsWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::YListWriteContext add_channels_y_list(typename ContextTypes::ChannelsWriteContext &ctx, unsigned int index, int info) = 0; + virtual inline void finish_channels_y_list(typename ContextTypes::YListWriteContext &ctx) = 0; + virtual inline size_t num_channels_y_list(typename ContextTypes::ChannelsReadContext &ctx) = 0; + virtual inline typename ContextTypes::YListReadContext get_channels_y_list(int n, typename ContextTypes::ChannelsReadContext &ctx) = 0; + + /** Generated for complex type "timing": + * + * + * + * + * + * + * + * + */ + virtual inline float get_timing_Cin(typename ContextTypes::TimingReadContext &ctx) = 0; + virtual inline void set_timing_Cin(float Cin, typename ContextTypes::TimingWriteContext &ctx) = 0; + virtual inline float get_timing_Cinternal(typename ContextTypes::TimingReadContext &ctx) = 0; + virtual inline void set_timing_Cinternal(float Cinternal, typename ContextTypes::TimingWriteContext &ctx) = 0; + virtual inline float get_timing_Cout(typename ContextTypes::TimingReadContext &ctx) = 0; + virtual inline void set_timing_Cout(float Cout, typename ContextTypes::TimingWriteContext &ctx) = 0; + virtual inline float get_timing_R(typename ContextTypes::TimingReadContext &ctx) = 0; + virtual inline void set_timing_R(float R, typename ContextTypes::TimingWriteContext &ctx) = 0; + virtual inline float get_timing_Tdel(typename ContextTypes::TimingReadContext &ctx) = 0; + virtual inline void set_timing_Tdel(float Tdel, typename ContextTypes::TimingWriteContext &ctx) = 0; + + /** Generated for complex type "sizing": + * + * + * + * + */ + virtual inline float get_sizing_buf_size(typename ContextTypes::SizingReadContext &ctx) = 0; + virtual inline float get_sizing_mux_trans_size(typename ContextTypes::SizingReadContext &ctx) = 0; + + /** Generated for complex type "switch": + * + * + * + * + * + * + * + * + * + * + * + */ + virtual inline int get_switch_id(typename ContextTypes::SwitchReadContext &ctx) = 0; + virtual inline const char * get_switch_name(typename ContextTypes::SwitchReadContext &ctx) = 0; + virtual inline void set_switch_name(const char * name, typename ContextTypes::SwitchWriteContext &ctx) = 0; + virtual inline enum_switch_type get_switch_type(typename ContextTypes::SwitchReadContext &ctx) = 0; + virtual inline void set_switch_type(enum_switch_type type, typename ContextTypes::SwitchWriteContext &ctx) = 0; + virtual inline typename ContextTypes::TimingWriteContext init_switch_timing(typename ContextTypes::SwitchWriteContext &ctx) = 0; + virtual inline void finish_switch_timing(typename ContextTypes::TimingWriteContext &ctx) = 0; + virtual inline typename ContextTypes::TimingReadContext get_switch_timing(typename ContextTypes::SwitchReadContext &ctx) = 0; + virtual inline bool has_switch_timing(typename ContextTypes::SwitchReadContext &ctx) = 0; + virtual inline typename ContextTypes::SizingWriteContext init_switch_sizing(typename ContextTypes::SwitchWriteContext &ctx, float buf_size, float mux_trans_size) = 0; + virtual inline void finish_switch_sizing(typename ContextTypes::SizingWriteContext &ctx) = 0; + virtual inline typename ContextTypes::SizingReadContext get_switch_sizing(typename ContextTypes::SwitchReadContext &ctx) = 0; + + /** Generated for complex type "switches": + * + * + * + * + * + */ + virtual inline void preallocate_switches_switch(typename ContextTypes::SwitchesWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::SwitchWriteContext add_switches_switch(typename ContextTypes::SwitchesWriteContext &ctx, int id) = 0; + virtual inline void finish_switches_switch(typename ContextTypes::SwitchWriteContext &ctx) = 0; + virtual inline size_t num_switches_switch(typename ContextTypes::SwitchesReadContext &ctx) = 0; + virtual inline typename ContextTypes::SwitchReadContext get_switches_switch(int n, typename ContextTypes::SwitchesReadContext &ctx) = 0; + + /** Generated for complex type "segment_timing": + * + * + * + * + */ + virtual inline float get_segment_timing_C_per_meter(typename ContextTypes::SegmentTimingReadContext &ctx) = 0; + virtual inline void set_segment_timing_C_per_meter(float C_per_meter, typename ContextTypes::SegmentTimingWriteContext &ctx) = 0; + virtual inline float get_segment_timing_R_per_meter(typename ContextTypes::SegmentTimingReadContext &ctx) = 0; + virtual inline void set_segment_timing_R_per_meter(float R_per_meter, typename ContextTypes::SegmentTimingWriteContext &ctx) = 0; + + /** Generated for complex type "segment": + * + * + * + * + * + * + * + */ + virtual inline int get_segment_id(typename ContextTypes::SegmentReadContext &ctx) = 0; + virtual inline const char * get_segment_name(typename ContextTypes::SegmentReadContext &ctx) = 0; + virtual inline void set_segment_name(const char * name, typename ContextTypes::SegmentWriteContext &ctx) = 0; + virtual inline typename ContextTypes::SegmentTimingWriteContext init_segment_timing(typename ContextTypes::SegmentWriteContext &ctx) = 0; + virtual inline void finish_segment_timing(typename ContextTypes::SegmentTimingWriteContext &ctx) = 0; + virtual inline typename ContextTypes::SegmentTimingReadContext get_segment_timing(typename ContextTypes::SegmentReadContext &ctx) = 0; + virtual inline bool has_segment_timing(typename ContextTypes::SegmentReadContext &ctx) = 0; + + /** Generated for complex type "segments": + * + * + * + * + * + */ + virtual inline void preallocate_segments_segment(typename ContextTypes::SegmentsWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::SegmentWriteContext add_segments_segment(typename ContextTypes::SegmentsWriteContext &ctx, int id) = 0; + virtual inline void finish_segments_segment(typename ContextTypes::SegmentWriteContext &ctx) = 0; + virtual inline size_t num_segments_segment(typename ContextTypes::SegmentsReadContext &ctx) = 0; + virtual inline typename ContextTypes::SegmentReadContext get_segments_segment(int n, typename ContextTypes::SegmentsReadContext &ctx) = 0; + + /** Generated for complex type "pin": + * + * + * + * + * + * + * + */ + virtual inline int get_pin_ptc(typename ContextTypes::PinReadContext &ctx) = 0; + virtual inline void set_pin_value(const char * value, typename ContextTypes::PinWriteContext &ctx) = 0; + virtual inline const char * get_pin_value(typename ContextTypes::PinReadContext &ctx) = 0; + + /** Generated for complex type "pin_class": + * + * + * + * + * + * + */ + virtual inline enum_pin_type get_pin_class_type(typename ContextTypes::PinClassReadContext &ctx) = 0; + virtual inline void preallocate_pin_class_pin(typename ContextTypes::PinClassWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::PinWriteContext add_pin_class_pin(typename ContextTypes::PinClassWriteContext &ctx, int ptc) = 0; + virtual inline void finish_pin_class_pin(typename ContextTypes::PinWriteContext &ctx) = 0; + virtual inline size_t num_pin_class_pin(typename ContextTypes::PinClassReadContext &ctx) = 0; + virtual inline typename ContextTypes::PinReadContext get_pin_class_pin(int n, typename ContextTypes::PinClassReadContext &ctx) = 0; + + /** Generated for complex type "block_type": + * + * + * + * + * + * + * + * + * + */ + virtual inline int get_block_type_height(typename ContextTypes::BlockTypeReadContext &ctx) = 0; + virtual inline int get_block_type_id(typename ContextTypes::BlockTypeReadContext &ctx) = 0; + virtual inline const char * get_block_type_name(typename ContextTypes::BlockTypeReadContext &ctx) = 0; + virtual inline void set_block_type_name(const char * name, typename ContextTypes::BlockTypeWriteContext &ctx) = 0; + virtual inline int get_block_type_width(typename ContextTypes::BlockTypeReadContext &ctx) = 0; + virtual inline void preallocate_block_type_pin_class(typename ContextTypes::BlockTypeWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::PinClassWriteContext add_block_type_pin_class(typename ContextTypes::BlockTypeWriteContext &ctx, enum_pin_type type) = 0; + virtual inline void finish_block_type_pin_class(typename ContextTypes::PinClassWriteContext &ctx) = 0; + virtual inline size_t num_block_type_pin_class(typename ContextTypes::BlockTypeReadContext &ctx) = 0; + virtual inline typename ContextTypes::PinClassReadContext get_block_type_pin_class(int n, typename ContextTypes::BlockTypeReadContext &ctx) = 0; + + /** Generated for complex type "block_types": + * + * + * + * + * + */ + virtual inline void preallocate_block_types_block_type(typename ContextTypes::BlockTypesWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::BlockTypeWriteContext add_block_types_block_type(typename ContextTypes::BlockTypesWriteContext &ctx, int height, int id, int width) = 0; + virtual inline void finish_block_types_block_type(typename ContextTypes::BlockTypeWriteContext &ctx) = 0; + virtual inline size_t num_block_types_block_type(typename ContextTypes::BlockTypesReadContext &ctx) = 0; + virtual inline typename ContextTypes::BlockTypeReadContext get_block_types_block_type(int n, typename ContextTypes::BlockTypesReadContext &ctx) = 0; + + /** Generated for complex type "grid_loc": + * + * + * + * + * + * + * + */ + virtual inline int get_grid_loc_block_type_id(typename ContextTypes::GridLocReadContext &ctx) = 0; + virtual inline int get_grid_loc_height_offset(typename ContextTypes::GridLocReadContext &ctx) = 0; + virtual inline int get_grid_loc_width_offset(typename ContextTypes::GridLocReadContext &ctx) = 0; + virtual inline int get_grid_loc_x(typename ContextTypes::GridLocReadContext &ctx) = 0; + virtual inline int get_grid_loc_y(typename ContextTypes::GridLocReadContext &ctx) = 0; + + /** Generated for complex type "grid_locs": + * + * + * + * + * + */ + virtual inline void preallocate_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::GridLocWriteContext add_grid_locs_grid_loc(typename ContextTypes::GridLocsWriteContext &ctx, int block_type_id, int height_offset, int width_offset, int x, int y) = 0; + virtual inline void finish_grid_locs_grid_loc(typename ContextTypes::GridLocWriteContext &ctx) = 0; + virtual inline size_t num_grid_locs_grid_loc(typename ContextTypes::GridLocsReadContext &ctx) = 0; + virtual inline typename ContextTypes::GridLocReadContext get_grid_locs_grid_loc(int n, typename ContextTypes::GridLocsReadContext &ctx) = 0; + + /** Generated for complex type "node_loc": + * + * + * + * + * + * + * + * + */ + virtual inline int get_node_loc_ptc(typename ContextTypes::NodeLocReadContext &ctx) = 0; + virtual inline enum_loc_side get_node_loc_side(typename ContextTypes::NodeLocReadContext &ctx) = 0; + virtual inline void set_node_loc_side(enum_loc_side side, typename ContextTypes::NodeLocWriteContext &ctx) = 0; + virtual inline int get_node_loc_xhigh(typename ContextTypes::NodeLocReadContext &ctx) = 0; + virtual inline int get_node_loc_xlow(typename ContextTypes::NodeLocReadContext &ctx) = 0; + virtual inline int get_node_loc_yhigh(typename ContextTypes::NodeLocReadContext &ctx) = 0; + virtual inline int get_node_loc_ylow(typename ContextTypes::NodeLocReadContext &ctx) = 0; + + /** Generated for complex type "node_timing": + * + * + * + * + */ + virtual inline float get_node_timing_C(typename ContextTypes::NodeTimingReadContext &ctx) = 0; + virtual inline float get_node_timing_R(typename ContextTypes::NodeTimingReadContext &ctx) = 0; + + /** Generated for complex type "node_segment": + * + * + * + */ + virtual inline int get_node_segment_segment_id(typename ContextTypes::NodeSegmentReadContext &ctx) = 0; + + /** Generated for complex type "meta": + * + * + * + * + * + * + * + */ + virtual inline const char * get_meta_name(typename ContextTypes::MetaReadContext &ctx) = 0; + virtual inline void set_meta_name(const char * name, typename ContextTypes::MetaWriteContext &ctx) = 0; + virtual inline void set_meta_value(const char * value, typename ContextTypes::MetaWriteContext &ctx) = 0; + virtual inline const char * get_meta_value(typename ContextTypes::MetaReadContext &ctx) = 0; + + /** Generated for complex type "metadata": + * + * + * + * + * + */ + virtual inline void preallocate_metadata_meta(typename ContextTypes::MetadataWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::MetaWriteContext add_metadata_meta(typename ContextTypes::MetadataWriteContext &ctx) = 0; + virtual inline void finish_metadata_meta(typename ContextTypes::MetaWriteContext &ctx) = 0; + virtual inline size_t num_metadata_meta(typename ContextTypes::MetadataReadContext &ctx) = 0; + virtual inline typename ContextTypes::MetaReadContext get_metadata_meta(int n, typename ContextTypes::MetadataReadContext &ctx) = 0; + + /** Generated for complex type "node": + * + * + * + * + * + * + * + * + * + * + * + * + */ + virtual inline unsigned int get_node_capacity(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline enum_node_direction get_node_direction(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline void set_node_direction(enum_node_direction direction, typename ContextTypes::NodeWriteContext &ctx) = 0; + virtual inline unsigned int get_node_id(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline enum_node_type get_node_type(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline typename ContextTypes::NodeLocWriteContext init_node_loc(typename ContextTypes::NodeWriteContext &ctx, int ptc, int xhigh, int xlow, int yhigh, int ylow) = 0; + virtual inline void finish_node_loc(typename ContextTypes::NodeLocWriteContext &ctx) = 0; + virtual inline typename ContextTypes::NodeLocReadContext get_node_loc(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline typename ContextTypes::NodeTimingWriteContext init_node_timing(typename ContextTypes::NodeWriteContext &ctx, float C, float R) = 0; + virtual inline void finish_node_timing(typename ContextTypes::NodeTimingWriteContext &ctx) = 0; + virtual inline typename ContextTypes::NodeTimingReadContext get_node_timing(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline bool has_node_timing(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline typename ContextTypes::NodeSegmentWriteContext init_node_segment(typename ContextTypes::NodeWriteContext &ctx, int segment_id) = 0; + virtual inline void finish_node_segment(typename ContextTypes::NodeSegmentWriteContext &ctx) = 0; + virtual inline typename ContextTypes::NodeSegmentReadContext get_node_segment(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline bool has_node_segment(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline typename ContextTypes::MetadataWriteContext init_node_metadata(typename ContextTypes::NodeWriteContext &ctx) = 0; + virtual inline void finish_node_metadata(typename ContextTypes::MetadataWriteContext &ctx) = 0; + virtual inline typename ContextTypes::MetadataReadContext get_node_metadata(typename ContextTypes::NodeReadContext &ctx) = 0; + virtual inline bool has_node_metadata(typename ContextTypes::NodeReadContext &ctx) = 0; + + /** Generated for complex type "rr_nodes": + * + * + * + * + * + */ + virtual inline void preallocate_rr_nodes_node(typename ContextTypes::RrNodesWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::NodeWriteContext add_rr_nodes_node(typename ContextTypes::RrNodesWriteContext &ctx, unsigned int capacity, unsigned int id, enum_node_type type) = 0; + virtual inline void finish_rr_nodes_node(typename ContextTypes::NodeWriteContext &ctx) = 0; + virtual inline size_t num_rr_nodes_node(typename ContextTypes::RrNodesReadContext &ctx) = 0; + virtual inline typename ContextTypes::NodeReadContext get_rr_nodes_node(int n, typename ContextTypes::RrNodesReadContext &ctx) = 0; + + /** Generated for complex type "edge": + * + * + * + * + * + * + * + * + */ + virtual inline unsigned int get_edge_sink_node(typename ContextTypes::EdgeReadContext &ctx) = 0; + virtual inline unsigned int get_edge_src_node(typename ContextTypes::EdgeReadContext &ctx) = 0; + virtual inline unsigned int get_edge_switch_id(typename ContextTypes::EdgeReadContext &ctx) = 0; + virtual inline typename ContextTypes::MetadataWriteContext init_edge_metadata(typename ContextTypes::EdgeWriteContext &ctx) = 0; + virtual inline void finish_edge_metadata(typename ContextTypes::MetadataWriteContext &ctx) = 0; + virtual inline typename ContextTypes::MetadataReadContext get_edge_metadata(typename ContextTypes::EdgeReadContext &ctx) = 0; + virtual inline bool has_edge_metadata(typename ContextTypes::EdgeReadContext &ctx) = 0; + + /** Generated for complex type "rr_edges": + * + * + * + * + * + */ + virtual inline void preallocate_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext &ctx, size_t size) = 0; + virtual inline typename ContextTypes::EdgeWriteContext add_rr_edges_edge(typename ContextTypes::RrEdgesWriteContext &ctx, unsigned int sink_node, unsigned int src_node, unsigned int switch_id) = 0; + virtual inline void finish_rr_edges_edge(typename ContextTypes::EdgeWriteContext &ctx) = 0; + virtual inline size_t num_rr_edges_edge(typename ContextTypes::RrEdgesReadContext &ctx) = 0; + virtual inline typename ContextTypes::EdgeReadContext get_rr_edges_edge(int n, typename ContextTypes::RrEdgesReadContext &ctx) = 0; + + /** Generated for complex type "rr_graph": + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + virtual inline const char * get_rr_graph_tool_comment(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline void set_rr_graph_tool_comment(const char * tool_comment, typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline const char * get_rr_graph_tool_name(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline void set_rr_graph_tool_name(const char * tool_name, typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline const char * get_rr_graph_tool_version(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline void set_rr_graph_tool_version(const char * tool_version, typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline typename ContextTypes::ChannelsWriteContext init_rr_graph_channels(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_channels(typename ContextTypes::ChannelsWriteContext &ctx) = 0; + virtual inline typename ContextTypes::ChannelsReadContext get_rr_graph_channels(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::SwitchesWriteContext init_rr_graph_switches(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_switches(typename ContextTypes::SwitchesWriteContext &ctx) = 0; + virtual inline typename ContextTypes::SwitchesReadContext get_rr_graph_switches(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::SegmentsWriteContext init_rr_graph_segments(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_segments(typename ContextTypes::SegmentsWriteContext &ctx) = 0; + virtual inline typename ContextTypes::SegmentsReadContext get_rr_graph_segments(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::BlockTypesWriteContext init_rr_graph_block_types(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_block_types(typename ContextTypes::BlockTypesWriteContext &ctx) = 0; + virtual inline typename ContextTypes::BlockTypesReadContext get_rr_graph_block_types(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::GridLocsWriteContext init_rr_graph_grid(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_grid(typename ContextTypes::GridLocsWriteContext &ctx) = 0; + virtual inline typename ContextTypes::GridLocsReadContext get_rr_graph_grid(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::RrNodesWriteContext init_rr_graph_rr_nodes(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_rr_nodes(typename ContextTypes::RrNodesWriteContext &ctx) = 0; + virtual inline typename ContextTypes::RrNodesReadContext get_rr_graph_rr_nodes(typename ContextTypes::RrGraphReadContext &ctx) = 0; + virtual inline typename ContextTypes::RrEdgesWriteContext init_rr_graph_rr_edges(typename ContextTypes::RrGraphWriteContext &ctx) = 0; + virtual inline void finish_rr_graph_rr_edges(typename ContextTypes::RrEdgesWriteContext &ctx) = 0; + virtual inline typename ContextTypes::RrEdgesReadContext get_rr_graph_rr_edges(typename ContextTypes::RrGraphReadContext &ctx) = 0; }; } /* namespace uxsd */ diff --git a/vpr/src/route/rr_graph.xsd b/libs/librrgraph/src/base/rr_graph.xsd similarity index 100% rename from vpr/src/route/rr_graph.xsd rename to libs/librrgraph/src/base/rr_graph.xsd diff --git a/vpr/CMakeLists.txt b/vpr/CMakeLists.txt index 04321effc03..2326313b439 100644 --- a/vpr/CMakeLists.txt +++ b/vpr/CMakeLists.txt @@ -274,24 +274,3 @@ add_test(NAME test_vpr WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) -# add_custom_target( -# generate_rr_graph_serializers -# COMMAND ${CMAKE_COMMAND} -E remove_directory rr_graph_generate -# COMMAND ${CMAKE_COMMAND} -E make_directory rr_graph_generate -# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate git clone https://github.com/duck2/uxsdcxx -# COMMAND python3 -mpip install --user -r rr_graph_generate/uxsdcxx/requirements.txt -# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd -# COMMAND ${CMAKE_COMMAND} -E chdir rr_graph_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd -# COMMAND ${CMAKE_COMMAND} -E copy -# rr_graph_generate/rr_graph_uxsdcxx.h -# rr_graph_generate/rr_graph_uxsdcxx_capnp.h -# rr_graph_generate/rr_graph_uxsdcxx_interface.h -# ${CMAKE_CURRENT_SOURCE_DIR}/src/route/gen -# COMMAND ${CMAKE_COMMAND} -E copy -# rr_graph_generate/rr_graph_uxsdcxx.capnp -# ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libvtrcapnproto/gen -# DEPENDS -# ${CMAKE_CURRENT_SOURCE_DIR}/src/route/rr_graph.xsd -# WORKING_DIRECTORY -# ${CMAKE_CURRENT_BINARY_DIR} -# ) From e428f8a7f93788b7e775a2c645b91e3a08e7ef1c Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Wed, 20 Jul 2022 16:57:10 -0700 Subject: [PATCH 06/19] [vpr] clean up dead code --- libs/libarchfpga/src/device_grid.cpp | 1 - .../src/unified_to_parallel_seg_index.h | 3 ++ libs/librrgraph/src/base/check_rr_graph.cpp | 18 ---------- libs/librrgraph/src/base/rr_graph_reader.cpp | 4 --- .../src/base/rr_graph_uxsdcxx_serializer.h | 22 +++++-------- libs/librrgraph/src/base/rr_graph_writer.cpp | 4 +-- libs/librrgraph/src/base/rr_metadata.cpp | 2 -- libs/librrgraph/src/base/rr_rc_data.cpp | 2 -- vpr/src/base/vpr_types.h | 33 ------------------- vpr/src/route/rr_graph.h | 12 ------- vpr/src/route/rr_graph2.h | 9 ----- vpr/src/route/rr_graph_indexed_data.h | 6 ---- 12 files changed, 12 insertions(+), 104 deletions(-) diff --git a/libs/libarchfpga/src/device_grid.cpp b/libs/libarchfpga/src/device_grid.cpp index 9fc8c0afca9..ffe0cc50eb3 100644 --- a/libs/libarchfpga/src/device_grid.cpp +++ b/libs/libarchfpga/src/device_grid.cpp @@ -1,5 +1,4 @@ #include "device_grid.h" -//#include "vpr_utils.h" DeviceGrid::DeviceGrid(std::string grid_name, vtr::Matrix grid) : name_(grid_name) diff --git a/libs/libarchfpga/src/unified_to_parallel_seg_index.h b/libs/libarchfpga/src/unified_to_parallel_seg_index.h index 55fabd4bd33..47db42e8e5b 100644 --- a/libs/libarchfpga/src/unified_to_parallel_seg_index.h +++ b/libs/libarchfpga/src/unified_to_parallel_seg_index.h @@ -3,6 +3,9 @@ #include "physical_types.h" +/* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment, + * from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments + * regardless of their axis. (see get_parallel_segs for more details)*/ typedef std::unordered_multimap> t_unified_to_parallel_seg_index; #endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp index ae9287f28ea..00cb20faaef 100644 --- a/libs/librrgraph/src/base/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -3,9 +3,6 @@ #include "vtr_util.h" #include "vpr_error.h" - -//#include "globals.h" -//#include "rr_graph.h" #include "check_rr_graph.h" #include "rr_node.h" @@ -56,9 +53,6 @@ void check_rr_graph(const RRGraphView& rr_graph, route_type = GLOBAL; } - //auto& device_ctx = g_vpr_ctx.device(); - //const auto& rr_graph = device_ctx.rr_graph; - auto total_edges_to_node = std::vector(rr_graph.num_nodes()); auto switch_types_from_current_to_node = std::vector(rr_graph.num_nodes()); const int num_rr_switches = rr_graph.num_rr_switches(); @@ -283,9 +277,6 @@ static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const Device int ipin; t_physical_tile_type_ptr type; - // auto& device_ctx = g_vpr_ctx.device(); - // const auto& rr_graph = device_ctx.rr_graph; - type = grid[rr_graph.node_xlow(inode)][rr_graph.node_ylow(inode)].type; if (rr_graph.node_type(inode) != IPIN) @@ -312,7 +303,6 @@ void check_rr_node(const RRGraphView& rr_graph, int nodes_per_chan, tracks_per_node, num_edges; RRIndexedDataId cost_index; float C, R; - //const auto& rr_graph = device_ctx.rr_graph; RRNodeId rr_node = RRNodeId(inode); rr_type = rr_graph.node_type(rr_node); @@ -325,7 +315,6 @@ void check_rr_node(const RRGraphView& rr_graph, cost_index = rr_graph.node_cost_index(rr_node); type = nullptr; - //const auto& grid = device_ctx.grid; if (xlow > xhigh || ylow > yhigh) { VPR_ERROR(VPR_ERROR_ROUTE, "in check_rr_node: rr endpoints are (%d,%d) and (%d,%d).\n", xlow, ylow, xhigh, yhigh); @@ -347,7 +336,6 @@ void check_rr_node(const RRGraphView& rr_graph, } /* Check that the segment is within the array and such. */ - // type = device_ctx.grid[xlow][ylow].type; type = grid[xlow][ylow].type; switch (rr_type) { @@ -552,9 +540,6 @@ static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node) { short from_switch_type; bool trans_matched; - // auto& device_ctx = g_vpr_ctx.device(); - // const auto& rr_graph = device_ctx.rr_graph; - from_rr_type = rr_graph.node_type(RRNodeId(from_node)); if (from_rr_type != CHANX && from_rr_type != CHANY) return; @@ -603,7 +588,6 @@ static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& /* TODO: this function should be reworked later to adapt RRGraphView interface * once xlow(), ylow(), side() APIs are implemented */ - //const auto& rr_graph = g_vpr_ctx.device().rr_graph; VTR_ASSERT(rr_graph.node_type(node.id()) == IPIN || rr_graph.node_type(node.id()) == OPIN); if ((rr_graph.node_xlow(node.id()) == 0 && !rr_graph.is_node_on_specific_side(node.id(), RIGHT)) //left device edge connects only along block's right side @@ -617,8 +601,6 @@ static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& } static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int iedge, int to_node) { - // auto& device_ctx = g_vpr_ctx.device(); - // const auto& rr_graph = device_ctx.rr_graph; //Check that to to_node's fan-in is correct, given the switch type int iswitch = rr_graph.edge_switch(RRNodeId(from_node), iedge); diff --git a/libs/librrgraph/src/base/rr_graph_reader.cpp b/libs/librrgraph/src/base/rr_graph_reader.cpp index 47ab78fd84c..938dd4bee7c 100644 --- a/libs/librrgraph/src/base/rr_graph_reader.cpp +++ b/libs/librrgraph/src/base/rr_graph_reader.cpp @@ -21,8 +21,6 @@ #include #include "vtr_time.h" -//#include "vpr_types.h" -//#include "globals.h" #include "pugixml.hpp" #include "pugixml_util.hpp" @@ -61,8 +59,6 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, bool do_check_rr_graph) { vtr::ScopedStartFinishTimer timer("Loading routing resource graph"); - // auto& device_ctx = g_vpr_ctx.mutable_device(); - size_t num_segments = segment_inf.size(); rr_graph_builder->reserve_segments(num_segments); for (size_t iseg = 0; iseg < num_segments; ++iseg) { diff --git a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h index 734e1a810b3..2ed954ec062 100644 --- a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h @@ -4,19 +4,17 @@ #include #include +#include "rr_graph_uxsdcxx_interface.h" + #include "rr_node.h" +#include "rr_rc_data.h" #include "rr_metadata.h" -#include "rr_graph_uxsdcxx_interface.h" +#include "rr_graph_view.h" +#include "rr_graph_builder.h" #include "check_rr_graph.h" #include "read_xml_arch_file.h" -#include "vtr_log.h" -#include "vtr_version.h" - -#include "vpr_error.h" -//#include "vpr_utils.h" - #include "device_grid.h" #include "chan_width.h" #include "base_cost_type.h" @@ -26,15 +24,13 @@ #include "alloc_and_load_rr_indexed_data.h" #include "get_parallel_segs.h" -#include "rr_graph_view.h" -#include "rr_graph_builder.h" -#include "rr_rc_data.h" - +#include "vpr_error.h" +#include "vtr_log.h" +#include "vtr_version.h" #include "vtr_util.h" #include "arch_util.h" #include "physical_types_util.h" - class MetadataBind { public: MetadataBind(MetadataStorage* rr_node_metadata, MetadataStorage>* rr_edge_metadata, @@ -1910,8 +1906,6 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { vtr::vector* rr_indexed_data_; t_rr_node_indices* rr_node_indices_; std::string* read_rr_graph_filename_; - - //Newly Added std::vector& rr_rc_data_; const int virtual_clock_network_root_idx_; diff --git a/libs/librrgraph/src/base/rr_graph_writer.cpp b/libs/librrgraph/src/base/rr_graph_writer.cpp index 4d09460dbce..46b92623c74 100644 --- a/libs/librrgraph/src/base/rr_graph_writer.cpp +++ b/libs/librrgraph/src/base/rr_graph_writer.cpp @@ -19,8 +19,6 @@ # include "rr_graph_uxsdcxx_capnp.h" #endif -//#include "globals.h" - /************************ Subroutine definitions ****************************/ /* This function is used to write the rr_graph into xml format into a a file with name: file_name */ @@ -41,7 +39,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, const size_t num_arch_switches, const char* file_name, const int virtual_clock_network_root_idx) { - //auto& device_ctx = g_vpr_ctx.mutable_device(); + RrGraphSerializer reader( /*graph_type=*/t_graph_type(), /*base_cost_type=*/e_base_cost_type(), diff --git a/libs/librrgraph/src/base/rr_metadata.cpp b/libs/librrgraph/src/base/rr_metadata.cpp index 9ddd13decc3..dea18543770 100644 --- a/libs/librrgraph/src/base/rr_metadata.cpp +++ b/libs/librrgraph/src/base/rr_metadata.cpp @@ -1,7 +1,5 @@ #include "rr_metadata.h" -//#include "globals.h" - namespace vpr { const t_metadata_value* rr_node_metadata(const RRGraphBuilder& rr_graph_builder, int src_node, vtr::interned_string key) { diff --git a/libs/librrgraph/src/base/rr_rc_data.cpp b/libs/librrgraph/src/base/rr_rc_data.cpp index 899e714e938..fc24bf396c7 100644 --- a/libs/librrgraph/src/base/rr_rc_data.cpp +++ b/libs/librrgraph/src/base/rr_rc_data.cpp @@ -1,12 +1,10 @@ #include "rr_rc_data.h" -//#include "globals.h" t_rr_rc_data::t_rr_rc_data(float Rval, float Cval) noexcept : R(Rval) , C(Cval) {} short find_create_rr_rc_data(const float R, const float C, std::vector& rr_rc_data) { - //auto& device_ctx = g_vpr_ctx.mutable_device(); auto match = [&](const t_rr_rc_data& val) { return val.R == R diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index ffd3dcc9040..a10b6b76fa3 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -1120,26 +1120,11 @@ struct t_placer_opts { * write_rr_graph_name: stores the file name of the output rr graph * * read_rr_graph_name: stores the file name of the rr graph to be read by vpr */ -// enum e_route_type { -// GLOBAL, -// DETAILED -// }; - enum e_router_algorithm { BREADTH_FIRST, TIMING_DRIVEN, }; -// enum e_base_cost_type { -// DELAY_NORMALIZED, -// DELAY_NORMALIZED_LENGTH, -// DELAY_NORMALIZED_FREQUENCY, -// DELAY_NORMALIZED_LENGTH_FREQUENCY, -// DELAY_NORMALIZED_LENGTH_BOUNDED, -// DEMAND_ONLY, -// DEMAND_ONLY_NORMALIZED_LENGTH -// }; - enum e_routing_failure_predictor { OFF, SAFE, @@ -1601,15 +1586,6 @@ struct t_non_configurable_rr_sets { #define NO_PREVIOUS -1 -// ///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. -// enum e_cost_indices { -// SOURCE_COST_INDEX = 0, -// SINK_COST_INDEX, -// OPIN_COST_INDEX, -// IPIN_COST_INDEX, -// CHANX_COST_INDEX_START -// }; - ///@brief Power estimation options struct t_power_opts { bool do_power; /// x_list; -// std::vector y_list; -// }; ///@brief Type to store our list of token to enum pairings struct t_TokenPair { diff --git a/vpr/src/route/rr_graph.h b/vpr/src/route/rr_graph.h index 526406180a4..a718a862e07 100644 --- a/vpr/src/route/rr_graph.h +++ b/vpr/src/route/rr_graph.h @@ -11,15 +11,6 @@ #include "graph_type.h" #include "describe_rr_node.h" -// enum e_graph_type { -// GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */ -// GRAPH_BIDIR, /* Detailed bidirectional graph */ -// GRAPH_UNIDIR, /* Detailed unidir graph, untilable */ -// /* RESEARCH TODO: Get this option debugged */ -// GRAPH_UNIDIR_TILEABLE /* Detail unidir graph with wire groups multiples of 2*L */ -// }; -// typedef enum e_graph_type t_graph_type; - /* Warnings about the routing graph that can be returned. * This is to avoid output messages during a value sweep */ enum { @@ -43,9 +34,6 @@ void create_rr_graph(const t_graph_type graph_type, void free_rr_graph(); -// //Returns a brief one-line summary of an RR node -// std::string describe_rr_node(int inode); - t_rr_switch_inf create_rr_switch_from_arch_switch(int arch_switch_idx, const float R_minW_nmos, const float R_minW_pmos); diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 913ebc64078..5b007256cf3 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -19,11 +19,6 @@ * originally initialized to UN_SET until alloc_and_load_sb is called */ typedef vtr::NdMatrix t_sblock_pattern; -/* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment, - * from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments - * regardless of their axis. (see get_parallel_segs for more details)*/ -//typedef std::unordered_multimap> t_unified_to_parallel_seg_index; - /******************* Subroutines exported by rr_graph2.c *********************/ void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder, @@ -186,10 +181,6 @@ void load_sblock_pattern_lookup(const int i, const enum e_switch_block_type switch_block_type, t_sblock_pattern& sblock_pattern); -// std::vector get_parallel_segs(const std::vector& segment_inf, -// t_unified_to_parallel_seg_index& seg_index_map, -// enum e_parallel_axis parallel_axis); - int get_parallel_seg_index(const int abs, const t_unified_to_parallel_seg_index& index_map, const e_parallel_axis parallel_axis); diff --git a/vpr/src/route/rr_graph_indexed_data.h b/vpr/src/route/rr_graph_indexed_data.h index 41d1624109b..f973703b662 100644 --- a/vpr/src/route/rr_graph_indexed_data.h +++ b/vpr/src/route/rr_graph_indexed_data.h @@ -3,12 +3,6 @@ #include "physical_types.h" #include "alloc_and_load_rr_indexed_data.h" -// void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, -// const std::vector& segment_inf_x, -// const std::vector& segment_inf_y, -// int wire_to_ipin_switch, -// enum e_base_cost_type base_cost_type); - void load_rr_index_segments(const int num_segment); std::vector find_ortho_cost_index(const std::vector segment_inf_x, From a30ca695a7bb97608f4ead086038b9597efbca36 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Wed, 20 Jul 2022 17:03:16 -0700 Subject: [PATCH 07/19] [vpr] clean up dead code 2 --- libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h | 1 + libs/librrgraph/src/base/check_rr_graph.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h index 70fb5c85ccd..897477165bc 100644 --- a/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h +++ b/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h @@ -2,6 +2,7 @@ #define ALLOC_AND_LOAD_RR_INDEXED_DATA_H #include "physical_types.h" + void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, const std::vector& segment_inf_x, const std::vector& segment_inf_y, diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index e5761941fec..f30aeb65eaa 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -2,8 +2,6 @@ #define CHECK_RR_GRAPH_H #include "physical_types.h" -//#include "vpr_context.h" - #include "graph_type.h" #include "device_grid.h" #include "route_type.h" From 7840120744cfebc6a237390e4900f6ab721c5330 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Thu, 21 Jul 2022 11:41:51 -0700 Subject: [PATCH 08/19] [vpr] format fix --- vpr/src/route/rr_graph.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 4d6d333c204..f640d96db38 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -341,7 +341,6 @@ void create_rr_graph(const t_graph_type graph_type, &det_routing_arch->read_rr_graph_filename, router_opts.read_rr_edge_metadata, router_opts.do_check_rr_graph); - if (router_opts.reorder_rr_graph_nodes_algorithm != DONT_REORDER) { mutable_device_ctx.rr_graph_builder.reorder_nodes(router_opts.reorder_rr_graph_nodes_algorithm, router_opts.reorder_rr_graph_nodes_threshold, From 3200ba9f01413e3360b3344057d82a39a8fb9a7b Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Fri, 22 Jul 2022 17:00:21 -0700 Subject: [PATCH 09/19] [vpr] move files to corresponding folder in librrgraph/src --- libs/librrgraph/src/base/check_rr_graph.h | 2 +- .../src/graph_type.h => librrgraph/src/base/rr_graph_type.h} | 0 libs/librrgraph/src/{base => io}/gen/README.gen.md | 0 libs/librrgraph/src/{base => io}/gen/rr_graph_uxsdcxx.h | 0 libs/librrgraph/src/{base => io}/gen/rr_graph_uxsdcxx_capnp.h | 0 .../src/{base => io}/gen/rr_graph_uxsdcxx_interface.h | 0 libs/librrgraph/src/{base => io}/rr_graph.xsd | 0 libs/librrgraph/src/{base => io}/rr_graph_reader.cpp | 0 libs/librrgraph/src/{base => io}/rr_graph_reader.h | 2 +- libs/librrgraph/src/{base => io}/rr_graph_uxsdcxx_serializer.h | 2 +- libs/librrgraph/src/{base => io}/rr_graph_writer.cpp | 0 libs/librrgraph/src/{base => io}/rr_graph_writer.h | 0 .../src/{base => utils}/alloc_and_load_rr_indexed_data.h | 0 libs/librrgraph/src/{base => utils}/describe_rr_node.h | 0 vpr/src/route/rr_graph.h | 2 +- 15 files changed, 4 insertions(+), 4 deletions(-) rename libs/{libarchfpga/src/graph_type.h => librrgraph/src/base/rr_graph_type.h} (100%) rename libs/librrgraph/src/{base => io}/gen/README.gen.md (100%) rename libs/librrgraph/src/{base => io}/gen/rr_graph_uxsdcxx.h (100%) rename libs/librrgraph/src/{base => io}/gen/rr_graph_uxsdcxx_capnp.h (100%) rename libs/librrgraph/src/{base => io}/gen/rr_graph_uxsdcxx_interface.h (100%) rename libs/librrgraph/src/{base => io}/rr_graph.xsd (100%) rename libs/librrgraph/src/{base => io}/rr_graph_reader.cpp (100%) rename libs/librrgraph/src/{base => io}/rr_graph_reader.h (98%) rename libs/librrgraph/src/{base => io}/rr_graph_uxsdcxx_serializer.h (99%) rename libs/librrgraph/src/{base => io}/rr_graph_writer.cpp (100%) rename libs/librrgraph/src/{base => io}/rr_graph_writer.h (100%) rename libs/librrgraph/src/{base => utils}/alloc_and_load_rr_indexed_data.h (100%) rename libs/librrgraph/src/{base => utils}/describe_rr_node.h (100%) diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index f30aeb65eaa..2098a9afb96 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -2,7 +2,7 @@ #define CHECK_RR_GRAPH_H #include "physical_types.h" -#include "graph_type.h" +#include "rr_graph_type.h" #include "device_grid.h" #include "route_type.h" #include "rr_graph_view.h" diff --git a/libs/libarchfpga/src/graph_type.h b/libs/librrgraph/src/base/rr_graph_type.h similarity index 100% rename from libs/libarchfpga/src/graph_type.h rename to libs/librrgraph/src/base/rr_graph_type.h diff --git a/libs/librrgraph/src/base/gen/README.gen.md b/libs/librrgraph/src/io/gen/README.gen.md similarity index 100% rename from libs/librrgraph/src/base/gen/README.gen.md rename to libs/librrgraph/src/io/gen/README.gen.md diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h b/libs/librrgraph/src/io/gen/rr_graph_uxsdcxx.h similarity index 100% rename from libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h rename to libs/librrgraph/src/io/gen/rr_graph_uxsdcxx.h diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h b/libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_capnp.h similarity index 100% rename from libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h rename to libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_capnp.h diff --git a/libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h b/libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_interface.h similarity index 100% rename from libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h rename to libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_interface.h diff --git a/libs/librrgraph/src/base/rr_graph.xsd b/libs/librrgraph/src/io/rr_graph.xsd similarity index 100% rename from libs/librrgraph/src/base/rr_graph.xsd rename to libs/librrgraph/src/io/rr_graph.xsd diff --git a/libs/librrgraph/src/base/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp similarity index 100% rename from libs/librrgraph/src/base/rr_graph_reader.cpp rename to libs/librrgraph/src/io/rr_graph_reader.cpp diff --git a/libs/librrgraph/src/base/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h similarity index 98% rename from libs/librrgraph/src/base/rr_graph_reader.h rename to libs/librrgraph/src/io/rr_graph_reader.h index 199ec460f9e..35d15bb51b0 100644 --- a/libs/librrgraph/src/base/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -3,7 +3,7 @@ #ifndef RR_GRAPH_READER_H #define RR_GRAPH_READER_H -#include "graph_type.h" +#include "rr_graph_type.h" #include "device_grid.h" #include "physical_types.h" #include "base_cost_type.h" diff --git a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h similarity index 99% rename from libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h rename to libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index 2ed954ec062..5dea4c71c4b 100644 --- a/libs/librrgraph/src/base/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -19,7 +19,7 @@ #include "chan_width.h" #include "base_cost_type.h" #include "unified_to_parallel_seg_index.h" -#include "graph_type.h" +#include "rr_graph_type.h" #include "cost_indices.h" #include "alloc_and_load_rr_indexed_data.h" #include "get_parallel_segs.h" diff --git a/libs/librrgraph/src/base/rr_graph_writer.cpp b/libs/librrgraph/src/io/rr_graph_writer.cpp similarity index 100% rename from libs/librrgraph/src/base/rr_graph_writer.cpp rename to libs/librrgraph/src/io/rr_graph_writer.cpp diff --git a/libs/librrgraph/src/base/rr_graph_writer.h b/libs/librrgraph/src/io/rr_graph_writer.h similarity index 100% rename from libs/librrgraph/src/base/rr_graph_writer.h rename to libs/librrgraph/src/io/rr_graph_writer.h diff --git a/libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h similarity index 100% rename from libs/librrgraph/src/base/alloc_and_load_rr_indexed_data.h rename to libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h diff --git a/libs/librrgraph/src/base/describe_rr_node.h b/libs/librrgraph/src/utils/describe_rr_node.h similarity index 100% rename from libs/librrgraph/src/base/describe_rr_node.h rename to libs/librrgraph/src/utils/describe_rr_node.h diff --git a/vpr/src/route/rr_graph.h b/vpr/src/route/rr_graph.h index a718a862e07..e2639d67e11 100644 --- a/vpr/src/route/rr_graph.h +++ b/vpr/src/route/rr_graph.h @@ -8,7 +8,7 @@ #include "device_grid.h" #include "vpr_types.h" -#include "graph_type.h" +#include "rr_graph_type.h" #include "describe_rr_node.h" /* Warnings about the routing graph that can be returned. From 916c6fefe260ef864807fc5680f4d6ab5574799d Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Fri, 22 Jul 2022 17:24:11 -0700 Subject: [PATCH 10/19] [vpr] fix parameters of check_rr_graph, check_rr_node, RrGraphSerializer, find_create_rr_rc_data. --- libs/librrgraph/src/base/check_rr_graph.cpp | 4 ++-- libs/librrgraph/src/base/check_rr_graph.h | 4 ++-- libs/librrgraph/src/io/rr_graph_reader.cpp | 2 +- libs/librrgraph/src/io/rr_graph_reader.h | 2 +- libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h | 8 ++++---- libs/librrgraph/src/io/rr_graph_writer.cpp | 2 +- libs/librrgraph/src/io/rr_graph_writer.h | 2 +- utils/fasm/test/test_fasm.cpp | 2 +- vpr/src/route/rr_graph.cpp | 4 ++-- vpr/test/test_vpr.cpp | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libs/librrgraph/src/base/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp index 00cb20faaef..ef0e7000796 100644 --- a/libs/librrgraph/src/base/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -43,7 +43,7 @@ class node_edge_sorter { void check_rr_graph(const RRGraphView& rr_graph, const std::vector& types, - const vtr::vector rr_indexed_data, + const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, const t_graph_type graph_type, @@ -288,7 +288,7 @@ static bool rr_node_is_global_clb_ipin(const RRGraphView& rr_graph, const Device } void check_rr_node(const RRGraphView& rr_graph, - const vtr::vector rr_indexed_data, + const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, enum e_route_type route_type, diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index 2098a9afb96..e46cae50844 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -11,14 +11,14 @@ void check_rr_graph(const RRGraphView& rr_graph, const std::vector& types, - const vtr::vector rr_indexed_data, + const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, const t_graph_type graph_type, int virtual_clock_network_root_idx); void check_rr_node(const RRGraphView& rr_graph, - const vtr::vector rr_indexed_data, + const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, enum e_route_type route_type, diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 938dd4bee7c..5129c2940dc 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -43,7 +43,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const std::vector& physical_tile_types, const std::vector& segment_inf, vtr::vector* rr_indexed_data, - std::vector& rr_rc_data, + std::vector* rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_graph_type graph_type, diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index 35d15bb51b0..4bf3f58717a 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -19,7 +19,7 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const std::vector& physical_tile_types, const std::vector& segment_inf, vtr::vector* rr_indexed_data, - std::vector& rr_rc_data, + std::vector* rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_graph_type graph_type, diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index 5dea4c71c4b..e74e5a03c32 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -285,7 +285,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { RRGraphView* rr_graph, vtr::vector* rr_switch_inf, vtr::vector* rr_indexed_data, - std::vector& rr_rc_data, + std::vector* rr_rc_data, const int virtual_clock_network_root_idx, const size_t num_arch_switches, const t_arch_switch_inf* arch_switch_inf, @@ -699,7 +699,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { inline int init_node_timing(int& inode, float C, float R) final { auto node = (*rr_nodes_)[inode]; RRNodeId node_id = node.id(); - rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(R, C, rr_rc_data_))); + rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(R, C, *rr_rc_data_))); return inode; } inline void finish_node_timing(int& /*inode*/) final {} @@ -819,7 +819,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { type); } - rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(0, 0, rr_rc_data_))); + rr_graph_builder_->set_node_rc_index(node_id, NodeRCIndex(find_create_rr_rc_data(0, 0, *rr_rc_data_))); return id; } @@ -1906,7 +1906,7 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { vtr::vector* rr_indexed_data_; t_rr_node_indices* rr_node_indices_; std::string* read_rr_graph_filename_; - std::vector& rr_rc_data_; + std::vector* rr_rc_data_; const int virtual_clock_network_root_idx_; // Constant data for loads and writes. diff --git a/libs/librrgraph/src/io/rr_graph_writer.cpp b/libs/librrgraph/src/io/rr_graph_writer.cpp index 46b92623c74..2101d2e75d7 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.cpp +++ b/libs/librrgraph/src/io/rr_graph_writer.cpp @@ -31,7 +31,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph_view, const std::vector& physical_tile_types, vtr::vector* rr_indexed_data, - std::vector& rr_rc_data, + std::vector* rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_arch* arch, diff --git a/libs/librrgraph/src/io/rr_graph_writer.h b/libs/librrgraph/src/io/rr_graph_writer.h index 90259f17b72..7bac7bbc650 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.h +++ b/libs/librrgraph/src/io/rr_graph_writer.h @@ -19,7 +19,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph, const std::vector& physical_tile_types, vtr::vector* rr_indexed_data, - std::vector& rr_rc_data, + std::vector* rr_rc_data, const DeviceGrid& grid, const t_arch_switch_inf* arch_switch_inf, const t_arch* arch, diff --git a/utils/fasm/test/test_fasm.cpp b/utils/fasm/test/test_fasm.cpp index 9c5066c100c..e6b4685af20 100644 --- a/utils/fasm/test/test_fasm.cpp +++ b/utils/fasm/test/test_fasm.cpp @@ -283,7 +283,7 @@ TEST_CASE("fasm_integration_test", "[fasm]") { &device_ctx.rr_graph, device_ctx.physical_tile_types, &device_ctx.rr_indexed_data, - device_ctx.rr_rc_data, + &device_ctx.rr_rc_data, device_ctx.grid, device_ctx.arch_switch_inf, device_ctx.arch, diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index f640d96db38..5e54a6eb062 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -327,7 +327,7 @@ void create_rr_graph(const t_graph_type graph_type, device_ctx.physical_tile_types, segment_inf, &mutable_device_ctx.rr_indexed_data, - mutable_device_ctx.rr_rc_data, + &mutable_device_ctx.rr_rc_data, grid, device_ctx.arch_switch_inf, graph_type, @@ -393,7 +393,7 @@ void create_rr_graph(const t_graph_type graph_type, &mutable_device_ctx.rr_graph, device_ctx.physical_tile_types, &mutable_device_ctx.rr_indexed_data, - mutable_device_ctx.rr_rc_data, + &mutable_device_ctx.rr_rc_data, grid, device_ctx.arch_switch_inf, device_ctx.arch, diff --git a/vpr/test/test_vpr.cpp b/vpr/test/test_vpr.cpp index b37bd0837c4..8605a3938fa 100644 --- a/vpr/test/test_vpr.cpp +++ b/vpr/test/test_vpr.cpp @@ -156,7 +156,7 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { &mutable_device_ctx.rr_graph, device_ctx.physical_tile_types, &mutable_device_ctx.rr_indexed_data, - mutable_device_ctx.rr_rc_data, + &mutable_device_ctx.rr_rc_data, device_ctx.grid, device_ctx.arch_switch_inf, device_ctx.arch, From ff83a487fdd02932f455799e17e817988078a1ba Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 25 Jul 2022 15:16:21 -0700 Subject: [PATCH 11/19] [vpr] move histogram to libarchfpga, merge rr_graph_util, add alloc_and_load_rr_indexed_data.cpp to librrgraph/src/util --- .../libarchfpga/src}/histogram.cpp | 0 .../util => libs/libarchfpga/src}/histogram.h | 0 libs/librrgraph/src/base/rr_graph_util.cpp | 92 +++ libs/librrgraph/src/base/rr_graph_util.h | 9 + libs/librrgraph/src/io/rr_graph_reader.cpp | 6 +- libs/librrgraph/src/io/rr_graph_reader.h | 4 +- .../src/io/rr_graph_uxsdcxx_serializer.h | 13 +- libs/librrgraph/src/io/rr_graph_writer.cpp | 6 +- libs/librrgraph/src/io/rr_graph_writer.h | 4 +- .../utils/alloc_and_load_rr_indexed_data.cpp | 755 +++++++++++++++++ .../utils/alloc_and_load_rr_indexed_data.h | 19 +- utils/fasm/test/test_fasm.cpp | 6 +- vpr/src/route/rr_graph.cpp | 20 +- vpr/src/route/rr_graph_area.cpp | 6 +- vpr/src/route/rr_graph_indexed_data.cpp | 765 +----------------- vpr/src/route/rr_graph_indexed_data.h | 4 - vpr/src/route/rr_graph_timing_params.cpp | 6 +- vpr/src/route/rr_graph_util.cpp | 101 --- vpr/src/route/rr_graph_util.h | 14 - vpr/test/test_vpr.cpp | 7 +- 20 files changed, 934 insertions(+), 903 deletions(-) rename {vpr/src/util => libs/libarchfpga/src}/histogram.cpp (100%) rename {vpr/src/util => libs/libarchfpga/src}/histogram.h (100%) create mode 100644 libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp delete mode 100644 vpr/src/route/rr_graph_util.cpp delete mode 100644 vpr/src/route/rr_graph_util.h diff --git a/vpr/src/util/histogram.cpp b/libs/libarchfpga/src/histogram.cpp similarity index 100% rename from vpr/src/util/histogram.cpp rename to libs/libarchfpga/src/histogram.cpp diff --git a/vpr/src/util/histogram.h b/libs/libarchfpga/src/histogram.h similarity index 100% rename from vpr/src/util/histogram.h rename to libs/libarchfpga/src/histogram.h diff --git a/libs/librrgraph/src/base/rr_graph_util.cpp b/libs/librrgraph/src/base/rr_graph_util.cpp index 495a6658158..186c5318913 100644 --- a/libs/librrgraph/src/base/rr_graph_util.cpp +++ b/libs/librrgraph/src/base/rr_graph_util.cpp @@ -2,7 +2,17 @@ * This file include most-utilized functions that manipulate on the * RRGraph object ***************************************************************************/ +#include +#include +#include + #include "rr_graph_util.h" + +#include "vtr_memory.h" +#include "vtr_time.h" + +#include "vpr_error.h" + #include "rr_graph_obj.h" /**************************************************************************** @@ -28,3 +38,85 @@ std::vector find_rr_graph_switches(const RRGraph& rr_graph, return switches; } + +int seg_index_of_cblock(const RRGraphView& rr_graph, t_rr_type from_rr_type, int to_node) { + /* Returns the segment number (distance along the channel) of the connection * + * box from from_rr_type (CHANX or CHANY) to to_node (IPIN). */ + + if (from_rr_type == CHANX) + return (rr_graph.node_xlow(RRNodeId(to_node))); + else + /* CHANY */ + return (rr_graph.node_ylow(RRNodeId(to_node))); +} + +int seg_index_of_sblock(const RRGraphView& rr_graph, int from_node, int to_node) { + /* Returns the segment number (distance along the channel) of the switch box * + * box from from_node (CHANX or CHANY) to to_node (CHANX or CHANY). The * + * switch box on the left side of a CHANX segment at (i,j) has seg_index = * + * i-1, while the switch box on the right side of that segment has seg_index * + * = i. CHANY stuff works similarly. Hence the range of values returned is * + * 0 to device_ctx.grid.width()-1 (if from_node is a CHANX) or 0 to device_ctx.grid.height()-1 (if from_node is a CHANY). */ + + t_rr_type from_rr_type, to_rr_type; + + from_rr_type = rr_graph.node_type(RRNodeId(from_node)); + to_rr_type = rr_graph.node_type(RRNodeId(to_node)); + + if (from_rr_type == CHANX) { + if (to_rr_type == CHANY) { + return (rr_graph.node_xlow(RRNodeId(to_node))); + } else if (to_rr_type == CHANX) { + if (rr_graph.node_xlow(RRNodeId(to_node)) > rr_graph.node_xlow(RRNodeId(from_node))) { /* Going right */ + return (rr_graph.node_xhigh(RRNodeId(from_node))); + } else { /* Going left */ + return (rr_graph.node_xhigh(RRNodeId(to_node))); + } + } else { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "in seg_index_of_sblock: to_node %d is of type %d.\n", + to_node, to_rr_type); + return OPEN; //Should not reach here once thrown + } + } + /* End from_rr_type is CHANX */ + else if (from_rr_type == CHANY) { + if (to_rr_type == CHANX) { + return (rr_graph.node_ylow(RRNodeId(to_node))); + } else if (to_rr_type == CHANY) { + if (rr_graph.node_ylow(RRNodeId(to_node)) > rr_graph.node_ylow(RRNodeId(from_node))) { /* Going up */ + return (rr_graph.node_yhigh(RRNodeId(from_node))); + } else { /* Going down */ + return (rr_graph.node_yhigh(RRNodeId(to_node))); + } + } else { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "in seg_index_of_sblock: to_node %d is of type %d.\n", + to_node, to_rr_type); + return OPEN; //Should not reach here once thrown + } + } + /* End from_rr_type is CHANY */ + else { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, + "in seg_index_of_sblock: from_node %d is of type %d.\n", + from_node, from_rr_type); + return OPEN; //Should not reach here once thrown + } +} + +vtr::vector> get_fan_in_list(const RRGraphView& rr_graph) { + vtr::vector> node_fan_in_list; + + node_fan_in_list.resize(rr_graph.num_nodes(), std::vector(0)); + node_fan_in_list.shrink_to_fit(); + + //Walk the graph and increment fanin on all dwnstream nodes + rr_graph.rr_nodes().for_each_edge( + [&](RREdgeId edge, __attribute__((unused)) RRNodeId src, RRNodeId sink) { + node_fan_in_list[sink].push_back(edge); + }); + + return node_fan_in_list; +} + diff --git a/libs/librrgraph/src/base/rr_graph_util.h b/libs/librrgraph/src/base/rr_graph_util.h index 027356b86f9..93947654c5b 100644 --- a/libs/librrgraph/src/base/rr_graph_util.h +++ b/libs/librrgraph/src/base/rr_graph_util.h @@ -6,10 +6,19 @@ */ #include #include "rr_graph_fwd.h" +#include "rr_node_types.h" +#include "rr_graph_view.h" /* Get node-to-node switches in a RRGraph */ std::vector find_rr_graph_switches(const RRGraph& rr_graph, const RRNodeId& from_node, const RRNodeId& to_node); +// This function generates and returns a vector indexed by RRNodeId +// containing a list of fan-in edges for each node. +vtr::vector> get_fan_in_list(const RRGraphView& rr_graph); + +int seg_index_of_cblock(const RRGraphView& rr_graph, t_rr_type from_rr_type, int to_node); +int seg_index_of_sblock(const RRGraphView& rr_graph, int from_node, int to_node); + #endif diff --git a/libs/librrgraph/src/io/rr_graph_reader.cpp b/libs/librrgraph/src/io/rr_graph_reader.cpp index 5129c2940dc..1bf7cb32219 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.cpp +++ b/libs/librrgraph/src/io/rr_graph_reader.cpp @@ -56,7 +56,9 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const char* read_rr_graph_name, std::string* read_rr_graph_filename, bool read_edge_metadata, - bool do_check_rr_graph) { + bool do_check_rr_graph, + bool echo_enabled, + const char* echo_file_name) { vtr::ScopedStartFinishTimer timer("Loading routing resource graph"); size_t num_segments = segment_inf.size(); @@ -73,6 +75,8 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, read_rr_graph_name, read_rr_graph_filename, read_edge_metadata, + echo_enabled, + echo_file_name, chan_width, &rr_graph_builder->rr_nodes(), rr_graph_builder, diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index 4bf3f58717a..c5e129f033d 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -32,6 +32,8 @@ void load_rr_file(RRGraphBuilder* rr_graph_builder, const char* read_rr_graph_name, std::string* read_rr_graph_filename, bool read_edge_metadata, - bool do_check_rr_graph); + bool do_check_rr_graph, + bool echo_enabled, + const char* echo_file_name); #endif /* RR_GRAPH_READER_H */ diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index e74e5a03c32..2d117bf5f48 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -279,6 +279,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { const char* read_rr_graph_name, std::string* read_rr_graph_filename, bool read_edge_metadata, + bool echo_enabled, + const char* echo_file_name, t_chan_width* chan_width, t_rr_graph_storage* rr_nodes, RRGraphBuilder* rr_graph_builder, @@ -310,6 +312,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { , do_check_rr_graph_(do_check_rr_graph) , read_rr_graph_name_(read_rr_graph_name) , read_edge_metadata_(read_edge_metadata) + , echo_enabled_ (echo_enabled) + , echo_file_name_ (echo_file_name) , num_arch_switches_(num_arch_switches) , arch_switch_inf_(arch_switch_inf) , segment_inf_(segment_inf) @@ -1593,11 +1597,16 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { auto segment_inf_y_ = get_parallel_segs(temp_rr_segs, seg_index_map, Y_AXIS); alloc_and_load_rr_indexed_data( + *rr_graph_, + grid_, temp_rr_segs, segment_inf_x_, segment_inf_y_, + *rr_indexed_data_, *wire_to_rr_ipin_switch_, - base_cost_type_); + base_cost_type_, + echo_enabled_, + echo_file_name_); VTR_ASSERT(rr_indexed_data_->size() == seg_index_.size()); for (size_t i = 0; i < seg_index_.size(); ++i) { @@ -1915,6 +1924,8 @@ class RrGraphSerializer final : public uxsd::RrGraphBase { const bool do_check_rr_graph_; const char* read_rr_graph_name_; const bool read_edge_metadata_; + const bool echo_enabled_; + const char* echo_file_name_; const size_t num_arch_switches_; const t_arch_switch_inf* arch_switch_inf_; diff --git a/libs/librrgraph/src/io/rr_graph_writer.cpp b/libs/librrgraph/src/io/rr_graph_writer.cpp index 2101d2e75d7..5c8bb677bc2 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.cpp +++ b/libs/librrgraph/src/io/rr_graph_writer.cpp @@ -38,7 +38,9 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, t_chan_width* chan_width, const size_t num_arch_switches, const char* file_name, - const int virtual_clock_network_root_idx) { + const int virtual_clock_network_root_idx, + bool echo_enabled, + const char* echo__file_name) { RrGraphSerializer reader( /*graph_type=*/t_graph_type(), @@ -48,6 +50,8 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, /*read_rr_graph_name=*/nullptr, /*read_rr_graph_filename=*/nullptr, /*read_edge_metadata=*/false, + echo_enabled, + echo__file_name, chan_width, &rr_graph_builder->rr_nodes(), rr_graph_builder, diff --git a/libs/librrgraph/src/io/rr_graph_writer.h b/libs/librrgraph/src/io/rr_graph_writer.h index 7bac7bbc650..c1de365c053 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.h +++ b/libs/librrgraph/src/io/rr_graph_writer.h @@ -26,6 +26,8 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, t_chan_width* chan_width, const size_t num_arch_switches, const char* file_name, - const int virtual_clock_network_root_idx); + const int virtual_clock_network_root_idx, + bool echo_enabled, + const char* echo__file_name); #endif diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp new file mode 100644 index 00000000000..7df6c7f92b4 --- /dev/null +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp @@ -0,0 +1,755 @@ +#include /* Needed only for sqrt call (remove if sqrt removed) */ +#include +#include +#include +#include /* Needed for ortho_Cost_index calculation*/ + +#include "alloc_and_load_rr_indexed_data.h" + +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_memory.h" +#include "vtr_math.h" + +#include "vpr_error.h" + +#include "rr_graph_util.h" +#include "read_xml_arch_file.h" + +#include "base_cost_type.h" +#include "cost_indices.h" + +#include "histogram.h" + +/******************* Subroutines local to this module ************************/ + +static void load_rr_indexed_data_base_costs(const RRGraphView& rr_graph, vtr::vector& rr_indexed_data, enum e_base_cost_type base_cost_type, const bool echo_enabled, const char* echo_file_name); + +static float get_delay_normalization_fac(const vtr::vector& rr_indexed_data, const bool echo_enabled, const char* echo_file_name); + +static void load_rr_indexed_data_T_values(const RRGraphView& rr_graph, vtr::vector& rr_indexed_data); + +static void calculate_average_switch(const RRGraphView& rr_graph, int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, short& buffered, vtr::vector>& fan_in_list); + +static void fixup_rr_indexed_data_T_values(vtr::vector& rr_indexed_data, size_t num_segment); + +static std::vector count_rr_segment_types(const RRGraphView& rr_graph, const vtr::vector& rr_indexed_data); + +static void print_rr_index_info(const vtr::vector& rr_indexed_data, const char* fname, const std::vector& segment_inf, size_t y_chan_cost_offset); + +/******************** Subroutine definitions *********************************/ + +/* Allocates the rr_indexed_data array and loads it with appropriate values. * + * It currently stores the segment type (or OPEN if the index doesn't * + * correspond to an CHANX or CHANY type), the base cost of nodes of that * + * type, and some info to allow rapid estimates of time to get to a target * + * to be computed by the router. * + * + * Right now all SOURCES have the same base cost; and similarly there's only * + * one base cost for each of SINKs, OPINs, and IPINs (four total). This can * + * be changed just by allocating more space in the array below and changing * + * the cost_index values for these rr_nodes, if you want to make some pins * + * etc. more expensive than others. I give each segment type in an * + * x-channel its own cost_index, and each segment type in a y-channel its * + * own cost_index. */ +void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, + const DeviceGrid& grid, + const std::vector& segment_inf, + const std::vector& segment_inf_x, + const std::vector& segment_inf_y, + vtr::vector& rr_indexed_data, + int wire_to_ipin_switch, + enum e_base_cost_type base_cost_type, + const bool echo_enabled, + const char* echo_file_name) { + int length, i, index; + + (void)segment_inf; + int total_num_segment = segment_inf_x.size() + segment_inf_y.size(); + /*CHAX & CHANY segment lsit sizes may differ. but if we're using uniform channels, they + * will each have size equal to segment_inf.size()*/ + int num_rr_indexed_data = CHANX_COST_INDEX_START + total_num_segment; + rr_indexed_data.resize(num_rr_indexed_data); + + /* For rr_types that aren't CHANX or CHANY, base_cost is valid, but most * + * * other fields are invalid. For IPINs, the T_linear field is also valid; * + * * all other fields are invalid. For SOURCES, SINKs and OPINs, all fields * + * * other than base_cost are invalid. Mark invalid fields as OPEN for safety. */ + + constexpr float nan = std::numeric_limits::quiet_NaN(); + for (i = SOURCE_COST_INDEX; i <= IPIN_COST_INDEX; i++) { + rr_indexed_data[RRIndexedDataId(i)].ortho_cost_index = OPEN; + rr_indexed_data[RRIndexedDataId(i)].seg_index = OPEN; + rr_indexed_data[RRIndexedDataId(i)].inv_length = nan; + rr_indexed_data[RRIndexedDataId(i)].T_linear = 0.; + rr_indexed_data[RRIndexedDataId(i)].T_quadratic = 0.; + rr_indexed_data[RRIndexedDataId(i)].C_load = 0.; + } + rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].T_linear = rr_graph.rr_switch_inf(RRSwitchId(wire_to_ipin_switch)).Tdel; + + std::vector ortho_costs; + + ortho_costs = find_ortho_cost_index(rr_graph, segment_inf_x, segment_inf_y, X_AXIS); + + /* AA: The code below should replace find_ortho_cost_index call once we deprecate the CLASSIC lookahead as it is the only lookahead + * that actively uses the orthogonal cost indices. To avoid complicated dependencies with the rr_graph reader, regardless of the lookahead, + * we walk to the rr_graph edges to get these indices. */ + /* + * + * std::vector x_costs(segment_inf_x.size(), CHANX_COST_INDEX_START + segment_inf_x.size()); + * std::vector y_costs(segment_inf_y.size(), CHANX_COST_INDEX_START); + * + * std::move(x_costs.begin(), x_costs.end(), std::back_inserter(ortho_costs)); + * std::move(y_costs.begin(), y_costs.end(), std::back_inserter(ortho_costs)); + */ + + /* X-directed segments*/ + + for (size_t iseg = 0; iseg < segment_inf_x.size(); ++iseg) { + index = iseg + CHANX_COST_INDEX_START; + + rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; + + if (segment_inf_x[iseg].longline) + length = grid.width(); + else + length = std::min(segment_inf_x[iseg].length, grid.width()); + + rr_indexed_data[RRIndexedDataId(index)].inv_length = 1. / length; + /*We use the index fo the segment in the **unified** seg_inf vector not iseg which is relative + * to parallel axis segments vector */ + rr_indexed_data[RRIndexedDataId(index)].seg_index = segment_inf_x[iseg].seg_index; + } + + /* Y-directed segments*/ + + for (size_t iseg = segment_inf_x.size(); iseg < ortho_costs.size(); ++iseg) { + index = iseg + CHANX_COST_INDEX_START; + rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; + + if (segment_inf_x[iseg - segment_inf_x.size()].longline) + length = grid.width(); + else + length = std::min(segment_inf_y[iseg - segment_inf_x.size()].length, grid.width()); + + rr_indexed_data[RRIndexedDataId(index)].inv_length = 1. / length; + /*We use the index fo the segment in the **unified** seg_inf vector not iseg which is relative + * to parallel axis segments vector */ + rr_indexed_data[RRIndexedDataId(index)].seg_index = segment_inf_y[iseg - segment_inf_x.size()].seg_index; + } + + load_rr_indexed_data_T_values(rr_graph, rr_indexed_data); + + fixup_rr_indexed_data_T_values(rr_indexed_data, total_num_segment); + + load_rr_indexed_data_base_costs(rr_graph, rr_indexed_data, base_cost_type, echo_enabled, echo_file_name); + + if (echo_enabled) { + print_rr_index_info(rr_indexed_data, + echo_file_name, + segment_inf, segment_inf_x.size()); + } +} + +/* AA: We use a normalized product of frequency and length to find the segment that is most likely + * to connect to in the perpendicular axis. Note that the size of segment_inf_x & segment_inf_y is not + * the same necessarly. The result vector will contain the indices in segment_inf_perp + * of the most likely perp segments for each segment at index i in segment_inf_parallel. + * + * Note: We use the seg_index field of t_segment_inf to store the segment index + * in the **unified** t_segment_inf vector. We will temporarly use this field in + * a copy passed to the function to store the index w.r.t the parallel axis segment list.*/ + +std::vector find_ortho_cost_index(const RRGraphView& rr_graph, + const std::vector segment_inf_x, + const std::vector segment_inf_y, + e_parallel_axis parallel_axis) { + auto segment_inf_parallel = parallel_axis == X_AXIS ? segment_inf_x : segment_inf_y; + auto segment_inf_perp = parallel_axis == X_AXIS ? segment_inf_y : segment_inf_x; + + size_t num_segments = segment_inf_x.size() + segment_inf_y.size(); + std::vector> dest_nodes_count; + + // x segments are perpendicular to y segments + + dest_nodes_count.resize(num_segments); + + for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { + dest_nodes_count[iseg].resize(segment_inf_y.size()); + } + // y segments are perpendicular to x segments + for (size_t iseg = segment_inf_x.size(); iseg < num_segments; iseg++) { + dest_nodes_count[iseg].resize(segment_inf_x.size()); + } + + std::vector ortho_cost_indices(dest_nodes_count.size(), 0); + + //Go through all rr_Nodes. Look at the ones with CHAN type. Count all outgoing edges to CHAN typed nodes from each CHAN type node. + for (const RRNodeId& rr_node : rr_graph.nodes()) { + for (size_t iedge = 0; iedge < rr_graph.num_edges(rr_node); ++iedge) { + RRNodeId to_node = rr_graph.edge_sink_node(rr_node, iedge); + t_rr_type from_node_type = rr_graph.node_type(rr_node); + t_rr_type to_node_type = rr_graph.node_type(to_node); + + size_t from_node_cost_index = (size_t)rr_graph.node_cost_index(rr_node); + size_t to_node_cost_index = (size_t)rr_graph.node_cost_index(to_node); + + //if the type is smaller than start index, means destination is not a CHAN type node. + + if ((from_node_type == CHANX && to_node_type == CHANY) || (from_node_type == CHANY && to_node_type == CHANX)) { + if (to_node_type == CHANY) { + dest_nodes_count[from_node_cost_index - CHANX_COST_INDEX_START][to_node_cost_index - (CHANX_COST_INDEX_START + segment_inf_x.size())]++; + } else { + dest_nodes_count[from_node_cost_index - CHANX_COST_INDEX_START][to_node_cost_index - CHANX_COST_INDEX_START]++; + } + } else { + continue; + } + } + } + + for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { + dest_nodes_count[iseg].resize(segment_inf_y.size()); + } + + for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { + ortho_cost_indices[iseg] = std::max_element(dest_nodes_count[iseg].begin(), dest_nodes_count[iseg].end()) - dest_nodes_count[iseg].begin(); + ortho_cost_indices[iseg] += CHANX_COST_INDEX_START + segment_inf_x.size(); + } + + for (size_t iseg = segment_inf_x.size(); iseg < num_segments; iseg++) { + ortho_cost_indices[iseg] = std::max_element(dest_nodes_count[iseg].begin(), dest_nodes_count[iseg].end()) - dest_nodes_count[iseg].begin(); + ortho_cost_indices[iseg] += CHANX_COST_INDEX_START; + } + + return ortho_cost_indices; + + /*Update seg_index */ + +#ifdef FREQ_LENGTH_ORTHO_COSTS + + for (int i = 0; i < (int)segment_inf_perp.size(); ++i) + segment_inf_perp[i].seg_index = i; + + std::vector ortho_costs_indices; + ortho_costs_indices.resize(segment_inf_parallel.size()); + + int num_segments = (int)segment_inf_parallel.size(); + for (int seg_index = 0; seg_index < num_segments; ++seg_index) { + auto segment = segment_inf_parallel[seg_index]; + auto lambda_cmp = [&segment](t_segment_inf& a, t_segment_inf& b) { + float a_freq = a.frequency / (float)segment.frequency; + float b_freq = b.frequency / (float)segment.frequency; + float a_len = (float)segment.length / a.length; + float b_len = (float)segment.length / b.length; + + float a_product = a_len * a_freq; + float b_product = b_len * b_freq; + + if (std::abs(a_product - 1) < std::abs(b_product - 1)) + return true; + else if (std::abs(a_product - 1) > std::abs(b_product - 1)) + return false; + else { + if ((segment.name == a.name && segment.parallel_axis == BOTH_AXIS) || (segment.length == a.length && segment.frequency == a.frequency)) + return true; + else { + if (a.frequency > b.frequency) + return true; + else if (a.frequency < b.frequency) + return false; + else + return a.length < b.length; + } + } + }; + + std::sort(segment_inf_perp.begin(), segment_inf_perp.end(), lambda_cmp); + + /* The compartor behaves as operator< mostly, so the first element in the + * sorted vector will have the lowest cost difference from segment. */ + ortho_costs_indices[seg_index] = segment_inf_perp[0].seg_index + start_channel_cost; + ortho_costs_indices[seg_index] = parallel_axis == X_AXIS ? ortho_costs_indices[seg_index] + num_segments : ortho_costs_indices[seg_index]; + } + + /*Pertubate indices to make sure all perp seg types have a corresponding perp segment.*/ +# ifdef PERTURB_ORTHO_COST_indices + std::vector perp_segments; + std::unordered_multimap indices_map; + auto cmp_greater = [](std::pair a, std::pair b) { + return a.second < b.second; + }; + std::priority_queue, std::vector>, decltype(cmp_greater)> indices_q_greater(cmp_greater); + + auto cmp_less = [](std::pair a, std::pair b) { + return a.second > b.second; + }; + + std::priority_queue, std::vector>, decltype(cmp_less)> indices_q_less(cmp_less); + + perp_segments.resize(segment_inf_perp.size(), 0); + + for (int i = 0; i < num_segments; ++i) { + int index = parallel_axis == X_AXIS ? ortho_costs_indices[i] - num_segments - start_channel_cost : ortho_costs_indices[i] - start_channel_cost; + indices_map.insert(std::make_pair(index, i)); + perp_segments[index]++; + } + + for (int i = 0; i < (int)perp_segments.size(); ++i) { + auto pair = std::make_pair(i, perp_segments[i]); + indices_q_greater.push(pair); + indices_q_less.push(pair); + } + + while (!indices_q_greater.empty()) { + auto g_index_pair = indices_q_greater.top(); + auto l_index_pair = indices_q_less.top(); + + if (l_index_pair.second != 0) + break; + + indices_q_greater.pop(); + indices_q_less.pop(); + + g_index_pair.second--; + l_index_pair.second++; + auto itr_to_change = indices_map.find(g_index_pair.first); + VTR_ASSERT(itr_to_change != indices_map.end()); + int index = l_index_pair.first + start_channel_cost; + index = parallel_axis == X_AXIS ? index + num_segments : index; + ortho_costs_indices[itr_to_change->second] = index; + indices_map.erase(itr_to_change); + + indices_q_greater.push(g_index_pair); + indices_q_less.push(l_index_pair); + } +# endif + + return ortho_costs_indices; +#endif +} + +static void load_rr_indexed_data_base_costs(const RRGraphView& rr_graph, + vtr::vector& rr_indexed_data, + enum e_base_cost_type base_cost_type, + const bool echo_enabled, + const char* echo_file_name) { + /* Loads the base_cost member of rr_indexed_data according to the specified * + * base_cost_type. */ + + float delay_normalization_fac; + size_t index; + + if (base_cost_type == DEMAND_ONLY || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) { + delay_normalization_fac = 1.; + } else { + delay_normalization_fac = get_delay_normalization_fac(rr_indexed_data, echo_enabled, echo_file_name); + } + + rr_indexed_data[RRIndexedDataId(SOURCE_COST_INDEX)].base_cost = delay_normalization_fac; + rr_indexed_data[RRIndexedDataId(SINK_COST_INDEX)].base_cost = 0.; + rr_indexed_data[RRIndexedDataId(OPIN_COST_INDEX)].base_cost = delay_normalization_fac; + rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].base_cost = 0.95 * delay_normalization_fac; + + auto rr_segment_counts = count_rr_segment_types(rr_graph, rr_indexed_data); + size_t total_segments = std::accumulate(rr_segment_counts.begin(), rr_segment_counts.end(), 0u); + + /* Load base costs for CHANX and CHANY segments */ + float max_length = 0; + float min_length = 1; + if (base_cost_type == DELAY_NORMALIZED_LENGTH_BOUNDED) { + for (index = CHANX_COST_INDEX_START; index < rr_indexed_data.size(); index++) { + float length = (1 / rr_indexed_data[RRIndexedDataId(index)].inv_length); + max_length = std::max(max_length, length); + } + } + + //Future Work: Since we can now have wire types which don't connect to IPINs, + // perhaps consider lowering cost of wires which connect to IPINs + // so they get explored earlier (same rational as lowering IPIN costs) + + for (index = CHANX_COST_INDEX_START; index < rr_indexed_data.size(); index++) { + if (base_cost_type == DELAY_NORMALIZED || base_cost_type == DEMAND_ONLY) { + rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac; + + } else if (base_cost_type == DELAY_NORMALIZED_LENGTH || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) { + rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / rr_indexed_data[RRIndexedDataId(index)].inv_length; + + } else if (base_cost_type == DELAY_NORMALIZED_LENGTH_BOUNDED) { + float length = (1 / rr_indexed_data[RRIndexedDataId(index)].inv_length); + if (max_length != min_length) { + float length_scale = 1.f + 3.f * (length - min_length) / (max_length - min_length); + rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac * length_scale; + } else { + rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac; + } + + } else if (base_cost_type == DELAY_NORMALIZED_FREQUENCY) { + int seg_index = rr_indexed_data[RRIndexedDataId(index)].seg_index; + + VTR_ASSERT(total_segments > 0); + float freq_fac = float(rr_segment_counts[seg_index]) / total_segments; + + rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / freq_fac; + + } else if (base_cost_type == DELAY_NORMALIZED_LENGTH_FREQUENCY) { + int seg_index = rr_indexed_data[RRIndexedDataId(index)].seg_index; + + VTR_ASSERT(total_segments > 0); + float freq_fac = float(rr_segment_counts[seg_index]) / total_segments; + + //Base cost = delay_norm / (len * freq) + //rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / ((1. / rr_indexed_data[RRIndexedDataId(index)].inv_length) * freq_fac); + + //Base cost = (delay_norm * len) * (1 + (1-freq)) + rr_indexed_data[RRIndexedDataId(index)].base_cost = (delay_normalization_fac / rr_indexed_data[RRIndexedDataId(index)].inv_length) * (1 + (1 - freq_fac)); + + } else { + VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Unrecognized base cost type"); + } + } + + /* Save a copy of the base costs -- if dynamic costing is used by the * + * router, the base_cost values will get changed all the time and being * + * able to restore them from a saved version is useful. */ + + for (index = 0; index < rr_indexed_data.size(); index++) { + rr_indexed_data[RRIndexedDataId(index)].saved_base_cost = rr_indexed_data[RRIndexedDataId(index)].base_cost; + } +} + +static std::vector count_rr_segment_types(const RRGraphView& rr_graph, const vtr::vector& rr_indexed_data) { + std::vector rr_segment_type_counts; + + for (const RRNodeId& id : rr_graph.nodes()) { + if (rr_graph.node_type(id) != CHANX && rr_graph.node_type(id) != CHANY) continue; + + auto cost_index = rr_graph.node_cost_index(id); + + int seg_index = rr_indexed_data[cost_index].seg_index; + + VTR_ASSERT(seg_index != OPEN); + + if (seg_index >= int(rr_segment_type_counts.size())) { + rr_segment_type_counts.resize(seg_index + 1, 0); + } + VTR_ASSERT(seg_index < int(rr_segment_type_counts.size())); + + ++rr_segment_type_counts[seg_index]; + } + + return rr_segment_type_counts; +} + +static float get_delay_normalization_fac(const vtr::vector& rr_indexed_data, + const bool echo_enabled, + const char* echo_file_name) { + /* Returns the average delay to go 1 CLB distance along a wire. */ + + float Tdel_sum = 0.0; + int Tdel_num = 0; + for (size_t cost_index = CHANX_COST_INDEX_START; cost_index < rr_indexed_data.size(); cost_index++) { + float inv_length = rr_indexed_data[RRIndexedDataId(cost_index)].inv_length; + float T_value = rr_indexed_data[RRIndexedDataId(cost_index)].T_linear * inv_length + rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic * std::pow(inv_length, 2); + + if (T_value == 0.0) continue; + + Tdel_sum += T_value; + Tdel_num += 1; + } + + if (Tdel_num == 0) { + VTR_LOG_WARN("No valid cost index was found to get the delay normalization factor. Setting delay normalization factor to 1e-9 (1 ns)\n"); + return 1e-9; + } + + float delay_norm_fac = Tdel_sum / Tdel_num; + + if (echo_enabled) { + std::ofstream out_file; + + out_file.open(echo_file_name); + out_file << "Delay normalization factor: " << delay_norm_fac << std::endl; + + out_file.close(); + } + + return delay_norm_fac; +} + +/* + * Scans all the RR nodes of CHAN type getting the medians for their R and C values (delays) + * as well as the delay data of all the nodes' switches, averaging them to find the following + * indexed data values for each wire type: + * - T_linear + * - T_quadratic + * - C_load + * + * The indexed data is used in different locations such as: + * - Base cost calculation for each cost_index + * - Lookahead map computation + * - Placement Delay Matrix computation + */ +static void load_rr_indexed_data_T_values(const RRGraphView& rr_graph, + vtr::vector& rr_indexed_data) { + auto fan_in_list = get_fan_in_list(rr_graph); + + vtr::vector num_nodes_of_index(rr_indexed_data.size(), 0); + vtr::vector> C_total(rr_indexed_data.size()); + vtr::vector> R_total(rr_indexed_data.size()); + + /* + * Not all wire-to-wire switches connecting from some wire segment will necessarily have the same delay. + * i.e. a mux with less inputs will have smaller delay than a mux with a greater number of inputs. + * So to account for these differences we will get the average R/Tdel/Cinternal values by first averaging + * them for a single wire segment, and then by averaging this value over all the average values corresponding + * to the switches node + */ + vtr::vector> switch_R_total(rr_indexed_data.size()); + vtr::vector> switch_T_total(rr_indexed_data.size()); + vtr::vector> switch_Cinternal_total(rr_indexed_data.size()); + vtr::vector switches_buffered(rr_indexed_data.size(), UNDEFINED); + + /* + * Walk through the RR graph and collect all R and C values of all the nodes, + * as well as their fan-in switches R, T_del, and Cinternal values. + * + * The median of R and C values for each cost index is assigned to the indexed + * data. + */ + for (const RRNodeId& rr_id : rr_graph.nodes()) { + t_rr_type rr_type = rr_graph.node_type(rr_id); + + if (rr_type != CHANX && rr_type != CHANY) { + continue; + } + + auto cost_index = rr_graph.node_cost_index(rr_id); + + auto node_cords = rr_graph.node_coordinate_to_string(RRNodeId(rr_id)); + + /* get average switch parameters */ + double avg_switch_R = 0; + double avg_switch_T = 0; + double avg_switch_Cinternal = 0; + int num_switches = 0; + short buffered = UNDEFINED; + calculate_average_switch(rr_graph, (size_t)rr_id, avg_switch_R, avg_switch_T, avg_switch_Cinternal, num_switches, buffered, fan_in_list); + + if (num_switches == 0) { + VTR_LOG_WARN("Node: %d with RR_type: %s at Location:%s, had no out-going switches\n", rr_id, + rr_graph.node_type_string(rr_id), node_cords.c_str()); + continue; + } + VTR_ASSERT(num_switches > 0); + + num_nodes_of_index[cost_index]++; + C_total[cost_index].push_back(rr_graph.node_C(rr_id)); + R_total[cost_index].push_back(rr_graph.node_R(rr_id)); + + switch_R_total[cost_index].push_back(avg_switch_R); + switch_T_total[cost_index].push_back(avg_switch_T); + switch_Cinternal_total[cost_index].push_back(avg_switch_Cinternal); + if (buffered == UNDEFINED) { + /* this segment does not have any outgoing edges to other general routing wires */ + continue; + } + + /* need to make sure all wire switches of a given wire segment type have the same 'buffered' value */ + if (switches_buffered[cost_index] == UNDEFINED) { + switches_buffered[cost_index] = buffered; + } else { + if (switches_buffered[cost_index] != buffered) { + // If a previous buffering state is inconsistent with the current one, + // the node should be treated as buffered, as there are only two possible + // values for the buffering state (except for the UNDEFINED case). + // + // This means that at least one edge of this node has a buffered switch, + // which prevails over unbuffered ones. + switches_buffered[cost_index] = 1; + } + } + } + + for (size_t cost_index = CHANX_COST_INDEX_START; + cost_index < rr_indexed_data.size(); cost_index++) { + if (num_nodes_of_index[RRIndexedDataId(cost_index)] == 0) { /* Segments don't exist. */ + VTR_LOG_WARN("Found no instances of RR node with cost index %d\n", cost_index); + rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = 0.0; + rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = 0.0; + rr_indexed_data[RRIndexedDataId(cost_index)].C_load = 0.0; + } else { + auto C_total_histogram = build_histogram(C_total[RRIndexedDataId(cost_index)], 10); + auto R_total_histogram = build_histogram(R_total[RRIndexedDataId(cost_index)], 10); + auto switch_R_total_histogram = build_histogram(switch_R_total[RRIndexedDataId(cost_index)], 10); + auto switch_T_total_histogram = build_histogram(switch_T_total[RRIndexedDataId(cost_index)], 10); + auto switch_Cinternal_total_histogram = build_histogram(switch_Cinternal_total[RRIndexedDataId(cost_index)], 10); + + // Sort Rnode and Cnode + float Cnode = vtr::median(C_total[RRIndexedDataId(cost_index)]); + float Rnode = vtr::median(R_total[RRIndexedDataId(cost_index)]); + float Rsw = get_histogram_mode(switch_R_total_histogram); + float Tsw = get_histogram_mode(switch_T_total_histogram); + float Cinternalsw = get_histogram_mode(switch_Cinternal_total_histogram); + + if (switches_buffered[RRIndexedDataId(cost_index)]) { + // Here, we are computing the linear time delay for buffered switches. Tlinear is + // the estimated sum of the intrinsic time delay of the switch and the two transient + // responses. The key assumption behind the estimate is that one switch will be turned on + // from each wire and so we will correspondingly add one load for internal capacitance. + // The first transient response is the product between the resistance of the switch with + // the combined capacitance of the node and internal capacitance of the switch. The + // multiplication by the second term by 0.5 is the result of the Rnode being distributed halfway along a + // wire segment's length times the total capacitance. + rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = Tsw + Rsw * (Cinternalsw + Cnode) + + 0.5 * Rnode * (Cnode + Cinternalsw); + rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = 0.; + rr_indexed_data[RRIndexedDataId(cost_index)].C_load = 0.; + } else { /* Pass transistor, does not have an internal capacitance*/ + rr_indexed_data[RRIndexedDataId(cost_index)].C_load = Cnode; + + /* See Dec. 23, 1997 notes for deriviation of formulae. */ + + rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = Tsw + 0.5 * Rsw * Cnode; + rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = (Rsw + Rnode) * 0.5 + * Cnode; + } + } + } +} + +/* + * This routine calculates the average R/Tdel/Cinternal values of all the switches corresponding + * to the fan-in edges of the input inode. + * + * It is not safe to assume that each node of the same wire type has the same switches with the same + * delays, therefore we take their average to take into account the possible differences + */ +static void calculate_average_switch(const RRGraphView& rr_graph, int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, short& buffered, vtr::vector>& fan_in_list) { + auto node = RRNodeId(inode); + + avg_switch_R = 0; + avg_switch_T = 0; + avg_switch_Cinternal = 0; + num_switches = 0; + buffered = UNDEFINED; + for (const auto& edge : fan_in_list[node]) { + /* want to get C/R/Tdel/Cinternal of switches that connect this track segment to other track segments */ + if (rr_graph.node_type(node) == CHANX || rr_graph.node_type(node) == CHANY) { + int switch_index = rr_graph.rr_nodes().edge_switch(edge); + + if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).type() == SwitchType::SHORT) continue; + + avg_switch_R += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).R; + avg_switch_T += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Tdel; + avg_switch_Cinternal += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cinternal; + + if (buffered == UNDEFINED) { + if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered()) { + buffered = 1; + } else { + buffered = 0; + } + } else if (buffered != rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered()) { + // If a previous buffering state is inconsistent with the current one, + // the node should be treated as buffered, as there are only two possible + // values for the buffering state (except for the UNDEFINED case). + // + // This means that at least one edge of this node has a buffered switch, + // which prevails over unbuffered ones. + buffered = 1; + } + + num_switches++; + } + } + + if (num_switches > 0) { + avg_switch_R /= num_switches; + avg_switch_T /= num_switches; + avg_switch_Cinternal /= num_switches; + } + + VTR_ASSERT(std::isfinite(avg_switch_R)); + VTR_ASSERT(std::isfinite(avg_switch_T)); + VTR_ASSERT(std::isfinite(avg_switch_Cinternal)); +} + +static void fixup_rr_indexed_data_T_values(vtr::vector& rr_indexed_data, + size_t total_num_segments) { + // Scan CHANX/CHANY indexed data and search for uninitialized costs. + // + // This would occur if a segment ends up only being used as CHANX or a + // CHANY, but not both. If this occurs, then copying the orthogonal + // pair's cost data is likely a better choice than leaving it uninitialized. + // + // The primary reason for this fixup is to avoid propagating negative + // values in cost functions. + for (size_t cost_index = CHANX_COST_INDEX_START; + cost_index < CHANX_COST_INDEX_START + total_num_segments; cost_index++) { + int ortho_cost_index = rr_indexed_data[RRIndexedDataId(cost_index)].ortho_cost_index; + + auto& indexed_data = rr_indexed_data[RRIndexedDataId(cost_index)]; + auto& ortho_indexed_data = rr_indexed_data[RRIndexedDataId(ortho_cost_index)]; + // Check if this data is uninitialized, but the orthogonal data is + // initialized. + // Uninitialized data is set to zero by default. + bool needs_fixup = indexed_data.T_linear == 0 && indexed_data.T_quadratic == 0 && indexed_data.C_load == 0; + bool ortho_data_valid = ortho_indexed_data.T_linear != 0 || ortho_indexed_data.T_quadratic != 0 || ortho_indexed_data.C_load != 0; + if (needs_fixup && ortho_data_valid) { + // Copy orthogonal data over. + indexed_data.T_linear = ortho_indexed_data.T_linear; + indexed_data.T_quadratic = ortho_indexed_data.T_quadratic; + indexed_data.C_load = ortho_indexed_data.C_load; + } + } +} + +static void print_rr_index_info(const vtr::vector& rr_indexed_data, + const char* fname, + const std::vector& segment_inf, + size_t y_chan_cost_offset) { + std::ofstream out_file; + + out_file.open(fname, std::ios_base::app); + out_file << std::left << std::setw(30) << "Cost Index"; + out_file << std::left << std::setw(20) << "Base Cost"; + out_file << std::left << std::setw(20) << "Ortho Cost Index"; + out_file << std::left << std::setw(20) << "Seg Index"; + out_file << std::left << std::setw(20) << "Inv. Length"; + out_file << std::left << std::setw(20) << "T. Linear"; + out_file << std::left << std::setw(20) << "T. Quadratic"; + out_file << std::left << std::setw(20) << "C. Load" << std::endl; + for (size_t cost_index = 0; cost_index < rr_indexed_data.size(); ++cost_index) { + auto& index_data = rr_indexed_data[RRIndexedDataId(cost_index)]; + + std::ostringstream string_stream; + + if (cost_index == SOURCE_COST_INDEX) { + string_stream << cost_index << " SOURCE"; + } else if (cost_index == SINK_COST_INDEX) { + string_stream << cost_index << " SINK"; + } else if (cost_index == OPIN_COST_INDEX) { + string_stream << cost_index << " OPIN"; + } else if (cost_index == IPIN_COST_INDEX) { + string_stream << cost_index << " IPIN"; + } else if (cost_index <= IPIN_COST_INDEX + y_chan_cost_offset) { + string_stream << cost_index << " CHANX " << segment_inf[index_data.seg_index].name.c_str(); + } else { + string_stream << cost_index << " CHANY " << segment_inf[index_data.seg_index].name.c_str(); + } + + std::string cost_index_str = string_stream.str(); + + out_file << std::left << std::setw(30) << cost_index_str; + out_file << std::left << std::setw(20) << index_data.base_cost; + out_file << std::left << std::setw(20) << index_data.ortho_cost_index; + out_file << std::left << std::setw(20) << index_data.seg_index; + out_file << std::left << std::setw(20) << index_data.inv_length; + out_file << std::left << std::setw(20) << index_data.T_linear; + out_file << std::left << std::setw(20) << index_data.T_quadratic; + out_file << std::left << std::setw(20) << index_data.C_load << std::endl; + } + + out_file.close(); +} diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h index 897477165bc..ccec5ee5b13 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h @@ -1,12 +1,25 @@ #ifndef ALLOC_AND_LOAD_RR_INDEXED_DATA_H #define ALLOC_AND_LOAD_RR_INDEXED_DATA_H -#include "physical_types.h" +#include "rr_graph_view.h" +#include "rr_node.h" +#include "base_cost_type.h" +#include "device_grid.h" -void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, +void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, + const DeviceGrid& grid, + const std::vector& segment_inf, const std::vector& segment_inf_x, const std::vector& segment_inf_y, + vtr::vector& rr_indexed_data, int wire_to_ipin_switch, - enum e_base_cost_type base_cost_type); + enum e_base_cost_type base_cost_type, + const bool echo_enabled, + const char* echo_file_name); + +std::vector find_ortho_cost_index(const RRGraphView& rr_graph, + const std::vector segment_inf_x, + const std::vector segment_inf_y, + e_parallel_axis parallel_axis); #endif \ No newline at end of file diff --git a/utils/fasm/test/test_fasm.cpp b/utils/fasm/test/test_fasm.cpp index e6b4685af20..e4388455c3e 100644 --- a/utils/fasm/test/test_fasm.cpp +++ b/utils/fasm/test/test_fasm.cpp @@ -254,6 +254,8 @@ TEST_CASE("fasm_integration_test", "[fasm]") { auto &device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; + bool echo_enabled = getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA); + const char* echo_file_name = getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA); for (const RRNodeId& inode : rr_graph.nodes()){ for(t_edge_size iedge = 0; iedge < rr_graph.num_edges(inode); ++iedge) { auto sink_inode = size_t(rr_graph.edge_sink_node(inode, iedge)); @@ -290,7 +292,9 @@ TEST_CASE("fasm_integration_test", "[fasm]") { &device_ctx.chan_width, device_ctx.num_arch_switches, kRrGraphFile, - device_ctx.virtual_clock_network_root_idx); + device_ctx.virtual_clock_network_root_idx, + echo_enabled, + echo_file_name); vpr_free_all(arch, vpr_setup); } diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 5e54a6eb062..3068531320c 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -37,6 +37,7 @@ #include "rr_graph_builder.h" #include "rr_types.h" +#include "echo_files.h" //#define VERBOSE //used for getting the exact count of each edge type and printing it to std out. @@ -318,6 +319,8 @@ void create_rr_graph(const t_graph_type graph_type, int* Warnings) { const auto& device_ctx = g_vpr_ctx.device(); auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); + bool echo_enabled = getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA); + const char* echo_file_name = getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA); if (!det_routing_arch->read_rr_graph_filename.empty()) { if (device_ctx.read_rr_graph_filename != det_routing_arch->read_rr_graph_filename) { free_rr_graph(); @@ -340,7 +343,9 @@ void create_rr_graph(const t_graph_type graph_type, det_routing_arch->read_rr_graph_filename.c_str(), &det_routing_arch->read_rr_graph_filename, router_opts.read_rr_edge_metadata, - router_opts.do_check_rr_graph); + router_opts.do_check_rr_graph, + echo_enabled, + echo_file_name); if (router_opts.reorder_rr_graph_nodes_algorithm != DONT_REORDER) { mutable_device_ctx.rr_graph_builder.reorder_nodes(router_opts.reorder_rr_graph_nodes_algorithm, router_opts.reorder_rr_graph_nodes_threshold, @@ -400,7 +405,9 @@ void create_rr_graph(const t_graph_type graph_type, &mutable_device_ctx.chan_width, num_arch_switches, det_routing_arch->write_rr_graph_filename.c_str(), - device_ctx.virtual_clock_network_root_idx); + device_ctx.virtual_clock_network_root_idx, + echo_enabled, + echo_file_name); } } @@ -1068,9 +1075,14 @@ static void rr_graph_externals(const std::vector& segment_inf, enum e_base_cost_type base_cost_type) { auto& device_ctx = g_vpr_ctx.device(); const auto& rr_graph = device_ctx.rr_graph; + const auto& grid = device_ctx.grid; + auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); + auto& rr_indexed_data = mutable_device_ctx.rr_indexed_data; + bool echo_enabled = getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA); + const char* echo_file_name = getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA); add_rr_graph_C_from_switches(rr_graph.rr_switch_inf(RRSwitchId(wire_to_rr_ipin_switch)).Cin); - alloc_and_load_rr_indexed_data(segment_inf, segment_inf_x, - segment_inf_y, wire_to_rr_ipin_switch, base_cost_type); + alloc_and_load_rr_indexed_data(rr_graph, device_ctx.grid, segment_inf, segment_inf_x, + segment_inf_y, rr_indexed_data, wire_to_rr_ipin_switch, base_cost_type, echo_enabled, echo_file_name); //load_rr_index_segments(segment_inf.size()); } diff --git a/vpr/src/route/rr_graph_area.cpp b/vpr/src/route/rr_graph_area.cpp index e5de121d295..db5255dadcb 100644 --- a/vpr/src/route/rr_graph_area.cpp +++ b/vpr/src/route/rr_graph_area.cpp @@ -187,7 +187,7 @@ void count_bidir_routing_transistors(int num_switch, int wire_to_ipin_switch, fl iswitch = rr_graph.edge_switch(RRNodeId(from_node), iedge); if (rr_graph.rr_switch_inf(RRSwitchId(iswitch)).buffered()) { - iseg = seg_index_of_sblock(from_node, size_t(to_node)); + iseg = seg_index_of_sblock(rr_graph, from_node, size_t(to_node)); shared_buffer_trans[iseg] = std::max(shared_buffer_trans[iseg], sharable_switch_trans[iswitch]); @@ -208,7 +208,7 @@ void count_bidir_routing_transistors(int num_switch, int wire_to_ipin_switch, fl max_inputs_to_cblock = std::max(max_inputs_to_cblock, num_inputs_to_cblock[size_t(to_node)]); - iseg = seg_index_of_cblock(from_rr_type, size_t(to_node)); + iseg = seg_index_of_cblock(rr_graph, from_rr_type, size_t(to_node)); if (cblock_counted[iseg] == false) { cblock_counted[iseg] = true; @@ -430,7 +430,7 @@ void count_unidir_routing_transistors(std::vector& /*segment_inf* num_inputs_to_cblock[size_t(to_node)]++; max_inputs_to_cblock = std::max(max_inputs_to_cblock, num_inputs_to_cblock[size_t(to_node)]); - iseg = seg_index_of_cblock(from_rr_type, size_t(to_node)); + iseg = seg_index_of_cblock(rr_graph, from_rr_type, size_t(to_node)); if (cblock_counted[iseg] == false) { cblock_counted[iseg] = true; diff --git a/vpr/src/route/rr_graph_indexed_data.cpp b/vpr/src/route/rr_graph_indexed_data.cpp index 63f7646714d..115f29b0445 100644 --- a/vpr/src/route/rr_graph_indexed_data.cpp +++ b/vpr/src/route/rr_graph_indexed_data.cpp @@ -1,333 +1,5 @@ -#include /* Needed only for sqrt call (remove if sqrt removed) */ -#include -#include -#include -#include /* Needed for ortho_Cost_index calculation*/ - -#include "vtr_assert.h" -#include "vtr_log.h" -#include "vtr_memory.h" -#include "vtr_math.h" - -#include "vpr_types.h" -#include "vpr_error.h" - #include "globals.h" -#include "rr_graph_util.h" -#include "rr_graph2.h" -#include "rr_graph.h" #include "rr_graph_indexed_data.h" -#include "read_xml_arch_file.h" - -#include "histogram.h" - -#include "echo_files.h" - -/******************* Subroutines local to this module ************************/ - -static void load_rr_indexed_data_base_costs(enum e_base_cost_type base_cost_type); - -static float get_delay_normalization_fac(); - -static void load_rr_indexed_data_T_values(); - -static void calculate_average_switch(int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, short& buffered, vtr::vector>& fan_in_list); - -static void fixup_rr_indexed_data_T_values(size_t num_segment); - -static std::vector count_rr_segment_types(); - -static void print_rr_index_info(const char* fname, const std::vector& segment_inf, size_t y_chan_cost_offset); - -/******************** Subroutine definitions *********************************/ - -/* Allocates the device_ctx.rr_indexed_data array and loads it with appropriate values. * - * It currently stores the segment type (or OPEN if the index doesn't * - * correspond to an CHANX or CHANY type), the base cost of nodes of that * - * type, and some info to allow rapid estimates of time to get to a target * - * to be computed by the router. * - * - * Right now all SOURCES have the same base cost; and similarly there's only * - * one base cost for each of SINKs, OPINs, and IPINs (four total). This can * - * be changed just by allocating more space in the array below and changing * - * the cost_index values for these rr_nodes, if you want to make some pins * - * etc. more expensive than others. I give each segment type in an * - * x-channel its own cost_index, and each segment type in a y-channel its * - * own cost_index. */ -void alloc_and_load_rr_indexed_data(const std::vector& segment_inf, - const std::vector& segment_inf_x, - const std::vector& segment_inf_y, - int wire_to_ipin_switch, - enum e_base_cost_type base_cost_type) { - int length, i, index; - - (void)segment_inf; - auto& device_ctx = g_vpr_ctx.mutable_device(); - const auto& rr_graph = device_ctx.rr_graph; - int total_num_segment = segment_inf_x.size() + segment_inf_y.size(); - /*CHAX & CHANY segment lsit sizes may differ. but if we're using uniform channels, they - * will each have size equal to segment_inf.size()*/ - int num_rr_indexed_data = CHANX_COST_INDEX_START + total_num_segment; - device_ctx.rr_indexed_data.resize(num_rr_indexed_data); - - /* For rr_types that aren't CHANX or CHANY, base_cost is valid, but most * - * * other fields are invalid. For IPINs, the T_linear field is also valid; * - * * all other fields are invalid. For SOURCES, SINKs and OPINs, all fields * - * * other than base_cost are invalid. Mark invalid fields as OPEN for safety. */ - - constexpr float nan = std::numeric_limits::quiet_NaN(); - for (i = SOURCE_COST_INDEX; i <= IPIN_COST_INDEX; i++) { - device_ctx.rr_indexed_data[RRIndexedDataId(i)].ortho_cost_index = OPEN; - device_ctx.rr_indexed_data[RRIndexedDataId(i)].seg_index = OPEN; - device_ctx.rr_indexed_data[RRIndexedDataId(i)].inv_length = nan; - device_ctx.rr_indexed_data[RRIndexedDataId(i)].T_linear = 0.; - device_ctx.rr_indexed_data[RRIndexedDataId(i)].T_quadratic = 0.; - device_ctx.rr_indexed_data[RRIndexedDataId(i)].C_load = 0.; - } - device_ctx.rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].T_linear = rr_graph.rr_switch_inf(RRSwitchId(wire_to_ipin_switch)).Tdel; - - std::vector ortho_costs; - - ortho_costs = find_ortho_cost_index(segment_inf_x, segment_inf_y, X_AXIS); - - /* AA: The code below should replace find_ortho_cost_index call once we deprecate the CLASSIC lookahead as it is the only lookahead - * that actively uses the orthogonal cost indices. To avoid complicated dependencies with the rr_graph reader, regardless of the lookahead, - * we walk to the rr_graph edges to get these indices. */ - /* - * - * std::vector x_costs(segment_inf_x.size(), CHANX_COST_INDEX_START + segment_inf_x.size()); - * std::vector y_costs(segment_inf_y.size(), CHANX_COST_INDEX_START); - * - * std::move(x_costs.begin(), x_costs.end(), std::back_inserter(ortho_costs)); - * std::move(y_costs.begin(), y_costs.end(), std::back_inserter(ortho_costs)); - */ - - /* X-directed segments*/ - - for (size_t iseg = 0; iseg < segment_inf_x.size(); ++iseg) { - index = iseg + CHANX_COST_INDEX_START; - - device_ctx.rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; - - if (segment_inf_x[iseg].longline) - length = device_ctx.grid.width(); - else - length = std::min(segment_inf_x[iseg].length, device_ctx.grid.width()); - - device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length = 1. / length; - /*We use the index fo the segment in the **unified** seg_inf vector not iseg which is relative - * to parallel axis segments vector */ - device_ctx.rr_indexed_data[RRIndexedDataId(index)].seg_index = segment_inf_x[iseg].seg_index; - } - - /* Y-directed segments*/ - - for (size_t iseg = segment_inf_x.size(); iseg < ortho_costs.size(); ++iseg) { - index = iseg + CHANX_COST_INDEX_START; - device_ctx.rr_indexed_data[RRIndexedDataId(index)].ortho_cost_index = ortho_costs[iseg]; - - if (segment_inf_x[iseg - segment_inf_x.size()].longline) - length = device_ctx.grid.width(); - else - length = std::min(segment_inf_y[iseg - segment_inf_x.size()].length, device_ctx.grid.width()); - - device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length = 1. / length; - /*We use the index fo the segment in the **unified** seg_inf vector not iseg which is relative - * to parallel axis segments vector */ - device_ctx.rr_indexed_data[RRIndexedDataId(index)].seg_index = segment_inf_y[iseg - segment_inf_x.size()].seg_index; - } - - load_rr_indexed_data_T_values(); - - fixup_rr_indexed_data_T_values(total_num_segment); - - load_rr_indexed_data_base_costs(base_cost_type); - - if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA)) { - print_rr_index_info(getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA), - segment_inf, segment_inf_x.size()); - } -} - -/* AA: We use a normalized product of frequency and length to find the segment that is most likely - * to connect to in the perpendicular axis. Note that the size of segment_inf_x & segment_inf_y is not - * the same necessarly. The result vector will contain the indices in segment_inf_perp - * of the most likely perp segments for each segment at index i in segment_inf_parallel. - * - * Note: We use the seg_index field of t_segment_inf to store the segment index - * in the **unified** t_segment_inf vector. We will temporarly use this field in - * a copy passed to the function to store the index w.r.t the parallel axis segment list.*/ - -std::vector find_ortho_cost_index(std::vector segment_inf_x, - std::vector segment_inf_y, - e_parallel_axis parallel_axis) { - auto segment_inf_parallel = parallel_axis == X_AXIS ? segment_inf_x : segment_inf_y; - auto segment_inf_perp = parallel_axis == X_AXIS ? segment_inf_y : segment_inf_x; - auto& device_ctx = g_vpr_ctx.device(); - - const auto& rr_graph = device_ctx.rr_graph; - - size_t num_segments = segment_inf_x.size() + segment_inf_y.size(); - std::vector> dest_nodes_count; - - // x segments are perpendicular to y segments - - dest_nodes_count.resize(num_segments); - - for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { - dest_nodes_count[iseg].resize(segment_inf_y.size()); - } - // y segments are perpendicular to x segments - for (size_t iseg = segment_inf_x.size(); iseg < num_segments; iseg++) { - dest_nodes_count[iseg].resize(segment_inf_x.size()); - } - - std::vector ortho_cost_indices(dest_nodes_count.size(), 0); - - //Go through all rr_Nodes. Look at the ones with CHAN type. Count all outgoing edges to CHAN typed nodes from each CHAN type node. - for (const RRNodeId& rr_node : rr_graph.nodes()) { - for (size_t iedge = 0; iedge < rr_graph.num_edges(rr_node); ++iedge) { - RRNodeId to_node = rr_graph.edge_sink_node(rr_node, iedge); - t_rr_type from_node_type = rr_graph.node_type(rr_node); - t_rr_type to_node_type = rr_graph.node_type(to_node); - - size_t from_node_cost_index = (size_t)rr_graph.node_cost_index(rr_node); - size_t to_node_cost_index = (size_t)rr_graph.node_cost_index(to_node); - - //if the type is smaller than start index, means destination is not a CHAN type node. - - if ((from_node_type == CHANX && to_node_type == CHANY) || (from_node_type == CHANY && to_node_type == CHANX)) { - if (to_node_type == CHANY) { - dest_nodes_count[from_node_cost_index - CHANX_COST_INDEX_START][to_node_cost_index - (CHANX_COST_INDEX_START + segment_inf_x.size())]++; - } else { - dest_nodes_count[from_node_cost_index - CHANX_COST_INDEX_START][to_node_cost_index - CHANX_COST_INDEX_START]++; - } - } else { - continue; - } - } - } - - for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { - dest_nodes_count[iseg].resize(segment_inf_y.size()); - } - - for (size_t iseg = 0; iseg < segment_inf_x.size(); iseg++) { - ortho_cost_indices[iseg] = std::max_element(dest_nodes_count[iseg].begin(), dest_nodes_count[iseg].end()) - dest_nodes_count[iseg].begin(); - ortho_cost_indices[iseg] += CHANX_COST_INDEX_START + segment_inf_x.size(); - } - - for (size_t iseg = segment_inf_x.size(); iseg < num_segments; iseg++) { - ortho_cost_indices[iseg] = std::max_element(dest_nodes_count[iseg].begin(), dest_nodes_count[iseg].end()) - dest_nodes_count[iseg].begin(); - ortho_cost_indices[iseg] += CHANX_COST_INDEX_START; - } - - return ortho_cost_indices; - - /*Update seg_index */ - -#ifdef FREQ_LENGTH_ORTHO_COSTS - - for (int i = 0; i < (int)segment_inf_perp.size(); ++i) - segment_inf_perp[i].seg_index = i; - - std::vector ortho_costs_indices; - ortho_costs_indices.resize(segment_inf_parallel.size()); - - int num_segments = (int)segment_inf_parallel.size(); - for (int seg_index = 0; seg_index < num_segments; ++seg_index) { - auto segment = segment_inf_parallel[seg_index]; - auto lambda_cmp = [&segment](t_segment_inf& a, t_segment_inf& b) { - float a_freq = a.frequency / (float)segment.frequency; - float b_freq = b.frequency / (float)segment.frequency; - float a_len = (float)segment.length / a.length; - float b_len = (float)segment.length / b.length; - - float a_product = a_len * a_freq; - float b_product = b_len * b_freq; - - if (std::abs(a_product - 1) < std::abs(b_product - 1)) - return true; - else if (std::abs(a_product - 1) > std::abs(b_product - 1)) - return false; - else { - if ((segment.name == a.name && segment.parallel_axis == BOTH_AXIS) || (segment.length == a.length && segment.frequency == a.frequency)) - return true; - else { - if (a.frequency > b.frequency) - return true; - else if (a.frequency < b.frequency) - return false; - else - return a.length < b.length; - } - } - }; - - std::sort(segment_inf_perp.begin(), segment_inf_perp.end(), lambda_cmp); - - /* The compartor behaves as operator< mostly, so the first element in the - * sorted vector will have the lowest cost difference from segment. */ - ortho_costs_indices[seg_index] = segment_inf_perp[0].seg_index + start_channel_cost; - ortho_costs_indices[seg_index] = parallel_axis == X_AXIS ? ortho_costs_indices[seg_index] + num_segments : ortho_costs_indices[seg_index]; - } - - /*Pertubate indices to make sure all perp seg types have a corresponding perp segment.*/ -# ifdef PERTURB_ORTHO_COST_indices - std::vector perp_segments; - std::unordered_multimap indices_map; - auto cmp_greater = [](std::pair a, std::pair b) { - return a.second < b.second; - }; - std::priority_queue, std::vector>, decltype(cmp_greater)> indices_q_greater(cmp_greater); - - auto cmp_less = [](std::pair a, std::pair b) { - return a.second > b.second; - }; - - std::priority_queue, std::vector>, decltype(cmp_less)> indices_q_less(cmp_less); - - perp_segments.resize(segment_inf_perp.size(), 0); - - for (int i = 0; i < num_segments; ++i) { - int index = parallel_axis == X_AXIS ? ortho_costs_indices[i] - num_segments - start_channel_cost : ortho_costs_indices[i] - start_channel_cost; - indices_map.insert(std::make_pair(index, i)); - perp_segments[index]++; - } - - for (int i = 0; i < (int)perp_segments.size(); ++i) { - auto pair = std::make_pair(i, perp_segments[i]); - indices_q_greater.push(pair); - indices_q_less.push(pair); - } - - while (!indices_q_greater.empty()) { - auto g_index_pair = indices_q_greater.top(); - auto l_index_pair = indices_q_less.top(); - - if (l_index_pair.second != 0) - break; - - indices_q_greater.pop(); - indices_q_less.pop(); - - g_index_pair.second--; - l_index_pair.second++; - auto itr_to_change = indices_map.find(g_index_pair.first); - VTR_ASSERT(itr_to_change != indices_map.end()); - int index = l_index_pair.first + start_channel_cost; - index = parallel_axis == X_AXIS ? index + num_segments : index; - ortho_costs_indices[itr_to_change->second] = index; - indices_map.erase(itr_to_change); - - indices_q_greater.push(g_index_pair); - indices_q_less.push(l_index_pair); - } -# endif - - return ortho_costs_indices; -#endif -} void load_rr_index_segments(const int num_segment) { auto& device_ctx = g_vpr_ctx.mutable_device(); @@ -347,439 +19,4 @@ void load_rr_index_segments(const int num_segment) { index = CHANX_COST_INDEX_START + num_segment + iseg; device_ctx.rr_indexed_data[RRIndexedDataId(index)].seg_index = iseg; } -} - -static void load_rr_indexed_data_base_costs(enum e_base_cost_type base_cost_type) { - /* Loads the base_cost member of device_ctx.rr_indexed_data according to the specified * - * base_cost_type. */ - - float delay_normalization_fac; - size_t index; - - auto& device_ctx = g_vpr_ctx.mutable_device(); - - if (base_cost_type == DEMAND_ONLY || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) { - delay_normalization_fac = 1.; - } else { - delay_normalization_fac = get_delay_normalization_fac(); - } - - device_ctx.rr_indexed_data[RRIndexedDataId(SOURCE_COST_INDEX)].base_cost = delay_normalization_fac; - device_ctx.rr_indexed_data[RRIndexedDataId(SINK_COST_INDEX)].base_cost = 0.; - device_ctx.rr_indexed_data[RRIndexedDataId(OPIN_COST_INDEX)].base_cost = delay_normalization_fac; - device_ctx.rr_indexed_data[RRIndexedDataId(IPIN_COST_INDEX)].base_cost = 0.95 * delay_normalization_fac; - - auto rr_segment_counts = count_rr_segment_types(); - size_t total_segments = std::accumulate(rr_segment_counts.begin(), rr_segment_counts.end(), 0u); - - /* Load base costs for CHANX and CHANY segments */ - float max_length = 0; - float min_length = 1; - if (base_cost_type == DELAY_NORMALIZED_LENGTH_BOUNDED) { - for (index = CHANX_COST_INDEX_START; index < device_ctx.rr_indexed_data.size(); index++) { - float length = (1 / device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length); - max_length = std::max(max_length, length); - } - } - - //Future Work: Since we can now have wire types which don't connect to IPINs, - // perhaps consider lowering cost of wires which connect to IPINs - // so they get explored earlier (same rational as lowering IPIN costs) - - for (index = CHANX_COST_INDEX_START; index < device_ctx.rr_indexed_data.size(); index++) { - if (base_cost_type == DELAY_NORMALIZED || base_cost_type == DEMAND_ONLY) { - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac; - - } else if (base_cost_type == DELAY_NORMALIZED_LENGTH || base_cost_type == DEMAND_ONLY_NORMALIZED_LENGTH) { - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length; - - } else if (base_cost_type == DELAY_NORMALIZED_LENGTH_BOUNDED) { - float length = (1 / device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length); - if (max_length != min_length) { - float length_scale = 1.f + 3.f * (length - min_length) / (max_length - min_length); - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac * length_scale; - } else { - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac; - } - - } else if (base_cost_type == DELAY_NORMALIZED_FREQUENCY) { - int seg_index = device_ctx.rr_indexed_data[RRIndexedDataId(index)].seg_index; - - VTR_ASSERT(total_segments > 0); - float freq_fac = float(rr_segment_counts[seg_index]) / total_segments; - - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / freq_fac; - - } else if (base_cost_type == DELAY_NORMALIZED_LENGTH_FREQUENCY) { - int seg_index = device_ctx.rr_indexed_data[RRIndexedDataId(index)].seg_index; - - VTR_ASSERT(total_segments > 0); - float freq_fac = float(rr_segment_counts[seg_index]) / total_segments; - - //Base cost = delay_norm / (len * freq) - //device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = delay_normalization_fac / ((1. / device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length) * freq_fac); - - //Base cost = (delay_norm * len) * (1 + (1-freq)) - device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost = (delay_normalization_fac / device_ctx.rr_indexed_data[RRIndexedDataId(index)].inv_length) * (1 + (1 - freq_fac)); - - } else { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, "Unrecognized base cost type"); - } - } - - /* Save a copy of the base costs -- if dynamic costing is used by the * - * router, the base_cost values will get changed all the time and being * - * able to restore them from a saved version is useful. */ - - for (index = 0; index < device_ctx.rr_indexed_data.size(); index++) { - device_ctx.rr_indexed_data[RRIndexedDataId(index)].saved_base_cost = device_ctx.rr_indexed_data[RRIndexedDataId(index)].base_cost; - } -} - -static std::vector count_rr_segment_types() { - std::vector rr_segment_type_counts; - - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - - for (const RRNodeId& id : rr_graph.nodes()) { - if (rr_graph.node_type(id) != CHANX && rr_graph.node_type(id) != CHANY) continue; - - auto cost_index = rr_graph.node_cost_index(id); - - int seg_index = device_ctx.rr_indexed_data[cost_index].seg_index; - - VTR_ASSERT(seg_index != OPEN); - - if (seg_index >= int(rr_segment_type_counts.size())) { - rr_segment_type_counts.resize(seg_index + 1, 0); - } - VTR_ASSERT(seg_index < int(rr_segment_type_counts.size())); - - ++rr_segment_type_counts[seg_index]; - } - - return rr_segment_type_counts; -} - -static float get_delay_normalization_fac() { - /* Returns the average delay to go 1 CLB distance along a wire. */ - - auto& device_ctx = g_vpr_ctx.device(); - auto& rr_indexed_data = device_ctx.rr_indexed_data; - - float Tdel_sum = 0.0; - int Tdel_num = 0; - for (size_t cost_index = CHANX_COST_INDEX_START; cost_index < rr_indexed_data.size(); cost_index++) { - float inv_length = device_ctx.rr_indexed_data[RRIndexedDataId(cost_index)].inv_length; - float T_value = rr_indexed_data[RRIndexedDataId(cost_index)].T_linear * inv_length + rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic * std::pow(inv_length, 2); - - if (T_value == 0.0) continue; - - Tdel_sum += T_value; - Tdel_num += 1; - } - - if (Tdel_num == 0) { - VTR_LOG_WARN("No valid cost index was found to get the delay normalization factor. Setting delay normalization factor to 1e-9 (1 ns)\n"); - return 1e-9; - } - - float delay_norm_fac = Tdel_sum / Tdel_num; - - if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA)) { - std::ofstream out_file; - - out_file.open(getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA)); - out_file << "Delay normalization factor: " << delay_norm_fac << std::endl; - - out_file.close(); - } - - return delay_norm_fac; -} - -/* - * Scans all the RR nodes of CHAN type getting the medians for their R and C values (delays) - * as well as the delay data of all the nodes' switches, averaging them to find the following - * indexed data values for each wire type: - * - T_linear - * - T_quadratic - * - C_load - * - * The indexed data is used in different locations such as: - * - Base cost calculation for each cost_index - * - Lookahead map computation - * - Placement Delay Matrix computation - */ -static void load_rr_indexed_data_T_values() { - auto& device_ctx = g_vpr_ctx.mutable_device(); - const auto& rr_graph = device_ctx.rr_graph; - auto& rr_indexed_data = device_ctx.rr_indexed_data; - - auto fan_in_list = get_fan_in_list(); - - vtr::vector num_nodes_of_index(rr_indexed_data.size(), 0); - vtr::vector> C_total(rr_indexed_data.size()); - vtr::vector> R_total(rr_indexed_data.size()); - - /* - * Not all wire-to-wire switches connecting from some wire segment will necessarily have the same delay. - * i.e. a mux with less inputs will have smaller delay than a mux with a greater number of inputs. - * So to account for these differences we will get the average R/Tdel/Cinternal values by first averaging - * them for a single wire segment, and then by averaging this value over all the average values corresponding - * to the switches node - */ - vtr::vector> switch_R_total(rr_indexed_data.size()); - vtr::vector> switch_T_total(rr_indexed_data.size()); - vtr::vector> switch_Cinternal_total(rr_indexed_data.size()); - vtr::vector switches_buffered(rr_indexed_data.size(), UNDEFINED); - - /* - * Walk through the RR graph and collect all R and C values of all the nodes, - * as well as their fan-in switches R, T_del, and Cinternal values. - * - * The median of R and C values for each cost index is assigned to the indexed - * data. - */ - for (const RRNodeId& rr_id : device_ctx.rr_graph.nodes()) { - t_rr_type rr_type = rr_graph.node_type(rr_id); - - if (rr_type != CHANX && rr_type != CHANY) { - continue; - } - - auto cost_index = rr_graph.node_cost_index(rr_id); - - auto node_cords = rr_graph.node_coordinate_to_string(RRNodeId(rr_id)); - - /* get average switch parameters */ - double avg_switch_R = 0; - double avg_switch_T = 0; - double avg_switch_Cinternal = 0; - int num_switches = 0; - short buffered = UNDEFINED; - calculate_average_switch((size_t)rr_id, avg_switch_R, avg_switch_T, avg_switch_Cinternal, num_switches, buffered, fan_in_list); - - if (num_switches == 0) { - VTR_LOG_WARN("Node: %d with RR_type: %s at Location:%s, had no out-going switches\n", rr_id, - rr_graph.node_type_string(rr_id), node_cords.c_str()); - continue; - } - VTR_ASSERT(num_switches > 0); - - num_nodes_of_index[cost_index]++; - C_total[cost_index].push_back(rr_graph.node_C(rr_id)); - R_total[cost_index].push_back(rr_graph.node_R(rr_id)); - - switch_R_total[cost_index].push_back(avg_switch_R); - switch_T_total[cost_index].push_back(avg_switch_T); - switch_Cinternal_total[cost_index].push_back(avg_switch_Cinternal); - if (buffered == UNDEFINED) { - /* this segment does not have any outgoing edges to other general routing wires */ - continue; - } - - /* need to make sure all wire switches of a given wire segment type have the same 'buffered' value */ - if (switches_buffered[cost_index] == UNDEFINED) { - switches_buffered[cost_index] = buffered; - } else { - if (switches_buffered[cost_index] != buffered) { - // If a previous buffering state is inconsistent with the current one, - // the node should be treated as buffered, as there are only two possible - // values for the buffering state (except for the UNDEFINED case). - // - // This means that at least one edge of this node has a buffered switch, - // which prevails over unbuffered ones. - switches_buffered[cost_index] = 1; - } - } - } - - for (size_t cost_index = CHANX_COST_INDEX_START; - cost_index < rr_indexed_data.size(); cost_index++) { - if (num_nodes_of_index[RRIndexedDataId(cost_index)] == 0) { /* Segments don't exist. */ - VTR_LOG_WARN("Found no instances of RR node with cost index %d\n", cost_index); - rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = 0.0; - rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = 0.0; - rr_indexed_data[RRIndexedDataId(cost_index)].C_load = 0.0; - } else { - auto C_total_histogram = build_histogram(C_total[RRIndexedDataId(cost_index)], 10); - auto R_total_histogram = build_histogram(R_total[RRIndexedDataId(cost_index)], 10); - auto switch_R_total_histogram = build_histogram(switch_R_total[RRIndexedDataId(cost_index)], 10); - auto switch_T_total_histogram = build_histogram(switch_T_total[RRIndexedDataId(cost_index)], 10); - auto switch_Cinternal_total_histogram = build_histogram(switch_Cinternal_total[RRIndexedDataId(cost_index)], 10); - - // Sort Rnode and Cnode - float Cnode = vtr::median(C_total[RRIndexedDataId(cost_index)]); - float Rnode = vtr::median(R_total[RRIndexedDataId(cost_index)]); - float Rsw = get_histogram_mode(switch_R_total_histogram); - float Tsw = get_histogram_mode(switch_T_total_histogram); - float Cinternalsw = get_histogram_mode(switch_Cinternal_total_histogram); - - if (switches_buffered[RRIndexedDataId(cost_index)]) { - // Here, we are computing the linear time delay for buffered switches. Tlinear is - // the estimated sum of the intrinsic time delay of the switch and the two transient - // responses. The key assumption behind the estimate is that one switch will be turned on - // from each wire and so we will correspondingly add one load for internal capacitance. - // The first transient response is the product between the resistance of the switch with - // the combined capacitance of the node and internal capacitance of the switch. The - // multiplication by the second term by 0.5 is the result of the Rnode being distributed halfway along a - // wire segment's length times the total capacitance. - rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = Tsw + Rsw * (Cinternalsw + Cnode) - + 0.5 * Rnode * (Cnode + Cinternalsw); - rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = 0.; - rr_indexed_data[RRIndexedDataId(cost_index)].C_load = 0.; - } else { /* Pass transistor, does not have an internal capacitance*/ - rr_indexed_data[RRIndexedDataId(cost_index)].C_load = Cnode; - - /* See Dec. 23, 1997 notes for deriviation of formulae. */ - - rr_indexed_data[RRIndexedDataId(cost_index)].T_linear = Tsw + 0.5 * Rsw * Cnode; - rr_indexed_data[RRIndexedDataId(cost_index)].T_quadratic = (Rsw + Rnode) * 0.5 - * Cnode; - } - } - } -} - -/* - * This routine calculates the average R/Tdel/Cinternal values of all the switches corresponding - * to the fan-in edges of the input inode. - * - * It is not safe to assume that each node of the same wire type has the same switches with the same - * delays, therefore we take their average to take into account the possible differences - */ -static void calculate_average_switch(int inode, double& avg_switch_R, double& avg_switch_T, double& avg_switch_Cinternal, int& num_switches, short& buffered, vtr::vector>& fan_in_list) { - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - - auto node = RRNodeId(inode); - - avg_switch_R = 0; - avg_switch_T = 0; - avg_switch_Cinternal = 0; - num_switches = 0; - buffered = UNDEFINED; - for (const auto& edge : fan_in_list[node]) { - /* want to get C/R/Tdel/Cinternal of switches that connect this track segment to other track segments */ - if (rr_graph.node_type(node) == CHANX || rr_graph.node_type(node) == CHANY) { - int switch_index = rr_graph.rr_nodes().edge_switch(edge); - - if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).type() == SwitchType::SHORT) continue; - - avg_switch_R += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).R; - avg_switch_T += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Tdel; - avg_switch_Cinternal += rr_graph.rr_switch_inf(RRSwitchId(switch_index)).Cinternal; - - if (buffered == UNDEFINED) { - if (rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered()) { - buffered = 1; - } else { - buffered = 0; - } - } else if (buffered != rr_graph.rr_switch_inf(RRSwitchId(switch_index)).buffered()) { - // If a previous buffering state is inconsistent with the current one, - // the node should be treated as buffered, as there are only two possible - // values for the buffering state (except for the UNDEFINED case). - // - // This means that at least one edge of this node has a buffered switch, - // which prevails over unbuffered ones. - buffered = 1; - } - - num_switches++; - } - } - - if (num_switches > 0) { - avg_switch_R /= num_switches; - avg_switch_T /= num_switches; - avg_switch_Cinternal /= num_switches; - } - - VTR_ASSERT(std::isfinite(avg_switch_R)); - VTR_ASSERT(std::isfinite(avg_switch_T)); - VTR_ASSERT(std::isfinite(avg_switch_Cinternal)); -} - -static void fixup_rr_indexed_data_T_values(size_t total_num_segments) { - auto& device_ctx = g_vpr_ctx.mutable_device(); - - // Scan CHANX/CHANY indexed data and search for uninitialized costs. - // - // This would occur if a segment ends up only being used as CHANX or a - // CHANY, but not both. If this occurs, then copying the orthogonal - // pair's cost data is likely a better choice than leaving it uninitialized. - // - // The primary reason for this fixup is to avoid propagating negative - // values in cost functions. - for (size_t cost_index = CHANX_COST_INDEX_START; - cost_index < CHANX_COST_INDEX_START + total_num_segments; cost_index++) { - int ortho_cost_index = device_ctx.rr_indexed_data[RRIndexedDataId(cost_index)].ortho_cost_index; - - auto& indexed_data = device_ctx.rr_indexed_data[RRIndexedDataId(cost_index)]; - auto& ortho_indexed_data = device_ctx.rr_indexed_data[RRIndexedDataId(ortho_cost_index)]; - // Check if this data is uninitialized, but the orthogonal data is - // initialized. - // Uninitialized data is set to zero by default. - bool needs_fixup = indexed_data.T_linear == 0 && indexed_data.T_quadratic == 0 && indexed_data.C_load == 0; - bool ortho_data_valid = ortho_indexed_data.T_linear != 0 || ortho_indexed_data.T_quadratic != 0 || ortho_indexed_data.C_load != 0; - if (needs_fixup && ortho_data_valid) { - // Copy orthogonal data over. - indexed_data.T_linear = ortho_indexed_data.T_linear; - indexed_data.T_quadratic = ortho_indexed_data.T_quadratic; - indexed_data.C_load = ortho_indexed_data.C_load; - } - } -} - -static void print_rr_index_info(const char* fname, - const std::vector& segment_inf, - size_t y_chan_cost_offset) { - auto& device_ctx = g_vpr_ctx.device(); - - std::ofstream out_file; - - out_file.open(fname, std::ios_base::app); - out_file << std::left << std::setw(30) << "Cost Index"; - out_file << std::left << std::setw(20) << "Base Cost"; - out_file << std::left << std::setw(20) << "Ortho Cost Index"; - out_file << std::left << std::setw(20) << "Seg Index"; - out_file << std::left << std::setw(20) << "Inv. Length"; - out_file << std::left << std::setw(20) << "T. Linear"; - out_file << std::left << std::setw(20) << "T. Quadratic"; - out_file << std::left << std::setw(20) << "C. Load" << std::endl; - for (size_t cost_index = 0; cost_index < device_ctx.rr_indexed_data.size(); ++cost_index) { - auto& index_data = device_ctx.rr_indexed_data[RRIndexedDataId(cost_index)]; - - std::ostringstream string_stream; - - if (cost_index == SOURCE_COST_INDEX) { - string_stream << cost_index << " SOURCE"; - } else if (cost_index == SINK_COST_INDEX) { - string_stream << cost_index << " SINK"; - } else if (cost_index == OPIN_COST_INDEX) { - string_stream << cost_index << " OPIN"; - } else if (cost_index == IPIN_COST_INDEX) { - string_stream << cost_index << " IPIN"; - } else if (cost_index <= IPIN_COST_INDEX + y_chan_cost_offset) { - string_stream << cost_index << " CHANX " << segment_inf[index_data.seg_index].name.c_str(); - } else { - string_stream << cost_index << " CHANY " << segment_inf[index_data.seg_index].name.c_str(); - } - - std::string cost_index_str = string_stream.str(); - - out_file << std::left << std::setw(30) << cost_index_str; - out_file << std::left << std::setw(20) << index_data.base_cost; - out_file << std::left << std::setw(20) << index_data.ortho_cost_index; - out_file << std::left << std::setw(20) << index_data.seg_index; - out_file << std::left << std::setw(20) << index_data.inv_length; - out_file << std::left << std::setw(20) << index_data.T_linear; - out_file << std::left << std::setw(20) << index_data.T_quadratic; - out_file << std::left << std::setw(20) << index_data.C_load << std::endl; - } - - out_file.close(); -} +} \ No newline at end of file diff --git a/vpr/src/route/rr_graph_indexed_data.h b/vpr/src/route/rr_graph_indexed_data.h index f973703b662..64e6f8cc4b2 100644 --- a/vpr/src/route/rr_graph_indexed_data.h +++ b/vpr/src/route/rr_graph_indexed_data.h @@ -5,8 +5,4 @@ void load_rr_index_segments(const int num_segment); -std::vector find_ortho_cost_index(const std::vector segment_inf_x, - const std::vector segment_inf_y, - e_parallel_axis parallel_axis); - #endif diff --git a/vpr/src/route/rr_graph_timing_params.cpp b/vpr/src/route/rr_graph_timing_params.cpp index b65ce58db9f..4dc3362e62f 100644 --- a/vpr/src/route/rr_graph_timing_params.cpp +++ b/vpr/src/route/rr_graph_timing_params.cpp @@ -98,7 +98,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { * be added now since each edge is actually a driver */ rr_node_C[to_node] += Cout; } - isblock = seg_index_of_sblock(inode, to_node); + isblock = seg_index_of_sblock(rr_graph, inode, to_node); buffer_Cin[isblock] = std::max(buffer_Cin[isblock], Cin); } @@ -109,7 +109,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { /* Implements sharing of the track to connection box buffer. * Such a buffer exists at every segment of the wire at which * at least one logic block input connects. */ - icblock = seg_index_of_cblock(from_rr_type, to_node); + icblock = seg_index_of_cblock(rr_graph, from_rr_type, to_node); if (cblock_counted[icblock] == false) { rr_node_C[inode] += C_ipin_cblock; cblock_counted[icblock] = true; @@ -129,7 +129,7 @@ void add_rr_graph_C_from_switches(float C_ipin_cblock) { /* for (iedge=0;iedge -#include -#include - -#include "vtr_memory.h" -#include "vtr_time.h" - -#include "vpr_types.h" -#include "vpr_error.h" - -#include "globals.h" -#include "rr_graph_util.h" - -int seg_index_of_cblock(t_rr_type from_rr_type, int to_node) { - /* Returns the segment number (distance along the channel) of the connection * - * box from from_rr_type (CHANX or CHANY) to to_node (IPIN). */ - - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - - if (from_rr_type == CHANX) - return (rr_graph.node_xlow(RRNodeId(to_node))); - else - /* CHANY */ - return (rr_graph.node_ylow(RRNodeId(to_node))); -} - -int seg_index_of_sblock(int from_node, int to_node) { - /* Returns the segment number (distance along the channel) of the switch box * - * box from from_node (CHANX or CHANY) to to_node (CHANX or CHANY). The * - * switch box on the left side of a CHANX segment at (i,j) has seg_index = * - * i-1, while the switch box on the right side of that segment has seg_index * - * = i. CHANY stuff works similarly. Hence the range of values returned is * - * 0 to device_ctx.grid.width()-1 (if from_node is a CHANX) or 0 to device_ctx.grid.height()-1 (if from_node is a CHANY). */ - - t_rr_type from_rr_type, to_rr_type; - - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - - from_rr_type = rr_graph.node_type(RRNodeId(from_node)); - to_rr_type = rr_graph.node_type(RRNodeId(to_node)); - - if (from_rr_type == CHANX) { - if (to_rr_type == CHANY) { - return (rr_graph.node_xlow(RRNodeId(to_node))); - } else if (to_rr_type == CHANX) { - if (rr_graph.node_xlow(RRNodeId(to_node)) > rr_graph.node_xlow(RRNodeId(from_node))) { /* Going right */ - return (rr_graph.node_xhigh(RRNodeId(from_node))); - } else { /* Going left */ - return (rr_graph.node_xhigh(RRNodeId(to_node))); - } - } else { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "in seg_index_of_sblock: to_node %d is of type %d.\n", - to_node, to_rr_type); - return OPEN; //Should not reach here once thrown - } - } - /* End from_rr_type is CHANX */ - else if (from_rr_type == CHANY) { - if (to_rr_type == CHANX) { - return (rr_graph.node_ylow(RRNodeId(to_node))); - } else if (to_rr_type == CHANY) { - if (rr_graph.node_ylow(RRNodeId(to_node)) > rr_graph.node_ylow(RRNodeId(from_node))) { /* Going up */ - return (rr_graph.node_yhigh(RRNodeId(from_node))); - } else { /* Going down */ - return (rr_graph.node_yhigh(RRNodeId(to_node))); - } - } else { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "in seg_index_of_sblock: to_node %d is of type %d.\n", - to_node, to_rr_type); - return OPEN; //Should not reach here once thrown - } - } - /* End from_rr_type is CHANY */ - else { - VPR_FATAL_ERROR(VPR_ERROR_ROUTE, - "in seg_index_of_sblock: from_node %d is of type %d.\n", - from_node, from_rr_type); - return OPEN; //Should not reach here once thrown - } -} - -vtr::vector> get_fan_in_list() { - auto& rr_graph = g_vpr_ctx.device().rr_graph; - - vtr::vector> node_fan_in_list; - - node_fan_in_list.resize(rr_graph.num_nodes(), std::vector(0)); - node_fan_in_list.shrink_to_fit(); - - //Walk the graph and increment fanin on all dwnstream nodes - rr_graph.rr_nodes().for_each_edge( - [&](RREdgeId edge, __attribute__((unused)) RRNodeId src, RRNodeId sink) { - node_fan_in_list[sink].push_back(edge); - }); - - return node_fan_in_list; -} diff --git a/vpr/src/route/rr_graph_util.h b/vpr/src/route/rr_graph_util.h deleted file mode 100644 index 3b61263c566..00000000000 --- a/vpr/src/route/rr_graph_util.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef RR_GRAPH_UTIL_H -#define RR_GRAPH_UTIL_H - -#include "vpr_types.h" - -int seg_index_of_cblock(t_rr_type from_rr_type, int to_node); - -int seg_index_of_sblock(int from_node, int to_node); - -// This function generates and returns a vector indexed by RRNodeId -// containing a list of fan-in edges for each node. -vtr::vector> get_fan_in_list(); - -#endif diff --git a/vpr/test/test_vpr.cpp b/vpr/test/test_vpr.cpp index 8605a3938fa..a74ebca2bb9 100644 --- a/vpr/test/test_vpr.cpp +++ b/vpr/test/test_vpr.cpp @@ -6,6 +6,7 @@ #include "rr_graph_writer.h" #include "arch_util.h" #include "vpr_api.h" +#include "echo_files.h" #include #include @@ -137,6 +138,8 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { auto& mutable_device_ctx = g_vpr_ctx.mutable_device(); const auto& rr_graph = device_ctx.rr_graph; auto& rr_graph_builder = mutable_device_ctx.rr_graph_builder; + bool echo_enabled = getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA); + const char* echo_file_name = getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA); for (const RRNodeId& inode : device_ctx.rr_graph.nodes()) { if ((rr_graph.node_type(inode) == CHANX || rr_graph.node_type(inode) == CHANY) && rr_graph.num_edges(inode) > 0) { @@ -163,7 +166,9 @@ TEST_CASE("read_rr_graph_metadata", "[vpr]") { &mutable_device_ctx.chan_width, device_ctx.num_arch_switches, kRrGraphFile, - device_ctx.virtual_clock_network_root_idx); + device_ctx.virtual_clock_network_root_idx, + echo_enabled, + echo_file_name); vpr_free_all(arch, vpr_setup); auto& atom_ctx = g_vpr_ctx.mutable_atom(); From bfcb7ec7c48209157b21a5a3bb1a92e1330c5a84 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 25 Jul 2022 16:40:04 -0700 Subject: [PATCH 12/19] [vpr] move describe_rr_node.cpp to librrgraph/src/utils --- libs/librrgraph/src/base/check_rr_graph.cpp | 10 ++-- .../librrgraph/src/utils/describe_rr_node.cpp | 50 +++++++++++++++++++ libs/librrgraph/src/utils/describe_rr_node.h | 7 ++- vpr/src/draw/draw.cpp | 4 +- vpr/src/draw/search_bar.cpp | 5 +- vpr/src/route/annotate_routing.cpp | 2 +- vpr/src/route/check_route.cpp | 14 +++--- vpr/src/route/connection_router.cpp | 14 ++++-- vpr/src/route/route_common.cpp | 7 +-- vpr/src/route/route_profiling.cpp | 10 ++-- vpr/src/route/route_timing.cpp | 8 +-- .../route/router_lookahead_extended_map.cpp | 2 +- vpr/src/route/router_lookahead_map.cpp | 6 +-- vpr/src/route/rr_graph.cpp | 48 +----------------- vpr/src/route/rr_graph2.cpp | 25 +++++----- vpr/src/route/rr_graph2.h | 1 + vpr/src/route/rr_graph_area.cpp | 2 +- 17 files changed, 121 insertions(+), 94 deletions(-) create mode 100644 libs/librrgraph/src/utils/describe_rr_node.cpp diff --git a/libs/librrgraph/src/base/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp index ef0e7000796..74d1228fbae 100644 --- a/libs/librrgraph/src/base/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -18,7 +18,7 @@ static void check_unbuffered_edges(const RRGraphView& rr_graph, int from_node); static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_rr_node& node); -static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int from_edge, int to_node); +static void check_rr_edge(const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector& rr_indexed_data, int from_node, int from_edge, int to_node); /************************ Subroutine definitions ****************************/ @@ -92,7 +92,7 @@ void check_rr_graph(const RRGraphView& rr_graph, inode, to_node); } - check_rr_edge(rr_graph, inode, iedge, to_node); + check_rr_edge(rr_graph, grid, rr_indexed_data, inode, iedge, to_node); edges.emplace_back(to_node, iedge); total_edges_to_node[to_node]++; @@ -503,7 +503,7 @@ void check_rr_node(const RRGraphView& rr_graph, } if (check_for_out_edges) { - std::string info = describe_rr_node(inode); + std::string info = describe_rr_node(rr_graph, grid, rr_indexed_data, inode); VTR_LOG_WARN("in check_rr_node: %s has no out-going edges.\n", info.c_str()); } } @@ -600,7 +600,7 @@ static bool has_adjacent_channel(const RRGraphView& rr_graph, const DeviceGrid& return true; //All other blocks will be surrounded on all sides by channels } -static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int iedge, int to_node) { +static void check_rr_edge(const RRGraphView& rr_graph, const DeviceGrid& grid, const vtr::vector& rr_indexed_data, int from_node, int iedge, int to_node) { //Check that to to_node's fan-in is correct, given the switch type int iswitch = rr_graph.edge_switch(RRNodeId(from_node), iedge); @@ -614,7 +614,7 @@ static void check_rr_edge(const RRGraphView& rr_graph, int from_node, int iedge, std::string msg = "Non-configurable BUFFER type switch must have only one driver. "; msg += vtr::string_fmt(" Actual fan-in was %d (expected 1).\n", to_fanin); msg += " Possible cause is complex block output pins connecting to:\n"; - msg += " " + describe_rr_node(to_node); + msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, to_node); VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str()); } diff --git a/libs/librrgraph/src/utils/describe_rr_node.cpp b/libs/librrgraph/src/utils/describe_rr_node.cpp new file mode 100644 index 00000000000..43e2084e453 --- /dev/null +++ b/libs/librrgraph/src/utils/describe_rr_node.cpp @@ -0,0 +1,50 @@ +#include "describe_rr_node.h" + +#include "rr_node.h" +#include "physical_types_util.h" +#include "vtr_util.h" + +/* TODO: This function should adapt RRNodeId */ +std::string describe_rr_node(const RRGraphView& rr_graph, + const DeviceGrid& grid, + const vtr::vector& rr_indexed_data, + int inode) { + + std::string msg = vtr::string_fmt("RR node: %d", inode); + + if (rr_graph.node_type(RRNodeId(inode)) == CHANX || rr_graph.node_type(RRNodeId(inode)) == CHANY) { + auto cost_index = rr_graph.node_cost_index(RRNodeId(inode)); + + int seg_index = rr_indexed_data[cost_index].seg_index; + std::string rr_node_direction_string = rr_graph.node_direction_string(RRNodeId(inode)); + + if (seg_index < (int)rr_graph.num_rr_segments()) { + msg += vtr::string_fmt(" track: %d longline: %d", + rr_graph.node_track_num(RRNodeId(inode)), + rr_graph.rr_segments(RRSegmentId(seg_index)).longline); + } else { + msg += vtr::string_fmt(" track: %d seg_type: ILLEGAL_SEG_INDEX %d", + rr_graph.node_track_num(RRNodeId(inode)), + seg_index); + } + } else if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) { + auto type = grid[rr_graph.node_xlow(RRNodeId(inode))][rr_graph.node_ylow(RRNodeId(inode))].type; + std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(RRNodeId(inode))); + + msg += vtr::string_fmt(" pin: %d pin_name: %s", + rr_graph.node_pin_num(RRNodeId(inode)), + pin_name.c_str()); + } else { + VTR_ASSERT(rr_graph.node_type(RRNodeId(inode)) == SOURCE || rr_graph.node_type(RRNodeId(inode)) == SINK); + + msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(RRNodeId(inode))); + } + + msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(RRNodeId(inode))); + msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(RRNodeId(inode))); + msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(RRNodeId(inode))); + + msg += " " + rr_graph.node_coordinate_to_string(RRNodeId(inode)); + + return msg; +} \ No newline at end of file diff --git a/libs/librrgraph/src/utils/describe_rr_node.h b/libs/librrgraph/src/utils/describe_rr_node.h index 9b4b8dee18f..eba215f6af5 100644 --- a/libs/librrgraph/src/utils/describe_rr_node.h +++ b/libs/librrgraph/src/utils/describe_rr_node.h @@ -2,8 +2,13 @@ #define DESCRIBE_RR_NODE #include +#include "rr_graph_view.h" +#include "device_grid.h" //Returns a brief one-line summary of an RR node -std::string describe_rr_node(int inode); +std::string describe_rr_node(const RRGraphView& rr_graph, + const DeviceGrid& grid, + const vtr::vector& rr_indexed_data, + int inode); #endif \ No newline at end of file diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index daff060d12b..6259dbce68a 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -759,6 +759,8 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x, void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x, double y) { // std::cout << "Mouse move at coordinates (" << x << "," << y << ") "<< std::endl; + const auto& device_ctx = g_vpr_ctx.device(); + // user has clicked the window button, in window mode if (window_point_1_collected) { // draw a grey, dashed-line box to indicate the zoom-in region @@ -780,7 +782,7 @@ void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x, if (hit_node != OPEN) { //Update message - std::string info = describe_rr_node(hit_node); + std::string info = describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, hit_node); std::string msg = vtr::string_fmt("Moused over %s", info.c_str()); app->update_message(msg.c_str()); } else { diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 02592fc8c1a..6f3d8b94665 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -136,6 +136,7 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) { } bool highlight_rr_nodes(int hit_node) { + const auto& device_ctx = g_vpr_ctx.device(); t_draw_state* draw_state = get_draw_state_vars(); char message[250] = ""; @@ -157,11 +158,11 @@ bool highlight_rr_nodes(int hit_node) { draw_state->draw_rr_node[node].node_highlighted = false; } //Print info about all nodes to terminal - VTR_LOG("%s\n", describe_rr_node(node).c_str()); + VTR_LOG("%s\n", describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, node).c_str()); } //Show info about *only* hit node to graphics - std::string info = describe_rr_node(hit_node); + std::string info = describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, hit_node); sprintf(message, "Selected %s", info.c_str()); rr_highlight_message = message; diff --git a/vpr/src/route/annotate_routing.cpp b/vpr/src/route/annotate_routing.cpp index 6a1b8b95e75..12b1464e491 100644 --- a/vpr/src/route/annotate_routing.cpp +++ b/vpr/src/route/annotate_routing.cpp @@ -59,7 +59,7 @@ vtr::vector annotate_rr_node_nets(const DeviceContext& d clustering_ctx.clb_nlist.net_name(net_id).c_str(), clustering_ctx.clb_nlist.net_name(rr_node_nets[rr_node]).c_str(), size_t(rr_node), - describe_rr_node((int)size_t(rr_node)).c_str()); + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, (int)size_t(rr_node)).c_str()); } else { rr_node_nets[rr_node] = net_id; } diff --git a/vpr/src/route/check_route.cpp b/vpr/src/route/check_route.cpp index ac0095a7ad2..067d9342746 100644 --- a/vpr/src/route/check_route.cpp +++ b/vpr/src/route/check_route.cpp @@ -130,8 +130,8 @@ void check_route(enum e_route_type route_type, e_check_route_option check_route_ " %s\n" " %s\n", size_t(net_id), - describe_rr_node(prev_node).c_str(), - describe_rr_node(inode).c_str()); + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, prev_node).c_str(), + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str()); } connected_to_route[inode] = true; /* Mark as in path. */ @@ -621,6 +621,7 @@ static void check_all_non_configurable_edges() { //For routing to be legal if *any* non-configurable edge is used, so must *all* //other non-configurable edges in the same set static bool check_non_configurable_edges(ClusterNetId net, const t_non_configurable_rr_sets& non_configurable_rr_sets) { + const auto& device_ctx = g_vpr_ctx.device(); auto& route_ctx = g_vpr_ctx.routing(); auto& cluster_ctx = g_vpr_ctx.clustering(); @@ -686,7 +687,7 @@ static bool check_non_configurable_edges(ClusterNetId net, const t_non_configura cluster_ctx.clb_nlist.net_name(net).c_str(), size_t(net)); for (auto inode : difference) { - msg += vtr::string_fmt(" Missing %s\n", describe_rr_node(inode).c_str()); + msg += vtr::string_fmt(" Missing %s\n", describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str()); } VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str()); @@ -754,8 +755,8 @@ static bool check_non_configurable_edges(ClusterNetId net, const t_non_configura for (t_node_edge missing_edge : dedupped_difference) { msg += vtr::string_fmt(" Expected RR Node: %d and RR Node: %d to be non-configurably connected, but edge missing from routing:\n", missing_edge.from_node, missing_edge.to_node); - msg += vtr::string_fmt(" %s\n", describe_rr_node(missing_edge.from_node).c_str()); - msg += vtr::string_fmt(" %s\n", describe_rr_node(missing_edge.to_node).c_str()); + msg += vtr::string_fmt(" %s\n", describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, missing_edge.from_node).c_str()); + msg += vtr::string_fmt(" %s\n", describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, missing_edge.to_node).c_str()); } VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str()); @@ -801,11 +802,12 @@ void check_net_for_stubs(ClusterNetId net) { bool any_stubs = stub_finder.CheckNet(net); if (any_stubs) { + const auto& device_ctx = g_vpr_ctx.device(); auto& cluster_ctx = g_vpr_ctx.clustering(); std::string msg = vtr::string_fmt("Route tree for net '%s' (#%zu) contains stub branches rooted at:\n", cluster_ctx.clb_nlist.net_name(net).c_str(), size_t(net)); for (int inode : stub_finder.stub_nodes()) { - msg += vtr::string_fmt(" %s\n", describe_rr_node(inode).c_str()); + msg += vtr::string_fmt(" %s\n", describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str()); } VPR_THROW(VPR_ERROR_ROUTE, msg.c_str()); diff --git a/vpr/src/route/connection_router.cpp b/vpr/src/route/connection_router.cpp index 9ddf0da5c84..96e629a6140 100644 --- a/vpr/src/route/connection_router.cpp +++ b/vpr/src/route/connection_router.cpp @@ -203,6 +203,7 @@ t_heap* ConnectionRouter::timing_driven_route_connection_from_heap(int sin VTR_LOGV_DEBUG(router_debug_, " Initial heap empty (no source)\n"); } + const auto& device_ctx = g_vpr_ctx.device(); auto& route_ctx = g_vpr_ctx.mutable_routing(); t_heap* cheapest = nullptr; @@ -224,7 +225,7 @@ t_heap* ConnectionRouter::timing_driven_route_connection_from_heap(int sin rcv_path_manager.insert_backwards_path_into_traceback(cheapest->path_data, cheapest->cost, cheapest->backward_path_cost, route_ctx); } - VTR_LOGV_DEBUG(router_debug_, " Found target %8d (%s)\n", inode, describe_rr_node(inode).c_str()); + VTR_LOGV_DEBUG(router_debug_, " Found target %8d (%s)\n", inode, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str()); break; } @@ -523,6 +524,7 @@ void ConnectionRouter::timing_driven_add_to_heap(const t_conn_cost_params const int to_node, const RREdgeId from_edge, const int target_node) { + const auto& device_ctx = g_vpr_ctx.device(); t_heap next; // Initalize RCV data struct if needed, otherwise it's set to nullptr @@ -540,7 +542,7 @@ void ConnectionRouter::timing_driven_add_to_heap(const t_conn_cost_params next.R_upstream = current->R_upstream; - VTR_LOGV_DEBUG(router_debug_, " Expanding to node %d (%s)\n", to_node, describe_rr_node(to_node).c_str()); + VTR_LOGV_DEBUG(router_debug_, " Expanding to node %d (%s)\n", to_node, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, to_node).c_str()); evaluate_timing_driven_node_costs(&next, cost_params, @@ -760,12 +762,13 @@ void ConnectionRouter::evaluate_timing_driven_node_costs(t_heap* to, total_cost = compute_node_cost_using_rcv(cost_params, to_node, target_node, to->path_data->backward_delay, to->path_data->backward_cong, to->R_upstream); } else { + const auto& device_ctx = g_vpr_ctx.device(); //Update total cost float expected_cost = router_lookahead_.get_expected_cost(RRNodeId(to_node), RRNodeId(target_node), cost_params, to->R_upstream); VTR_LOGV_DEBUG(router_debug_ && !std::isfinite(expected_cost), " Lookahead from %s (%s) to %s (%s) is non-finite, expected_cost = %f, to->R_upstream = %f\n", - rr_node_arch_name(to_node).c_str(), describe_rr_node(to_node).c_str(), - rr_node_arch_name(target_node).c_str(), describe_rr_node(target_node).c_str(), + rr_node_arch_name(to_node).c_str(), describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, to_node).c_str(), + rr_node_arch_name(target_node).c_str(), describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, target_node).c_str(), expected_cost, to->R_upstream); total_cost += to->backward_path_cost + cost_params.astar_fac * expected_cost; } @@ -833,6 +836,7 @@ void ConnectionRouter::add_route_tree_node_to_heap( t_rt_node* rt_node, int target_node, const t_conn_cost_params cost_params) { + const auto& device_ctx = g_vpr_ctx.device(); int inode = rt_node->inode; float backward_path_cost = cost_params.criticality * rt_node->Tdel; @@ -849,7 +853,7 @@ void ConnectionRouter::add_route_tree_node_to_heap( float tot_cost = backward_path_cost + cost_params.astar_fac * router_lookahead_.get_expected_cost(RRNodeId(inode), RRNodeId(target_node), cost_params, R_upstream); - VTR_LOGV_DEBUG(router_debug_, " Adding node %8d to heap from init route tree with cost %g (%s)\n", inode, tot_cost, describe_rr_node(inode).c_str()); + VTR_LOGV_DEBUG(router_debug_, " Adding node %8d to heap from init route tree with cost %g (%s)\n", inode, tot_cost, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str()); push_back_node(&heap_, rr_node_route_inf_, inode, tot_cost, NO_PREVIOUS, RREdgeId::INVALID(), diff --git a/vpr/src/route/route_common.cpp b/vpr/src/route/route_common.cpp index 255de24ce8a..fabfe460fe5 100644 --- a/vpr/src/route/route_common.cpp +++ b/vpr/src/route/route_common.cpp @@ -1620,7 +1620,7 @@ void print_invalid_routing_info() { int occ = route_ctx.rr_node_route_inf[inode].occ(); int cap = rr_graph.node_capacity(rr_id); if (occ > cap) { - VTR_LOG(" %s is overused (occ=%d capacity=%d)\n", describe_rr_node(inode).c_str(), occ, cap); + VTR_LOG(" %s is overused (occ=%d capacity=%d)\n", describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, inode).c_str(), occ, cap); auto range = rr_node_nets.equal_range(inode); for (auto itr = range.first; itr != range.second; ++itr) { @@ -1734,11 +1734,12 @@ bool router_needs_lookahead(enum e_router_algorithm router_algorithm) { } std::string describe_unrouteable_connection(const int source_node, const int sink_node) { + const auto& device_ctx = g_vpr_ctx.device(); std::string msg = vtr::string_fmt( "Cannot route from %s (%s) to " "%s (%s) -- no possible path", - rr_node_arch_name(source_node).c_str(), describe_rr_node(source_node).c_str(), - rr_node_arch_name(sink_node).c_str(), describe_rr_node(sink_node).c_str()); + rr_node_arch_name(source_node).c_str(), describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, source_node).c_str(), + rr_node_arch_name(sink_node).c_str(), describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, sink_node).c_str()); return msg; } diff --git a/vpr/src/route/route_profiling.cpp b/vpr/src/route/route_profiling.cpp index 88068520c2e..b7c88749335 100644 --- a/vpr/src/route/route_profiling.cpp +++ b/vpr/src/route/route_profiling.cpp @@ -214,6 +214,7 @@ void conn_start() { conn_start_time = clock(); } void conn_finish(int src_rr, int sink_rr, float criticality) { + const auto& device_ctx = g_vpr_ctx.device(); float route_time = static_cast(clock() - conn_start_time) / CLOCKS_PER_SEC; if (route_time > worst_conn_time) { worst_src_rr = src_rr; @@ -223,16 +224,17 @@ void conn_finish(int src_rr, int sink_rr, float criticality) { } VTR_LOG("%s to %s (crit: %f) took %f\n", - describe_rr_node(src_rr).c_str(), - describe_rr_node(sink_rr).c_str(), + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, src_rr).c_str(), + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, sink_rr).c_str(), criticality, route_time); } void net_finish() { if (worst_conn_time > 0.f) { + const auto& device_ctx = g_vpr_ctx.device(); VTR_LOG("Worst conn was %s to %s (crit: %f) took %f\n", - describe_rr_node(worst_src_rr).c_str(), - describe_rr_node(worst_sink_rr).c_str(), + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, worst_src_rr).c_str(), + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, worst_sink_rr).c_str(), worst_crit, worst_conn_time); } diff --git a/vpr/src/route/route_timing.cpp b/vpr/src/route/route_timing.cpp index b2ebaa43791..2c60a4c217f 100644 --- a/vpr/src/route/route_timing.cpp +++ b/vpr/src/route/route_timing.cpp @@ -1184,13 +1184,14 @@ static bool timing_driven_pre_route_to_clock_root( t_rt_node* rt_root, SpatialRouteTreeLookup& spatial_rt_lookup, RouterStats& router_stats) { + const auto& device_ctx = g_vpr_ctx.device(); auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& cluster_ctx = g_vpr_ctx.clustering(); auto& m_route_ctx = g_vpr_ctx.mutable_routing(); bool high_fanout = is_high_fanout(cluster_ctx.clb_nlist.net_sinks(net_id).size(), high_fanout_threshold); - VTR_LOGV_DEBUG(f_router_debug, "Net %zu pre-route to (%s)\n", size_t(net_id), describe_rr_node(sink_node).c_str()); + VTR_LOGV_DEBUG(f_router_debug, "Net %zu pre-route to (%s)\n", size_t(net_id), describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, sink_node).c_str()); profiling::sink_criticality_start(); @@ -1214,7 +1215,7 @@ static bool timing_driven_pre_route_to_clock_root( ClusterBlockId src_block = cluster_ctx.clb_nlist.net_driver_block(net_id); VTR_LOG("Failed to route connection from '%s' to '%s' for net '%s' (#%zu)\n", cluster_ctx.clb_nlist.block_name(src_block).c_str(), - describe_rr_node(sink_node).c_str(), + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, sink_node).c_str(), cluster_ctx.clb_nlist.net_name(net_id).c_str(), size_t(net_id)); if (f_router_debug) { @@ -1284,13 +1285,14 @@ static bool timing_driven_route_sink( const RoutingPredictor& routing_predictor) { /* Build a path from the existing route tree rooted at rt_root to the target_node * add this branch to the existing route tree and update pathfinder costs and rr_node_route_inf to reflect this */ + const auto& device_ctx = g_vpr_ctx.device(); auto& route_ctx = g_vpr_ctx.mutable_routing(); auto& cluster_ctx = g_vpr_ctx.clustering(); profiling::sink_criticality_start(); int sink_node = route_ctx.net_rr_terminals[net_id][target_pin]; - VTR_LOGV_DEBUG(f_router_debug, "Net %zu Target %d (%s)\n", size_t(net_id), itarget, describe_rr_node(sink_node).c_str()); + VTR_LOGV_DEBUG(f_router_debug, "Net %zu Target %d (%s)\n", size_t(net_id), itarget, describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, sink_node).c_str()); VTR_ASSERT_DEBUG(verify_traceback_route_tree_equivalent(route_ctx.trace[net_id].head, rt_root)); diff --git a/vpr/src/route/router_lookahead_extended_map.cpp b/vpr/src/route/router_lookahead_extended_map.cpp index beb954d6cea..f1d0df2fd91 100644 --- a/vpr/src/route/router_lookahead_extended_map.cpp +++ b/vpr/src/route/router_lookahead_extended_map.cpp @@ -135,7 +135,7 @@ std::pair ExtendedMapLookahead::get_src_opin_cost(RRNodeId from_no VTR_ASSERT_SAFE_MSG(false, vtr::string_fmt("Lookahead failed to estimate cost from %s: %s", rr_node_arch_name(size_t(from_node)).c_str(), - describe_rr_node(size_t(from_node)).c_str()) + describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, size_t(from_node)).c_str()) .c_str()); } diff --git a/vpr/src/route/router_lookahead_map.cpp b/vpr/src/route/router_lookahead_map.cpp index 6916ec43924..69884dca59d 100644 --- a/vpr/src/route/router_lookahead_map.cpp +++ b/vpr/src/route/router_lookahead_map.cpp @@ -328,7 +328,7 @@ std::pair MapLookahead::get_expected_delay_and_cong(RRNodeId from_ VTR_ASSERT_SAFE_MSG(std::isfinite(expected_delay_cost), vtr::string_fmt("Lookahead failed to estimate cost from %s: %s", rr_node_arch_name(size_t(from_node)).c_str(), - describe_rr_node(size_t(from_node)).c_str()) + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, size_t(from_node)).c_str()) .c_str()); } else if (from_type == CHANX || from_type == CHANY) { @@ -352,7 +352,7 @@ std::pair MapLookahead::get_expected_delay_and_cong(RRNodeId from_ VTR_ASSERT_SAFE_MSG(std::isfinite(expected_delay_cost), vtr::string_fmt("Lookahead failed to estimate cost from %s: %s", rr_node_arch_name(size_t(from_node)).c_str(), - describe_rr_node(size_t(from_node)).c_str()) + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, size_t(from_node)).c_str()) .c_str()); } else if (from_type == IPIN) { /* Change if you're allowing route-throughs */ return std::make_pair(0., device_ctx.rr_indexed_data[RRIndexedDataId(SINK_COST_INDEX)].base_cost); @@ -628,7 +628,7 @@ static void run_dijkstra(RRNodeId start_node, int start_x, int start_y, t_routin continue; } - //VTR_LOG("Expanding with delay=%10.3g cong=%10.3g (%s)\n", current.delay, current.congestion_upstream, describe_rr_node(curr_node).c_str()); + //VTR_LOG("Expanding with delay=%10.3g cong=%10.3g (%s)\n", current.delay, current.congestion_upstream, describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, curr_node).c_str()); /* if this node is an ipin record its congestion/delay in the routing_cost_map */ if (rr_graph.node_type(curr_node) == IPIN) { diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index 3068531320c..c80efbf51d3 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -388,7 +388,7 @@ void create_rr_graph(const t_graph_type graph_type, process_non_config_sets(); - verify_rr_node_indices(grid, device_ctx.rr_graph, device_ctx.rr_graph.rr_nodes()); + verify_rr_node_indices(grid, device_ctx.rr_graph, device_ctx.rr_indexed_data, device_ctx.rr_graph.rr_nodes()); print_rr_graph_stats(); @@ -1081,7 +1081,7 @@ static void rr_graph_externals(const std::vector& segment_inf, bool echo_enabled = getEchoEnabled() && isEchoFileEnabled(E_ECHO_RR_GRAPH_INDEXED_DATA); const char* echo_file_name = getEchoFileName(E_ECHO_RR_GRAPH_INDEXED_DATA); add_rr_graph_C_from_switches(rr_graph.rr_switch_inf(RRSwitchId(wire_to_rr_ipin_switch)).Cin); - alloc_and_load_rr_indexed_data(rr_graph, device_ctx.grid, segment_inf, segment_inf_x, + alloc_and_load_rr_indexed_data(rr_graph, grid, segment_inf, segment_inf_x, segment_inf_y, rr_indexed_data, wire_to_rr_ipin_switch, base_cost_type, echo_enabled, echo_file_name); //load_rr_index_segments(segment_inf.size()); } @@ -2634,50 +2634,6 @@ static vtr::NdMatrix, 4> alloc_and_load_track_to_pin_lookup(vtr return track_to_pin_lookup; } -/* TODO: This function should adapt RRNodeId */ -std::string describe_rr_node(int inode) { - auto& device_ctx = g_vpr_ctx.device(); - const auto& rr_graph = device_ctx.rr_graph; - - std::string msg = vtr::string_fmt("RR node: %d", inode); - - if (rr_graph.node_type(RRNodeId(inode)) == CHANX || rr_graph.node_type(RRNodeId(inode)) == CHANY) { - auto cost_index = rr_graph.node_cost_index(RRNodeId(inode)); - - int seg_index = device_ctx.rr_indexed_data[cost_index].seg_index; - std::string rr_node_direction_string = rr_graph.node_direction_string(RRNodeId(inode)); - - if (seg_index < (int)rr_graph.num_rr_segments()) { - msg += vtr::string_fmt(" track: %d longline: %d", - rr_graph.node_track_num(RRNodeId(inode)), - rr_graph.rr_segments(RRSegmentId(seg_index)).longline); - } else { - msg += vtr::string_fmt(" track: %d seg_type: ILLEGAL_SEG_INDEX %d", - rr_graph.node_track_num(RRNodeId(inode)), - seg_index); - } - } else if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) { - auto type = device_ctx.grid[rr_graph.node_xlow(RRNodeId(inode))][rr_graph.node_ylow(RRNodeId(inode))].type; - std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(RRNodeId(inode))); - - msg += vtr::string_fmt(" pin: %d pin_name: %s", - rr_graph.node_pin_num(RRNodeId(inode)), - pin_name.c_str()); - } else { - VTR_ASSERT(rr_graph.node_type(RRNodeId(inode)) == SOURCE || rr_graph.node_type(RRNodeId(inode)) == SINK); - - msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(RRNodeId(inode))); - } - - msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(RRNodeId(inode))); - msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(RRNodeId(inode))); - msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(RRNodeId(inode))); - - msg += " " + rr_graph.node_coordinate_to_string(RRNodeId(inode)); - - return msg; -} - /*AA: * So I need to update this cause the Fc_xofs and Fc_yofs are size of * X and Y segment counts. When going through the side of the logic block, diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 28f81a27dce..03758ea9103 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -1290,6 +1290,7 @@ void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder, */ bool verify_rr_node_indices(const DeviceGrid& grid, const RRGraphView& rr_graph, + const vtr::vector& rr_indexed_data, const t_rr_graph_storage& rr_nodes) { std::unordered_map rr_node_counts; @@ -1313,7 +1314,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, VPR_ERROR(VPR_ERROR_ROUTE, "RR node type does not match between rr_nodes and rr_node_indices (%s/%s): %s", rr_node_typename[rr_graph.node_type(inode)], rr_node_typename[rr_type], - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } if (rr_graph.node_type(inode) == CHANX) { @@ -1323,7 +1324,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, VPR_ERROR(VPR_ERROR_ROUTE, "RR node y position does not agree between rr_nodes (%d) and rr_node_indices (%d): %s", rr_graph.node_ylow(inode), y, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } if (!rr_graph.x_in_node_range(x, inode)) { @@ -1331,7 +1332,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, rr_graph.node_xlow(inode), rr_graph.node_xlow(inode), x, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } } else if (rr_graph.node_type(inode) == CHANY) { VTR_ASSERT_MSG(rr_graph.node_xlow(inode) == rr_graph.node_xhigh(inode), "CHANY should be veritcal"); @@ -1340,7 +1341,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, VPR_ERROR(VPR_ERROR_ROUTE, "RR node x position does not agree between rr_nodes (%d) and rr_node_indices (%d): %s", rr_graph.node_xlow(inode), x, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } if (!rr_graph.y_in_node_range(y, inode)) { @@ -1348,7 +1349,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, rr_graph.node_ylow(inode), rr_graph.node_ylow(inode), y, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } } else if (rr_graph.node_type(inode) == SOURCE || rr_graph.node_type(inode) == SINK) { //Sources have co-ordintes covering the entire block they are in @@ -1357,7 +1358,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, rr_graph.node_xlow(inode), rr_graph.node_xlow(inode), x, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } if (!rr_graph.y_in_node_range(y, inode)) { @@ -1365,7 +1366,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, rr_graph.node_ylow(inode), rr_graph.node_ylow(inode), y, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } } else { @@ -1376,14 +1377,14 @@ bool verify_rr_node_indices(const DeviceGrid& grid, * VPR_ERROR(VPR_ERROR_ROUTE, "RR node xlow does not match between rr_nodes and rr_node_indices (%d/%d): %s", * rr_node.xlow(), * x, - * describe_rr_node(inode).c_str()); + * describe_rr_node(rr_graph, grid, rr_indexed_data, inode).c_str()); * } * * if (rr_node.ylow() != y) { * VPR_ERROR(VPR_ERROR_ROUTE, "RR node ylow does not match between rr_nodes and rr_node_indices (%d/%d): %s", * rr_node.ylow(), * y, - * describe_rr_node(inode).c_str()); + * describe_rr_node(rr_graph, grid, rr_indexed_data, inode).c_str()); * } */ } @@ -1395,7 +1396,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, * VPR_ERROR(VPR_ERROR_ROUTE, "RR node xlow does not match between rr_nodes and rr_node_indices (%s/%s): %s", * SIDE_STRING[rr_node.side()], * SIDE_STRING[side], - * describe_rr_node(inode).c_str()); + * describe_rr_node(rr_graph, grid, rr_indexed_data, inode).c_str()); * } else { * VTR_ASSERT(rr_node.side() == side); * } @@ -1427,7 +1428,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, rr_area, rr_node.length(), count, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } /* As we allow a pin to be indexable on multiple sides, * This check code should not be applied to input and output pins @@ -1437,7 +1438,7 @@ bool verify_rr_node_indices(const DeviceGrid& grid, VPR_ERROR(VPR_ERROR_ROUTE, "Mismatch between RR node length (%d) and count within rr_node_indices (%d, should be length + 1): %s", rr_node.length(), count, - describe_rr_node(size_t(inode)).c_str()); + describe_rr_node(rr_graph, grid, rr_indexed_data, size_t(inode)).c_str()); } } } diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 5b007256cf3..8f3edd64e84 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -30,6 +30,7 @@ void alloc_and_load_rr_node_indices(RRGraphBuilder& rr_graph_builder, bool verify_rr_node_indices(const DeviceGrid& grid, const RRGraphView& rr_graph, + const vtr::vector& rr_indexed_data, const t_rr_graph_storage& rr_nodes); //Returns all x-channel or y-channel wires at the specified location diff --git a/vpr/src/route/rr_graph_area.cpp b/vpr/src/route/rr_graph_area.cpp index db5255dadcb..55af5302e82 100644 --- a/vpr/src/route/rr_graph_area.cpp +++ b/vpr/src/route/rr_graph_area.cpp @@ -411,7 +411,7 @@ void count_unidir_routing_transistors(std::vector& /*segment_inf* "Uni-directional RR node driven by non-configurable " "BUFFER has fan in %d (expected 1)\n", fan_in); - msg += " " + describe_rr_node(size_t(to_node)); + msg += " " + describe_rr_node(rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, size_t(to_node)); VPR_FATAL_ERROR(VPR_ERROR_OTHER, msg.c_str()); } From c3ff42401b04efd028263fc7bccd2c1cec037417 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 25 Jul 2022 17:02:52 -0700 Subject: [PATCH 13/19] [vpr] add get_parallel_segs.cpp to librrgraph --- libs/librrgraph/src/base/get_parallel_segs.cpp | 17 +++++++++++++++++ vpr/src/draw/draw.cpp | 3 +-- vpr/src/draw/search_bar.cpp | 2 +- vpr/src/route/rr_graph2.cpp | 15 --------------- 4 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 libs/librrgraph/src/base/get_parallel_segs.cpp diff --git a/libs/librrgraph/src/base/get_parallel_segs.cpp b/libs/librrgraph/src/base/get_parallel_segs.cpp new file mode 100644 index 00000000000..d20b3066992 --- /dev/null +++ b/libs/librrgraph/src/base/get_parallel_segs.cpp @@ -0,0 +1,17 @@ +#include "get_parallel_segs.h" + +/*Gets t_segment_inf for parallel segments as defined by the user. + *Segments that have BOTH_AXIS attribute value are always included in the returned vector.*/ +std::vector get_parallel_segs(const std::vector& segment_inf, + t_unified_to_parallel_seg_index& seg_index_map, + enum e_parallel_axis parallel_axis) { + std::vector result; + for (size_t i = 0; i < segment_inf.size(); ++i) { + if (segment_inf[i].parallel_axis == parallel_axis || segment_inf[i].parallel_axis == BOTH_AXIS) { + result.push_back(segment_inf[i]); + result[result.size() - 1].seg_index = i; + seg_index_map.insert(std::make_pair(i, std::make_pair(result.size() - 1, parallel_axis))); + } + } + return result; +} \ No newline at end of file diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp index 6259dbce68a..c5be6b8e1f8 100644 --- a/vpr/src/draw/draw.cpp +++ b/vpr/src/draw/draw.cpp @@ -759,8 +759,6 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x, void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x, double y) { // std::cout << "Mouse move at coordinates (" << x << "," << y << ") "<< std::endl; - const auto& device_ctx = g_vpr_ctx.device(); - // user has clicked the window button, in window mode if (window_point_1_collected) { // draw a grey, dashed-line box to indicate the zoom-in region @@ -782,6 +780,7 @@ void act_on_mouse_move(ezgl::application* app, GdkEventButton* event, double x, if (hit_node != OPEN) { //Update message + const auto& device_ctx = g_vpr_ctx.device(); std::string info = describe_rr_node(device_ctx.rr_graph, device_ctx.grid, device_ctx.rr_indexed_data, hit_node); std::string msg = vtr::string_fmt("Moused over %s", info.c_str()); app->update_message(msg.c_str()); diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 6f3d8b94665..737fba28450 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -136,12 +136,12 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) { } bool highlight_rr_nodes(int hit_node) { - const auto& device_ctx = g_vpr_ctx.device(); t_draw_state* draw_state = get_draw_state_vars(); char message[250] = ""; if (hit_node != OPEN) { + const auto& device_ctx = g_vpr_ctx.device(); auto nodes = draw_expand_non_configurable_rr_nodes(hit_node); for (auto node : nodes) { if (draw_state->draw_rr_node[node].color != ezgl::MAGENTA) { diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index 03758ea9103..f3089c98611 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -203,21 +203,6 @@ std::unique_ptr get_seg_track_counts(const int num_sets, /* This must be freed by caller */ return result; } -/*Gets t_segment_inf for parallel segments as defined by the user. - *Segments that have BOTH_AXIS attribute value are always included in the returned vector.*/ -std::vector get_parallel_segs(const std::vector& segment_inf, - t_unified_to_parallel_seg_index& seg_index_map, - enum e_parallel_axis parallel_axis) { - std::vector result; - for (size_t i = 0; i < segment_inf.size(); ++i) { - if (segment_inf[i].parallel_axis == parallel_axis || segment_inf[i].parallel_axis == BOTH_AXIS) { - result.push_back(segment_inf[i]); - result[result.size() - 1].seg_index = i; - seg_index_map.insert(std::make_pair(i, std::make_pair(result.size() - 1, parallel_axis))); - } - } - return result; -} int get_parallel_seg_index(const int abs_index, const t_unified_to_parallel_seg_index& index_map, From ca391d3c81aa8adeedba88d9abbfbaedf030225d Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Mon, 25 Jul 2022 17:29:54 -0700 Subject: [PATCH 14/19] [vpr] format fix --- vpr/src/draw/search_bar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 737fba28450..3f734f31866 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -141,8 +141,8 @@ bool highlight_rr_nodes(int hit_node) { char message[250] = ""; if (hit_node != OPEN) { - const auto& device_ctx = g_vpr_ctx.device(); auto nodes = draw_expand_non_configurable_rr_nodes(hit_node); + const auto& device_ctx = g_vpr_ctx.device(); for (auto node : nodes) { if (draw_state->draw_rr_node[node].color != ezgl::MAGENTA) { /* If the node hasn't been clicked on before, highlight it From 70cc0b4e4f6b8411f6a708c18bb9c6bcf310bdfb Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Tue, 26 Jul 2022 10:28:21 -0700 Subject: [PATCH 15/19] [vpr] format --- vpr/src/draw/search_bar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index 3f734f31866..a2ea6469653 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -139,10 +139,10 @@ bool highlight_rr_nodes(int hit_node) { t_draw_state* draw_state = get_draw_state_vars(); char message[250] = ""; + auto& device_ctx = g_vpr_ctx.device(); if (hit_node != OPEN) { auto nodes = draw_expand_non_configurable_rr_nodes(hit_node); - const auto& device_ctx = g_vpr_ctx.device(); for (auto node : nodes) { if (draw_state->draw_rr_node[node].color != ezgl::MAGENTA) { /* If the node hasn't been clicked on before, highlight it From 9682216906a0a30ecc40ddb55050591348449e0d Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Tue, 26 Jul 2022 10:36:21 -0700 Subject: [PATCH 16/19] [vpr] format fix 2 --- vpr/src/draw/search_bar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vpr/src/draw/search_bar.cpp b/vpr/src/draw/search_bar.cpp index a2ea6469653..e2c8a9b670b 100644 --- a/vpr/src/draw/search_bar.cpp +++ b/vpr/src/draw/search_bar.cpp @@ -138,10 +138,11 @@ void search_and_highlight(GtkWidget* /*widget*/, ezgl::application* app) { bool highlight_rr_nodes(int hit_node) { t_draw_state* draw_state = get_draw_state_vars(); + //TODO: fixed sized char array may cause overflow. char message[250] = ""; - auto& device_ctx = g_vpr_ctx.device(); if (hit_node != OPEN) { + const auto& device_ctx = g_vpr_ctx.device(); auto nodes = draw_expand_non_configurable_rr_nodes(hit_node); for (auto node : nodes) { if (draw_state->draw_rr_node[node].color != ezgl::MAGENTA) { From 228044559f43a6b4562330b8e75b4a6c2ee64e80 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Tue, 26 Jul 2022 15:37:02 -0700 Subject: [PATCH 17/19] [vpr] categorize files to rr_graph_type & rr_graph_cost in librrgraph --- libs/libarchfpga/src/base_cost_type.h | 14 -------- libs/libarchfpga/src/chan_width.h | 16 --------- libs/libarchfpga/src/cost_indices.h | 13 ------- libs/libarchfpga/src/route_type.h | 9 ----- .../src/unified_to_parallel_seg_index.h | 11 ------ libs/librrgraph/src/base/check_rr_graph.h | 6 +--- libs/librrgraph/src/base/get_parallel_segs.h | 2 +- libs/librrgraph/src/base/rr_graph_cost.h | 23 ++++++++++++ libs/librrgraph/src/base/rr_graph_storage.h | 2 +- .../src/base/rr_graph_storage_utils.h | 27 ++++++++++++++ libs/librrgraph/src/base/rr_graph_type.h | 23 ++++++++++++ libs/librrgraph/src/base/rr_graph_util.h | 24 ------------- .../{rr_graph_util.cpp => rr_graph_utils.cpp} | 6 ++-- libs/librrgraph/src/base/rr_graph_utils.h | 36 +++++++++---------- libs/librrgraph/src/io/rr_graph_reader.h | 9 +++-- .../src/io/rr_graph_uxsdcxx_serializer.h | 11 +++--- libs/librrgraph/src/io/rr_graph_writer.h | 5 ++- .../utils/alloc_and_load_rr_indexed_data.cpp | 6 ++-- .../utils/alloc_and_load_rr_indexed_data.h | 2 +- vpr/src/base/vpr_types.h | 7 ++-- vpr/src/route/rr_graph.cpp | 2 +- vpr/src/route/rr_graph2.cpp | 2 +- vpr/src/route/rr_graph2.h | 4 +-- vpr/src/route/rr_graph_area.cpp | 2 +- vpr/src/route/rr_graph_clock.cpp | 2 +- vpr/src/route/rr_graph_sbox.cpp | 2 +- vpr/src/route/rr_graph_timing_params.cpp | 2 +- 27 files changed, 120 insertions(+), 148 deletions(-) delete mode 100644 libs/libarchfpga/src/base_cost_type.h delete mode 100644 libs/libarchfpga/src/chan_width.h delete mode 100644 libs/libarchfpga/src/cost_indices.h delete mode 100644 libs/libarchfpga/src/route_type.h delete mode 100644 libs/libarchfpga/src/unified_to_parallel_seg_index.h create mode 100644 libs/librrgraph/src/base/rr_graph_cost.h create mode 100644 libs/librrgraph/src/base/rr_graph_storage_utils.h delete mode 100644 libs/librrgraph/src/base/rr_graph_util.h rename libs/librrgraph/src/base/{rr_graph_util.cpp => rr_graph_utils.cpp} (99%) diff --git a/libs/libarchfpga/src/base_cost_type.h b/libs/libarchfpga/src/base_cost_type.h deleted file mode 100644 index 8112b97bb37..00000000000 --- a/libs/libarchfpga/src/base_cost_type.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef BASE_COST_TYPE_H -#define BASE_COST_TYPE_H - -enum e_base_cost_type { - DELAY_NORMALIZED, - DELAY_NORMALIZED_LENGTH, - DELAY_NORMALIZED_FREQUENCY, - DELAY_NORMALIZED_LENGTH_FREQUENCY, - DELAY_NORMALIZED_LENGTH_BOUNDED, - DEMAND_ONLY, - DEMAND_ONLY_NORMALIZED_LENGTH -}; - -#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/chan_width.h b/libs/libarchfpga/src/chan_width.h deleted file mode 100644 index eae2e08701b..00000000000 --- a/libs/libarchfpga/src/chan_width.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CHAN_WIDTH_H -#define CHAN_WIDTH_H - -#include - -struct t_chan_width { - int max = 0; - int x_max = 0; - int y_max = 0; - int x_min = 0; - int y_min = 0; - std::vector x_list; - std::vector y_list; -}; - -#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/cost_indices.h b/libs/libarchfpga/src/cost_indices.h deleted file mode 100644 index e3cff80b1aa..00000000000 --- a/libs/libarchfpga/src/cost_indices.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef COST_INDICES_H -#define COST_INDICES_H - -///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. -enum e_cost_indices { - SOURCE_COST_INDEX = 0, - SINK_COST_INDEX, - OPIN_COST_INDEX, - IPIN_COST_INDEX, - CHANX_COST_INDEX_START -}; - -#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/route_type.h b/libs/libarchfpga/src/route_type.h deleted file mode 100644 index a01adffba6c..00000000000 --- a/libs/libarchfpga/src/route_type.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef ROUTE_TYPE_H -#define ROUTE_TYPE_H - -enum e_route_type { - GLOBAL, - DETAILED -}; - -#endif \ No newline at end of file diff --git a/libs/libarchfpga/src/unified_to_parallel_seg_index.h b/libs/libarchfpga/src/unified_to_parallel_seg_index.h deleted file mode 100644 index 47db42e8e5b..00000000000 --- a/libs/libarchfpga/src/unified_to_parallel_seg_index.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef UNIFIED_TO_PARALLEL_SEG_INDEX_H -#define UNIFIED_TO_PARALLEL_SEG_INDEX_H - -#include "physical_types.h" - -/* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment, - * from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments - * regardless of their axis. (see get_parallel_segs for more details)*/ -typedef std::unordered_multimap> t_unified_to_parallel_seg_index; - -#endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index e46cae50844..81471d68bfb 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -1,13 +1,9 @@ #ifndef CHECK_RR_GRAPH_H #define CHECK_RR_GRAPH_H -#include "physical_types.h" -#include "rr_graph_type.h" #include "device_grid.h" -#include "route_type.h" #include "rr_graph_view.h" -#include "chan_width.h" - +#include "rr_graph_type.h" void check_rr_graph(const RRGraphView& rr_graph, const std::vector& types, diff --git a/libs/librrgraph/src/base/get_parallel_segs.h b/libs/librrgraph/src/base/get_parallel_segs.h index 938702e7aef..c88b2c88701 100644 --- a/libs/librrgraph/src/base/get_parallel_segs.h +++ b/libs/librrgraph/src/base/get_parallel_segs.h @@ -1,7 +1,7 @@ #ifndef GET_PARALLEL_SEGS_H #define GET_PARALLEL_SEGS_H -#include "unified_to_parallel_seg_index.h" +#include "rr_graph_type.h" #include "physical_types.h" std::vector get_parallel_segs(const std::vector& segment_inf, diff --git a/libs/librrgraph/src/base/rr_graph_cost.h b/libs/librrgraph/src/base/rr_graph_cost.h new file mode 100644 index 00000000000..00c14c912c2 --- /dev/null +++ b/libs/librrgraph/src/base/rr_graph_cost.h @@ -0,0 +1,23 @@ +#ifndef RR_GRAPH_COST_H +#define RR_GRAPH_COST_H + +enum e_base_cost_type { + DELAY_NORMALIZED, + DELAY_NORMALIZED_LENGTH, + DELAY_NORMALIZED_FREQUENCY, + DELAY_NORMALIZED_LENGTH_FREQUENCY, + DELAY_NORMALIZED_LENGTH_BOUNDED, + DEMAND_ONLY, + DEMAND_ONLY_NORMALIZED_LENGTH +}; + +///@brief Index of the SOURCE, SINK, OPIN, IPIN, etc. member of device_ctx.rr_indexed_data. +enum e_cost_indices { + SOURCE_COST_INDEX = 0, + SINK_COST_INDEX, + OPIN_COST_INDEX, + IPIN_COST_INDEX, + CHANX_COST_INDEX_START +}; + +#endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/rr_graph_storage.h b/libs/librrgraph/src/base/rr_graph_storage.h index 63dc4c9b38d..ebfb3b147df 100644 --- a/libs/librrgraph/src/base/rr_graph_storage.h +++ b/libs/librrgraph/src/base/rr_graph_storage.h @@ -6,6 +6,7 @@ #include "vtr_vector.h" #include "physical_types.h" +#include "rr_graph_storage_utils.h" #include "rr_node_types.h" #include "rr_graph_fwd.h" #include "rr_node_fwd.h" @@ -14,7 +15,6 @@ #include "vtr_memory.h" #include "vtr_strong_id_range.h" #include "vtr_array_view.h" -#include "rr_graph_utils.h" /* Main structure describing one routing resource node. Everything in * * this structure should describe the graph -- information needed only * diff --git a/libs/librrgraph/src/base/rr_graph_storage_utils.h b/libs/librrgraph/src/base/rr_graph_storage_utils.h new file mode 100644 index 00000000000..a2c9dfdeb70 --- /dev/null +++ b/libs/librrgraph/src/base/rr_graph_storage_utils.h @@ -0,0 +1,27 @@ +#ifndef RR_GRAPH_STORAGE_UTILS_H +#define RR_GRAPH_STORAGE_UTILS_H + +// Make room in a vector, with amortized O(1) time by using a pow2 growth pattern. +// +// This enables potentially random insertion into a vector with amortized O(1) +// time. + +template +void make_room_in_vector(T* vec, size_t elem_position) { + if (elem_position < vec->size()) { + return; + } + + size_t capacity = std::max(vec->capacity(), size_t(16)); + while (elem_position >= capacity) { + capacity *= 2; + } + + if (capacity >= vec->capacity()) { + vec->reserve(capacity); + } + + vec->resize(elem_position + 1); +} + +#endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/rr_graph_type.h b/libs/librrgraph/src/base/rr_graph_type.h index c7875a1e573..725d788173a 100644 --- a/libs/librrgraph/src/base/rr_graph_type.h +++ b/libs/librrgraph/src/base/rr_graph_type.h @@ -1,6 +1,24 @@ #ifndef GRAPH_TYPE_H #define GRAPH_TYPE_H +#include +#include "physical_types.h" + +struct t_chan_width { + int max = 0; + int x_max = 0; + int y_max = 0; + int x_min = 0; + int y_min = 0; + std::vector x_list; + std::vector y_list; +}; + +enum e_route_type { + GLOBAL, + DETAILED +}; + enum e_graph_type { GRAPH_GLOBAL, /* One node per channel with wire capacity > 1 and full connectivity */ GRAPH_BIDIR, /* Detailed bidirectional graph */ @@ -10,4 +28,9 @@ enum e_graph_type { }; typedef enum e_graph_type t_graph_type; +/* This map is used to get indices w.r.t segment_inf_x or segment_inf_y based on parallel_axis of a segment, + * from indices w.r.t the **unified** segment vector, segment_inf in devices context which stores all segments + * regardless of their axis. (see get_parallel_segs for more details)*/ +typedef std::unordered_multimap> t_unified_to_parallel_seg_index; + #endif \ No newline at end of file diff --git a/libs/librrgraph/src/base/rr_graph_util.h b/libs/librrgraph/src/base/rr_graph_util.h deleted file mode 100644 index 93947654c5b..00000000000 --- a/libs/librrgraph/src/base/rr_graph_util.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef RR_GRAPH_UTIL_H -#define RR_GRAPH_UTIL_H - -/* Include header files which include data structures used by - * the function declaration - */ -#include -#include "rr_graph_fwd.h" -#include "rr_node_types.h" -#include "rr_graph_view.h" - -/* Get node-to-node switches in a RRGraph */ -std::vector find_rr_graph_switches(const RRGraph& rr_graph, - const RRNodeId& from_node, - const RRNodeId& to_node); - -// This function generates and returns a vector indexed by RRNodeId -// containing a list of fan-in edges for each node. -vtr::vector> get_fan_in_list(const RRGraphView& rr_graph); - -int seg_index_of_cblock(const RRGraphView& rr_graph, t_rr_type from_rr_type, int to_node); -int seg_index_of_sblock(const RRGraphView& rr_graph, int from_node, int to_node); - -#endif diff --git a/libs/librrgraph/src/base/rr_graph_util.cpp b/libs/librrgraph/src/base/rr_graph_utils.cpp similarity index 99% rename from libs/librrgraph/src/base/rr_graph_util.cpp rename to libs/librrgraph/src/base/rr_graph_utils.cpp index 186c5318913..6552c8c214b 100644 --- a/libs/librrgraph/src/base/rr_graph_util.cpp +++ b/libs/librrgraph/src/base/rr_graph_utils.cpp @@ -1,3 +1,4 @@ + /**************************************************************************** * This file include most-utilized functions that manipulate on the * RRGraph object @@ -6,7 +7,7 @@ #include #include -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "vtr_memory.h" #include "vtr_time.h" @@ -118,5 +119,4 @@ vtr::vector> get_fan_in_list(const RRGraphView& }); return node_fan_in_list; -} - +} \ No newline at end of file diff --git a/libs/librrgraph/src/base/rr_graph_utils.h b/libs/librrgraph/src/base/rr_graph_utils.h index 71c8453eb12..d3ef4440daa 100644 --- a/libs/librrgraph/src/base/rr_graph_utils.h +++ b/libs/librrgraph/src/base/rr_graph_utils.h @@ -1,26 +1,24 @@ #ifndef RR_GRAPH_UTILS_H #define RR_GRAPH_UTILS_H -// Make room in a vector, with amortized O(1) time by using a pow2 growth pattern. -// -// This enables potentially random insertion into a vector with amortized O(1) -// time. -template -void make_room_in_vector(T* vec, size_t elem_position) { - if (elem_position < vec->size()) { - return; - } +/* Include header files which include data structures used by + * the function declaration + */ +#include +#include "rr_graph_fwd.h" +#include "rr_node_types.h" +#include "rr_graph_view.h" - size_t capacity = std::max(vec->capacity(), size_t(16)); - while (elem_position >= capacity) { - capacity *= 2; - } +/* Get node-to-node switches in a RRGraph */ +std::vector find_rr_graph_switches(const RRGraph& rr_graph, + const RRNodeId& from_node, + const RRNodeId& to_node); - if (capacity >= vec->capacity()) { - vec->reserve(capacity); - } +// This function generates and returns a vector indexed by RRNodeId +// containing a list of fan-in edges for each node. +vtr::vector> get_fan_in_list(const RRGraphView& rr_graph); - vec->resize(elem_position + 1); -} +int seg_index_of_cblock(const RRGraphView& rr_graph, t_rr_type from_rr_type, int to_node); +int seg_index_of_sblock(const RRGraphView& rr_graph, int from_node, int to_node); -#endif +#endif \ No newline at end of file diff --git a/libs/librrgraph/src/io/rr_graph_reader.h b/libs/librrgraph/src/io/rr_graph_reader.h index c5e129f033d..d7cd871a61f 100644 --- a/libs/librrgraph/src/io/rr_graph_reader.h +++ b/libs/librrgraph/src/io/rr_graph_reader.h @@ -4,14 +4,13 @@ #define RR_GRAPH_READER_H #include "rr_graph_type.h" -#include "device_grid.h" -#include "physical_types.h" -#include "base_cost_type.h" -#include "chan_width.h" -#include "rr_node.h" +#include "rr_graph_cost.h" #include "rr_graph_builder.h" #include "rr_graph_view.h" #include "rr_graph_fwd.h" +#include "rr_node.h" +#include "device_grid.h" +#include "physical_types.h" void load_rr_file(RRGraphBuilder* rr_graph_builder, diff --git a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h index 2d117bf5f48..e7c6f125f85 100644 --- a/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h +++ b/libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h @@ -7,20 +7,17 @@ #include "rr_graph_uxsdcxx_interface.h" #include "rr_node.h" -#include "rr_rc_data.h" -#include "rr_metadata.h" +#include "rr_graph_type.h" +#include "rr_graph_cost.h" #include "rr_graph_view.h" #include "rr_graph_builder.h" +#include "rr_rc_data.h" +#include "rr_metadata.h" #include "check_rr_graph.h" #include "read_xml_arch_file.h" #include "device_grid.h" -#include "chan_width.h" -#include "base_cost_type.h" -#include "unified_to_parallel_seg_index.h" -#include "rr_graph_type.h" -#include "cost_indices.h" #include "alloc_and_load_rr_indexed_data.h" #include "get_parallel_segs.h" diff --git a/libs/librrgraph/src/io/rr_graph_writer.h b/libs/librrgraph/src/io/rr_graph_writer.h index c1de365c053..572aa1500c2 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.h +++ b/libs/librrgraph/src/io/rr_graph_writer.h @@ -6,14 +6,13 @@ #ifndef RR_GRAPH_WRITER_H #define RR_GRAPH_WRITER_H -#include "physical_types.h" -#include "chan_width.h" #include "rr_node.h" +#include "rr_graph_type.h" #include "rr_graph_builder.h" #include "rr_graph_view.h" #include "rr_graph_fwd.h" -#include "chan_width.h" #include "device_grid.h" +#include "physical_types.h" void write_rr_graph(RRGraphBuilder* rr_graph_builder, RRGraphView* rr_graph, diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp index 7df6c7f92b4..b33fcd0eca1 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.cpp @@ -13,11 +13,11 @@ #include "vpr_error.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "read_xml_arch_file.h" -#include "base_cost_type.h" -#include "cost_indices.h" +#include "rr_graph_cost.h" +#include "rr_graph_type.h" #include "histogram.h" diff --git a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h index ccec5ee5b13..1a96141163a 100644 --- a/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h +++ b/libs/librrgraph/src/utils/alloc_and_load_rr_indexed_data.h @@ -3,7 +3,7 @@ #include "rr_graph_view.h" #include "rr_node.h" -#include "base_cost_type.h" +#include "rr_graph_cost.h" #include "device_grid.h" void alloc_and_load_rr_indexed_data(const RRGraphView& rr_graph, diff --git a/vpr/src/base/vpr_types.h b/vpr/src/base/vpr_types.h index a10b6b76fa3..1581d1ad138 100644 --- a/vpr/src/base/vpr_types.h +++ b/vpr/src/base/vpr_types.h @@ -35,11 +35,6 @@ #include "clock_modeling.h" #include "heap_type.h" -#include "base_cost_type.h" -#include "chan_width.h" -#include "cost_indices.h" -#include "route_type.h" - #include "vtr_assert.h" #include "vtr_ndmatrix.h" #include "vtr_vector.h" @@ -50,6 +45,8 @@ #include "vtr_dynamic_bitset.h" #include "rr_node_types.h" #include "rr_graph_fwd.h" +#include "rr_graph_cost.h" +#include "rr_graph_type.h" /******************************************************************************* * Global data types and constants diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp index c80efbf51d3..48e0d935745 100644 --- a/vpr/src/route/rr_graph.cpp +++ b/vpr/src/route/rr_graph.cpp @@ -17,7 +17,7 @@ #include "vpr_error.h" #include "globals.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph.h" #include "rr_graph_area.h" #include "rr_graph2.h" diff --git a/vpr/src/route/rr_graph2.cpp b/vpr/src/route/rr_graph2.cpp index f3089c98611..49b885d4d17 100644 --- a/vpr/src/route/rr_graph2.cpp +++ b/vpr/src/route/rr_graph2.cpp @@ -9,7 +9,7 @@ #include "vpr_error.h" #include "globals.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph2.h" #include "rr_graph.h" #include "rr_graph_sbox.h" diff --git a/vpr/src/route/rr_graph2.h b/vpr/src/route/rr_graph2.h index 8f3edd64e84..24fbef9afc5 100644 --- a/vpr/src/route/rr_graph2.h +++ b/vpr/src/route/rr_graph2.h @@ -3,13 +3,13 @@ #include #include "build_switchblocks.h" +#include "rr_graph_type.h" #include "rr_graph_fwd.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph_view.h" #include "rr_graph_builder.h" #include "rr_types.h" #include "device_grid.h" -#include "unified_to_parallel_seg_index.h" #include "get_parallel_segs.h" /******************* Types shared by rr_graph2 functions *********************/ diff --git a/vpr/src/route/rr_graph_area.cpp b/vpr/src/route/rr_graph_area.cpp index 55af5302e82..deff6680563 100644 --- a/vpr/src/route/rr_graph_area.cpp +++ b/vpr/src/route/rr_graph_area.cpp @@ -10,7 +10,7 @@ #include "globals.h" #include "rr_graph.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph_area.h" /* Select which transistor area equation to use. As found by Chiasson's and Betz's FPL 2013 paper diff --git a/vpr/src/route/rr_graph_clock.cpp b/vpr/src/route/rr_graph_clock.cpp index c4e5f4bd1ed..7ad0b402bf0 100644 --- a/vpr/src/route/rr_graph_clock.cpp +++ b/vpr/src/route/rr_graph_clock.cpp @@ -4,7 +4,7 @@ #include "rr_graph.h" #include "rr_graph2.h" #include "rr_graph_area.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph_indexed_data.h" #include "vtr_assert.h" diff --git a/vpr/src/route/rr_graph_sbox.cpp b/vpr/src/route/rr_graph_sbox.cpp index 04830f78529..22a4db0c4be 100644 --- a/vpr/src/route/rr_graph_sbox.cpp +++ b/vpr/src/route/rr_graph_sbox.cpp @@ -5,7 +5,7 @@ #include "vpr_types.h" #include "rr_graph_sbox.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph2.h" #include "echo_files.h" diff --git a/vpr/src/route/rr_graph_timing_params.cpp b/vpr/src/route/rr_graph_timing_params.cpp index 4dc3362e62f..bd3a50c7afc 100644 --- a/vpr/src/route/rr_graph_timing_params.cpp +++ b/vpr/src/route/rr_graph_timing_params.cpp @@ -7,7 +7,7 @@ #include "globals.h" #include "rr_graph.h" -#include "rr_graph_util.h" +#include "rr_graph_utils.h" #include "rr_graph2.h" #include "rr_graph_timing_params.h" From 4a4eb964005217eb95b55db7b513f74a39226ada Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Fri, 29 Jul 2022 16:17:29 -0700 Subject: [PATCH 18/19] [vpr] code cleanup --- libs/librrgraph/src/base/check_rr_graph.cpp | 6 +++--- libs/librrgraph/src/base/check_rr_graph.h | 6 +++--- libs/librrgraph/src/base/rr_graph_type.h | 4 ++-- libs/librrgraph/src/io/rr_graph_writer.cpp | 4 ++-- libs/librrgraph/src/io/rr_graph_writer.h | 3 +-- libs/librrgraph/src/utils/describe_rr_node.h | 4 ++-- utils/fasm/src/fasm.cpp | 2 +- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/libs/librrgraph/src/base/check_rr_graph.cpp b/libs/librrgraph/src/base/check_rr_graph.cpp index 74d1228fbae..1675afebd04 100644 --- a/libs/librrgraph/src/base/check_rr_graph.cpp +++ b/libs/librrgraph/src/base/check_rr_graph.cpp @@ -47,7 +47,7 @@ void check_rr_graph(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_chan_width& chan_width, const t_graph_type graph_type, - int virtual_clock_network_root_idx) { + const int virtual_clock_network_root_idx) { e_route_type route_type = DETAILED; if (graph_type == GRAPH_GLOBAL) { route_type = GLOBAL; @@ -291,8 +291,8 @@ void check_rr_node(const RRGraphView& rr_graph, const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, - enum e_route_type route_type, - int inode) { + const enum e_route_type route_type, + const int inode) { /* This routine checks that the rr_node is inside the grid and has a valid * pin number, etc. */ diff --git a/libs/librrgraph/src/base/check_rr_graph.h b/libs/librrgraph/src/base/check_rr_graph.h index 81471d68bfb..7fc168ee673 100644 --- a/libs/librrgraph/src/base/check_rr_graph.h +++ b/libs/librrgraph/src/base/check_rr_graph.h @@ -11,13 +11,13 @@ void check_rr_graph(const RRGraphView& rr_graph, const DeviceGrid& grid, const t_chan_width& chan_width, const t_graph_type graph_type, - int virtual_clock_network_root_idx); + const int virtual_clock_network_root_idx); void check_rr_node(const RRGraphView& rr_graph, const vtr::vector& rr_indexed_data, const DeviceGrid& grid, const t_chan_width& chan_width, - enum e_route_type route_type, - int inode); + const enum e_route_type route_type, + const int inode); #endif diff --git a/libs/librrgraph/src/base/rr_graph_type.h b/libs/librrgraph/src/base/rr_graph_type.h index 725d788173a..f6c5bc7efb5 100644 --- a/libs/librrgraph/src/base/rr_graph_type.h +++ b/libs/librrgraph/src/base/rr_graph_type.h @@ -1,5 +1,5 @@ -#ifndef GRAPH_TYPE_H -#define GRAPH_TYPE_H +#ifndef RR_GRAPH_TYPE_H +#define RR_GRAPH_TYPE_H #include #include "physical_types.h" diff --git a/libs/librrgraph/src/io/rr_graph_writer.cpp b/libs/librrgraph/src/io/rr_graph_writer.cpp index 5c8bb677bc2..35e472218c3 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.cpp +++ b/libs/librrgraph/src/io/rr_graph_writer.cpp @@ -40,7 +40,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, const char* file_name, const int virtual_clock_network_root_idx, bool echo_enabled, - const char* echo__file_name) { + const char* echo_file_name) { RrGraphSerializer reader( /*graph_type=*/t_graph_type(), @@ -51,7 +51,7 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, /*read_rr_graph_filename=*/nullptr, /*read_edge_metadata=*/false, echo_enabled, - echo__file_name, + echo_file_name, chan_width, &rr_graph_builder->rr_nodes(), rr_graph_builder, diff --git a/libs/librrgraph/src/io/rr_graph_writer.h b/libs/librrgraph/src/io/rr_graph_writer.h index 572aa1500c2..6bc4d511900 100644 --- a/libs/librrgraph/src/io/rr_graph_writer.h +++ b/libs/librrgraph/src/io/rr_graph_writer.h @@ -10,7 +10,6 @@ #include "rr_graph_type.h" #include "rr_graph_builder.h" #include "rr_graph_view.h" -#include "rr_graph_fwd.h" #include "device_grid.h" #include "physical_types.h" @@ -27,6 +26,6 @@ void write_rr_graph(RRGraphBuilder* rr_graph_builder, const char* file_name, const int virtual_clock_network_root_idx, bool echo_enabled, - const char* echo__file_name); + const char* echo_file_name); #endif diff --git a/libs/librrgraph/src/utils/describe_rr_node.h b/libs/librrgraph/src/utils/describe_rr_node.h index eba215f6af5..d43d06c10ec 100644 --- a/libs/librrgraph/src/utils/describe_rr_node.h +++ b/libs/librrgraph/src/utils/describe_rr_node.h @@ -1,5 +1,5 @@ -#ifndef DESCRIBE_RR_NODE -#define DESCRIBE_RR_NODE +#ifndef DESCRIBE_RR_NODE_H +#define DESCRIBE_RR_NODE_H #include #include "rr_graph_view.h" diff --git a/utils/fasm/src/fasm.cpp b/utils/fasm/src/fasm.cpp index df800ad3c2c..4c962733f34 100644 --- a/utils/fasm/src/fasm.cpp +++ b/utils/fasm/src/fasm.cpp @@ -635,7 +635,7 @@ void FasmWriterVisitor::walk_route_tree(const RRGraphBuilder& rr_graph_builder, void FasmWriterVisitor::walk_routing() { auto& route_ctx = g_vpr_ctx.mutable_routing(); - auto& device_ctx = g_vpr_ctx.mutable_device(); + const auto& device_ctx = g_vpr_ctx.device(); for(const auto &trace : route_ctx.trace) { t_trace *head = trace.head; From e900c680823d47c2642eac3b3f9ff74edf1b3811 Mon Sep 17 00:00:00 2001 From: oscarcheng105 Date: Tue, 2 Aug 2022 13:34:55 -0700 Subject: [PATCH 19/19] [vpr] doc update --- libs/librrgraph/src/base/SCHEMA_GENERATOR.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/librrgraph/src/base/SCHEMA_GENERATOR.md b/libs/librrgraph/src/base/SCHEMA_GENERATOR.md index 6ac74dd122c..5a61deacde7 100644 --- a/libs/librrgraph/src/base/SCHEMA_GENERATOR.md +++ b/libs/librrgraph/src/base/SCHEMA_GENERATOR.md @@ -6,16 +6,16 @@ mediated via RrGraphBase located in `rr_graph_uxsdcxx_interface.h`. If `rr_graph.xsd` is modified, then the following files must be updated: - - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx.h` - - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_capnp.h` - - `libs/librrgraph/src/base/gen/rr_graph_uxsdcxx_interface.h` + - `libs/librrgraph/src/io/gen/rr_graph_uxsdcxx.h` + - `libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_capnp.h` + - `libs/librrgraph/src/io/gen/rr_graph_uxsdcxx_interface.h` - `libs/libvtrcapnproto/rr_graph_uxsdcxx.capnp` ### Instructions to update generated files (using CMake) 1. Run target `generate_rr_graph_serializers`, e.g. run `make generate_rr_graph_serializers`. 2. Run target `format`, e.g. run `make format`. -3. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or +3. Update `libs/librrgraph/src/io/rr_graph_uxsdcxx_interface_impl.h`, implement or update interfaces that are new or are changed. The compiler will complain that virtual methods are missing if the schema has changed. @@ -23,13 +23,13 @@ If `rr_graph.xsd` is modified, then the following files must be updated: 1. Clone https://github.com/duck2/uxsdcxx/ 2. Run `python3 -mpip install --user -r requirements.txt` -3. Run `python3 uxsdcxx.py libs/librrgraph/src/base/rr_graph.xsd` -3. Run `python3 uxsdcap.py libs/librrgraph/src/base/rr_graph.xsd` +3. Run `python3 uxsdcxx.py libs/librrgraph/src/io/rr_graph.xsd` +3. Run `python3 uxsdcap.py libs/librrgraph/src/io/rr_graph.xsd` 4. Copy `rr_graph_uxsdcxx.h`, `rr_graph_uxsdcxx_capnp.h`, - `rr_graph_uxsdcxx_interface.h` to `libs/librrgraph/src/base/` + `rr_graph_uxsdcxx_interface.h` to `libs/librrgraph/src/io/` 5. Copy `rr_graph_uxsdcxx.capnp` to `../libvtrcapnproto/` 6. Run `make format` -7. Update `libs/librrgraph/src/base/rr_graph_uxsdcxx_interface_impl.h`, implement or +7. Update `libs/librrgraph/src/io/rr_graph_uxsdcxx_interface_impl.h`, implement or update interfaces that are new or are changed. The compiler will complain that virtual methods are missing if the schema has changed.