Skip to content

Instantly share code, notes, and snippets.

@duck2
Created August 1, 2019 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duck2/80d341fb90c799f98c323c69c6886ff4 to your computer and use it in GitHub Desktop.
Save duck2/80d341fb90c799f98c323c69c6886ff4 to your computer and use it in GitHub Desktop.
#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