Created
August 1, 2019 02:34
-
-
Save duck2/80d341fb90c799f98c323c69c6886ff4 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 <iostream> | |
#include <limits> | |
#include <memory> | |
#include <string> | |
#include <vector> | |
#include <error.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include "pugixml.hpp" | |
/* | |
* This file is generated by uxsdcxx. | |
* Modify only if your build process doesn't involve regenerating this file. | |
* | |
* Cmdline: uxsdcxx.py rr_graph.xsd | |
* Input file: rr_graph.xsd | |
* md5sum of input file: 6ef4715172b99929591635a0de1e99b8 | |
*/ | |
/* 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_segment_timing; | |
struct t_pin; | |
struct t_meta; | |
struct t_grid_loc; | |
struct t_node_loc; | |
struct t_node_timing; | |
struct t_node_segment; | |
struct t_switch; | |
struct t_segment; | |
struct t_pin_class; | |
struct t_metadata; | |
struct t_channels; | |
struct t_grid_locs; | |
struct t_block_type; | |
struct t_node; | |
struct t_edge; | |
struct t_switches; | |
struct t_segments; | |
struct t_block_types; | |
struct t_rr_nodes; | |
struct t_rr_edges; | |
struct t_rr_graph; | |
enum class enum_switch_type {UXSD_INVALID = 0, MUX, TRISTATE, PASS_GATE, SHORT, BUFFER}; | |
const char *lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", "pass_gate", "short", "buffer"}; | |
enum class enum_pin_type {UXSD_INVALID = 0, OPEN, OUTPUT, INPUT}; | |
const char *lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; | |
enum class enum_loc_side {UXSD_INVALID = 0, LEFT, RIGHT, TOP, BOTTOM}; | |
const char *lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM"}; | |
enum class enum_node_type {UXSD_INVALID = 0, CHANX, CHANY, SOURCE, SINK, OPIN, IPIN}; | |
const char *lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; | |
enum class enum_node_direction {UXSD_INVALID = 0, INC_DIR, DEC_DIR, BI_DIR}; | |
const char *lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; | |
struct t_channel { | |
int chan_width_max; | |
int x_min; | |
int y_min; | |
int x_max; | |
int y_max; | |
}; | |
struct t_x_list { | |
int index; | |
int info; | |
}; | |
struct t_y_list { | |
int index; | |
int info; | |
}; | |
struct t_timing { | |
float R; | |
float Cin; | |
float Cinternal; | |
float Cout; | |
float Tdel; | |
}; | |
struct t_sizing { | |
float mux_trans_size; | |
float buf_size; | |
}; | |
struct t_segment_timing { | |
float R_per_meter; | |
float C_per_meter; | |
}; | |
struct t_pin { | |
int ptc; | |
const char * value; | |
}; | |
struct t_meta { | |
const char * name; | |
const char * value; | |
}; | |
struct t_grid_loc { | |
int x; | |
int y; | |
int block_type_id; | |
int width_offset; | |
int height_offset; | |
}; | |
struct t_node_loc { | |
int xlow; | |
int ylow; | |
int xhigh; | |
int yhigh; | |
enum_loc_side side; | |
int ptc; | |
}; | |
struct t_node_timing { | |
float R; | |
float C; | |
}; | |
struct t_node_segment { | |
int segment_id; | |
}; | |
struct t_switch { | |
int id; | |
const char * name; | |
enum_switch_type type; | |
bool has_timing; | |
t_timing timing; | |
t_sizing sizing; | |
}; | |
struct t_segment { | |
int id; | |
const char * name; | |
bool has_timing; | |
t_segment_timing timing; | |
}; | |
struct t_pin_class { | |
enum_pin_type type; | |
int num_pin; | |
t_pin * pin_list; | |
}; | |
struct t_metadata { | |
int num_meta; | |
t_meta * meta_list; | |
}; | |
struct t_channels { | |
t_channel channel; | |
int num_x_list; | |
t_x_list * x_list_list; | |
int num_y_list; | |
t_y_list * y_list_list; | |
}; | |
struct t_grid_locs { | |
int num_grid_loc; | |
t_grid_loc * grid_loc_list; | |
}; | |
struct t_block_type { | |
int id; | |
const char * name; | |
int width; | |
int height; | |
int num_pin_class; | |
t_pin_class * pin_class_list; | |
}; | |
struct t_node { | |
int id; | |
enum_node_type type; | |
enum_node_direction direction; | |
int capacity; | |
t_node_loc loc; | |
bool has_timing; | |
t_node_timing timing; | |
bool has_segment; | |
t_node_segment segment; | |
bool has_metadata; | |
t_metadata metadata; | |
}; | |
struct t_edge { | |
int id; | |
int src_node; | |
int sink_node; | |
int switch_id; | |
bool has_metadata; | |
t_metadata metadata; | |
}; | |
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_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_name; | |
const char * tool_version; | |
const char * tool_comment; | |
t_channels channels; | |
t_switches switches; | |
t_segments segments; | |
t_block_types block_types; | |
t_grid_locs grid; | |
t_rr_nodes rr_nodes; | |
t_rr_edges rr_edges; | |
}; | |
int g_num_block_type = 0; | |
t_block_type *block_type_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_meta = 0; | |
t_meta *meta_arena; | |
int g_num_node = 0; | |
t_node *node_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_segment = 0; | |
t_segment *segment_arena; | |
int g_num_switch = 0; | |
t_switch *switch_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_segment_timing(const pugi::xml_node &root); | |
void count_pin(const pugi::xml_node &root); | |
void count_meta(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_switch(const pugi::xml_node &root); | |
void count_segment(const pugi::xml_node &root); | |
void count_pin_class(const pugi::xml_node &root); | |
void count_metadata(const pugi::xml_node &root); | |
void count_channels(const pugi::xml_node &root); | |
void count_grid_locs(const pugi::xml_node &root); | |
void count_block_type(const pugi::xml_node &root); | |
void count_node(const pugi::xml_node &root); | |
void count_edge(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_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_segment_timing(const pugi::xml_node &root, t_segment_timing *out); | |
void load_pin(const pugi::xml_node &root, t_pin *out); | |
void load_meta(const pugi::xml_node &root, t_meta *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_switch(const pugi::xml_node &root, t_switch *out); | |
void load_segment(const pugi::xml_node &root, t_segment *out); | |
void load_pin_class(const pugi::xml_node &root, t_pin_class *out); | |
void load_metadata(const pugi::xml_node &root, t_metadata *out); | |
void load_channels(const pugi::xml_node &root, t_channels *out); | |
void load_grid_locs(const pugi::xml_node &root, t_grid_locs *out); | |
void load_block_type(const pugi::xml_node &root, t_block_type *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_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_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 all_error(std::bitset<N> gstate, const char **lookup); | |
template<std::size_t N> | |
void attr_error(std::bitset<N> astate, const char **lookup); | |
void alloc_arenas(void); | |
void get_root_element(const char *filename); | |
void write_root_element(std::ostream &os); | |
/** | |
* Tokens for attribute and node names. | |
**/ | |
enum class atok_t_channel {CHAN_WIDTH_MAX, X_MIN, Y_MIN, X_MAX, Y_MAX}; | |
const char *atok_lookup_t_channel[] = {"chan_width_max", "x_min", "y_min", "x_max", "y_max"}; | |
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 {R, CIN, CINTERNAL, COUT, TDEL}; | |
const char *atok_lookup_t_timing[] = {"R", "Cin", "Cinternal", "Cout", "Tdel"}; | |
enum class atok_t_sizing {MUX_TRANS_SIZE, BUF_SIZE}; | |
const char *atok_lookup_t_sizing[] = {"mux_trans_size", "buf_size"}; | |
enum class atok_t_segment_timing {R_PER_METER, C_PER_METER}; | |
const char *atok_lookup_t_segment_timing[] = {"R_per_meter", "C_per_meter"}; | |
enum class atok_t_pin {PTC}; | |
const char *atok_lookup_t_pin[] = {"ptc"}; | |
enum class atok_t_meta {NAME}; | |
const char *atok_lookup_t_meta[] = {"name"}; | |
enum class atok_t_grid_loc {X, Y, BLOCK_TYPE_ID, WIDTH_OFFSET, HEIGHT_OFFSET}; | |
const char *atok_lookup_t_grid_loc[] = {"x", "y", "block_type_id", "width_offset", "height_offset"}; | |
enum class atok_t_node_loc {XLOW, YLOW, XHIGH, YHIGH, SIDE, PTC}; | |
const char *atok_lookup_t_node_loc[] = {"xlow", "ylow", "xhigh", "yhigh", "side", "ptc"}; | |
enum class atok_t_node_timing {R, C}; | |
const char *atok_lookup_t_node_timing[] = {"R", "C"}; | |
enum class atok_t_node_segment {SEGMENT_ID}; | |
const char *atok_lookup_t_node_segment[] = {"segment_id"}; | |
enum class gtok_t_switch {TIMING, SIZING}; | |
const char *gtok_lookup_t_switch[] = {"timing", "sizing"}; | |
enum class atok_t_switch {ID, NAME, TYPE}; | |
const char *atok_lookup_t_switch[] = {"id", "name", "type"}; | |
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 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 gtok_t_metadata {META}; | |
const char *gtok_lookup_t_metadata[] = {"meta"}; | |
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_grid_locs {GRID_LOC}; | |
const char *gtok_lookup_t_grid_locs[] = {"grid_loc"}; | |
enum class gtok_t_block_type {PIN_CLASS}; | |
const char *gtok_lookup_t_block_type[] = {"pin_class"}; | |
enum class atok_t_block_type {ID, NAME, WIDTH, HEIGHT}; | |
const char *atok_lookup_t_block_type[] = {"id", "name", "width", "height"}; | |
enum class gtok_t_node {LOC, TIMING, SEGMENT, METADATA}; | |
const char *gtok_lookup_t_node[] = {"loc", "timing", "segment", "metadata"}; | |
enum class atok_t_node {ID, TYPE, DIRECTION, CAPACITY}; | |
const char *atok_lookup_t_node[] = {"id", "type", "direction", "capacity"}; | |
enum class gtok_t_edge {METADATA}; | |
const char *gtok_lookup_t_edge[] = {"metadata"}; | |
enum class atok_t_edge {ID, SRC_NODE, SINK_NODE, SWITCH_ID}; | |
const char *atok_lookup_t_edge[] = {"id", "src_node", "sink_node", "switch_id"}; | |
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_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 {CHANNELS, SWITCHES, SEGMENTS, BLOCK_TYPES, GRID, RR_NODES, RR_EDGES}; | |
const char *gtok_lookup_t_rr_graph[] = {"channels", "switches", "segments", "block_types", "grid", "rr_nodes", "rr_edges"}; | |
enum class atok_t_rr_graph {TOOL_NAME, TOOL_VERSION, TOOL_COMMENT}; | |
const char *atok_lookup_t_rr_graph[] = {"tool_name", "tool_version", "tool_comment"}; | |
/** | |
* 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, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('m', 0, 8): | |
switch(in[1]){ | |
case onechar('u', 0, 8): | |
switch(in[2]){ | |
case onechar('x', 0, 8): | |
return enum_switch_type::MUX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('h', 8, 32) | onechar('o', 16, 32) | onechar('r', 24, 32): | |
switch(in[4]){ | |
case onechar('t', 0, 8): | |
return enum_switch_type::SHORT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('b', 0, 32) | onechar('u', 8, 32) | onechar('f', 16, 32) | onechar('f', 24, 32): | |
switch(in[4]){ | |
case onechar('e', 0, 8): | |
switch(in[5]){ | |
case onechar('r', 0, 8): | |
return enum_switch_type::BUFFER; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('t', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('s', 24, 64) | onechar('t', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64): | |
return enum_switch_type::TRISTATE; | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('s', 16, 64) | onechar('s', 24, 64) | onechar('_', 32, 64) | onechar('g', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64): | |
switch(in[8]){ | |
case onechar('e', 0, 8): | |
return enum_switch_type::PASS_GATE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_switch_type."); | |
return enum_switch_type::UXSD_INVALID; | |
} | |
inline enum_pin_type lex_pin_type(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('E', 16, 32) | onechar('N', 24, 32): | |
return enum_pin_type::OPEN; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('P', 16, 32) | onechar('U', 24, 32): | |
switch(in[4]){ | |
case onechar('T', 0, 8): | |
return enum_pin_type::INPUT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('O', 0, 32) | onechar('U', 8, 32) | onechar('T', 16, 32) | onechar('P', 24, 32): | |
switch(in[4]){ | |
case onechar('U', 0, 8): | |
switch(in[5]){ | |
case onechar('T', 0, 8): | |
return enum_pin_type::OUTPUT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_pin_type."); | |
return enum_pin_type::UXSD_INVALID; | |
} | |
inline enum_loc_side lex_loc_side(const char *in, bool throw_on_invalid){ | |
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; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_loc_side."); | |
return enum_loc_side::UXSD_INVALID; | |
} | |
inline enum_node_type lex_node_type(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('I', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): | |
return enum_node_type::IPIN; | |
break; | |
case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): | |
return enum_node_type::OPIN; | |
break; | |
case onechar('S', 0, 32) | onechar('I', 8, 32) | onechar('N', 16, 32) | onechar('K', 24, 32): | |
return enum_node_type::SINK; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('C', 0, 32) | onechar('H', 8, 32) | onechar('A', 16, 32) | onechar('N', 24, 32): | |
switch(in[4]){ | |
case onechar('X', 0, 8): | |
return enum_node_type::CHANX; | |
break; | |
case onechar('Y', 0, 8): | |
return enum_node_type::CHANY; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('S', 0, 32) | onechar('O', 8, 32) | onechar('U', 16, 32) | onechar('R', 24, 32): | |
switch(in[4]){ | |
case onechar('C', 0, 8): | |
switch(in[5]){ | |
case onechar('E', 0, 8): | |
return enum_node_type::SOURCE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_node_type."); | |
return enum_node_type::UXSD_INVALID; | |
} | |
inline enum_node_direction lex_node_direction(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('B', 0, 32) | onechar('I', 8, 32) | onechar('_', 16, 32) | onechar('D', 24, 32): | |
switch(in[4]){ | |
case onechar('I', 0, 8): | |
switch(in[5]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::BI_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 7: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('D', 0, 32) | onechar('E', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): | |
switch(in[4]){ | |
case onechar('D', 0, 8): | |
switch(in[5]){ | |
case onechar('I', 0, 8): | |
switch(in[6]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::DEC_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): | |
switch(in[4]){ | |
case onechar('D', 0, 8): | |
switch(in[5]){ | |
case onechar('I', 0, 8): | |
switch(in[6]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::INC_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + "of enum_node_direction."); | |
return enum_node_direction::UXSD_INVALID; | |
} | |
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 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 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 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; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <meta>."); | |
} | |
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_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 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 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 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_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_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_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 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_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_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 <xs:choice> or <xs:sequence>s */ | |
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<N; 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(", ") + missing[i]; | |
throw std::runtime_error("Didn't find required attributes " + missing_and + "."); | |
} | |
/* runtime error for <xs:all>s */ | |
template<std::size_t N> | |
void all_error(std::bitset<N> gstate, const char **lookup){ | |
std::vector<std::string> missing; | |
for(unsigned int i=0; i<N; i++){ | |
if(gstate[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(", ") + missing[i]; | |
throw std::runtime_error("Didn't find required elements " + 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>."); | |
} | |
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>."); | |
} | |
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>."); | |
} | |
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>."); | |
} | |
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>."); | |
} | |
void count_switch(const pugi::xml_node &root){ | |
std::bitset<2> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switch in = glex_t_switch(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <switch>."); | |
switch(in){ | |
case gtok_t_switch::TIMING: | |
count_timing(node); | |
break; | |
case gtok_t_switch::SIZING: | |
count_sizing(node); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_state = gstate | std::bitset<2>(0b01); | |
if(!test_state.all()) all_error(test_state, gtok_lookup_t_switch); | |
} | |
void count_segment(const pugi::xml_node &root){ | |
std::bitset<1> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segment in = glex_t_segment(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <segment>."); | |
switch(in){ | |
case gtok_t_segment::TIMING: | |
count_segment_timing(node); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_state = gstate | std::bitset<1>(0b1); | |
if(!test_state.all()) all_error(test_state, gtok_lookup_t_segment); | |
} | |
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); | |
} | |
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_channels[4][3] = { | |
{-1, -1, 0}, | |
{-1, 1, 0}, | |
{-1, 1, -1}, | |
{2, -1, -1}, | |
}; | |
void count_channels(const pugi::xml_node &root){ | |
int next, state=3; | |
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); | |
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_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_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_node(const pugi::xml_node &root){ | |
std::bitset<4> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_node in = glex_t_node(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <node>."); | |
switch(in){ | |
case gtok_t_node::LOC: | |
count_node_loc(node); | |
break; | |
case gtok_t_node::TIMING: | |
count_node_timing(node); | |
break; | |
case gtok_t_node::SEGMENT: | |
count_node_segment(node); | |
break; | |
case gtok_t_node::METADATA: | |
count_metadata(node); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_state = gstate | std::bitset<4>(0b1110); | |
if(!test_state.all()) all_error(test_state, gtok_lookup_t_node); | |
} | |
void count_edge(const pugi::xml_node &root){ | |
std::bitset<1> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_edge in = glex_t_edge(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <edge>."); | |
switch(in){ | |
case gtok_t_edge::METADATA: | |
count_metadata(node); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_state = gstate | std::bitset<1>(0b1); | |
if(!test_state.all()) all_error(test_state, gtok_lookup_t_edge); | |
} | |
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_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); | |
} | |
void count_rr_graph(const pugi::xml_node &root){ | |
std::bitset<7> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_graph in = glex_t_rr_graph(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <rr_graph>."); | |
switch(in){ | |
case gtok_t_rr_graph::CHANNELS: | |
count_channels(node); | |
break; | |
case gtok_t_rr_graph::SWITCHES: | |
count_switches(node); | |
break; | |
case gtok_t_rr_graph::SEGMENTS: | |
count_segments(node); | |
break; | |
case gtok_t_rr_graph::BLOCK_TYPES: | |
count_block_types(node); | |
break; | |
case gtok_t_rr_graph::GRID: | |
count_grid_locs(node); | |
break; | |
case gtok_t_rr_graph::RR_NODES: | |
count_rr_nodes(node); | |
break; | |
case gtok_t_rr_graph::RR_EDGES: | |
count_rr_edges(node); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<7> test_state = gstate | std::bitset<7>(0b0000000); | |
if(!test_state.all()) all_error(test_state, gtok_lookup_t_rr_graph); | |
} | |
/** | |
* 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(!(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(!(meta_arena = (t_meta *)std::calloc(g_num_meta, sizeof(t_meta)))) | |
throw std::runtime_error("Couldn't get memory for <meta> 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(!(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(!(segment_arena = (t_segment *)std::calloc(g_num_segment, sizeof(t_segment)))) | |
throw std::runtime_error("Couldn't get memory for <segment> 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(!(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_edge = 0; | |
g_num_grid_loc = 0; | |
g_num_meta = 0; | |
g_num_node = 0; | |
g_num_pin = 0; | |
g_num_pin_class = 0; | |
g_num_segment = 0; | |
g_num_switch = 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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->chan_width_max."); | |
break; | |
case atok_t_channel::X_MIN: | |
out->x_min = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->x_min."); | |
break; | |
case atok_t_channel::Y_MIN: | |
out->y_min = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->y_min."); | |
break; | |
case atok_t_channel::X_MAX: | |
out->x_max = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->x_max."); | |
break; | |
case atok_t_channel::Y_MAX: | |
out->y_max = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->y_max."); | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->index."); | |
break; | |
case atok_t_x_list::INFO: | |
out->info = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->info."); | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->index."); | |
break; | |
case atok_t_y_list::INFO: | |
out->info = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->info."); | |
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::R: | |
out->R = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->R."); | |
break; | |
case atok_t_timing::CIN: | |
out->Cin = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->Cin."); | |
break; | |
case atok_t_timing::CINTERNAL: | |
out->Cinternal = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->Cinternal."); | |
break; | |
case atok_t_timing::COUT: | |
out->Cout = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->Cout."); | |
break; | |
case atok_t_timing::TDEL: | |
out->Tdel = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->Tdel."); | |
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::MUX_TRANS_SIZE: | |
out->mux_trans_size = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->mux_trans_size."); | |
break; | |
case atok_t_sizing::BUF_SIZE: | |
out->buf_size = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->buf_size."); | |
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_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::R_PER_METER: | |
out->R_per_meter = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->R_per_meter."); | |
break; | |
case atok_t_segment_timing::C_PER_METER: | |
out->C_per_meter = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->C_per_meter."); | |
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_pin(const pugi::xml_node &root, t_pin *out){ | |
out->value = strdup(root.child_value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(root.child_value()) + "` to load a const char * into out->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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->ptc."); | |
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_meta(const pugi::xml_node &root, t_meta *out){ | |
out->value = strdup(root.child_value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(root.child_value()) + "` to load a const char * into out->value."); | |
std::bitset<1> 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()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->name."); | |
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_meta); | |
} | |
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::X: | |
out->x = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->x."); | |
break; | |
case atok_t_grid_loc::Y: | |
out->y = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->y."); | |
break; | |
case atok_t_grid_loc::BLOCK_TYPE_ID: | |
out->block_type_id = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->block_type_id."); | |
break; | |
case atok_t_grid_loc::WIDTH_OFFSET: | |
out->width_offset = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->width_offset."); | |
break; | |
case atok_t_grid_loc::HEIGHT_OFFSET: | |
out->height_offset = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->height_offset."); | |
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::XLOW: | |
out->xlow = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->xlow."); | |
break; | |
case atok_t_node_loc::YLOW: | |
out->ylow = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->ylow."); | |
break; | |
case atok_t_node_loc::XHIGH: | |
out->xhigh = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->xhigh."); | |
break; | |
case atok_t_node_loc::YHIGH: | |
out->yhigh = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->yhigh."); | |
break; | |
case atok_t_node_loc::SIDE: | |
out->side = lex_loc_side(attr.value(), true); | |
break; | |
case atok_t_node_loc::PTC: | |
out->ptc = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->ptc."); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<6> test_state = astate | std::bitset<6>(0b010000); | |
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::R: | |
out->R = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->R."); | |
break; | |
case atok_t_node_timing::C: | |
out->C = std::strtof(attr.value(), NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a float into out->C."); | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->segment_id."); | |
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_switch(const pugi::xml_node &root, t_switch *out){ | |
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::TIMING: | |
load_timing(node, &out->timing); | |
out->has_timing = 1; | |
break; | |
case gtok_t_switch::SIZING: | |
load_sizing(node, &out->sizing); | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->id."); | |
break; | |
case atok_t_switch::NAME: | |
out->name = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->name."); | |
break; | |
case atok_t_switch::TYPE: | |
out->type = lex_switch_type(attr.value(), true); | |
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(const pugi::xml_node &root, t_segment *out){ | |
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, &out->timing); | |
out->has_timing = 1; | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->id."); | |
break; | |
case atok_t_segment::NAME: | |
out->name = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->name."); | |
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_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(), true); | |
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_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_channels(const pugi::xml_node &root, t_channels *out){ | |
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, &out->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_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_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::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->id."); | |
break; | |
case atok_t_block_type::NAME: | |
out->name = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->name."); | |
break; | |
case atok_t_block_type::WIDTH: | |
out->width = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->width."); | |
break; | |
case atok_t_block_type::HEIGHT: | |
out->height = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->height."); | |
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_node(const pugi::xml_node &root, t_node *out){ | |
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, &out->loc); | |
break; | |
case gtok_t_node::TIMING: | |
load_node_timing(node, &out->timing); | |
out->has_timing = 1; | |
break; | |
case gtok_t_node::SEGMENT: | |
load_node_segment(node, &out->segment); | |
out->has_segment = 1; | |
break; | |
case gtok_t_node::METADATA: | |
load_metadata(node, &out->metadata); | |
out->has_metadata = 1; | |
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::ID: | |
out->id = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->id."); | |
break; | |
case atok_t_node::TYPE: | |
out->type = lex_node_type(attr.value(), true); | |
break; | |
case atok_t_node::DIRECTION: | |
out->direction = lex_node_direction(attr.value(), true); | |
break; | |
case atok_t_node::CAPACITY: | |
out->capacity = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->capacity."); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_state = astate | std::bitset<4>(0b0100); | |
if(!test_state.all()) attr_error(test_state, atok_lookup_t_node); | |
} | |
void load_edge(const pugi::xml_node &root, t_edge *out){ | |
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, &out->metadata); | |
out->has_metadata = 1; | |
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); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->id."); | |
break; | |
case atok_t_edge::SRC_NODE: | |
out->src_node = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->src_node."); | |
break; | |
case atok_t_edge::SINK_NODE: | |
out->sink_node = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->sink_node."); | |
break; | |
case atok_t_edge::SWITCH_ID: | |
out->switch_id = std::strtol(attr.value(), NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a int into out->switch_id."); | |
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_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_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){ | |
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::CHANNELS: | |
load_channels(node, &out->channels); | |
break; | |
case gtok_t_rr_graph::SWITCHES: | |
load_switches(node, &out->switches); | |
break; | |
case gtok_t_rr_graph::SEGMENTS: | |
load_segments(node, &out->segments); | |
break; | |
case gtok_t_rr_graph::BLOCK_TYPES: | |
load_block_types(node, &out->block_types); | |
break; | |
case gtok_t_rr_graph::GRID: | |
load_grid_locs(node, &out->grid); | |
break; | |
case gtok_t_rr_graph::RR_NODES: | |
load_rr_nodes(node, &out->rr_nodes); | |
break; | |
case gtok_t_rr_graph::RR_EDGES: | |
load_rr_edges(node, &out->rr_edges); | |
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_NAME: | |
out->tool_name = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->tool_name."); | |
break; | |
case atok_t_rr_graph::TOOL_VERSION: | |
out->tool_version = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->tool_version."); | |
break; | |
case atok_t_rr_graph::TOOL_COMMENT: | |
out->tool_comment = strdup(attr.value()); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(attr.value()) + "` to load a const char * into out->tool_comment."); | |
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); | |
} | |
/** | |
* Global variable to hold the root element. | |
**/ | |
t_rr_graph rr_graph = {}; | |
/** | |
* Load into root element from file. | |
**/ | |
void get_root_element(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(); | |
errno = 0; /* If errno is set up to this point, it messes with strtol errno checking. */ | |
load_rr_graph(node, &rr_graph); | |
} | |
else throw std::runtime_error("Invalid root-level element " + std::string(node.name())); | |
} | |
} | |
/** | |
* Write to output stream from root element. | |
**/ | |
void write_root_element(std::ostream &os){ | |
/* Print floating points with max double precision. */ | |
os.precision(std::numeric_limits<double>::max_digits10); | |
os << "<rr_graph"; | |
if((bool)rr_graph.tool_name) | |
os << " tool_name=\"" << rr_graph.tool_name << "\""; | |
if((bool)rr_graph.tool_version) | |
os << " tool_version=\"" << rr_graph.tool_version << "\""; | |
if((bool)rr_graph.tool_comment) | |
os << " tool_comment=\"" << rr_graph.tool_comment << "\""; | |
os << ">"; | |
os << "<channels>"; | |
os << "<channel"; | |
os << " chan_width_max=\"" << rr_graph.channels.channel.chan_width_max << "\""; | |
os << " x_min=\"" << rr_graph.channels.channel.x_min << "\""; | |
os << " y_min=\"" << rr_graph.channels.channel.y_min << "\""; | |
os << " x_max=\"" << rr_graph.channels.channel.x_max << "\""; | |
os << " y_max=\"" << rr_graph.channels.channel.y_max << "\""; | |
os << ">"; | |
os << "</channel>"; | |
for(int j=0; j<rr_graph.channels.num_x_list; j++){ | |
auto &x_list = rr_graph.channels.x_list_list[j]; | |
os << "<x_list"; | |
os << " index=\"" << x_list.index << "\""; | |
os << " info=\"" << x_list.info << "\""; | |
os << ">"; | |
os << "</x_list>"; | |
} | |
for(int j=0; j<rr_graph.channels.num_y_list; j++){ | |
auto &y_list = rr_graph.channels.y_list_list[j]; | |
os << "<y_list"; | |
os << " index=\"" << y_list.index << "\""; | |
os << " info=\"" << y_list.info << "\""; | |
os << ">"; | |
os << "</y_list>"; | |
} | |
os << "</channels>"; | |
os << "<switches>"; | |
for(int j=0; j<rr_graph.switches.num_switch; j++){ | |
auto &switch_ = rr_graph.switches.switch_list[j]; | |
os << "<switch"; | |
os << " id=\"" << switch_.id << "\""; | |
os << " name=\"" << switch_.name << "\""; | |
if((bool)switch_.type) | |
os << " type=\"" << lookup_switch_type[(int)switch_.type] << "\""; | |
os << ">"; | |
if(switch_.has_timing){ | |
os << "<timing"; | |
if((bool)switch_.timing.R) | |
os << " R=\"" << switch_.timing.R << "\""; | |
if((bool)switch_.timing.Cin) | |
os << " Cin=\"" << switch_.timing.Cin << "\""; | |
if((bool)switch_.timing.Cinternal) | |
os << " Cinternal=\"" << switch_.timing.Cinternal << "\""; | |
if((bool)switch_.timing.Cout) | |
os << " Cout=\"" << switch_.timing.Cout << "\""; | |
if((bool)switch_.timing.Tdel) | |
os << " Tdel=\"" << switch_.timing.Tdel << "\""; | |
os << ">"; | |
os << "</timing>"; | |
} | |
os << "<sizing"; | |
os << " mux_trans_size=\"" << switch_.sizing.mux_trans_size << "\""; | |
os << " buf_size=\"" << switch_.sizing.buf_size << "\""; | |
os << ">"; | |
os << "</sizing>"; | |
os << "</switch>"; | |
} | |
os << "</switches>"; | |
os << "<segments>"; | |
for(int j=0; j<rr_graph.segments.num_segment; j++){ | |
auto &segment = rr_graph.segments.segment_list[j]; | |
os << "<segment"; | |
os << " id=\"" << segment.id << "\""; | |
os << " name=\"" << segment.name << "\""; | |
os << ">"; | |
if(segment.has_timing){ | |
os << "<timing"; | |
if((bool)segment.timing.R_per_meter) | |
os << " R_per_meter=\"" << segment.timing.R_per_meter << "\""; | |
if((bool)segment.timing.C_per_meter) | |
os << " C_per_meter=\"" << segment.timing.C_per_meter << "\""; | |
os << ">"; | |
os << "</timing>"; | |
} | |
os << "</segment>"; | |
} | |
os << "</segments>"; | |
os << "<block_types>"; | |
for(int j=0; j<rr_graph.block_types.num_block_type; j++){ | |
auto &block_type = rr_graph.block_types.block_type_list[j]; | |
os << "<block_type"; | |
os << " id=\"" << block_type.id << "\""; | |
os << " name=\"" << block_type.name << "\""; | |
os << " width=\"" << block_type.width << "\""; | |
os << " height=\"" << block_type.height << "\""; | |
os << ">"; | |
for(int k=0; k<block_type.num_pin_class; k++){ | |
auto &pin_class = block_type.pin_class_list[k]; | |
os << "<pin_class"; | |
os << " type=\"" << lookup_pin_type[(int)pin_class.type] << "\""; | |
os << ">"; | |
for(int l=0; l<pin_class.num_pin; l++){ | |
auto &pin = pin_class.pin_list[l]; | |
os << "<pin"; | |
os << " ptc=\"" << pin.ptc << "\""; | |
os << ">"; | |
os << pin.value; | |
os << "</pin>"; | |
} | |
os << "</pin_class>"; | |
} | |
os << "</block_type>"; | |
} | |
os << "</block_types>"; | |
os << "<grid>"; | |
for(int j=0; j<rr_graph.grid.num_grid_loc; j++){ | |
auto &grid_loc = rr_graph.grid.grid_loc_list[j]; | |
os << "<grid_loc"; | |
os << " x=\"" << grid_loc.x << "\""; | |
os << " y=\"" << grid_loc.y << "\""; | |
os << " block_type_id=\"" << grid_loc.block_type_id << "\""; | |
os << " width_offset=\"" << grid_loc.width_offset << "\""; | |
os << " height_offset=\"" << grid_loc.height_offset << "\""; | |
os << ">"; | |
os << "</grid_loc>"; | |
} | |
os << "</grid>"; | |
os << "<rr_nodes>"; | |
for(int j=0; j<rr_graph.rr_nodes.num_node; j++){ | |
auto &node = rr_graph.rr_nodes.node_list[j]; | |
os << "<node"; | |
os << " id=\"" << node.id << "\""; | |
os << " type=\"" << lookup_node_type[(int)node.type] << "\""; | |
if((bool)node.direction) | |
os << " direction=\"" << lookup_node_direction[(int)node.direction] << "\""; | |
os << " capacity=\"" << node.capacity << "\""; | |
os << ">"; | |
os << "<loc"; | |
os << " xlow=\"" << node.loc.xlow << "\""; | |
os << " ylow=\"" << node.loc.ylow << "\""; | |
os << " xhigh=\"" << node.loc.xhigh << "\""; | |
os << " yhigh=\"" << node.loc.yhigh << "\""; | |
if((bool)node.loc.side) | |
os << " side=\"" << lookup_loc_side[(int)node.loc.side] << "\""; | |
os << " ptc=\"" << node.loc.ptc << "\""; | |
os << ">"; | |
os << "</loc>"; | |
if(node.has_timing){ | |
os << "<timing"; | |
os << " R=\"" << node.timing.R << "\""; | |
os << " C=\"" << node.timing.C << "\""; | |
os << ">"; | |
os << "</timing>"; | |
} | |
if(node.has_segment){ | |
os << "<segment"; | |
os << " segment_id=\"" << node.segment.segment_id << "\""; | |
os << ">"; | |
os << "</segment>"; | |
} | |
if(node.has_metadata){ | |
os << "<metadata>"; | |
for(int l=0; l<node.metadata.num_meta; l++){ | |
auto &meta = node.metadata.meta_list[l]; | |
os << "<meta"; | |
os << " name=\"" << meta.name << "\""; | |
os << ">"; | |
os << meta.value; | |
os << "</meta>"; | |
} | |
os << "</metadata>"; | |
} | |
os << "</node>"; | |
} | |
os << "</rr_nodes>"; | |
os << "<rr_edges>"; | |
for(int j=0; j<rr_graph.rr_edges.num_edge; j++){ | |
auto &edge = rr_graph.rr_edges.edge_list[j]; | |
os << "<edge"; | |
if((bool)edge.id) | |
os << " id=\"" << edge.id << "\""; | |
os << " src_node=\"" << edge.src_node << "\""; | |
os << " sink_node=\"" << edge.sink_node << "\""; | |
os << " switch_id=\"" << edge.switch_id << "\""; | |
os << ">"; | |
if(edge.has_metadata){ | |
os << "<metadata>"; | |
for(int l=0; l<edge.metadata.num_meta; l++){ | |
auto &meta = edge.metadata.meta_list[l]; | |
os << "<meta"; | |
os << " name=\"" << meta.name << "\""; | |
os << ">"; | |
os << meta.value; | |
os << "</meta>"; | |
} | |
os << "</metadata>"; | |
} | |
os << "</edge>"; | |
} | |
os << "</rr_edges>"; | |
os << "</rr_graph>"; | |
} | |
} /* namespace rr_graph */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment