Created
July 20, 2019 01:47
-
-
Save duck2/fdf7e6ae3f33204e48a8a0a7e0ee08f0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bitset> | |
#include <cstring> | |
#include <memory> | |
#include <string> | |
#include <vector> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include "pugixml.hpp" | |
/* All uxsdcxx functions and structs live in this namespace. */ | |
namespace rr_graph { | |
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)) | |
#else | |
#define onechar(c, s, l) (((uint64_t)(c)) << (l-8-s)) | |
#endif | |
struct t_channel; | |
struct t_x_list; | |
struct t_y_list; | |
struct t_timing; | |
struct t_sizing; | |
struct t_switch; | |
struct t_segment_timing; | |
struct t_segment; | |
struct t_pin; | |
struct t_pin_class; | |
struct t_meta; | |
struct t_metadata; | |
struct t_block_type; | |
struct t_grid_loc; | |
struct t_node_loc; | |
struct t_node_timing; | |
struct t_node_segment; | |
struct t_node; | |
struct t_edge; | |
struct t_channels; | |
struct t_switches; | |
struct t_segments; | |
struct t_block_types; | |
struct t_grid_locs; | |
struct t_rr_nodes; | |
struct t_rr_edges; | |
struct t_rr_graph; | |
enum class enum_switch_type {MUX, TRISTATE, PASS_GATE, SHORT, BUFFER}; | |
enum class enum_pin_type {OPEN, OUTPUT, INPUT}; | |
enum class enum_loc_side {LEFT, RIGHT, TOP, BOTTOM}; | |
enum class enum_node_direction {INC_DIR, DEC_DIR, BI_DIR}; | |
enum class enum_node_type {CHANX, CHANY, SOURCE, SINK, OPIN, IPIN}; | |
struct t_channel { | |
int chan_width_max; | |
int x_max; | |
int x_min; | |
int y_max; | |
int y_min; | |
}; | |
struct t_x_list { | |
int index; | |
int info; | |
}; | |
struct t_y_list { | |
int index; | |
int info; | |
}; | |
struct t_timing { | |
double Cin; | |
double Cinternal; | |
double Cout; | |
double R; | |
double Tdel; | |
}; | |
struct t_sizing { | |
double buf_size; | |
double mux_trans_size; | |
}; | |
struct t_switch { | |
int id; | |
const char * name; | |
enum_switch_type type; | |
int num_timing; | |
t_timing * timing_list; | |
int num_sizing; | |
t_sizing * sizing_list; | |
}; | |
struct t_segment_timing { | |
double C_per_meter; | |
double R_per_meter; | |
}; | |
struct t_segment { | |
int id; | |
const char * name; | |
int num_timing; | |
t_segment_timing * timing_list; | |
}; | |
struct t_pin { | |
int ptc; | |
const char * value; | |
}; | |
struct t_pin_class { | |
enum_pin_type type; | |
int num_pin; | |
t_pin * pin_list; | |
}; | |
struct t_meta { | |
const char * name; | |
int x_offset; | |
int y_offset; | |
const char * value; | |
}; | |
struct t_metadata { | |
int num_meta; | |
t_meta * meta_list; | |
}; | |
struct t_block_type { | |
int height; | |
int id; | |
const char * name; | |
int width; | |
int num_pin_class; | |
t_pin_class * pin_class_list; | |
}; | |
struct t_grid_loc { | |
int block_type_id; | |
int height_offset; | |
int width_offset; | |
int x; | |
int y; | |
}; | |
struct t_node_loc { | |
int ptc; | |
enum_loc_side side; | |
int xhigh; | |
int xlow; | |
int yhigh; | |
int ylow; | |
}; | |
struct t_node_timing { | |
double C; | |
double R; | |
}; | |
struct t_node_segment { | |
int segment_id; | |
}; | |
struct t_node { | |
int capacity; | |
enum_node_direction direction; | |
int id; | |
enum_node_type type; | |
int num_loc; | |
t_node_loc * loc_list; | |
int num_timing; | |
t_node_timing * timing_list; | |
int num_segment; | |
t_node_segment * segment_list; | |
int num_metadata; | |
t_metadata * metadata_list; | |
}; | |
struct t_edge { | |
int id; | |
int sink_node; | |
int src_node; | |
int switch_id; | |
int num_metadata; | |
t_metadata * metadata_list; | |
}; | |
struct t_channels { | |
int num_channel; | |
t_channel * channel_list; | |
int num_x_list; | |
t_x_list * x_list_list; | |
int num_y_list; | |
t_y_list * y_list_list; | |
}; | |
struct t_switches { | |
int num_switch; | |
t_switch * switch_list; | |
}; | |
struct t_segments { | |
int num_segment; | |
t_segment * segment_list; | |
}; | |
struct t_block_types { | |
int num_block_type; | |
t_block_type * block_type_list; | |
}; | |
struct t_grid_locs { | |
int num_grid_loc; | |
t_grid_loc * grid_loc_list; | |
}; | |
struct t_rr_nodes { | |
int num_node; | |
t_node * node_list; | |
}; | |
struct t_rr_edges { | |
int num_edge; | |
t_edge * edge_list; | |
}; | |
struct t_rr_graph { | |
const char * tool_comment; | |
const char * tool_name; | |
const char * tool_version; | |
int num_channels; | |
t_channels * channels_list; | |
int num_switches; | |
t_switches * switches_list; | |
int num_segments; | |
t_segments * segments_list; | |
int num_block_types; | |
t_block_types * block_types_list; | |
int num_grid; | |
t_grid_locs * grid_list; | |
int num_rr_nodes; | |
t_rr_nodes * rr_nodes_list; | |
int num_rr_edges; | |
t_rr_edges * rr_edges_list; | |
}; | |
int g_num_block_type = 0; | |
t_block_type *block_type_arena; | |
int g_num_block_types = 0; | |
t_block_types *block_types_arena; | |
int g_num_channel = 0; | |
t_channel *channel_arena; | |
int g_num_channels = 0; | |
t_channels *channels_arena; | |
int g_num_edge = 0; | |
t_edge *edge_arena; | |
int g_num_grid_loc = 0; | |
t_grid_loc *grid_loc_arena; | |
int g_num_grid_locs = 0; | |
t_grid_locs *grid_locs_arena; | |
int g_num_meta = 0; | |
t_meta *meta_arena; | |
int g_num_metadata = 0; | |
t_metadata *metadata_arena; | |
int g_num_node = 0; | |
t_node *node_arena; | |
int g_num_node_loc = 0; | |
t_node_loc *node_loc_arena; | |
int g_num_node_segment = 0; | |
t_node_segment *node_segment_arena; | |
int g_num_node_timing = 0; | |
t_node_timing *node_timing_arena; | |
int g_num_pin = 0; | |
t_pin *pin_arena; | |
int g_num_pin_class = 0; | |
t_pin_class *pin_class_arena; | |
int g_num_rr_edges = 0; | |
t_rr_edges *rr_edges_arena; | |
int g_num_rr_nodes = 0; | |
t_rr_nodes *rr_nodes_arena; | |
int g_num_segment = 0; | |
t_segment *segment_arena; | |
int g_num_segment_timing = 0; | |
t_segment_timing *segment_timing_arena; | |
int g_num_segments = 0; | |
t_segments *segments_arena; | |
int g_num_sizing = 0; | |
t_sizing *sizing_arena; | |
int g_num_switch = 0; | |
t_switch *switch_arena; | |
int g_num_switches = 0; | |
t_switches *switches_arena; | |
int g_num_timing = 0; | |
t_timing *timing_arena; | |
int g_num_x_list = 0; | |
t_x_list *x_list_arena; | |
int g_num_y_list = 0; | |
t_y_list *y_list_arena; | |
void count_channel(const pugi::xml_node &root); | |
void count_x_list(const pugi::xml_node &root); | |
void count_y_list(const pugi::xml_node &root); | |
void count_timing(const pugi::xml_node &root); | |
void count_sizing(const pugi::xml_node &root); | |
void count_switch(const pugi::xml_node &root); | |
void count_segment_timing(const pugi::xml_node &root); | |
void count_segment(const pugi::xml_node &root); | |
void count_pin(const pugi::xml_node &root); | |
void count_pin_class(const pugi::xml_node &root); | |
void count_meta(const pugi::xml_node &root); | |
void count_metadata(const pugi::xml_node &root); | |
void count_block_type(const pugi::xml_node &root); | |
void count_grid_loc(const pugi::xml_node &root); | |
void count_node_loc(const pugi::xml_node &root); | |
void count_node_timing(const pugi::xml_node &root); | |
void count_node_segment(const pugi::xml_node &root); | |
void count_node(const pugi::xml_node &root); | |
void count_edge(const pugi::xml_node &root); | |
void count_channels(const pugi::xml_node &root); | |
void count_switches(const pugi::xml_node &root); | |
void count_segments(const pugi::xml_node &root); | |
void count_block_types(const pugi::xml_node &root); | |
void count_grid_locs(const pugi::xml_node &root); | |
void count_rr_nodes(const pugi::xml_node &root); | |
void count_rr_edges(const pugi::xml_node &root); | |
void count_rr_graph(const pugi::xml_node &root); | |
void load_channel(const pugi::xml_node &root, t_channel *out); | |
void load_x_list(const pugi::xml_node &root, t_x_list *out); | |
void load_y_list(const pugi::xml_node &root, t_y_list *out); | |
void load_timing(const pugi::xml_node &root, t_timing *out); | |
void load_sizing(const pugi::xml_node &root, t_sizing *out); | |
void load_switch(const pugi::xml_node &root, t_switch *out); | |
void load_segment_timing(const pugi::xml_node &root, t_segment_timing *out); | |
void load_segment(const pugi::xml_node &root, t_segment *out); | |
void load_pin(const pugi::xml_node &root, t_pin *out); | |
void load_pin_class(const pugi::xml_node &root, t_pin_class *out); | |
void load_meta(const pugi::xml_node &root, t_meta *out); | |
void load_metadata(const pugi::xml_node &root, t_metadata *out); | |
void load_block_type(const pugi::xml_node &root, t_block_type *out); | |
void load_grid_loc(const pugi::xml_node &root, t_grid_loc *out); | |
void load_node_loc(const pugi::xml_node &root, t_node_loc *out); | |
void load_node_timing(const pugi::xml_node &root, t_node_timing *out); | |
void load_node_segment(const pugi::xml_node &root, t_node_segment *out); | |
void load_node(const pugi::xml_node &root, t_node *out); | |
void load_edge(const pugi::xml_node &root, t_edge *out); | |
void load_channels(const pugi::xml_node &root, t_channels *out); | |
void load_switches(const pugi::xml_node &root, t_switches *out); | |
void load_segments(const pugi::xml_node &root, t_segments *out); | |
void load_block_types(const pugi::xml_node &root, t_block_types *out); | |
void load_grid_locs(const pugi::xml_node &root, t_grid_locs *out); | |
void load_rr_nodes(const pugi::xml_node &root, t_rr_nodes *out); | |
void load_rr_edges(const pugi::xml_node &root, t_rr_edges *out); | |
void load_rr_graph(const pugi::xml_node &root, t_rr_graph *out); | |
void dfa_error(const char *wrong, int *states, const char **lookup, int len); | |
template<std::size_t N> | |
void attr_error(std::bitset<N> astate, const char **lookup); | |
void alloc_arenas(void); | |
void get_root_elements(const char *filename); | |
/** | |
* Enums for attribute and node names. | |
**/ | |
enum class atok_t_channel {CHAN_WIDTH_MAX, X_MAX, X_MIN, Y_MAX, Y_MIN}; | |
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}; | |
const char *atok_lookup_t_x_list[] = {"index", "info"}; | |
enum class atok_t_y_list {INDEX, INFO}; | |
const char *atok_lookup_t_y_list[] = {"index", "info"}; | |
enum class atok_t_timing {CIN, CINTERNAL, COUT, R, TDEL}; | |
const char *atok_lookup_t_timing[] = {"Cin", "Cinternal", "Cout", "R", "Tdel"}; | |
enum class atok_t_sizing {BUF_SIZE, MUX_TRANS_SIZE}; | |
const char *atok_lookup_t_sizing[] = {"buf_size", "mux_trans_size"}; | |
enum class gtok_t_switch {SIZING, TIMING}; | |
const char *gtok_lookup_t_switch[] = {"sizing", "timing"}; | |
enum class atok_t_switch {ID, NAME, TYPE}; | |
const char *atok_lookup_t_switch[] = {"id", "name", "type"}; | |
enum class atok_t_segment_timing {C_PER_METER, R_PER_METER}; | |
const char *atok_lookup_t_segment_timing[] = {"C_per_meter", "R_per_meter"}; | |
enum class gtok_t_segment {TIMING}; | |
const char *gtok_lookup_t_segment[] = {"timing"}; | |
enum class atok_t_segment {ID, NAME}; | |
const char *atok_lookup_t_segment[] = {"id", "name"}; | |
enum class atok_t_pin {PTC}; | |
const char *atok_lookup_t_pin[] = {"ptc"}; | |
enum class gtok_t_pin_class {PIN}; | |
const char *gtok_lookup_t_pin_class[] = {"pin"}; | |
enum class atok_t_pin_class {TYPE}; | |
const char *atok_lookup_t_pin_class[] = {"type"}; | |
enum class atok_t_meta {NAME, X_OFFSET, Y_OFFSET}; | |
const char *atok_lookup_t_meta[] = {"name", "x_offset", "y_offset"}; | |
enum class gtok_t_metadata {META}; | |
const char *gtok_lookup_t_metadata[] = {"meta"}; | |
enum class gtok_t_block_type {PIN_CLASS}; | |
const char *gtok_lookup_t_block_type[] = {"pin_class"}; | |
enum class atok_t_block_type {HEIGHT, ID, NAME, WIDTH}; | |
const char *atok_lookup_t_block_type[] = {"height", "id", "name", "width"}; | |
enum class atok_t_grid_loc {BLOCK_TYPE_ID, HEIGHT_OFFSET, WIDTH_OFFSET, X, Y}; | |
const char *atok_lookup_t_grid_loc[] = {"block_type_id", "height_offset", "width_offset", "x", "y"}; | |
enum class atok_t_node_loc {PTC, SIDE, XHIGH, XLOW, YHIGH, YLOW}; | |
const char *atok_lookup_t_node_loc[] = {"ptc", "side", "xhigh", "xlow", "yhigh", "ylow"}; | |
enum class atok_t_node_timing {C, R}; | |
const char *atok_lookup_t_node_timing[] = {"C", "R"}; | |
enum class atok_t_node_segment {SEGMENT_ID}; | |
const char *atok_lookup_t_node_segment[] = {"segment_id"}; | |
enum class gtok_t_node {LOC, METADATA, SEGMENT, TIMING}; | |
const char *gtok_lookup_t_node[] = {"loc", "metadata", "segment", "timing"}; | |
enum class atok_t_node {CAPACITY, DIRECTION, ID, TYPE}; | |
const char *atok_lookup_t_node[] = {"capacity", "direction", "id", "type"}; | |
enum class gtok_t_edge {METADATA}; | |
const char *gtok_lookup_t_edge[] = {"metadata"}; | |
enum class atok_t_edge {ID, SINK_NODE, SRC_NODE, SWITCH_ID}; | |
const char *atok_lookup_t_edge[] = {"id", "sink_node", "src_node", "switch_id"}; | |
enum class gtok_t_channels {CHANNEL, X_LIST, Y_LIST}; | |
const char *gtok_lookup_t_channels[] = {"channel", "x_list", "y_list"}; | |
enum class gtok_t_switches {SWITCH}; | |
const char *gtok_lookup_t_switches[] = {"switch"}; | |
enum class gtok_t_segments {SEGMENT}; | |
const char *gtok_lookup_t_segments[] = {"segment"}; | |
enum class gtok_t_block_types {BLOCK_TYPE}; | |
const char *gtok_lookup_t_block_types[] = {"block_type"}; | |
enum class gtok_t_grid_locs {GRID_LOC}; | |
const char *gtok_lookup_t_grid_locs[] = {"grid_loc"}; | |
enum class gtok_t_rr_nodes {NODE}; | |
const char *gtok_lookup_t_rr_nodes[] = {"node"}; | |
enum class gtok_t_rr_edges {EDGE}; | |
const char *gtok_lookup_t_rr_edges[] = {"edge"}; | |
enum class gtok_t_rr_graph {BLOCK_TYPES, CHANNELS, GRID, RR_EDGES, RR_NODES, SEGMENTS, SWITCHES}; | |
const char *gtok_lookup_t_rr_graph[] = {"block_types", "channels", "grid", "rr_edges", "rr_nodes", "segments", "switches"}; | |
enum class atok_t_rr_graph {TOOL_COMMENT, TOOL_NAME, TOOL_VERSION}; | |
const char *atok_lookup_t_rr_graph[] = {"tool_comment", "tool_name", "tool_version"}; | |
/** | |
* Lexing functions. These convert the const char *s of PugiXML to enums. | |
* You may find numerous "break"s there. Without them, a warning explosion ensues. | |
**/ | |
inline enum_switch_type lex_switch_type(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_switch_type."); | |
} | |
inline enum_pin_type lex_pin_type(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_pin_type."); | |
} | |
inline enum_loc_side lex_loc_side(const char *in){ | |
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; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_loc_side."); | |
} | |
inline enum_node_direction lex_node_direction(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_node_direction."); | |
} | |
inline enum_node_type lex_node_type(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_node_type."); | |
} | |
inline atok_t_channel alex_t_channel(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <channel>."); | |
} | |
inline atok_t_x_list alex_t_x_list(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <x_list>."); | |
} | |
inline atok_t_y_list alex_t_y_list(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <y_list>."); | |
} | |
inline atok_t_timing alex_t_timing(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <timing>."); | |
} | |
inline atok_t_sizing alex_t_sizing(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <sizing>."); | |
} | |
inline gtok_t_switch glex_t_switch(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <switch>."); | |
} | |
inline atok_t_switch alex_t_switch(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <switch>."); | |
} | |
inline atok_t_segment_timing alex_t_segment_timing(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <segment_timing>."); | |
} | |
inline gtok_t_segment glex_t_segment(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <segment>."); | |
} | |
inline atok_t_segment alex_t_segment(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <segment>."); | |
} | |
inline atok_t_pin alex_t_pin(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <pin>."); | |
} | |
inline gtok_t_pin_class glex_t_pin_class(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <pin_class>."); | |
} | |
inline atok_t_pin_class alex_t_pin_class(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <pin_class>."); | |
} | |
inline atok_t_meta alex_t_meta(const char *in){ | |
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; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('x', 0, 64) | onechar('_', 8, 64) | onechar('o', 16, 64) | onechar('f', 24, 64) | onechar('f', 32, 64) | onechar('s', 40, 64) | onechar('e', 48, 64) | onechar('t', 56, 64): | |
return atok_t_meta::X_OFFSET; | |
break; | |
case onechar('y', 0, 64) | onechar('_', 8, 64) | onechar('o', 16, 64) | onechar('f', 24, 64) | onechar('f', 32, 64) | onechar('s', 40, 64) | onechar('e', 48, 64) | onechar('t', 56, 64): | |
return atok_t_meta::Y_OFFSET; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <meta>."); | |
} | |
inline gtok_t_metadata glex_t_metadata(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <metadata>."); | |
} | |
inline gtok_t_block_type glex_t_block_type(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <block_type>."); | |
} | |
inline atok_t_block_type alex_t_block_type(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <block_type>."); | |
} | |
inline atok_t_grid_loc alex_t_grid_loc(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <grid_loc>."); | |
} | |
inline atok_t_node_loc alex_t_node_loc(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_loc>."); | |
} | |
inline atok_t_node_timing alex_t_node_timing(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_timing>."); | |
} | |
inline atok_t_node_segment alex_t_node_segment(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_segment>."); | |
} | |
inline gtok_t_node glex_t_node(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <node>."); | |
} | |
inline atok_t_node alex_t_node(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node>."); | |
} | |
inline gtok_t_edge glex_t_edge(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <edge>."); | |
} | |
inline atok_t_edge alex_t_edge(const char *in){ | |
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_edge::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <edge>."); | |
} | |
inline gtok_t_channels glex_t_channels(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <channels>."); | |
} | |
inline gtok_t_switches glex_t_switches(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <switches>."); | |
} | |
inline gtok_t_segments glex_t_segments(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <segments>."); | |
} | |
inline gtok_t_block_types glex_t_block_types(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <block_types>."); | |
} | |
inline gtok_t_grid_locs glex_t_grid_locs(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <grid_locs>."); | |
} | |
inline gtok_t_rr_nodes glex_t_rr_nodes(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_nodes>."); | |
} | |
inline gtok_t_rr_edges glex_t_rr_edges(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_edges>."); | |
} | |
inline gtok_t_rr_graph glex_t_rr_graph(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_graph>."); | |
} | |
inline atok_t_rr_graph alex_t_rr_graph(const char *in){ | |
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; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <rr_graph>."); | |
} | |
/* runtime error for state machines */ | |
void dfa_error(const char *wrong, int *states, const char **lookup, int len){ | |
std::vector<std::string> expected; | |
for(int i=0; i<len; i++){ | |
if(states[i] != -1) expected.push_back(lookup[i]); | |
} | |
std::string expected_or = expected[0]; | |
for(unsigned int i=1; i<expected.size(); i++) | |
expected_or += std::string(" or ") + expected[i]; | |
throw std::runtime_error("Expected " + expected_or + ", found " + std::string(wrong)); | |
} | |
/* runtime error for attributes */ | |
template<std::size_t N> | |
void attr_error(std::bitset<N> astate, const char **lookup){ | |
std::vector<std::string> missing; | |
for(unsigned int i=0; i<astate.size(); i++){ | |
if(astate[i] == 0) missing.push_back(lookup[i]); | |
} | |
std::string missing_and = missing[0]; | |
for(unsigned int i=1; i<missing.size(); i++) | |
missing_and += std::string(" and ") + missing[i]; | |
throw std::runtime_error("Didn't find required attributes " + missing_and + "."); | |
} | |
/** | |
* Validating&counting functions. These do the tree validation and count elements to allocate arenas. | |
**/ | |
void count_channel(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <channel>."); | |
} | |
void count_x_list(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <x_list>."); | |
} | |
void count_y_list(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <y_list>."); | |
} | |
void count_timing(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <timing>."); | |
} | |
void count_sizing(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <sizing>."); | |
} | |
int gstate_t_switch[2][2] = { | |
{0, 0}, | |
{0, 0}, | |
}; | |
void count_switch(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switch in = glex_t_switch(node.name()); | |
next = gstate_t_switch[state][(int)in]; | |
if(next == -1) dfa_error(gtok_lookup_t_switch[(int)in], gstate_t_switch[state], gtok_lookup_t_switch, 2); | |
state = next; | |
switch(in){ | |
case gtok_t_switch::SIZING: | |
count_sizing(node); | |
g_num_sizing++; | |
break; | |
case gtok_t_switch::TIMING: | |
count_timing(node); | |
g_num_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_switch[state], gtok_lookup_t_switch, 2); | |
} | |
void count_segment_timing(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <segment_timing>."); | |
} | |
int gstate_t_segment[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_segment(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segment in = glex_t_segment(node.name()); | |
next = gstate_t_segment[state][(int)in]; | |
if(next == -1) dfa_error(gtok_lookup_t_segment[(int)in], gstate_t_segment[state], gtok_lookup_t_segment, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_segment::TIMING: | |
count_segment_timing(node); | |
g_num_segment_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_segment[state], gtok_lookup_t_segment, 1); | |
} | |
void count_pin(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <pin>."); | |
} | |
int gstate_t_pin_class[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_pin_class(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_pin_class in = glex_t_pin_class(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_pin_class::PIN: | |
count_pin(node); | |
g_num_pin++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1); | |
} | |
void count_meta(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <meta>."); | |
} | |
int gstate_t_metadata[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_metadata(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_metadata in = glex_t_metadata(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_metadata::META: | |
count_meta(node); | |
g_num_meta++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_metadata[state], gtok_lookup_t_metadata, 1); | |
} | |
int gstate_t_block_type[1][1] = { | |
{0}, | |
}; | |
void count_block_type(const pugi::xml_node &root){ | |
int next, state=0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_type in = glex_t_block_type(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_block_type::PIN_CLASS: | |
count_pin_class(node); | |
g_num_pin_class++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_block_type[state], gtok_lookup_t_block_type, 1); | |
} | |
void count_grid_loc(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <grid_loc>."); | |
} | |
void count_node_loc(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <node_loc>."); | |
} | |
void count_node_timing(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <node_timing>."); | |
} | |
void count_node_segment(const pugi::xml_node &root){ | |
if(root.first_child().type() == pugi::node_element) throw std::runtime_error("Unexpected child element in <node_segment>."); | |
} | |
int gstate_t_node[2][4] = { | |
{0, 0, 0, 0}, | |
{0, 0, 0, 0}, | |
}; | |
void count_node(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_node in = glex_t_node(node.name()); | |
next = gstate_t_node[state][(int)in]; | |
if(next == -1) dfa_error(gtok_lookup_t_node[(int)in], gstate_t_node[state], gtok_lookup_t_node, 4); | |
state = next; | |
switch(in){ | |
case gtok_t_node::LOC: | |
count_node_loc(node); | |
g_num_node_loc++; | |
break; | |
case gtok_t_node::METADATA: | |
count_metadata(node); | |
g_num_metadata++; | |
break; | |
case gtok_t_node::SEGMENT: | |
count_node_segment(node); | |
g_num_node_segment++; | |
break; | |
case gtok_t_node::TIMING: | |
count_node_timing(node); | |
g_num_node_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_node[state], gtok_lookup_t_node, 4); | |
} | |
int gstate_t_edge[1][1] = { | |
{0}, | |
}; | |
void count_edge(const pugi::xml_node &root){ | |
int next, state=0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_edge in = glex_t_edge(node.name()); | |
next = gstate_t_edge[state][(int)in]; | |
if(next == -1) dfa_error(gtok_lookup_t_edge[(int)in], gstate_t_edge[state], gtok_lookup_t_edge, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_edge::METADATA: | |
count_metadata(node); | |
g_num_metadata++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_edge[state], gtok_lookup_t_edge, 1); | |
} | |
int gstate_t_channels[2][3] = { | |
{0, 0, 0}, | |
{0, 0, 0}, | |
}; | |
void count_channels(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_channels in = glex_t_channels(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_channels::CHANNEL: | |
count_channel(node); | |
g_num_channel++; | |
break; | |
case gtok_t_channels::X_LIST: | |
count_x_list(node); | |
g_num_x_list++; | |
break; | |
case gtok_t_channels::Y_LIST: | |
count_y_list(node); | |
g_num_y_list++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_channels[state], gtok_lookup_t_channels, 3); | |
} | |
int gstate_t_switches[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_switches(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switches in = glex_t_switches(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_switches::SWITCH: | |
count_switch(node); | |
g_num_switch++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_switches[state], gtok_lookup_t_switches, 1); | |
} | |
int gstate_t_segments[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_segments(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segments in = glex_t_segments(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_segments::SEGMENT: | |
count_segment(node); | |
g_num_segment++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_segments[state], gtok_lookup_t_segments, 1); | |
} | |
int gstate_t_block_types[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_block_types(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_types in = glex_t_block_types(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_block_types::BLOCK_TYPE: | |
count_block_type(node); | |
g_num_block_type++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_block_types[state], gtok_lookup_t_block_types, 1); | |
} | |
int gstate_t_grid_locs[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_grid_locs(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_grid_locs in = glex_t_grid_locs(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_grid_locs::GRID_LOC: | |
count_grid_loc(node); | |
g_num_grid_loc++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1); | |
} | |
int gstate_t_rr_nodes[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_rr_nodes(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_nodes in = glex_t_rr_nodes(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_rr_nodes::NODE: | |
count_node(node); | |
g_num_node++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1); | |
} | |
int gstate_t_rr_edges[2][1] = { | |
{0}, | |
{0}, | |
}; | |
void count_rr_edges(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_edges in = glex_t_rr_edges(node.name()); | |
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); | |
state = next; | |
switch(in){ | |
case gtok_t_rr_edges::EDGE: | |
count_edge(node); | |
g_num_edge++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1); | |
} | |
int gstate_t_rr_graph[2][7] = { | |
{0, 0, 0, 0, 0, 0, 0}, | |
{0, 0, 0, 0, 0, 0, 0}, | |
}; | |
void count_rr_graph(const pugi::xml_node &root){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_graph in = glex_t_rr_graph(node.name()); | |
next = gstate_t_rr_graph[state][(int)in]; | |
if(next == -1) dfa_error(gtok_lookup_t_rr_graph[(int)in], gstate_t_rr_graph[state], gtok_lookup_t_rr_graph, 7); | |
state = next; | |
switch(in){ | |
case gtok_t_rr_graph::BLOCK_TYPES: | |
count_block_types(node); | |
g_num_block_types++; | |
break; | |
case gtok_t_rr_graph::CHANNELS: | |
count_channels(node); | |
g_num_channels++; | |
break; | |
case gtok_t_rr_graph::GRID: | |
count_grid_locs(node); | |
g_num_grid_locs++; | |
break; | |
case gtok_t_rr_graph::RR_EDGES: | |
count_rr_edges(node); | |
g_num_rr_edges++; | |
break; | |
case gtok_t_rr_graph::RR_NODES: | |
count_rr_nodes(node); | |
g_num_rr_nodes++; | |
break; | |
case gtok_t_rr_graph::SEGMENTS: | |
count_segments(node); | |
g_num_segments++; | |
break; | |
case gtok_t_rr_graph::SWITCHES: | |
count_switches(node); | |
g_num_switches++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_rr_graph[state], gtok_lookup_t_rr_graph, 7); | |
} | |
/** | |
* This allocates space for the complex types which can occur more than once. | |
* It resets the global type counters for use with loading functions. | |
**/ | |
void alloc_arenas(void){ | |
if(!(block_type_arena = (t_block_type *)std::calloc(g_num_block_type, sizeof(t_block_type)))) | |
throw std::runtime_error("Couldn't get memory for <block_type> arena."); | |
if(!(block_types_arena = (t_block_types *)std::calloc(g_num_block_types, sizeof(t_block_types)))) | |
throw std::runtime_error("Couldn't get memory for <block_types> arena."); | |
if(!(channel_arena = (t_channel *)std::calloc(g_num_channel, sizeof(t_channel)))) | |
throw std::runtime_error("Couldn't get memory for <channel> arena."); | |
if(!(channels_arena = (t_channels *)std::calloc(g_num_channels, sizeof(t_channels)))) | |
throw std::runtime_error("Couldn't get memory for <channels> arena."); | |
if(!(edge_arena = (t_edge *)std::calloc(g_num_edge, sizeof(t_edge)))) | |
throw std::runtime_error("Couldn't get memory for <edge> arena."); | |
if(!(grid_loc_arena = (t_grid_loc *)std::calloc(g_num_grid_loc, sizeof(t_grid_loc)))) | |
throw std::runtime_error("Couldn't get memory for <grid_loc> arena."); | |
if(!(grid_locs_arena = (t_grid_locs *)std::calloc(g_num_grid_locs, sizeof(t_grid_locs)))) | |
throw std::runtime_error("Couldn't get memory for <grid_locs> arena."); | |
if(!(meta_arena = (t_meta *)std::calloc(g_num_meta, sizeof(t_meta)))) | |
throw std::runtime_error("Couldn't get memory for <meta> arena."); | |
if(!(metadata_arena = (t_metadata *)std::calloc(g_num_metadata, sizeof(t_metadata)))) | |
throw std::runtime_error("Couldn't get memory for <metadata> arena."); | |
if(!(node_arena = (t_node *)std::calloc(g_num_node, sizeof(t_node)))) | |
throw std::runtime_error("Couldn't get memory for <node> arena."); | |
if(!(node_loc_arena = (t_node_loc *)std::calloc(g_num_node_loc, sizeof(t_node_loc)))) | |
throw std::runtime_error("Couldn't get memory for <node_loc> arena."); | |
if(!(node_segment_arena = (t_node_segment *)std::calloc(g_num_node_segment, sizeof(t_node_segment)))) | |
throw std::runtime_error("Couldn't get memory for <node_segment> arena."); | |
if(!(node_timing_arena = (t_node_timing *)std::calloc(g_num_node_timing, sizeof(t_node_timing)))) | |
throw std::runtime_error("Couldn't get memory for <node_timing> arena."); | |
if(!(pin_arena = (t_pin *)std::calloc(g_num_pin, sizeof(t_pin)))) | |
throw std::runtime_error("Couldn't get memory for <pin> arena."); | |
if(!(pin_class_arena = (t_pin_class *)std::calloc(g_num_pin_class, sizeof(t_pin_class)))) | |
throw std::runtime_error("Couldn't get memory for <pin_class> arena."); | |
if(!(rr_edges_arena = (t_rr_edges *)std::calloc(g_num_rr_edges, sizeof(t_rr_edges)))) | |
throw std::runtime_error("Couldn't get memory for <rr_edges> arena."); | |
if(!(rr_nodes_arena = (t_rr_nodes *)std::calloc(g_num_rr_nodes, sizeof(t_rr_nodes)))) | |
throw std::runtime_error("Couldn't get memory for <rr_nodes> arena."); | |
if(!(segment_arena = (t_segment *)std::calloc(g_num_segment, sizeof(t_segment)))) | |
throw std::runtime_error("Couldn't get memory for <segment> arena."); | |
if(!(segment_timing_arena = (t_segment_timing *)std::calloc(g_num_segment_timing, sizeof(t_segment_timing)))) | |
throw std::runtime_error("Couldn't get memory for <segment_timing> arena."); | |
if(!(segments_arena = (t_segments *)std::calloc(g_num_segments, sizeof(t_segments)))) | |
throw std::runtime_error("Couldn't get memory for <segments> arena."); | |
if(!(sizing_arena = (t_sizing *)std::calloc(g_num_sizing, sizeof(t_sizing)))) | |
throw std::runtime_error("Couldn't get memory for <sizing> arena."); | |
if(!(switch_arena = (t_switch *)std::calloc(g_num_switch, sizeof(t_switch)))) | |
throw std::runtime_error("Couldn't get memory for <switch> arena."); | |
if(!(switches_arena = (t_switches *)std::calloc(g_num_switches, sizeof(t_switches)))) | |
throw std::runtime_error("Couldn't get memory for <switches> arena."); | |
if(!(timing_arena = (t_timing *)std::calloc(g_num_timing, sizeof(t_timing)))) | |
throw std::runtime_error("Couldn't get memory for <timing> arena."); | |
if(!(x_list_arena = (t_x_list *)std::calloc(g_num_x_list, sizeof(t_x_list)))) | |
throw std::runtime_error("Couldn't get memory for <x_list> arena."); | |
if(!(y_list_arena = (t_y_list *)std::calloc(g_num_y_list, sizeof(t_y_list)))) | |
throw std::runtime_error("Couldn't get memory for <y_list> arena."); | |
g_num_block_type = 0; | |
g_num_block_types = 0; | |
g_num_channel = 0; | |
g_num_channels = 0; | |
g_num_edge = 0; | |
g_num_grid_loc = 0; | |
g_num_grid_locs = 0; | |
g_num_meta = 0; | |
g_num_metadata = 0; | |
g_num_node = 0; | |
g_num_node_loc = 0; | |
g_num_node_segment = 0; | |
g_num_node_timing = 0; | |
g_num_pin = 0; | |
g_num_pin_class = 0; | |
g_num_rr_edges = 0; | |
g_num_rr_nodes = 0; | |
g_num_segment = 0; | |
g_num_segment_timing = 0; | |
g_num_segments = 0; | |
g_num_sizing = 0; | |
g_num_switch = 0; | |
g_num_switches = 0; | |
g_num_timing = 0; | |
g_num_x_list = 0; | |
g_num_y_list = 0; | |
} | |
/** | |
* Loading functions. These load the DOM data into the generated structures. | |
**/ | |
void load_channel(const pugi::xml_node &root, t_channel *out){ | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_channel in = alex_t_channel(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <channel>."); | |
switch(in){ | |
case atok_t_channel::CHAN_WIDTH_MAX: | |
out->chan_width_max = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_channel::X_MAX: | |
out->x_max = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_channel::X_MIN: | |
out->x_min = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_channel::Y_MAX: | |
out->y_max = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_channel::Y_MIN: | |
out->y_min = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_state = astate | std::bitset<5>(0b00000); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_channel); | |
} | |
void load_x_list(const pugi::xml_node &root, t_x_list *out){ | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_x_list in = alex_t_x_list(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <x_list>."); | |
switch(in){ | |
case atok_t_x_list::INDEX: | |
out->index = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_x_list::INFO: | |
out->info = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b00); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_x_list); | |
} | |
void load_y_list(const pugi::xml_node &root, t_y_list *out){ | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_y_list in = alex_t_y_list(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <y_list>."); | |
switch(in){ | |
case atok_t_y_list::INDEX: | |
out->index = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_y_list::INFO: | |
out->info = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b00); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_y_list); | |
} | |
void load_timing(const pugi::xml_node &root, t_timing *out){ | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_timing in = alex_t_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <timing>."); | |
switch(in){ | |
case atok_t_timing::CIN: | |
out->Cin = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_timing::CINTERNAL: | |
out->Cinternal = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_timing::COUT: | |
out->Cout = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_timing::R: | |
out->R = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_timing::TDEL: | |
out->Tdel = std::strtod(attr.value(), NULL); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_state = astate | std::bitset<5>(0b11111); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_timing); | |
} | |
void load_sizing(const pugi::xml_node &root, t_sizing *out){ | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_sizing in = alex_t_sizing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <sizing>."); | |
switch(in){ | |
case atok_t_sizing::BUF_SIZE: | |
out->buf_size = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_sizing::MUX_TRANS_SIZE: | |
out->mux_trans_size = std::strtod(attr.value(), NULL); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b00); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_sizing); | |
} | |
void load_switch(const pugi::xml_node &root, t_switch *out){ | |
out->sizing_list = &sizing_arena[g_num_sizing]; | |
out->timing_list = &timing_arena[g_num_timing]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switch in = glex_t_switch(node.name()); | |
switch(in){ | |
case gtok_t_switch::SIZING: | |
load_sizing(node, &sizing_arena[g_num_sizing]); | |
g_num_sizing++; | |
out->num_sizing++; | |
break; | |
case gtok_t_switch::TIMING: | |
load_timing(node, &timing_arena[g_num_timing]); | |
g_num_timing++; | |
out->num_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_switch in = alex_t_switch(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <switch>."); | |
switch(in){ | |
case atok_t_switch::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_switch::NAME: | |
out->name = strdup(attr.value()); | |
break; | |
case atok_t_switch::TYPE: | |
out->type = lex_switch_type(attr.value()); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_state = astate | std::bitset<3>(0b100); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_switch); | |
} | |
void load_segment_timing(const pugi::xml_node &root, t_segment_timing *out){ | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_segment_timing in = alex_t_segment_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <segment_timing>."); | |
switch(in){ | |
case atok_t_segment_timing::C_PER_METER: | |
out->C_per_meter = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_segment_timing::R_PER_METER: | |
out->R_per_meter = std::strtod(attr.value(), NULL); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b11); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_segment_timing); | |
} | |
void load_segment(const pugi::xml_node &root, t_segment *out){ | |
out->timing_list = &segment_timing_arena[g_num_segment_timing]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segment in = glex_t_segment(node.name()); | |
switch(in){ | |
case gtok_t_segment::TIMING: | |
load_segment_timing(node, &segment_timing_arena[g_num_segment_timing]); | |
g_num_segment_timing++; | |
out->num_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_segment in = alex_t_segment(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <segment>."); | |
switch(in){ | |
case atok_t_segment::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_segment::NAME: | |
out->name = strdup(attr.value()); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b00); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_segment); | |
} | |
void load_pin(const pugi::xml_node &root, t_pin *out){ | |
out->value = strdup(root.child_value()); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_pin in = alex_t_pin(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <pin>."); | |
switch(in){ | |
case atok_t_pin::PTC: | |
out->ptc = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_state = astate | std::bitset<1>(0b0); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_pin); | |
} | |
void load_pin_class(const pugi::xml_node &root, t_pin_class *out){ | |
out->pin_list = &pin_arena[g_num_pin]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_pin_class in = glex_t_pin_class(node.name()); | |
switch(in){ | |
case gtok_t_pin_class::PIN: | |
load_pin(node, &pin_arena[g_num_pin]); | |
g_num_pin++; | |
out->num_pin++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_pin_class in = alex_t_pin_class(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <pin_class>."); | |
switch(in){ | |
case atok_t_pin_class::TYPE: | |
out->type = lex_pin_type(attr.value()); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_state = astate | std::bitset<1>(0b0); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_pin_class); | |
} | |
void load_meta(const pugi::xml_node &root, t_meta *out){ | |
out->value = strdup(root.child_value()); | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_meta in = alex_t_meta(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <meta>."); | |
switch(in){ | |
case atok_t_meta::NAME: | |
out->name = strdup(attr.value()); | |
break; | |
case atok_t_meta::X_OFFSET: | |
out->x_offset = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_meta::Y_OFFSET: | |
out->y_offset = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_state = astate | std::bitset<3>(0b110); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_meta); | |
} | |
void load_metadata(const pugi::xml_node &root, t_metadata *out){ | |
out->meta_list = &meta_arena[g_num_meta]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_metadata in = glex_t_metadata(node.name()); | |
switch(in){ | |
case gtok_t_metadata::META: | |
load_meta(node, &meta_arena[g_num_meta]); | |
g_num_meta++; | |
out->num_meta++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <metadata>."); | |
} | |
void load_block_type(const pugi::xml_node &root, t_block_type *out){ | |
out->pin_class_list = &pin_class_arena[g_num_pin_class]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_type in = glex_t_block_type(node.name()); | |
switch(in){ | |
case gtok_t_block_type::PIN_CLASS: | |
load_pin_class(node, &pin_class_arena[g_num_pin_class]); | |
g_num_pin_class++; | |
out->num_pin_class++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_block_type in = alex_t_block_type(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <block_type>."); | |
switch(in){ | |
case atok_t_block_type::HEIGHT: | |
out->height = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_block_type::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_block_type::NAME: | |
out->name = strdup(attr.value()); | |
break; | |
case atok_t_block_type::WIDTH: | |
out->width = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_state = astate | std::bitset<4>(0b0000); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_block_type); | |
} | |
void load_grid_loc(const pugi::xml_node &root, t_grid_loc *out){ | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_grid_loc in = alex_t_grid_loc(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <grid_loc>."); | |
switch(in){ | |
case atok_t_grid_loc::BLOCK_TYPE_ID: | |
out->block_type_id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_grid_loc::HEIGHT_OFFSET: | |
out->height_offset = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_grid_loc::WIDTH_OFFSET: | |
out->width_offset = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_grid_loc::X: | |
out->x = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_grid_loc::Y: | |
out->y = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_state = astate | std::bitset<5>(0b00000); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_grid_loc); | |
} | |
void load_node_loc(const pugi::xml_node &root, t_node_loc *out){ | |
std::bitset<6> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_loc in = alex_t_node_loc(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_loc>."); | |
switch(in){ | |
case atok_t_node_loc::PTC: | |
out->ptc = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node_loc::SIDE: | |
out->side = lex_loc_side(attr.value()); | |
break; | |
case atok_t_node_loc::XHIGH: | |
out->xhigh = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node_loc::XLOW: | |
out->xlow = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node_loc::YHIGH: | |
out->yhigh = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node_loc::YLOW: | |
out->ylow = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<6> test_state = astate | std::bitset<6>(0b000010); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_node_loc); | |
} | |
void load_node_timing(const pugi::xml_node &root, t_node_timing *out){ | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_timing in = alex_t_node_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_timing>."); | |
switch(in){ | |
case atok_t_node_timing::C: | |
out->C = std::strtod(attr.value(), NULL); | |
break; | |
case atok_t_node_timing::R: | |
out->R = std::strtod(attr.value(), NULL); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = astate | std::bitset<2>(0b00); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_node_timing); | |
} | |
void load_node_segment(const pugi::xml_node &root, t_node_segment *out){ | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_segment in = alex_t_node_segment(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_segment>."); | |
switch(in){ | |
case atok_t_node_segment::SEGMENT_ID: | |
out->segment_id = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_state = astate | std::bitset<1>(0b0); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_node_segment); | |
} | |
void load_node(const pugi::xml_node &root, t_node *out){ | |
out->loc_list = &node_loc_arena[g_num_node_loc]; | |
out->metadata_list = &metadata_arena[g_num_metadata]; | |
out->segment_list = &node_segment_arena[g_num_node_segment]; | |
out->timing_list = &node_timing_arena[g_num_node_timing]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_node in = glex_t_node(node.name()); | |
switch(in){ | |
case gtok_t_node::LOC: | |
load_node_loc(node, &node_loc_arena[g_num_node_loc]); | |
g_num_node_loc++; | |
out->num_loc++; | |
break; | |
case gtok_t_node::METADATA: | |
load_metadata(node, &metadata_arena[g_num_metadata]); | |
g_num_metadata++; | |
out->num_metadata++; | |
break; | |
case gtok_t_node::SEGMENT: | |
load_node_segment(node, &node_segment_arena[g_num_node_segment]); | |
g_num_node_segment++; | |
out->num_segment++; | |
break; | |
case gtok_t_node::TIMING: | |
load_node_timing(node, &node_timing_arena[g_num_node_timing]); | |
g_num_node_timing++; | |
out->num_timing++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node in = alex_t_node(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node>."); | |
switch(in){ | |
case atok_t_node::CAPACITY: | |
out->capacity = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node::DIRECTION: | |
out->direction = lex_node_direction(attr.value()); | |
break; | |
case atok_t_node::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_node::TYPE: | |
out->type = lex_node_type(attr.value()); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_state = astate | std::bitset<4>(0b0010); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_node); | |
} | |
void load_edge(const pugi::xml_node &root, t_edge *out){ | |
out->metadata_list = &metadata_arena[g_num_metadata]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_edge in = glex_t_edge(node.name()); | |
switch(in){ | |
case gtok_t_edge::METADATA: | |
load_metadata(node, &metadata_arena[g_num_metadata]); | |
g_num_metadata++; | |
out->num_metadata++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_edge in = alex_t_edge(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <edge>."); | |
switch(in){ | |
case atok_t_edge::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_edge::SINK_NODE: | |
out->sink_node = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_edge::SRC_NODE: | |
out->src_node = std::strtol(attr.value(), NULL, 10); | |
break; | |
case atok_t_edge::SWITCH_ID: | |
out->switch_id = std::strtol(attr.value(), NULL, 10); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_state = astate | std::bitset<4>(0b0001); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_edge); | |
} | |
void load_channels(const pugi::xml_node &root, t_channels *out){ | |
out->channel_list = &channel_arena[g_num_channel]; | |
out->x_list_list = &x_list_arena[g_num_x_list]; | |
out->y_list_list = &y_list_arena[g_num_y_list]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_channels in = glex_t_channels(node.name()); | |
switch(in){ | |
case gtok_t_channels::CHANNEL: | |
load_channel(node, &channel_arena[g_num_channel]); | |
g_num_channel++; | |
out->num_channel++; | |
break; | |
case gtok_t_channels::X_LIST: | |
load_x_list(node, &x_list_arena[g_num_x_list]); | |
g_num_x_list++; | |
out->num_x_list++; | |
break; | |
case gtok_t_channels::Y_LIST: | |
load_y_list(node, &y_list_arena[g_num_y_list]); | |
g_num_y_list++; | |
out->num_y_list++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <channels>."); | |
} | |
void load_switches(const pugi::xml_node &root, t_switches *out){ | |
out->switch_list = &switch_arena[g_num_switch]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switches in = glex_t_switches(node.name()); | |
switch(in){ | |
case gtok_t_switches::SWITCH: | |
load_switch(node, &switch_arena[g_num_switch]); | |
g_num_switch++; | |
out->num_switch++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <switches>."); | |
} | |
void load_segments(const pugi::xml_node &root, t_segments *out){ | |
out->segment_list = &segment_arena[g_num_segment]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segments in = glex_t_segments(node.name()); | |
switch(in){ | |
case gtok_t_segments::SEGMENT: | |
load_segment(node, &segment_arena[g_num_segment]); | |
g_num_segment++; | |
out->num_segment++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <segments>."); | |
} | |
void load_block_types(const pugi::xml_node &root, t_block_types *out){ | |
out->block_type_list = &block_type_arena[g_num_block_type]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_types in = glex_t_block_types(node.name()); | |
switch(in){ | |
case gtok_t_block_types::BLOCK_TYPE: | |
load_block_type(node, &block_type_arena[g_num_block_type]); | |
g_num_block_type++; | |
out->num_block_type++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <block_types>."); | |
} | |
void load_grid_locs(const pugi::xml_node &root, t_grid_locs *out){ | |
out->grid_loc_list = &grid_loc_arena[g_num_grid_loc]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_grid_locs in = glex_t_grid_locs(node.name()); | |
switch(in){ | |
case gtok_t_grid_locs::GRID_LOC: | |
load_grid_loc(node, &grid_loc_arena[g_num_grid_loc]); | |
g_num_grid_loc++; | |
out->num_grid_loc++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <grid_locs>."); | |
} | |
void load_rr_nodes(const pugi::xml_node &root, t_rr_nodes *out){ | |
out->node_list = &node_arena[g_num_node]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_nodes in = glex_t_rr_nodes(node.name()); | |
switch(in){ | |
case gtok_t_rr_nodes::NODE: | |
load_node(node, &node_arena[g_num_node]); | |
g_num_node++; | |
out->num_node++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <rr_nodes>."); | |
} | |
void load_rr_edges(const pugi::xml_node &root, t_rr_edges *out){ | |
out->edge_list = &edge_arena[g_num_edge]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_edges in = glex_t_rr_edges(node.name()); | |
switch(in){ | |
case gtok_t_rr_edges::EDGE: | |
load_edge(node, &edge_arena[g_num_edge]); | |
g_num_edge++; | |
out->num_edge++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(root.first_attribute()) throw std::runtime_error("Unexpected attribute in <rr_edges>."); | |
} | |
void load_rr_graph(const pugi::xml_node &root, t_rr_graph *out){ | |
out->block_types_list = &block_types_arena[g_num_block_types]; | |
out->channels_list = &channels_arena[g_num_channels]; | |
out->grid_list = &grid_locs_arena[g_num_grid_locs]; | |
out->rr_edges_list = &rr_edges_arena[g_num_rr_edges]; | |
out->rr_nodes_list = &rr_nodes_arena[g_num_rr_nodes]; | |
out->segments_list = &segments_arena[g_num_segments]; | |
out->switches_list = &switches_arena[g_num_switches]; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_graph in = glex_t_rr_graph(node.name()); | |
switch(in){ | |
case gtok_t_rr_graph::BLOCK_TYPES: | |
load_block_types(node, &block_types_arena[g_num_block_types]); | |
g_num_block_types++; | |
out->num_block_types++; | |
break; | |
case gtok_t_rr_graph::CHANNELS: | |
load_channels(node, &channels_arena[g_num_channels]); | |
g_num_channels++; | |
out->num_channels++; | |
break; | |
case gtok_t_rr_graph::GRID: | |
load_grid_locs(node, &grid_locs_arena[g_num_grid_locs]); | |
g_num_grid_locs++; | |
out->num_grid++; | |
break; | |
case gtok_t_rr_graph::RR_EDGES: | |
load_rr_edges(node, &rr_edges_arena[g_num_rr_edges]); | |
g_num_rr_edges++; | |
out->num_rr_edges++; | |
break; | |
case gtok_t_rr_graph::RR_NODES: | |
load_rr_nodes(node, &rr_nodes_arena[g_num_rr_nodes]); | |
g_num_rr_nodes++; | |
out->num_rr_nodes++; | |
break; | |
case gtok_t_rr_graph::SEGMENTS: | |
load_segments(node, &segments_arena[g_num_segments]); | |
g_num_segments++; | |
out->num_segments++; | |
break; | |
case gtok_t_rr_graph::SWITCHES: | |
load_switches(node, &switches_arena[g_num_switches]); | |
g_num_switches++; | |
out->num_switches++; | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_rr_graph in = alex_t_rr_graph(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <rr_graph>."); | |
switch(in){ | |
case atok_t_rr_graph::TOOL_COMMENT: | |
out->tool_comment = strdup(attr.value()); | |
break; | |
case atok_t_rr_graph::TOOL_NAME: | |
out->tool_name = strdup(attr.value()); | |
break; | |
case atok_t_rr_graph::TOOL_VERSION: | |
out->tool_version = strdup(attr.value()); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_state = astate | std::bitset<3>(0b111); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_rr_graph); | |
} | |
/** | |
* Root elements. | |
**/ | |
t_rr_graph rr_graph = {}; | |
void get_root_elements(const char *filename){ | |
pugi::xml_document doc; | |
pugi::xml_parse_result result = doc.load_file(filename); | |
if(!result) | |
throw std::runtime_error("Could not load XML file " + std::string(filename) + "."); | |
for(pugi::xml_node node= doc.first_child(); node; node = node.next_sibling()){ | |
if(std::strcmp(node.name(), "rr_graph") == 0){ | |
count_rr_graph(node); | |
alloc_arenas(); | |
load_rr_graph(node, &rr_graph); | |
} | |
else throw std::runtime_error("Invalid root-level element " + std::string(node.name())); | |
} | |
} | |
} /* namespace rr_graph */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment