/* The XML parser processes an XML file into a tree data structure composed of  
 * pugi::xml_nodes.  Each node represents an XML element.  For example          
 * <a> <b/> </a> will generate two pugi::xml_nodes.  One called "a" and its      
 * child "b".  Each pugi::xml_node can contain various XML data such as attribute 
 * information and text content.  The XML parser provides several functions to  
 * help the developer build, and traverse tree (this is also somtime referred to
 * as the Document Object Model or DOM).              
 *                                                                              
 * For convenience it often makes sense to use some wraper functions (provided in
 * the pugiutil namespace of libvtrutil) which simplify loading an XML file and 
 * error handling.
 *
 * The function pugiutil::load_xml() reads in an xml file.                 
 *                                                                              
 * The function pugiutil::get_single_child() returns a child xml_node for a given parent
 * xml_node if there is a child which matches the name provided by the developer.                          
 *                                                                              
 * The function pugiutil::get_attribute() is used to extract attributes from an 
 * xml_node, returning a pugi::xml_attribute. xml_attribute objects support accessors
 * such as as_float(), as_int() to retrieve semantic values. See pugixml documentation
 * for more details.
 * 
 * Architecture file checks already implemented (Daniel Chen):
 *		- Duplicate pb_types, pb_type ports, models, model ports,
 *			interconnects, interconnect annotations.
 *		- Port and pin range checking (port with 4 pins can only be
 *			accessed within [0:3].
 *		- LUT delay matrix size matches # of LUT inputs
 *		- Ensures XML tags are ordered.
 *		- Clocked primitives that have timing annotations must have a clock 
 *			name matching the primitive.
 *		- Enforced VPR definition of LUT and FF must have one input port (n pins) 
 *			and one output port(1 pin).
 *		- Checks file extension for blif and architecture xml file, avoid crashes if
 *			the two files are swapped on command line.
 *			
 */

#include <string.h>
#include <map>
#include <set>
#include <string>
#include <sstream>
#include <algorithm>

#include "pugixml.hpp"
#include "pugixml_util.hpp"

#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_util.h"
#include "vtr_memory.h"
#include "vtr_digest.h"

#include "arch_types.h"
#include "arch_util.h"
#include "arch_error.h"

#include "read_xml_arch_file.h"
#include "read_xml_util.h"
#include "parse_switchblocks.h"

using namespace std;
using namespace pugiutil;

struct t_fc_override {
    std::string port_name;
    std::string seg_name;
    e_fc_value_type fc_value_type;
    float fc_value;
};

/* This gives access to the architecture file name to 
 all architecture-parser functions       */
static const char* arch_file_name = NULL;

/* This identifies the t_type_ptr of an IO block */
static t_type_ptr IO_TYPE = NULL;

/* This identifies the t_type_ptr of an Empty block */
static t_type_ptr EMPTY_TYPE = NULL;

/* This identifies the t_type_ptr of the default logic block */
static t_type_ptr FILL_TYPE = NULL;

/* Describes the different types of CLBs available */
static struct s_type_descriptor *cb_type_descriptors;

/* Function prototypes */
/*   Populate data */
static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
		t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
static void SetupGridLocations(pugi::xml_node Locations, t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
/*    Process XML hiearchy */
static void ProcessPb_Type(pugi::xml_node Parent, t_pb_type * pb_type,
		t_mode * mode, const t_arch& arch, const pugiutil::loc_data& loc_data);
static void ProcessPb_TypePort(pugi::xml_node Parent, t_port * port,
		e_power_estimation_method power_method, const pugiutil::loc_data& loc_data);
static void ProcessPinToPinAnnotations(pugi::xml_node parent,
		t_pin_to_pin_annotation *annotation, t_pb_type * parent_pb_type, const pugiutil::loc_data& loc_data);
static void ProcessInterconnect(pugi::xml_node Parent, t_mode * mode, const pugiutil::loc_data& loc_data);
static void ProcessMode(pugi::xml_node Parent, t_mode * mode, const t_arch& arch,
		const pugiutil::loc_data& loc_data);
static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, t_segment_inf *segments, int num_segments, const pugiutil::loc_data& loc_data);
static t_fc_override Process_Fc_override(pugi::xml_node node, const pugiutil::loc_data& loc_data);
static e_fc_value_type string_to_fc_value_type(const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data);
static void ProcessComplexBlockProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data);
static void ProcessSizingTimingIpinCblock(pugi::xml_node Node,
		struct s_arch *arch, const bool timing_enabled, const pugiutil::loc_data& loc_data);
static void ProcessChanWidthDistr(pugi::xml_node Node,
		struct s_arch *arch, const pugiutil::loc_data& loc_data);
static void ProcessChanWidthDistrDir(pugi::xml_node Node, t_chan * chan, const pugiutil::loc_data& loc_data);
static void ProcessModels(pugi::xml_node Node, struct s_arch *arch, const pugiutil::loc_data& loc_data);
static void ProcessModelPorts(pugi::xml_node port_group, t_model* model, std::set<std::string>& port_names, const pugiutil::loc_data& loc_data);
static void ProcessLayout(pugi::xml_node Node, struct s_arch *arch, const pugiutil::loc_data& loc_data);
static void ProcessDevice(pugi::xml_node Node, struct s_arch *arch,
		const bool timing_enabled, const pugiutil::loc_data& loc_data);
static void ProcessComplexBlocks(pugi::xml_node Node,
		t_type_descriptor ** Types, int *NumTypes,
		const s_arch& arch, const pugiutil::loc_data& loc_data);
static void ProcessSwitches(pugi::xml_node Node,
		struct s_arch_switch_inf **Switches, int *NumSwitches,
		const bool timing_enabled, const pugiutil::loc_data& loc_data);
static void ProcessSwitchTdel(pugi::xml_node Node, const bool timing_enabled,
		const int switch_index, s_arch_switch_inf *Switches, const pugiutil::loc_data& loc_data);
static void ProcessDirects(pugi::xml_node Parent, t_direct_inf **Directs,
		 int *NumDirects, const struct s_arch_switch_inf *Switches, const int NumSwitches,
		 const pugiutil::loc_data& loc_data);
static void ProcessSegments(pugi::xml_node Parent,
		struct s_segment_inf **Segs, int *NumSegs,
		const struct s_arch_switch_inf *Switches, const int NumSwitches,
		const bool timing_enabled, const bool switchblocklist_required, const pugiutil::loc_data& loc_data);
static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiutil::loc_data& loc_data);
static void ProcessCB_SB(pugi::xml_node Node, bool * list,
		const int len, const pugiutil::loc_data& loc_data);
static void ProcessPower( pugi::xml_node parent,
		t_power_arch * power_arch,
        const pugiutil::loc_data& loc_data);

static void ProcessClocks(pugi::xml_node Parent, t_clock_arch * clocks, const pugiutil::loc_data& loc_data);

static void ProcessPb_TypePowerEstMethod(pugi::xml_node Parent, t_pb_type * pb_type, const pugiutil::loc_data& loc_data);
static void ProcessPb_TypePort_Power(pugi::xml_node Parent, t_port * port,
		e_power_estimation_method power_method, const pugiutil::loc_data& loc_data);


bool check_model_combinational_sinks(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model);
void warn_model_missing_timing(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model);
bool check_model_clocks(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model);
bool check_leaf_pb_model_timing_consistency(const t_pb_type* pb_type, const t_arch& arch);
std::string inst_port_to_port_name(std::string inst_port);

static bool attribute_to_bool(const pugi::xml_node node,
                const pugi::xml_attribute attr,
                const pugiutil::loc_data& loc_data);

/*
 *
 *
 * External Function Implementations
 *
 *
 */

/* Loads the given architecture file. */
void XmlReadArch(const char *ArchFile, const bool timing_enabled,
		struct s_arch *arch, t_type_descriptor ** Types,
		int *NumTypes) {

	const char *Prop;
	pugi::xml_node Next;
	ReqOpt POWER_REQD, SWITCHBLOCKLIST_REQD;

	if (vtr::check_file_name_extension(ArchFile, ".xml") == false) {
		vtr::printf_warning(__FILE__, __LINE__,
				"Architecture file '%s' may be in incorrect format. "
						"Expecting .xml format for architecture files.\n",
				ArchFile);
	}

    //Create a unique identifier for this architecture file based on it's contents
    arch->architecture_id = vtr::strdup(vtr::secure_digest_file(ArchFile).c_str());

	/* Parse the file */
	pugi::xml_document doc;
	pugiutil::loc_data loc_data;
	try {
		loc_data = pugiutil::load_xml(doc, ArchFile);

        arch_file_name = ArchFile;

        /* Root node should be architecture */
        auto architecture = get_single_child(doc, "architecture", loc_data);

        /* TODO: do version processing properly with string delimiting on the . */
        Prop = get_attribute(architecture, "version", loc_data, OPTIONAL).as_string(NULL);
        if (Prop != NULL) {
            if (atof(Prop) > atof(VPR_VERSION)) {
                vtr::printf_warning(__FILE__, __LINE__,
                        "This architecture version is for VPR %f while your current VPR version is " VPR_VERSION ", compatability issues may arise\n",
                        atof(Prop));
            }
        }

        /* Process models */
        Next = get_single_child(architecture, "models", loc_data);
        ProcessModels(Next, arch, loc_data);
        CreateModelLibrary(arch);

        /* Process layout */
        Next = get_single_child(architecture, "layout", loc_data);
        ProcessLayout(Next, arch, loc_data);

        /* Process device */
        Next = get_single_child(architecture, "device", loc_data);
        ProcessDevice(Next, arch, timing_enabled, loc_data);

        /* Process switches */
        Next = get_single_child(architecture, "switchlist", loc_data);
        ProcessSwitches(Next, &(arch->Switches), &(arch->num_switches),
                timing_enabled, loc_data);

        /* Process switchblocks. This depends on switches */
        bool switchblocklist_required = (arch->SBType == CUSTOM);	//require this section only if custom switchblocks are used
        SWITCHBLOCKLIST_REQD = BoolToReqOpt(switchblocklist_required);	


        /* Process segments. This depends on switches */
        Next = get_single_child(architecture, "segmentlist", loc_data);
        ProcessSegments(Next, &(arch->Segments), &(arch->num_segments),
                arch->Switches, arch->num_switches, timing_enabled, switchblocklist_required, loc_data);
        

        Next = get_single_child(architecture, "switchblocklist", loc_data, SWITCHBLOCKLIST_REQD);
        if (Next){
            ProcessSwitchblocks(Next, arch, loc_data);
        }

        /* Process types */
        Next = get_single_child(architecture, "complexblocklist", loc_data);
        ProcessComplexBlocks(Next, Types, NumTypes, *arch, loc_data);

        /* Process directs */
        Next = get_single_child(architecture, "directlist", loc_data, OPTIONAL);
        if (Next) {
            ProcessDirects(Next, &(arch->Directs), &(arch->num_directs),
                    arch->Switches, arch->num_switches,
                    loc_data);
        }

        /* Process architecture power information */

        /* If arch->power has been initialized, meaning the user has requested power estimation,
         * then the power architecture information is required.
         */
        if (arch->power) {
            POWER_REQD = REQUIRED;
        } else {
            POWER_REQD = OPTIONAL;
        }

        Next = get_single_child(architecture, "power", loc_data, POWER_REQD);
        if (Next) {
            if (arch->power) {
                ProcessPower(Next, arch->power, loc_data);
            } else {
                /* This information still needs to be read, even if it is just
                 * thrown away.
                 */
                t_power_arch * power_arch_fake = (t_power_arch*) vtr::calloc(1,
                        sizeof(t_power_arch));
                ProcessPower(Next, power_arch_fake, loc_data);
                free(power_arch_fake);
            }
        }

        // Process Clocks
        Next = get_single_child(architecture, "clocks", loc_data, POWER_REQD);
        if (Next) {
            if (arch->clocks) {
                ProcessClocks(Next, arch->clocks, loc_data);
            } else {
                /* This information still needs to be read, even if it is just
                 * thrown away.
                 */
                t_clock_arch * clocks_fake = (t_clock_arch*) vtr::calloc(1,
                        sizeof(t_clock_arch));
                ProcessClocks(Next, clocks_fake, loc_data);
                free(clocks_fake->clock_inf);
                free(clocks_fake);
            }
        }
        SyncModelsPbTypes(arch, *Types, *NumTypes);
        UpdateAndCheckModels(arch);

	} catch (XmlError& e) {
		archfpga_throw(ArchFile, e.line(),
				"%s", e.what());
	}
}


/*
 *
 *
 * File-scope function implementations
 *
 *
 */

/* Sets up the pinloc map and pin classes for the type. 
 * Pins and pin classses must already be setup by SetupPinClasses */
static void SetupPinLocationsAndPinClasses(pugi::xml_node Locations,
		t_type_descriptor * Type, const pugiutil::loc_data& loc_data) {
	int i, j, k, Count;
	int capacity, pin_count;
	int num_class;
	const char * Prop;

	pugi::xml_node Cur;

	capacity = Type->capacity;

	Prop = get_attribute(Locations, "pattern", loc_data).value();
	if (strcmp(Prop, "spread") == 0) {
		Type->pin_location_distribution = E_SPREAD_PIN_DISTR;
	} else if (strcmp(Prop, "custom") == 0) {
		Type->pin_location_distribution = E_CUSTOM_PIN_DISTR;
	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
				"%s is an invalid pin location pattern.\n", Prop);
	}

	/* Alloc and clear pin locations */
	Type->pin_width = (int *) vtr::calloc(Type->num_pins, sizeof(int));
	Type->pin_height = (int *) vtr::calloc(Type->num_pins, sizeof(int));
	Type->pinloc = (int ****) vtr::malloc(Type->width * sizeof(int ***));
	for (int width = 0; width < Type->width; ++width) {
		Type->pinloc[width] = (int ***) vtr::malloc(Type->height * sizeof(int **));
		for (int height = 0; height < Type->height; ++height) {
			Type->pinloc[width][height] = (int **) vtr::malloc(4 * sizeof(int *));
			for (int side = 0; side < 4; ++side) {
				Type->pinloc[width][height][side] = (int *) vtr::malloc(
						Type->num_pins * sizeof(int));
				for (int pin = 0; pin < Type->num_pins; ++pin) {
					Type->pinloc[width][height][side][pin] = 0;
				}
			}
		}
	}

	Type->pin_loc_assignments = (char *****) vtr::malloc(
			Type->width * sizeof(char ****));
	Type->num_pin_loc_assignments = (int ***) vtr::malloc(
			Type->width * sizeof(int **));
	for (int width = 0; width < Type->width; ++width) {
		Type->pin_loc_assignments[width] = (char ****) vtr::calloc(Type->height,
				sizeof(char ***));
		Type->num_pin_loc_assignments[width] = (int **) vtr::calloc(Type->height,
				sizeof(int *));
		for (int height = 0; height < Type->height; ++height) {
			Type->pin_loc_assignments[width][height] = (char ***) vtr::calloc(4,
					sizeof(char **));
			Type->num_pin_loc_assignments[width][height] = (int *) vtr::calloc(4,
					sizeof(int));
		}
	}

	/* Load the pin locations */
	if (Type->pin_location_distribution == E_CUSTOM_PIN_DISTR) {
		Cur = Locations.first_child();
        std::set<e_side> seen_sides;
		while (Cur) {
			check_node(Cur, "loc", loc_data);

			/* Get offset (ie. height) */
			int height = get_attribute(Cur, "offset", loc_data, OPTIONAL).as_int(0);
			if ((height < 0) || (height >= Type->height)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"'%d' is an invalid offset for type '%s'.\n", height,
						Type->name);
			}

			/* Get side */
			e_side side = TOP;
			Prop = get_attribute(Cur, "side", loc_data).value();
			if (0 == strcmp(Prop, "left")) {
				side = LEFT;
			} else if (0 == strcmp(Prop, "top")) {
				side = TOP;
			} else if (0 == strcmp(Prop, "right")) {
				side = RIGHT;
			} else if (0 == strcmp(Prop, "bottom")) {
				side = BOTTOM;
			} else {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"'%s' is not a valid side.\n", Prop);
			}

            //Check for duplicate side specifications, since the code below silently overwrites if there are duplicates
            if (seen_sides.count(side)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Duplicate pin location side specification. Only a single <loc> per side is permitted.\n");
            } else {
                seen_sides.insert(side);
            }

			/* Check location is on perimeter */
			if ((TOP == side) && (height != (Type->height - 1))) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Locations are only allowed on large block perimeter. 'top' side should be at offset %d only.\n",
						(Type->height - 1));
			}
			if ((BOTTOM == side) && (height != 0)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Locations are only allowed on large block perimeter. 'bottom' side should be at offset 0 only.\n");
			}

			/* Go through lists of pins */
			const std::vector<std::string> Tokens = vtr::split(Cur.child_value());
			Count = Tokens.size();
			Type->num_pin_loc_assignments[0][height][side] = Count;
			if (Count > 0) {
				Type->pin_loc_assignments[0][height][side] = (char**) vtr::calloc(Count, sizeof(char*));
				for (int pin = 0; pin < Count; ++pin) {
					/* Store location assignment */
					Type->pin_loc_assignments[0][height][side][pin] = vtr::strdup(Tokens[pin].c_str());

					/* Advance through list of pins in this location */
				}
			}
			Cur = Cur.next_sibling(Cur.name());
		}

        //Verify that all top-level pins have had thier locations specified

        //Count up all the specified pins
        std::map<std::string,std::set<int>> port_pins_with_specified_locations;
        for (int w = 0; w < Type->width; ++w) {
            for (int h = 0; h < Type->height; ++h) {
                for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
                    for (int itoken = 0; itoken < Type->num_pin_loc_assignments[w][h][side]; ++itoken) {
                        const char* pin_spec = Type->pin_loc_assignments[w][h][side][itoken];
                        InstPort inst_port(Type->pin_loc_assignments[w][h][side][itoken]);

                        //A pin specification should contain only the block name, and not any instace count information
                        if (inst_port.instance_low_index() != InstPort::UNSPECIFIED || inst_port.instance_high_index() != InstPort::UNSPECIFIED) {
                            archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
                                           "Pin location specification '%s' should not contain an instance range (should only be the block name)",
                                           pin_spec);
                        }

                        //Check that the block name matches
                        if (inst_port.instance_name() != Type->name) {
                            archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
                                           "Mismatched block name in pin location specification (expected '%s' was '%s')",
                                           Type->name, inst_port.instance_name().c_str());
                        }

                        int pin_low_idx = inst_port.port_low_index();
                        int pin_high_idx = inst_port.port_high_index();

                        if(pin_low_idx == InstPort::UNSPECIFIED && pin_high_idx == InstPort::UNSPECIFIED) {
                            //Empty range, so full port

                            //Find the matching pb type to get the total number of pins
                            const t_port* port = nullptr;
                            for (int iport = 0; iport < Type->pb_type->num_ports; ++iport) {
                                const t_port* tmp_port = &Type->pb_type->ports[iport];
                                if (tmp_port->name == inst_port.port_name()) {
                                    port = tmp_port;
                                    break;
                                }
                            }
                            VTR_ASSERT(port);

                            pin_low_idx = 0;
                            pin_high_idx = port->num_pins - 1;
                        }
                        VTR_ASSERT(pin_low_idx >= 0);
                        VTR_ASSERT(pin_high_idx >= 0);

                        for (int ipin = pin_low_idx; ipin <= pin_high_idx; ++ipin) {
                            //Record that the pin has it's location specified
                            port_pins_with_specified_locations[inst_port.port_name()].insert(ipin);
                        }
                    }
                }
            }
        }

        //Check for any pins missing location specs
        for (int iport = 0; iport < Type->pb_type->num_ports; ++iport) {
            const t_port* port = &Type->pb_type->ports[iport];

            for (int ipin = 0; ipin < port->num_pins; ++ipin) {
                if (!port_pins_with_specified_locations[port->name].count(ipin)) {
                    //Missing
                    archfpga_throw(loc_data.filename_c_str(), loc_data.line(Locations),
                                   "Pin '%s.%s[%d]' has no pin location specificed with pin location pattern=\"custom\"",
                                   Type->name, port->name, ipin);
                }
            }
        }
	}

	/* Setup pin classes */
	num_class = 0;
	for (i = 0; i < Type->pb_type->num_ports; i++) {
		if (Type->pb_type->ports[i].equivalent) {
			num_class += capacity;
		} else {
			num_class += capacity * Type->pb_type->ports[i].num_pins;
		}
	}
	Type->class_inf = (struct s_class*) vtr::calloc(num_class,
			sizeof(struct s_class));
	Type->num_class = num_class;
	Type->pin_class = (int*) vtr::malloc(Type->num_pins * sizeof(int) * capacity);
	Type->is_global_pin = (bool*) vtr::malloc(
        Type->num_pins * sizeof(bool)* capacity);
	for (i = 0; i < Type->num_pins * capacity; i++) {
		Type->pin_class[i] = OPEN;
		Type->is_global_pin[i] = true;
	}

	pin_count = 0;

	/* Equivalent pins share the same class, non-equivalent pins belong to different pin classes */
	num_class = 0;
	for (i = 0; i < capacity; ++i) {
		for (j = 0; j < Type->pb_type->num_ports; ++j) {
			if (Type->pb_type->ports[j].equivalent) {
				Type->class_inf[num_class].num_pins =
						Type->pb_type->ports[j].num_pins;
				Type->class_inf[num_class].pinlist = (int *) vtr::malloc(
						sizeof(int) * Type->pb_type->ports[j].num_pins);
			}

			for (k = 0; k < Type->pb_type->ports[j].num_pins; ++k) {
				if (!Type->pb_type->ports[j].equivalent) {
					Type->class_inf[num_class].num_pins = 1;
					Type->class_inf[num_class].pinlist = (int *) vtr::malloc(
							sizeof(int) * 1);
					Type->class_inf[num_class].pinlist[0] = pin_count;
				} else {
					Type->class_inf[num_class].pinlist[k] = pin_count;
				}

				if (Type->pb_type->ports[j].type == IN_PORT) {
					Type->class_inf[num_class].type = RECEIVER;
				} else {
					VTR_ASSERT(Type->pb_type->ports[j].type == OUT_PORT);
					Type->class_inf[num_class].type = DRIVER;
				}
				Type->pin_class[pin_count] = num_class;
				Type->is_global_pin[pin_count] = Type->pb_type->ports[j].is_clock || 
                    Type->pb_type->ports[j].is_non_clock_global;
				pin_count++;

				if (!Type->pb_type->ports[j].equivalent) {
					num_class++;
				}
			}
			if (Type->pb_type->ports[j].equivalent) {
				num_class++;
			}
		}
	}
	VTR_ASSERT(num_class == Type->num_class);
	VTR_ASSERT(pin_count == Type->num_pins);
}

/* Sets up the grid_loc_def for the type. */
static void SetupGridLocations(pugi::xml_node Locations, t_type_descriptor * Type, const pugiutil::loc_data& loc_data) {
	int i;

	pugi::xml_node Cur;
	const char *Prop;

	Type->num_grid_loc_def = count_children(Locations, "loc", loc_data);
	Type->grid_loc_def = (struct s_grid_loc_def *) vtr::calloc(
			Type->num_grid_loc_def, sizeof(struct s_grid_loc_def));

	/* Load the pin locations */
	Cur = Locations.first_child();
	i = 0;
	while (Cur) {
		check_node(Cur, "loc", loc_data);

		/* loc index */
		Prop = get_attribute(Cur, "type", loc_data).value();
		if (Prop) {
			if (strcmp(Prop, "perimeter") == 0) {
				if (Type->num_grid_loc_def != 1) {
					archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
							"Another loc specified for perimeter.\n");
				}
				Type->grid_loc_def[i].grid_loc_type = BOUNDARY;
				VTR_ASSERT(IO_TYPE == Type);
				/* IO goes to boundary */
			} else if (strcmp(Prop, "fill") == 0) {
				if (Type->num_grid_loc_def != 1 || FILL_TYPE != NULL) {
					archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
							"Another loc specified for fill.\n");
				}
				Type->grid_loc_def[i].grid_loc_type = FILL;
				FILL_TYPE = Type;
			} else if (strcmp(Prop, "col") == 0) {
				Type->grid_loc_def[i].grid_loc_type = COL_REPEAT;
			} else if (strcmp(Prop, "rel") == 0) {
				Type->grid_loc_def[i].grid_loc_type = COL_REL;
			} else {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Unknown grid location type '%s' for type '%s'.\n",
						Prop, Type->name);
			}
		}
		Prop = get_attribute(Cur, "start", loc_data, OPTIONAL).as_string(NULL);
		if (Type->grid_loc_def[i].grid_loc_type == COL_REPEAT) {
			if (Prop == NULL) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"grid location property 'start' must be specified for grid location type 'col'.\n");
			}
			Type->grid_loc_def[i].start_col = vtr::atoi(Prop);
		} else if (Prop != NULL) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
					"grid location property 'start' valid for grid location type 'col' only.\n");
		}
		Prop = get_attribute(Cur, "repeat", loc_data, OPTIONAL).as_string(NULL);
		if (Type->grid_loc_def[i].grid_loc_type == COL_REPEAT) {
			if (Prop != NULL) {
				Type->grid_loc_def[i].repeat = vtr::atoi(Prop);
			}
		} else if (Prop != NULL) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
					"Grid location property 'repeat' valid for grid location type 'col' only.\n");
		}
		Prop = get_attribute(Cur, "pos", loc_data, OPTIONAL).as_string(NULL);
		if (Type->grid_loc_def[i].grid_loc_type == COL_REL) {
			if (Prop == NULL) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Grid location property 'pos' must be specified for grid location type 'rel'.\n");
			}
			Type->grid_loc_def[i].col_rel = (float) atof(Prop);
		} else if (Prop != NULL) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
					"Grid location property 'pos' valid for grid location type 'rel' only.\n");
		}

		Type->grid_loc_def[i].priority = get_attribute(Cur, "priority", loc_data, OPTIONAL). as_int(1);

		Cur = Cur.next_sibling(Cur.name());
		i++;
	}
}

static void ProcessPinToPinAnnotations(pugi::xml_node Parent,
		t_pin_to_pin_annotation *annotation, t_pb_type * parent_pb_type, const pugiutil::loc_data& loc_data) {
	int i = 0;
	const char *Prop;
	
	if ( get_attribute(Parent, "max", loc_data, OPTIONAL).as_string(NULL) ){
		i++;
	}
	if ( get_attribute(Parent, "min", loc_data, OPTIONAL).as_string(NULL) ){
		i++;
	}
	if ( get_attribute(Parent, "type", loc_data, OPTIONAL).as_string(NULL) ){
		i++;
	}
	if ( get_attribute(Parent, "value", loc_data, OPTIONAL).as_string(NULL) ){
		i++;
	}
	if (0 == strcmp(Parent.name(), "C_constant")
			|| 0 == strcmp(Parent.name(), "C_matrix")
			|| 0 == strcmp(Parent.name(), "pack_pattern")) {
		i = 1;
	}

	annotation->num_value_prop_pairs = i;
	annotation->prop = (int*) vtr::calloc(i, sizeof(int));
	annotation->value = (char**) vtr::calloc(i, sizeof(char *));
	annotation->line_num = loc_data.line(Parent);
	/* Todo: This is slow, I should use a case lookup */
	i = 0;
	if (0 == strcmp(Parent.name(), "delay_constant")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_DELAY;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "max", loc_data, OPTIONAL).as_string(NULL);
		if (Prop) {
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_MAX;
			annotation->value[i] = vtr::strdup(Prop);
			i++;
		}
		Prop = get_attribute(Parent, "min",loc_data, OPTIONAL).as_string(NULL);
		if (Prop) {
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_MIN;
			annotation->value[i] = vtr::strdup(Prop);
			i++;
		}
		Prop = get_attribute(Parent, "in_port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "out_port", loc_data).value();
		annotation->output_pins = vtr::strdup(Prop);

	} else if (0 == strcmp(Parent.name(), "delay_matrix")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_DELAY;
		annotation->format = E_ANNOT_PIN_TO_PIN_MATRIX;
		Prop = get_attribute(Parent, "type", loc_data).value();
		annotation->value[i] = vtr::strdup(Parent.child_value());

		if (0 == strcmp(Prop, "max")) {
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_MAX;
		} else {
			VTR_ASSERT(0 == strcmp(Prop, "min"));
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_MIN;
		}

		i++;
		Prop = get_attribute(Parent, "in_port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "out_port", loc_data).value();
		annotation->output_pins = vtr::strdup(Prop);

	} else if (0 == strcmp(Parent.name(), "C_constant")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_CAPACITANCE;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "C", loc_data).value();
		annotation->value[i] = vtr::strdup(Prop);
		annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_CAPACITANCE_C;
		i++;

		Prop = get_attribute(Parent, "in_port", loc_data, OPTIONAL).as_string(NULL);
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "out_port", loc_data,OPTIONAL).as_string(NULL);
		annotation->output_pins = vtr::strdup(Prop);
		VTR_ASSERT(
				annotation->output_pins != NULL || annotation->input_pins != NULL);

	} else if (0 == strcmp(Parent.name(), "C_matrix")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_CAPACITANCE;
		annotation->format = E_ANNOT_PIN_TO_PIN_MATRIX;
		annotation->value[i] = vtr::strdup(Parent.child_value());
		annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_CAPACITANCE_C;
		i++;

		Prop = get_attribute(Parent, "in_port", loc_data, OPTIONAL).as_string(NULL);
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "out_port", loc_data, OPTIONAL).as_string(NULL);
		annotation->output_pins = vtr::strdup(Prop);
		VTR_ASSERT(
				annotation->output_pins != NULL || annotation->input_pins != NULL);

	} else if (0 == strcmp(Parent.name(), "T_setup")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_DELAY;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "value", loc_data).value();
		annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_TSETUP;
		annotation->value[i] = vtr::strdup(Prop);

		i++;
		Prop = get_attribute(Parent, "port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "clock", loc_data).value();
		annotation->clock = vtr::strdup(Prop);

		primitives_annotation_clock_match(annotation, parent_pb_type);

	} else if (0 == strcmp(Parent.name(), "T_clock_to_Q")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_DELAY;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "max", loc_data, OPTIONAL).as_string(NULL);

        bool found_min_max_attrib = false;
		if (Prop) {
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX;
			annotation->value[i] = vtr::strdup(Prop);
			i++;
            found_min_max_attrib = true;
		}
		Prop = get_attribute(Parent, "min", loc_data, OPTIONAL).as_string(NULL);
		if (Prop) {
			annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN;
			annotation->value[i] = vtr::strdup(Prop);
			i++;
            found_min_max_attrib = true;
		}

        if(!found_min_max_attrib) {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
                    "Failed to find either 'max' or 'min' attribute required for <%s> in <%s>",
                    Parent.name(), Parent.parent().name());
        }

		Prop = get_attribute(Parent, "port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "clock", loc_data).value();
		annotation->clock = vtr::strdup(Prop);

		primitives_annotation_clock_match(annotation, parent_pb_type);

	} else if (0 == strcmp(Parent.name(), "T_hold")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_DELAY;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "value", loc_data).value();
		annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_DELAY_THOLD;
		annotation->value[i] = vtr::strdup(Prop);
		i++;

		Prop = get_attribute(Parent, "port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "clock", loc_data).value();
		annotation->clock = vtr::strdup(Prop);

		primitives_annotation_clock_match(annotation, parent_pb_type);

	} else if (0 == strcmp(Parent.name(), "pack_pattern")) {
		annotation->type = E_ANNOT_PIN_TO_PIN_PACK_PATTERN;
		annotation->format = E_ANNOT_PIN_TO_PIN_CONSTANT;
		Prop = get_attribute(Parent, "name", loc_data).value();
		annotation->prop[i] = (int) E_ANNOT_PIN_TO_PIN_PACK_PATTERN_NAME;
		annotation->value[i] = vtr::strdup(Prop);
		i++;

		Prop = get_attribute(Parent, "in_port", loc_data).value();
		annotation->input_pins = vtr::strdup(Prop);

		Prop = get_attribute(Parent, "out_port", loc_data).value();
		annotation->output_pins = vtr::strdup(Prop);

	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
				"Unknown port type %s in %s in %s", Parent.name(),
				Parent.parent().name(), Parent.parent().parent().name() );
	} 
	VTR_ASSERT(i == annotation->num_value_prop_pairs);
}

static void ProcessPb_TypePowerPinToggle(pugi::xml_node parent, t_pb_type * pb_type, const pugiutil::loc_data& loc_data) {
	pugi::xml_node cur;
	const char * prop;
	t_port * port;
	int high, low;

	cur = get_first_child(parent, "port", loc_data, OPTIONAL);
	while (cur) {
		prop = get_attribute(cur, "name", loc_data).value();

		port = findPortByName(prop, pb_type, &high, &low);
		if (!port) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
					"Could not find port '%s' needed for energy per toggle.",
					prop);
		}
		if (high != port->num_pins - 1 || low != 0) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
					"Pin-toggle does not support pin indices (%s)", prop);
		}

		if (port->port_power->pin_toggle_initialized) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
					"Duplicate pin-toggle energy for port '%s'", port->name);
		}
		port->port_power->pin_toggle_initialized = true;

		/* Get energy per toggle */
		port->port_power->energy_per_toggle = get_attribute(cur,
				"energy_per_toggle", loc_data).as_float(0.);

		/* Get scaled by factor */
		bool reverse_scaled = false;
		prop = get_attribute(cur, "scaled_by_static_prob", loc_data, OPTIONAL).as_string(NULL);
		if (!prop) {
			prop = get_attribute(cur, "scaled_by_static_prob_n", loc_data, OPTIONAL).as_string(NULL);
			if (prop) {
				reverse_scaled = true;
			}
		}

		if (prop) {
			port->port_power->scaled_by_port = findPortByName(prop, pb_type,
					&high, &low);
			if (high != low) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Pin-toggle 'scaled_by_static_prob' must be a single pin (%s)",
						prop);
			}
			port->port_power->scaled_by_port_pin_idx = high;
			port->port_power->reverse_scaled = reverse_scaled;
		}

		cur = cur.next_sibling(cur.name());
	}
}

static void ProcessPb_TypePower(pugi::xml_node Parent, t_pb_type * pb_type, const pugiutil::loc_data& loc_data) {
	pugi::xml_node cur, child;
	bool require_dynamic_absolute = false;
	bool require_static_absolute = false;
	bool require_dynamic_C_internal = false;

	cur = get_first_child(Parent, "power", loc_data, OPTIONAL);
	if (!cur) {
		return;
	}

	switch (pb_type->pb_type_power->estimation_method) {
	case POWER_METHOD_TOGGLE_PINS:
		ProcessPb_TypePowerPinToggle(cur, pb_type, loc_data);
		require_static_absolute = true;
		break;
	case POWER_METHOD_C_INTERNAL:
		require_dynamic_C_internal = true;
		require_static_absolute = true;
		break;
	case POWER_METHOD_ABSOLUTE:
		require_dynamic_absolute = true;
		require_static_absolute = true;
		break;
	default:
		break;
	}

	if (require_static_absolute) {
		child = get_single_child(cur, "static_power", loc_data);
		pb_type->pb_type_power->absolute_power_per_instance.leakage =
				get_attribute(child, "power_per_instance", loc_data).as_float(0.);
	}

	if (require_dynamic_absolute) {
		child = get_single_child(cur, "dynamic_power", loc_data);
		pb_type->pb_type_power->absolute_power_per_instance.dynamic =
				get_attribute(child, "power_per_instance", loc_data).as_float(0.);
	}

	if (require_dynamic_C_internal) {
		child = get_single_child(cur, "dynamic_power", loc_data);
		pb_type->pb_type_power->C_internal = get_attribute(child,
				"C_internal", loc_data).as_float(0.);
	}

}

static void ProcessPb_TypePowerEstMethod(pugi::xml_node Parent, t_pb_type * pb_type, const pugiutil::loc_data& loc_data) {
	pugi::xml_node cur;
	const char * prop;

	e_power_estimation_method parent_power_method;

	prop = NULL;

	cur = get_first_child(Parent, "power", loc_data, OPTIONAL);
	if (cur) {
		prop = get_attribute(cur, "method", loc_data, OPTIONAL).as_string(NULL);
	}

	if (pb_type->parent_mode && pb_type->parent_mode->parent_pb_type) {
		parent_power_method =
				pb_type->parent_mode->parent_pb_type->pb_type_power->estimation_method;
	} else {
		parent_power_method = POWER_METHOD_AUTO_SIZES;
	}

	if (!prop) {
		/* default method is auto-size */
		pb_type->pb_type_power->estimation_method = power_method_inherited(
				parent_power_method);
	} else if (strcmp(prop, "auto-size") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_AUTO_SIZES;
	} else if (strcmp(prop, "specify-size") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_SPECIFY_SIZES;
	} else if (strcmp(prop, "pin-toggle") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_TOGGLE_PINS;
	} else if (strcmp(prop, "c-internal") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_C_INTERNAL;
	} else if (strcmp(prop, "absolute") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_ABSOLUTE;
	} else if (strcmp(prop, "ignore") == 0) {
		pb_type->pb_type_power->estimation_method = POWER_METHOD_IGNORE;
	} else if (strcmp(prop, "sum-of-children") == 0) {
		pb_type->pb_type_power->estimation_method =
				POWER_METHOD_SUM_OF_CHILDREN;
	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
				"Invalid power estimation method for pb_type '%s'",
				pb_type->name);
	}
}

/* Takes in a pb_type, allocates and loads data for it and recurses downwards */
static void ProcessPb_Type(pugi::xml_node Parent, t_pb_type * pb_type,
		t_mode * mode, const t_arch& arch, const pugiutil::loc_data& loc_data) {
	int num_ports, i, j, k, num_annotations;
	const char *Prop;
	pugi::xml_node Cur;

	char* class_name;
	/* STL maps for checking various duplicate names */
	map<string, int> pb_port_names;
	map<string, int> mode_names;
	pair<map<string, int>::iterator, bool> ret_pb_ports;
	pair<map<string, int>::iterator, bool> ret_mode_names;
	int num_in_ports, num_out_ports, num_clock_ports;
	int num_delay_constant, num_delay_matrix, num_C_constant, num_C_matrix,
			num_T_setup, num_T_cq, num_T_hold;

	pb_type->parent_mode = mode;
	if (mode != NULL && mode->parent_pb_type != NULL) {
		pb_type->depth = mode->parent_pb_type->depth + 1;
		Prop = get_attribute(Parent, "name", loc_data).value();
		pb_type->name = vtr::strdup(Prop);
	} else {
		pb_type->depth = 0;
		/* same name as type */
	}

	Prop = get_attribute(Parent, "blif_model", loc_data, OPTIONAL).as_string(NULL);
	pb_type->blif_model = vtr::strdup(Prop);

	pb_type->class_type = UNKNOWN_CLASS;
	Prop = get_attribute(Parent, "class", loc_data, OPTIONAL).as_string(NULL);
	class_name = vtr::strdup(Prop);

	if (class_name) {

		if (0 == strcmp(class_name, "lut")) {
			pb_type->class_type = LUT_CLASS;
		} else if (0 == strcmp(class_name, "flipflop")) {
			pb_type->class_type = LATCH_CLASS;
		} else if (0 == strcmp(class_name, "memory")) {
			pb_type->class_type = MEMORY_CLASS;
		} else {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
					"Unknown class '%s' in pb_type '%s'\n", class_name,
					pb_type->name);
		}
		free(class_name);
	}

	if (mode == NULL) {
		pb_type->num_pb = 1;
	} else {
		pb_type->num_pb = get_attribute(Parent, "num_pb", loc_data).as_int(0);
	}

	VTR_ASSERT(pb_type->num_pb > 0);
	num_ports = num_in_ports = num_out_ports = num_clock_ports = 0;
	num_in_ports = count_children(Parent, "input", loc_data, OPTIONAL);
	num_out_ports = count_children(Parent, "output", loc_data, OPTIONAL);
	num_clock_ports = count_children(Parent, "clock", loc_data, OPTIONAL);
	num_ports = num_in_ports + num_out_ports + num_clock_ports;
	pb_type->ports = (t_port*) vtr::calloc(num_ports, sizeof(t_port));
	pb_type->num_ports = num_ports;

	/* Enforce VPR's definition of LUT/FF by checking number of ports */
	if (pb_type->class_type == LUT_CLASS
			|| pb_type->class_type == LATCH_CLASS) {
		if (num_in_ports != 1 || num_out_ports != 1) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
					"%s primitives must contain exactly one input port and one output port."
							"Found '%d' input port(s) and '%d' output port(s) for '%s'",
					(pb_type->class_type == LUT_CLASS) ? "LUT" : "Latch",
					num_in_ports, num_out_ports, pb_type->name);
		}
	}


	/* Initialize Power Structure */
	pb_type->pb_type_power = (t_pb_type_power*) vtr::calloc(1,
			sizeof(t_pb_type_power));
	ProcessPb_TypePowerEstMethod(Parent, pb_type, loc_data);

	/* process ports */
	j = 0;
	for (i = 0; i < 3; i++) {
		if (i == 0) {
			k = 0;
			Cur = get_first_child(Parent, "input", loc_data, OPTIONAL);
		} else if (i == 1) {
			k = 0;
			Cur = get_first_child(Parent, "output", loc_data, OPTIONAL);
		} else {
			k = 0;
			Cur = get_first_child(Parent, "clock", loc_data, OPTIONAL);
		}
		while (Cur) {
			pb_type->ports[j].parent_pb_type = pb_type;
			pb_type->ports[j].index = j;
			pb_type->ports[j].port_index_by_type = k;
			ProcessPb_TypePort(Cur, &pb_type->ports[j],
					pb_type->pb_type_power->estimation_method, loc_data);

			//Check port name duplicates
			ret_pb_ports = pb_port_names.insert(
					pair<string, int>(pb_type->ports[j].name, 0));
			if (!ret_pb_ports.second) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Duplicate port names in pb_type '%s': port '%s'\n",
						pb_type->name, pb_type->ports[j].name);
			}

			/* get next iteration */
			j++;
			k++;
			Cur = Cur.next_sibling(Cur.name()); 
		}
	}

	VTR_ASSERT(j == num_ports);

	/* Count stats on the number of each type of pin */
	pb_type->num_clock_pins = pb_type->num_input_pins =
			pb_type->num_output_pins = 0;
	for (i = 0; i < pb_type->num_ports; i++) {
		if (pb_type->ports[i].type == IN_PORT
				&& pb_type->ports[i].is_clock == false) {
			pb_type->num_input_pins += pb_type->ports[i].num_pins;
		} else if (pb_type->ports[i].type == OUT_PORT) {
			pb_type->num_output_pins += pb_type->ports[i].num_pins;
		} else {
			VTR_ASSERT(
					pb_type->ports[i].is_clock
							&& pb_type->ports[i].type == IN_PORT);
			pb_type->num_clock_pins += pb_type->ports[i].num_pins;
		}
	}

	/* set max_internal_delay if exist */
	pb_type->max_internal_delay = UNDEFINED;
	Cur = get_single_child(Parent, "max_internal_delay", loc_data, OPTIONAL);
	if (Cur) {
		pb_type->max_internal_delay = get_attribute(Cur, "value", loc_data).as_float(UNDEFINED);
	}

	pb_type->annotations = NULL;
	pb_type->num_annotations = 0;
	i = 0;
	/* Determine if this is a leaf or container pb_type */
	if (pb_type->blif_model != NULL) {
		/* Process delay and capacitance annotations */
		num_annotations = 0;
		num_delay_constant = count_children(Parent, "delay_constant", loc_data, OPTIONAL);
		num_delay_matrix = count_children(Parent, "delay_matrix", loc_data, OPTIONAL);
		num_C_constant = count_children(Parent, "C_constant", loc_data, OPTIONAL);
		num_C_matrix = count_children(Parent, "C_matrix", loc_data, OPTIONAL);
		num_T_setup = count_children(Parent, "T_setup", loc_data, OPTIONAL);
		num_T_cq = count_children(Parent, "T_clock_to_Q", loc_data, OPTIONAL);
		num_T_hold = count_children(Parent, "T_hold", loc_data, OPTIONAL);
		num_annotations = num_delay_constant + num_delay_matrix + num_C_constant
				+ num_C_matrix + num_T_setup + num_T_cq + num_T_hold;

		pb_type->annotations = (t_pin_to_pin_annotation*) vtr::calloc(
				num_annotations, sizeof(t_pin_to_pin_annotation));
		pb_type->num_annotations = num_annotations;

		j = 0;
		for (i = 0; i < 7; i++) {
			if (i == 0) {
				Cur = get_first_child(Parent, "delay_constant", loc_data, OPTIONAL);
			} else if (i == 1) {
				Cur = get_first_child(Parent, "delay_matrix", loc_data, OPTIONAL);
			} else if (i == 2) {
				Cur = get_first_child(Parent, "C_constant", loc_data, OPTIONAL);
			} else if (i == 3) {
				Cur = get_first_child(Parent, "C_matrix", loc_data, OPTIONAL);
			} else if (i == 4) {
				Cur = get_first_child(Parent, "T_setup", loc_data, OPTIONAL);
			} else if (i == 5) {
				Cur = get_first_child(Parent, "T_clock_to_Q", loc_data, OPTIONAL);
			} else if (i == 6) {
				Cur = get_first_child(Parent, "T_hold", loc_data, OPTIONAL);
			}
			while (Cur) {
				ProcessPinToPinAnnotations(Cur, &pb_type->annotations[j],
						pb_type, loc_data);

				/* get next iteration */
				j++;
				Cur = Cur.next_sibling(Cur.name());
			}
		}
		VTR_ASSERT(j == num_annotations);

        check_leaf_pb_model_timing_consistency(pb_type, arch);

		/* leaf pb_type, if special known class, then read class lib otherwise treat as primitive */
		if (pb_type->class_type == LUT_CLASS) {
			ProcessLutClass(pb_type);
		} else if (pb_type->class_type == MEMORY_CLASS) {
			ProcessMemoryClass(pb_type);
		} else {
			/* other leaf pb_type do not have modes */
			pb_type->num_modes = 0;
			VTR_ASSERT(count_children(Parent, "mode", loc_data, OPTIONAL) == 0);
		}
	} else {
		/* container pb_type, process modes */
		VTR_ASSERT(pb_type->class_type == UNKNOWN_CLASS);
		pb_type->num_modes = count_children(Parent, "mode", loc_data, OPTIONAL);
		pb_type->pb_type_power->leakage_default_mode = 0;

		if (pb_type->num_modes == 0) {
			/* The pb_type operates in an implied one mode */
			pb_type->num_modes = 1;
			pb_type->modes = (t_mode*) vtr::calloc(pb_type->num_modes,
					sizeof(t_mode));
			pb_type->modes[i].parent_pb_type = pb_type;
			pb_type->modes[i].index = i;
			ProcessMode(Parent, &pb_type->modes[i], arch, loc_data);
			i++;
		} else {
			pb_type->modes = (t_mode*) vtr::calloc(pb_type->num_modes,
					sizeof(t_mode));

			Cur = get_first_child(Parent, "mode", loc_data);
			while (Cur != NULL) {
				if (0 == strcmp(Cur.name(), "mode")) {
					pb_type->modes[i].parent_pb_type = pb_type;
					pb_type->modes[i].index = i;
					ProcessMode(Cur, &pb_type->modes[i], arch, loc_data);

					ret_mode_names = mode_names.insert(
							pair<string, int>(pb_type->modes[i].name, 0));
					if (!ret_mode_names.second) {
						archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
								"Duplicate mode name: '%s' in pb_type '%s'.\n",
								pb_type->modes[i].name, pb_type->name);
					}

					/* get next iteration */
					i++;
					Cur = Cur.next_sibling(Cur.name());
				}
			}
		}
		VTR_ASSERT(i == pb_type->num_modes);
	}

	pb_port_names.clear();
	mode_names.clear();
	ProcessPb_TypePower(Parent, pb_type, loc_data);

}

static void ProcessPb_TypePort_Power(pugi::xml_node Parent, t_port * port,
		e_power_estimation_method power_method, const pugiutil::loc_data& loc_data) {
	pugi::xml_node cur;
	const char * prop;
	bool wire_defined = false;

	port->port_power = (t_port_power*) vtr::calloc(1, sizeof(t_port_power));

	//Defaults
	if (power_method == POWER_METHOD_AUTO_SIZES) {
		port->port_power->wire_type = POWER_WIRE_TYPE_AUTO;
		port->port_power->buffer_type = POWER_BUFFER_TYPE_AUTO;
	} else if (power_method == POWER_METHOD_SPECIFY_SIZES) {
		port->port_power->wire_type = POWER_WIRE_TYPE_IGNORED;
		port->port_power->buffer_type = POWER_BUFFER_TYPE_NONE;
	}

	cur = get_single_child(Parent, "power", loc_data, OPTIONAL);

	if (cur) {
		/* Wire capacitance */

		/* Absolute C provided */
		prop = get_attribute(cur, "wire_capacitance", loc_data, OPTIONAL).as_string(NULL);
		if (prop) {
			if (!(power_method == POWER_METHOD_AUTO_SIZES
					|| power_method == POWER_METHOD_SPECIFY_SIZES)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Wire capacitance defined for port '%s'.  This is an invalid option for the parent pb_type '%s' power estimation method.",
						port->name, port->parent_pb_type->name);
			} else {
				wire_defined = true;
				port->port_power->wire_type = POWER_WIRE_TYPE_C;
				port->port_power->wire.C = (float) atof(prop);
			}
		}

		/* Wire absolute length provided */
		prop = get_attribute(cur, "wire_length", loc_data, OPTIONAL).as_string(NULL);
		if (prop) {
			if (!(power_method == POWER_METHOD_AUTO_SIZES
					|| power_method == POWER_METHOD_SPECIFY_SIZES)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Wire length defined for port '%s'.  This is an invalid option for the parent pb_type '%s' power estimation method.",
						port->name, port->parent_pb_type->name);
			} else if (wire_defined) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Multiple wire properties defined for port '%s', pb_type '%s'.",
						port->name, port->parent_pb_type->name);
			} else if (strcmp(prop, "auto") == 0) {
				wire_defined = true;
				port->port_power->wire_type = POWER_WIRE_TYPE_AUTO;
			} else {
				wire_defined = true;
				port->port_power->wire_type = POWER_WIRE_TYPE_ABSOLUTE_LENGTH;
				port->port_power->wire.absolute_length = (float) atof(prop);
			}
		}

		/* Wire relative length provided */
		prop = get_attribute(cur, "wire_relative_length", loc_data, OPTIONAL).as_string(NULL);
		if (prop) {
			if (!(power_method == POWER_METHOD_AUTO_SIZES
					|| power_method == POWER_METHOD_SPECIFY_SIZES)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Wire relative length defined for port '%s'.  This is an invalid option for the parent pb_type '%s' power estimation method.",
						port->name, port->parent_pb_type->name);
			} else if (wire_defined) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Multiple wire properties defined for port '%s', pb_type '%s'.",
						port->name, port->parent_pb_type->name);
			} else {
				wire_defined = true;
				port->port_power->wire_type = POWER_WIRE_TYPE_RELATIVE_LENGTH;
				port->port_power->wire.relative_length = (float) atof(prop);
			}
		}

		/* Buffer Size */
		prop = get_attribute(cur, "buffer_size", loc_data, OPTIONAL).as_string(NULL);
		if (prop) {
			if (!(power_method == POWER_METHOD_AUTO_SIZES
					|| power_method == POWER_METHOD_SPECIFY_SIZES)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(cur),
						"Buffer size defined for port '%s'.  This is an invalid option for the parent pb_type '%s' power estimation method.",
						port->name, port->parent_pb_type->name);
			} else if (strcmp(prop, "auto") == 0) {
				port->port_power->buffer_type = POWER_BUFFER_TYPE_AUTO;
			} else {
				port->port_power->buffer_type = POWER_BUFFER_TYPE_ABSOLUTE_SIZE;
				port->port_power->buffer_size = (float) atof(prop);
			}
		}
	}
}

static void ProcessPb_TypePort(pugi::xml_node Parent, t_port * port,
		e_power_estimation_method power_method, const pugiutil::loc_data& loc_data) {
	const char *Prop;
	Prop = get_attribute(Parent, "name", loc_data).value();
	port->name = vtr::strdup(Prop);

	Prop = get_attribute(Parent, "port_class", loc_data, OPTIONAL).as_string(NULL);
	port->port_class = vtr::strdup(Prop);

	Prop = get_attribute(Parent, "chain", loc_data, OPTIONAL).as_string(NULL);
	port->chain_name = vtr::strdup(Prop);

	port->equivalent = get_attribute(Parent, "equivalent", loc_data, OPTIONAL).as_bool(false);
	port->num_pins = get_attribute(Parent, "num_pins", loc_data).as_int(0);
	port->is_non_clock_global = get_attribute(Parent,
			"is_non_clock_global", loc_data, OPTIONAL).as_bool(false);

	if (0 == strcmp(Parent.name(), "input")) {
		port->type = IN_PORT;
		port->is_clock = false;

		/* Check if LUT/FF port class is lut_in/D */
		if (port->parent_pb_type->class_type == LUT_CLASS) {
			if ((!port->port_class) || strcmp("lut_in", port->port_class)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Inputs to LUT primitives must have a port class named "
								"as \"lut_in\".");
			}
		} else if (port->parent_pb_type->class_type == LATCH_CLASS) {
			if ((!port->port_class) || strcmp("D", port->port_class)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Input to flipflop primitives must have a port class named "
								"as \"D\".");
			}
			/* Only allow one input pin for FF's */
			if (port->num_pins != 1) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Input port of flipflop primitives must have exactly one pin. "
								"Found %d.", port->num_pins);
			}
		}

	} else if (0 == strcmp(Parent.name(), "output")) {
		port->type = OUT_PORT;
		port->is_clock = false;

		/* Check if LUT/FF port class is lut_out/Q */
		if (port->parent_pb_type->class_type == LUT_CLASS) {
			if ((!port->port_class) || strcmp("lut_out", port->port_class)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Output to LUT primitives must have a port class named "
								"as \"lut_in\".");
			}
			/* Only allow one output pin for LUT's */
			if (port->num_pins != 1) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Output port of LUT primitives must have exactly one pin. "
								"Found %d.", port->num_pins);
			}
		} else if (port->parent_pb_type->class_type == LATCH_CLASS) {
			if ((!port->port_class) || strcmp("Q", port->port_class)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Output to flipflop primitives must have a port class named "
								"as \"D\".");
			}
			/* Only allow one output pin for FF's */
			if (port->num_pins != 1) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Output port of flipflop primitives must have exactly one pin. "
								"Found %d.", port->num_pins);
			}
		}
	} else if (0 == strcmp(Parent.name(), "clock")) {
		port->type = IN_PORT;
		port->is_clock = true;
		if (port->is_non_clock_global == true) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
					"Port %s cannot be both a clock and a non-clock simultaneously\n",
					Parent.name());
		}

		if (port->parent_pb_type->class_type == LATCH_CLASS) {
			if ((!port->port_class) || strcmp("clock", port->port_class)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Clock to flipflop primitives must have a port class named "
								"as \"clock\".");
			}
			/* Only allow one output pin for FF's */
			if (port->num_pins != 1) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
						"Clock port of flipflop primitives must have exactly one pin. "
								"Found %d.", port->num_pins);
			}
		}
	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Parent),
				"Unknown port type %s", Parent.name());
	}

	ProcessPb_TypePort_Power(Parent, port, power_method, loc_data);
}

static void ProcessInterconnect(pugi::xml_node Parent, t_mode * mode, const pugiutil::loc_data& loc_data) {
	int num_interconnect = 0;
	int num_complete, num_direct, num_mux;
	int i, j, k, L_index, num_annotations;
	int num_delay_constant, num_delay_matrix, num_C_constant, num_C_matrix,
			num_pack_pattern;
	const char *Prop;
	pugi::xml_node Cur;
	pugi::xml_node Cur2;

	map<string, int> interc_names;
	pair<map<string, int>::iterator, bool> ret_interc_names;

	num_complete = num_direct = num_mux = 0;
	num_complete = count_children(Parent, "complete", loc_data, OPTIONAL);
	num_direct = count_children(Parent, "direct", loc_data, OPTIONAL);
	num_mux = count_children(Parent, "mux", loc_data, OPTIONAL);
	num_interconnect = num_complete + num_direct + num_mux;

	mode->num_interconnect = num_interconnect;
	mode->interconnect = (t_interconnect*) vtr::calloc(num_interconnect,
			sizeof(t_interconnect));

	i = 0;
	for (L_index = 0; L_index < 3; L_index++) {
		if (L_index == 0) {
			Cur = get_first_child(Parent, "complete", loc_data, OPTIONAL);
		} else if (L_index == 1) {
			Cur = get_first_child(Parent, "direct", loc_data, OPTIONAL);
		} else {
			Cur = get_first_child(Parent, "mux", loc_data, OPTIONAL);
		}
		while (Cur != NULL) {
			if (0 == strcmp(Cur.name(), "complete")) {
				mode->interconnect[i].type = COMPLETE_INTERC;
			} else if (0 == strcmp(Cur.name(), "direct")) {
				mode->interconnect[i].type = DIRECT_INTERC;
			} else {
				VTR_ASSERT(0 == strcmp(Cur.name(), "mux"));
				mode->interconnect[i].type = MUX_INTERC;
			}

			mode->interconnect[i].line_num = loc_data.line(Cur);

			mode->interconnect[i].parent_mode_index = mode->index;
			mode->interconnect[i].parent_mode = mode;

			Prop = get_attribute(Cur, "input", loc_data).value();
			mode->interconnect[i].input_string = vtr::strdup(Prop);

			Prop = get_attribute(Cur, "output", loc_data).value();
			mode->interconnect[i].output_string = vtr::strdup(Prop);

			Prop = get_attribute(Cur, "name", loc_data).value();
			mode->interconnect[i].name = vtr::strdup(Prop);

			ret_interc_names = interc_names.insert(
					pair<string, int>(mode->interconnect[i].name, 0));
			if (!ret_interc_names.second) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
						"Duplicate interconnect name: '%s' in mode: '%s'.\n",
						mode->interconnect[i].name, mode->name);
			}

			/* Process delay and capacitance annotations */
			num_annotations = 0;
			num_delay_constant = count_children(Cur, "delay_constant", loc_data, OPTIONAL);
			num_delay_matrix = count_children(Cur, "delay_matrix", loc_data, OPTIONAL);
			num_C_constant = count_children(Cur, "C_constant", loc_data, OPTIONAL);
			num_C_matrix = count_children(Cur, "C_matrix", loc_data, OPTIONAL);
			num_pack_pattern = count_children(Cur, "pack_pattern", loc_data, OPTIONAL);
			num_annotations = num_delay_constant + num_delay_matrix
					+ num_C_constant + num_C_matrix + num_pack_pattern;


			mode->interconnect[i].annotations =
					(t_pin_to_pin_annotation*) vtr::calloc(num_annotations,
							sizeof(t_pin_to_pin_annotation));
			mode->interconnect[i].num_annotations = num_annotations;

			k = 0;
			for (j = 0; j < 5; j++) {
				if (j == 0) {
					Cur2 = get_first_child(Cur, "delay_constant", loc_data, OPTIONAL);
				} else if (j == 1) {
					Cur2 = get_first_child(Cur, "delay_matrix", loc_data, OPTIONAL);
				} else if (j == 2) {
					Cur2 = get_first_child(Cur, "C_constant", loc_data, OPTIONAL);
				} else if (j == 3) {
					Cur2 = get_first_child(Cur, "C_matrix", loc_data, OPTIONAL);
				} else if (j == 4) {
					Cur2 = get_first_child(Cur, "pack_pattern", loc_data, OPTIONAL);
				}
				while (Cur2 != NULL) {
					ProcessPinToPinAnnotations(Cur2,
							&(mode->interconnect[i].annotations[k]), NULL, loc_data);

					/* get next iteration */
					k++;
					Cur2 = Cur2.next_sibling(Cur2.name());
				}
			}
			VTR_ASSERT(k == num_annotations);

			/* Power */
			mode->interconnect[i].interconnect_power =
					(t_interconnect_power*) vtr::calloc(1,
							sizeof(t_interconnect_power));
			mode->interconnect[i].interconnect_power->port_info_initialized =
					false;

			/* get next iteration */
			Cur = Cur.next_sibling(Cur.name());			
			i++;
		}
	}

	interc_names.clear();
	VTR_ASSERT(i == num_interconnect);
}

static void ProcessMode(pugi::xml_node Parent, t_mode * mode, const t_arch& arch,
		const pugiutil::loc_data& loc_data) {
	int i;
	const char *Prop;
	pugi::xml_node Cur;
	map<string, int> pb_type_names;
	pair<map<string, int>::iterator, bool> ret_pb_types;

	if (0 == strcmp(Parent.name(), "pb_type")) {
		/* implied mode */
		mode->name = vtr::strdup(mode->parent_pb_type->name);
	} else {
		Prop = get_attribute(Parent, "name", loc_data).value();
		mode->name = vtr::strdup(Prop);
	}

	mode->num_pb_type_children = count_children(Parent, "pb_type", loc_data, OPTIONAL);
	if (mode->num_pb_type_children > 0) {
		mode->pb_type_children = (t_pb_type*) vtr::calloc(
				mode->num_pb_type_children, sizeof(t_pb_type));

		i = 0;
		Cur = get_first_child(Parent, "pb_type", loc_data);
		while (Cur != NULL) {
			if (0 == strcmp(Cur.name(), "pb_type")) {
				ProcessPb_Type(Cur, &mode->pb_type_children[i], mode, arch, loc_data);

				ret_pb_types = pb_type_names.insert(
						pair<string, int>(mode->pb_type_children[i].name, 0));
				if (!ret_pb_types.second) {
					archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
							"Duplicate pb_type name: '%s' in mode: '%s'.\n",
							mode->pb_type_children[i].name, mode->name);
				}

				/* get next iteration */
				i++;
				Cur = Cur.next_sibling(Cur.name());
			}
		}
	} else {
		mode->pb_type_children = NULL;
	}

	/* Allocate power structure */
	mode->mode_power = (t_mode_power*) vtr::calloc(1, sizeof(t_mode_power));

	/* Clear STL map used for duplicate checks */
	pb_type_names.clear();

	Cur = get_single_child(Parent, "interconnect", loc_data);
	ProcessInterconnect(Cur, mode, loc_data);
}

/* Takes in the node ptr for the 'fc' elements and initializes
 * the appropriate fields of type. */
static void Process_Fc(pugi::xml_node Node, t_type_descriptor * Type, t_segment_inf *segments, int num_segments, const pugiutil::loc_data& loc_data) {
    e_fc_value_type default_fc_in_value_type = e_fc_value_type::FRACTIONAL;
    e_fc_value_type default_fc_out_value_type = e_fc_value_type::FRACTIONAL;
    float default_fc_in_value = std::numeric_limits<float>::quiet_NaN();
    float default_fc_out_value = std::numeric_limits<float>::quiet_NaN();

	/* Load the default fc_in */
	auto default_fc_in_attrib = get_attribute(Node, "default_in_type", loc_data);
    default_fc_in_value_type = string_to_fc_value_type(default_fc_in_attrib.value(), Node, loc_data);

    auto default_in_val_attrib = get_attribute(Node, "default_in_val", loc_data);
    default_fc_in_value = vtr::atof(default_in_val_attrib.value());

	/* Load the default fc_out */
	auto default_fc_out_attrib = get_attribute(Node, "default_out_type", loc_data);
    default_fc_out_value_type = string_to_fc_value_type(default_fc_out_attrib.value(), Node, loc_data);

    auto default_out_val_attrib = get_attribute(Node, "default_out_val", loc_data);
    default_fc_out_value = vtr::atof(default_out_val_attrib.value());

    /* Load any <fc_override/> tags */
    std::vector<t_fc_override> fc_overrides;
    for (auto child_node : Node.children()) {
        t_fc_override fc_override = Process_Fc_override(child_node, loc_data);
        fc_overrides.push_back(fc_override);
    }


    /* Go through all the port/segment combinations and create the (potentially 
     * overriden) pin/seg Fc specifications */
    const t_pb_type* pb_type = Type->pb_type;
    int pins_per_capacity_instance = Type->num_pins / Type->capacity;
    for (int iseg = 0; iseg < num_segments; ++iseg) {

        for(int icapacity = 0; icapacity < Type->capacity; ++icapacity) {

            //If capacity > 0, we need t offset the block index by the number of pins per instance
            //this ensures that all pins have an Fc specification
            int iblk_pin = icapacity * pins_per_capacity_instance;

            for(int iport = 0; iport < pb_type->num_ports; ++iport) {
                const t_port* port = &pb_type->ports[iport];

                t_fc_specification fc_spec;

                fc_spec.seg_index = iseg;

                //Apply type and defaults
                if (port->type == IN_PORT) {
                    fc_spec.fc_type = e_fc_type::IN;
                    fc_spec.fc_value_type = default_fc_in_value_type;
                    fc_spec.fc_value = default_fc_in_value;
                } else {
                    VTR_ASSERT(port->type == OUT_PORT);
                    fc_spec.fc_type = e_fc_type::OUT;
                    fc_spec.fc_value_type = default_fc_out_value_type;
                    fc_spec.fc_value = default_fc_out_value;
                }

                //Apply any matching overrides
                bool default_overriden = false;
                for(const auto& fc_override : fc_overrides) {
                    bool apply_override = false;
                    if (!fc_override.port_name.empty() && !fc_override.seg_name.empty()) {
                        //Both port and seg names are specified require exact match on both
                        if (fc_override.port_name == port->name && fc_override.seg_name == segments[iseg].name) {
                            apply_override = true;
                        }
                        
                    } else if (!fc_override.port_name.empty()) {
                        VTR_ASSERT(fc_override.seg_name.empty());
                        //Only the port name specified, require it to match
                        if (fc_override.port_name == port->name) {
                            apply_override = true;
                        }
                    } else {
                        VTR_ASSERT(!fc_override.seg_name.empty());
                        VTR_ASSERT(fc_override.port_name.empty());
                        //Only the seg name specified, require it to match
                        if (fc_override.seg_name == segments[iseg].name) {
                            apply_override = true;
                        }
                    }

                    if (apply_override) {
                        //Exact match, or partial match to either port or seg name
                        // Note that we continue searching, this ensures that the last matching override (in file order)
                        // is applied last

                        if (default_overriden) {
                            //Warn if multiple overrides match
                            vtr::printf_warning(loc_data.filename_c_str(), loc_data.line(Node), "Multiple matching Fc overrides found; the last will be applied\n");
                        }

                        fc_spec.fc_value_type = fc_override.fc_value_type;
                        fc_spec.fc_value = fc_override.fc_value;

                        default_overriden = true;
                    }
                }

                //Add all the pins from this port
                for(int iport_pin = 0; iport_pin < port->num_pins; ++iport_pin) {
                    //XXX: this assumes that iterating through the pb_type ports 
                    //     in order yields the block pin order
                    fc_spec.pins.push_back(iblk_pin);
                    ++iblk_pin;
                }

                Type->fc_specs.push_back(fc_spec);
            }
        }
    }
}

static t_fc_override Process_Fc_override(pugi::xml_node node, const pugiutil::loc_data& loc_data) {
    if (node.name() != std::string("fc_override")) {
        archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                "Unexpeted node of type '%s' (expected optional 'fc_override')",
                node.name());
    }

    t_fc_override fc_override;

    expect_child_node_count(node, 0, loc_data);

    bool seen_fc_type = false;
    bool seen_fc_value = false;
    bool seen_port_or_seg = false;
    for(auto attrib : node.attributes()) {
        if (attrib.name() == std::string("port_name")) {
            fc_override.port_name = attrib.value();
            seen_port_or_seg |= true;
        } else if (attrib.name() == std::string("segment_name")) {
            fc_override.seg_name = attrib.value();
            seen_port_or_seg |= true;
        } else if (attrib.name() == std::string("fc_type")) {
            fc_override.fc_value_type = string_to_fc_value_type(attrib.value(), node, loc_data);
            seen_fc_type = true;
        } else if (attrib.name() == std::string("fc_val")) {
            fc_override.fc_value = vtr::atof(attrib.value());
            seen_fc_value = true;
        } else {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                    "Unexpected attribute '%s'", attrib.name());
        }
    }

    if (!seen_fc_type) {
        archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                "Missing expected attribute 'fc_type'");
    }

    if (!seen_fc_value) {
        archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                "Missing expected attribute 'fc_value'");
    }

    if (!seen_port_or_seg) {
        archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                "Missing expected attribute(s) 'port_name' and/or 'segment_name'");
    }

    return fc_override;
}

static e_fc_value_type string_to_fc_value_type(const std::string& str, pugi::xml_node node, const pugiutil::loc_data& loc_data) {
    e_fc_value_type fc_value_type = e_fc_value_type::FRACTIONAL;

    if (str == "frac") {
        fc_value_type = e_fc_value_type::FRACTIONAL;
    } else if (str == "abs") {
        fc_value_type = e_fc_value_type::ABSOLUTE;
    } else {
        archfpga_throw(loc_data.filename_c_str(), loc_data.line(node),
                "Invalid fc_type '%s'. Must be 'abs' or 'frac'.\n",
                str.c_str());
    }

    return fc_value_type;
}

/* Thie processes attributes of the 'type' tag */
static void ProcessComplexBlockProps(pugi::xml_node Node, t_type_descriptor * Type, const pugiutil::loc_data& loc_data) {
	const char *Prop;

	/* Load type name */
	Prop = get_attribute(Node, "name", loc_data).value();
	Type->name = vtr::strdup(Prop);

	/* Load properties */
	Type->capacity = get_attribute(Node, "capacity", loc_data, OPTIONAL).as_int(1); /* TODO: Any block with capacity > 1 that is not I/O has not been tested, must test */
	Type->width = get_attribute(Node, "width", loc_data, OPTIONAL).as_int(1);
	Type->height = get_attribute(Node, "height", loc_data, OPTIONAL).as_int(1);
	Type->area = get_attribute(Node, "area", loc_data, OPTIONAL).as_float(UNDEFINED);

	if (atof(Prop) < 0) {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
				"Area for type %s must be non-negative\n", Type->name);
	}
}

/* Takes in node pointing to <models> and loads all the
 * child type objects.  */
static void ProcessModels(pugi::xml_node Node, struct s_arch *arch, const pugiutil::loc_data& loc_data) {
	pugi::xml_node p;
	t_model *temp;
	int L_index;
	/* std::maps for checking duplicates */
	map<string, int> model_name_map;
	pair<map<string, int>::iterator, bool> ret_map_name;

	L_index = NUM_MODELS_IN_LIBRARY;

	arch->models = NULL;
    for(pugi::xml_node model : Node.children()) {
        //Process each model
        if(model.name() != std::string("model")) {
            bad_tag(model, loc_data, Node, {"model"});
        }

		temp = new t_model;
		temp->index = L_index;
		L_index++;

        //Process the <model> tag attributes
        for(pugi::xml_attribute attr : model.attributes()) {
            if(attr.name() != std::string("name")) {
                bad_attribute(attr, model, loc_data);
            } else {
                VTR_ASSERT(attr.name() == std::string("name"));

                if(!temp->name) {
                    //First name attr. seen
                    temp->name = vtr::strdup(attr.value());
                } else {
                    //Duplicate name
                    archfpga_throw(loc_data.filename_c_str(), loc_data.line(model),
                            "Duplicate 'name' attribute on <model> tag.");
                }
            }
        }

		/* Try insert new model, check if already exist at the same time */
		ret_map_name = model_name_map.insert(pair<string, int>(temp->name, 0));
		if (!ret_map_name.second) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(model),
					"Duplicate model name: '%s'.\n", temp->name);
		}

        //Process the ports
        std::set<std::string> port_names;
        for(pugi::xml_node port_group : model.children()) {
            if(port_group.name() == std::string("input_ports")) {
                ProcessModelPorts(port_group, temp, port_names, loc_data);
            } else if(port_group.name() == std::string("output_ports")) {
                ProcessModelPorts(port_group, temp, port_names, loc_data);
            } else {
                bad_tag(port_group, loc_data, model, {"input_ports", "output_ports"});
            }
        }

        //Sanity check the model
        check_model_clocks(model, loc_data, temp);
        check_model_combinational_sinks(model, loc_data, temp);
        warn_model_missing_timing(model, loc_data, temp);


        //Add the model
		temp->next = arch->models;
		arch->models = temp;
	}
	return;
}

static void ProcessModelPorts(pugi::xml_node port_group, t_model* model, std::set<std::string>& port_names, const pugiutil::loc_data& loc_data) {
    for(pugi::xml_attribute attr : port_group.attributes()) {
        bad_attribute(attr, port_group, loc_data);
    }

    enum PORTS dir = ERR_PORT;
    if(port_group.name() == std::string("input_ports")) {
        dir = IN_PORT;
    } else {
        VTR_ASSERT(port_group.name() == std::string("output_ports"));
        dir = OUT_PORT;
    }

    //Process each port
    for(pugi::xml_node port : port_group.children()) {
        //Should only be ports
        if(port.name() != std::string("port")) {
            bad_tag(port, loc_data, port_group, {"port"});
        }

        //Ports should have no children
        for(pugi::xml_node port_child : port.children()) {
            bad_tag(port_child, loc_data, port);
        }

        t_model_ports* model_port = new t_model_ports;

        model_port->dir = dir;

        //Process the attributes of each port
        for(pugi::xml_attribute attr : port.attributes()) {

            if(attr.name() == std::string("name")) {
                model_port->name = vtr::strdup(attr.value());

            } else if (attr.name() == std::string("is_clock")) {
                model_port->is_clock = attribute_to_bool(port, attr, loc_data);

            } else if (attr.name() == std::string("is_non_clock_global")) {
                model_port->is_non_clock_global = attribute_to_bool(port, attr, loc_data);

            } else if (attr.name() == std::string("clock")) {
                model_port->clock = std::string(attr.value());

            } else if (attr.name() == std::string("combinational_sink_ports")) {
                model_port->combinational_sink_ports = vtr::split(attr.value());

            } else {
                bad_attribute(attr, port, loc_data);
            }
        }

        //Sanity checks
        if (model_port->is_clock == true && model_port->is_non_clock_global == true) {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(port),
                    "Model port '%s' cannot be both a clock and a non-clock signal simultaneously", model_port->name);
        }

        if(port_names.count(model_port->name)) {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(port),
                    "Duplicate model port named '%s'", model_port->name);
        }

        if(dir == OUT_PORT && !model_port->combinational_sink_ports.empty()) {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(port),
                    "Model output ports can not have combinational sink ports");
            
        }

        //Add the port
        if(dir == IN_PORT) {
            model_port->next = model->inputs;
            model->inputs = model_port;

        } else {
            VTR_ASSERT(dir == OUT_PORT);

            model_port->next = model->outputs;
            model->outputs = model_port;
        }
    }
}

/* Takes in node pointing to <layout> and loads all the
 * child type objects. */
static void ProcessLayout(pugi::xml_node Node, struct s_arch *arch, const pugiutil::loc_data& loc_data) {
	const char *Prop;

	arch->clb_grid.IsAuto = true;
	ReqOpt CLB_GRID_ISAUTO;

	/* Load width and height if applicable */
	Prop = get_attribute(Node, "width", loc_data, OPTIONAL).as_string(NULL);
	if (Prop != NULL) {
		arch->clb_grid.IsAuto = false;
		arch->clb_grid.W = vtr::atoi(Prop);

		arch->clb_grid.H = get_attribute(Node, "height", loc_data).as_int(UNDEFINED);
	}

	/* Load aspect ratio if applicable */
	CLB_GRID_ISAUTO = BoolToReqOpt(arch->clb_grid.IsAuto);
	Prop = get_attribute(Node, "auto", loc_data, CLB_GRID_ISAUTO).as_string(NULL);
	if (Prop != NULL) {
		if (arch->clb_grid.IsAuto == false) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"Auto-sizing, width and height cannot be specified\n");
		}
		arch->clb_grid.Aspect = (float) atof(Prop);
		if (arch->clb_grid.Aspect <= 0) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"Grid aspect ratio is less than or equal to zero %g\n",
					arch->clb_grid.Aspect);
		}
	}
}

/* Takes in node pointing to <device> and loads all the
 * child type objects. */
static void ProcessDevice(pugi::xml_node Node, struct s_arch *arch,
		const bool timing_enabled, const pugiutil::loc_data& loc_data) {
	const char *Prop;
	pugi::xml_node Cur;
	bool custom_switch_block = false;

	ProcessSizingTimingIpinCblock(Node, arch, timing_enabled, loc_data);

	Cur = get_single_child(Node, "area", loc_data);
	arch->grid_logic_tile_area = get_attribute(Cur, "grid_logic_tile_area",
			loc_data, OPTIONAL).as_float(0);

	Cur = get_single_child(Node, "chan_width_distr", loc_data, OPTIONAL);
	if (Cur != NULL) {
		ProcessChanWidthDistr(Cur, arch, loc_data);
	}

	Cur = get_single_child(Node, "switch_block", loc_data);
	Prop = get_attribute(Cur, "type", loc_data).value();
	if (strcmp(Prop, "wilton") == 0) {
		arch->SBType = WILTON;
	} else if (strcmp(Prop, "universal") == 0) {
		arch->SBType = UNIVERSAL;
	} else if (strcmp(Prop, "subset") == 0) {
		arch->SBType = SUBSET;
	} else if (strcmp(Prop, "custom") == 0) {
		arch->SBType = CUSTOM;
		custom_switch_block = true;
	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Cur),
				"Unknown property %s for switch block type x\n", Prop);
	}
	
	ReqOpt CUSTOM_SWITCHBLOCK_REQD = BoolToReqOpt(!custom_switch_block);
	arch->Fs = get_attribute(Cur, "fs", loc_data, CUSTOM_SWITCHBLOCK_REQD).as_int(3);

}

/* Processes the sizing, timing, and ipin_cblock child objects of the 'device' node.
   We can specify an ipin cblock's info through the sizing/timing nodes (legacy),
   OR through the ipin_cblock node which specifies the info using the index of a switch. */
static void ProcessSizingTimingIpinCblock(pugi::xml_node Node,
		struct s_arch *arch, const bool timing_enabled, const pugiutil::loc_data& loc_data) {

	pugi::xml_node Cur;

	arch->ipin_mux_trans_size = UNDEFINED;
	arch->C_ipin_cblock = UNDEFINED;
	arch->T_ipin_cblock = UNDEFINED;
	ReqOpt TIMING_ENABLE_REQD;	
	

	TIMING_ENABLE_REQD = BoolToReqOpt(timing_enabled);

	Cur = get_single_child(Node, "sizing", loc_data);
	arch->R_minW_nmos = get_attribute(Cur, "R_minW_nmos", loc_data, TIMING_ENABLE_REQD).as_float(0);
	arch->R_minW_pmos = get_attribute(Cur, "R_minW_pmos", loc_data, TIMING_ENABLE_REQD).as_float(0);
	arch->ipin_mux_trans_size = get_attribute(Cur, "ipin_mux_trans_size",
			loc_data, OPTIONAL).as_float(0);

	/* currently only ipin cblock info is specified in the timing node */
	TIMING_ENABLE_REQD = BoolToReqOpt(timing_enabled);
	Cur = get_single_child(Node, "timing", loc_data, TIMING_ENABLE_REQD);
	if (Cur != NULL) {
		arch->C_ipin_cblock = get_attribute(Cur, "C_ipin_cblock", loc_data, OPTIONAL).as_float(0);
		arch->T_ipin_cblock = get_attribute(Cur, "T_ipin_cblock", loc_data, OPTIONAL).as_float(0);

	}
}

/* Takes in node pointing to <chan_width_distr> and loads all the
 * child type objects. */
static void ProcessChanWidthDistr(pugi::xml_node Node,
		struct s_arch *arch, const pugiutil::loc_data& loc_data) {
	pugi::xml_node Cur;

	Cur = get_single_child(Node, "io", loc_data);
	arch->Chans.chan_width_io = get_attribute(Cur, "width", loc_data).as_float(UNDEFINED);

	Cur = get_single_child(Node, "x", loc_data);
	ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_x_dist, loc_data);

	Cur = get_single_child(Node, "y", loc_data);
	ProcessChanWidthDistrDir(Cur, &arch->Chans.chan_y_dist, loc_data);
}

/* Takes in node within <chan_width_distr> and loads all the
 * child type objects. */
static void ProcessChanWidthDistrDir(pugi::xml_node Node, t_chan * chan, const pugiutil::loc_data& loc_data) {
	const char *Prop;

	ReqOpt hasXpeak, hasWidth, hasDc;
	hasXpeak = hasWidth = hasDc = OPTIONAL;

	Prop = get_attribute(Node, "distr", loc_data).value();
	if (strcmp(Prop, "uniform") == 0) {
		chan->type = UNIFORM;
	} else if (strcmp(Prop, "gaussian") == 0) {
		chan->type = GAUSSIAN;
		hasXpeak = hasWidth = hasDc = REQUIRED;
	} else if (strcmp(Prop, "pulse") == 0) {
		chan->type = PULSE;
		hasXpeak = hasWidth = hasDc = REQUIRED;
	} else if (strcmp(Prop, "delta") == 0) {
		hasXpeak = hasDc = REQUIRED;
		chan->type = DELTA;
	} else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
				"Unknown property %s for chan_width_distr x\n", Prop);
	}

	chan->peak = get_attribute(Node, "peak", loc_data).as_float(UNDEFINED);
	chan->width = get_attribute(Node, "width", loc_data, hasWidth).as_float(0);
	chan->xpeak = get_attribute(Node, "xpeak", loc_data, hasXpeak).as_float(0);
	chan->dc = get_attribute(Node, "dc", loc_data, hasDc).as_float(0);
}



/* Takes in node pointing to <typelist> and loads all the
 * child type objects. */
static void ProcessComplexBlocks(pugi::xml_node Node,
		t_type_descriptor ** Types, int *NumTypes,
		const s_arch& arch, const pugiutil::loc_data& loc_data) {
	pugi::xml_node CurType, Prev;
	pugi::xml_node Cur;
	t_type_descriptor * Type;
	int i;
	map<string, int> pb_type_descriptors;
	pair<map<string, int>::iterator, bool> ret_pb_type_descriptors;
	/* Alloc the type list. Need one additional t_type_desctiptors:
	 * 1: empty psuedo-type
	 */
	*NumTypes = count_children(Node, "pb_type", loc_data) + 1;
	*Types = new t_type_descriptor[*NumTypes];

	cb_type_descriptors = *Types;

	EMPTY_TYPE = &cb_type_descriptors[EMPTY_TYPE_INDEX];
	IO_TYPE = &cb_type_descriptors[IO_TYPE_INDEX];
	cb_type_descriptors[EMPTY_TYPE_INDEX].index = EMPTY_TYPE_INDEX;
	cb_type_descriptors[IO_TYPE_INDEX].index = IO_TYPE_INDEX;
	SetupEmptyType(cb_type_descriptors, EMPTY_TYPE);

	/* Process the types */
	/* TODO: I should make this more flexible but release is soon and I don't have time so assert values for empty and io types*/
	VTR_ASSERT(EMPTY_TYPE_INDEX == 0);
	VTR_ASSERT(IO_TYPE_INDEX == 1);
	i = 1; /* Skip over 'empty' type */

	CurType = Node.first_child();
	while (CurType) {
		check_node(CurType, "pb_type", loc_data);

		/* Alias to current type */
		Type = &(*Types)[i];

		/* Parses the properties fields of the type */
		ProcessComplexBlockProps(CurType, Type, loc_data);

		ret_pb_type_descriptors = pb_type_descriptors.insert(
				pair<string, int>(Type->name, 0));
		if (!ret_pb_type_descriptors.second) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurType),
					"Duplicate pb_type descriptor name: '%s'.\n", Type->name);
		}

		/* Load pb_type info */
		Type->pb_type = (t_pb_type*) vtr::malloc(sizeof(t_pb_type));
		Type->pb_type->name = vtr::strdup(Type->name);
		if (i == IO_TYPE_INDEX) {
			if (strcmp(Type->name, "io") != 0) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(CurType),
						"First complex block must be named \"io\" and define the inputs and outputs for the FPGA");
			}
		}
		ProcessPb_Type(CurType, Type->pb_type, NULL, arch, loc_data);
		Type->num_pins = Type->capacity
				* (Type->pb_type->num_input_pins
						+ Type->pb_type->num_output_pins
						+ Type->pb_type->num_clock_pins);
		Type->num_receivers = Type->capacity * Type->pb_type->num_input_pins;
		Type->num_drivers = Type->capacity * Type->pb_type->num_output_pins;

		/* Load pin names and classes and locations */
		Cur = get_single_child(CurType, "pinlocations", loc_data);
		SetupPinLocationsAndPinClasses(Cur, Type, loc_data);

		Cur = get_single_child(CurType, "gridlocations", loc_data);
		SetupGridLocations(Cur, Type, loc_data);

		/* Load Fc */
		Cur = get_single_child(CurType, "fc", loc_data);
		Process_Fc(Cur, Type, arch.Segments, arch.num_segments, loc_data);


		Type->index = i;

		/* Type fully read */
		++i;

		/* Free this node and get its next sibling node */
		CurType = CurType.next_sibling (CurType.name());

	}
	if (FILL_TYPE == NULL) {
		archfpga_throw(arch_file_name, 0,
				"grid location type 'fill' must be specified.\n");
	}
	pb_type_descriptors.clear();
}


static void ProcessSegments(pugi::xml_node Parent,
		struct s_segment_inf **Segs, int *NumSegs,
		const struct s_arch_switch_inf *Switches, const int NumSwitches,
		const bool timing_enabled, const bool switchblocklist_required, const pugiutil::loc_data& loc_data) {
	int i, j, length;
	const char *tmp;

	pugi::xml_node SubElem;
	pugi::xml_node Node;

	/* Count the number of segs and check they are in fact
	 * of segment elements. */
	*NumSegs = count_children(Parent, "segment", loc_data);

	/* Alloc segment list */
	*Segs = NULL;
	if (*NumSegs > 0) {
		*Segs = (struct s_segment_inf *) vtr::malloc(
				*NumSegs * sizeof(struct s_segment_inf));
		memset(*Segs, 0, (*NumSegs * sizeof(struct s_segment_inf)));
	}

	/* Load the segments. */
	Node = get_first_child(Parent, "segment", loc_data);
	for (i = 0; i < *NumSegs; ++i) {
		
		/* Get segment name */
		tmp = get_attribute(Node, "name", loc_data, OPTIONAL).as_string(NULL);
		if (tmp) {
			(*Segs)[i].name = vtr::strdup(tmp);
		} else {
			/* if swich block is "custom", then you have to provide a name for segment */
			if (switchblocklist_required) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"No name specified for the segment #%d.\n", i);

			}
			/* set name to default: "unnamed_segment_<segment_index>" */
			stringstream ss;
			ss << "unnamed_segment_" << i;
			string dummy = ss.str();
			tmp = dummy.c_str();
			(*Segs)[i].name = vtr::strdup(tmp);
		}

		/* Get segment length */
		length = 1; /* DEFAULT */
		tmp = get_attribute(Node, "length", loc_data, OPTIONAL).as_string(NULL);
		if (tmp) {
			if (strcmp(tmp, "longline") == 0) {
				(*Segs)[i].longline = true;
			} else {
				length = vtr::atoi(tmp);
			}
		}
		(*Segs)[i].length = length;

		/* Get the frequency */
		(*Segs)[i].frequency = 1; /* DEFAULT */
		tmp = get_attribute(Node, "freq", loc_data, OPTIONAL).as_string(NULL);
		if (tmp) {
			(*Segs)[i].frequency = (int) (atof(tmp) * MAX_CHANNEL_WIDTH);
		}

		/* Get timing info */
		ReqOpt TIMING_ENABLE_REQD = BoolToReqOpt(timing_enabled);
		(*Segs)[i].Rmetal = get_attribute(Node, "Rmetal", loc_data, TIMING_ENABLE_REQD).as_float(0);
		(*Segs)[i].Cmetal = get_attribute(Node, "Cmetal", loc_data, TIMING_ENABLE_REQD).as_float(0);

		/* Get Power info */
		/*
		 (*Segs)[i].Cmetal_per_m = get_attribute(Node, "Cmetal_per_m", false,
		 0.);*/

		/* Get the type */
		tmp = get_attribute(Node, "type", loc_data).value();
		if (0 == strcmp(tmp, "bidir")) {
			(*Segs)[i].directionality = BI_DIRECTIONAL;
		}

		else if (0 == strcmp(tmp, "unidir")) {
			(*Segs)[i].directionality = UNI_DIRECTIONAL;
		}

		else {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"Invalid switch type '%s'.\n", tmp);
		}

		/* Get the wire and opin switches, or mux switch if unidir */
		if (UNI_DIRECTIONAL == (*Segs)[i].directionality) {
			SubElem = get_single_child(Node, "mux", loc_data);
			tmp = get_attribute(SubElem, "name", loc_data).value();

			/* Match names */
			for (j = 0; j < NumSwitches; ++j) {
				if (0 == strcmp(tmp, Switches[j].name)) {
					break; /* End loop so j is where we want it */
				}
			}
			if (j >= NumSwitches) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
						"'%s' is not a valid mux name.\n", tmp);
			}

			/* Unidir muxes must have the same switch
			 * for wire and opin fanin since there is
			 * really only the mux in unidir. */
			(*Segs)[i].arch_wire_switch = j;
			(*Segs)[i].arch_opin_switch = j;
		}

		else {
			VTR_ASSERT(BI_DIRECTIONAL == (*Segs)[i].directionality);
			SubElem = get_single_child(Node, "wire_switch", loc_data);
			tmp = get_attribute(SubElem, "name", loc_data).value();

			/* Match names */
			for (j = 0; j < NumSwitches; ++j) {
				if (0 == strcmp(tmp, Switches[j].name)) {
					break; /* End loop so j is where we want it */
				}
			}
			if (j >= NumSwitches) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
						"'%s' is not a valid wire_switch name.\n", tmp);
			}
			(*Segs)[i].arch_wire_switch = j;
			SubElem = get_single_child(Node, "opin_switch", loc_data);
			tmp = get_attribute(SubElem, "name", loc_data).value();

			/* Match names */
			for (j = 0; j < NumSwitches; ++j) {
				if (0 == strcmp(tmp, Switches[j].name)) {
					break; /* End loop so j is where we want it */
				}
			}
			if (j >= NumSwitches) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem),
						"'%s' is not a valid opin_switch name.\n", tmp);
			}
			(*Segs)[i].arch_opin_switch = j;
		}

		/* Setup the CB list if they give one, otherwise use full */
		(*Segs)[i].cb_len = length;
		(*Segs)[i].cb = (bool *) vtr::malloc(length * sizeof(bool));
		for (j = 0; j < length; ++j) {
			(*Segs)[i].cb[j] = true;
		}
		SubElem = get_single_child(Node, "cb", loc_data, OPTIONAL);
		if (SubElem) {
			ProcessCB_SB(SubElem, (*Segs)[i].cb, length, loc_data);
		}

		/* Setup the SB list if they give one, otherwise use full */
		(*Segs)[i].sb_len = (length + 1);
		(*Segs)[i].sb = (bool *) vtr::malloc((length + 1) * sizeof(bool));
		for (j = 0; j < (length + 1); ++j) {
			(*Segs)[i].sb[j] = true;
		}
		SubElem = get_single_child(Node, "sb", loc_data, OPTIONAL);
		if (SubElem) {
			ProcessCB_SB(SubElem, (*Segs)[i].sb, (length + 1), loc_data);
		}
		
		/* Get next Node */
		Node = Node.next_sibling(Node.name());
	}
}

/* Processes the switchblocklist section from the xml architecture file. 
   See vpr/SRC/route/build_switchblocks.c for a detailed description of this 
   switch block format */
static void ProcessSwitchblocks(pugi::xml_node Parent, t_arch* arch, const pugiutil::loc_data& loc_data){

	pugi::xml_node Node;
	pugi::xml_node SubElem;
	const char *tmp;

	/* get the number of switchblocks */
	int num_switchblocks = count_children(Parent, "switchblock", loc_data);
	arch->switchblocks.reserve(num_switchblocks);

	
	/* read-in all switchblock data */
	Node = get_first_child(Parent, "switchblock", loc_data);
	for (int i_sb = 0; i_sb < num_switchblocks; i_sb++){
		/* use a temp variable which will be assigned to switchblocks later */
		t_switchblock_inf sb;

		/* get name */
		tmp = get_attribute(Node, "name", loc_data).as_string(NULL);
		if (tmp){
			sb.name = tmp;
		}

		/* get type */
		tmp = get_attribute(Node, "type", loc_data).as_string(NULL);
		if (tmp){
			if (0 == strcmp(tmp, "bidir")){
				sb.directionality = BI_DIRECTIONAL;
			} else if (0 == strcmp(tmp, "unidir")){
				sb.directionality = UNI_DIRECTIONAL;
			} else {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node), "Unsopported switchblock type: %s\n", tmp);
			}
		}

		/* get the switchblock location */
		SubElem = get_single_child(Node, "switchblock_location", loc_data);
		tmp = get_attribute(SubElem, "type", loc_data).as_string(NULL);
		if (tmp){
			if (strcmp(tmp, "EVERYWHERE") == 0){
				sb.location = E_EVERYWHERE;
			} else if (strcmp(tmp, "PERIMETER") == 0){
				sb.location = E_PERIMETER;
			} else if (strcmp(tmp, "CORE") == 0){
				sb.location = E_CORE;
			} else if (strcmp(tmp, "CORNER") == 0){
				sb.location = E_CORNER;
			} else if (strcmp(tmp, "FRINGE") == 0){
				sb.location = E_FRINGE;
			} else {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(SubElem), "unrecognized switchblock location: %s\n", tmp);
			}
		}

		/* get switchblock permutation functions */
		SubElem = get_first_child(Node, "switchfuncs", loc_data);
		read_sb_switchfuncs(SubElem, &sb, loc_data);
		
		read_sb_wireconns(arch->Switches, arch->num_switches, Node, &sb, loc_data);

		/* run error checks on switch blocks */
		check_switchblock(&sb, arch);

		/* assign the sb to the switchblocks vector */		
		arch->switchblocks.push_back(sb);

		Node = Node.next_sibling(Node.name());
	}

	return;
}


static void ProcessCB_SB(pugi::xml_node Node, bool * list,
		const int len, const pugiutil::loc_data& loc_data) {
	const char *tmp = NULL;
	int i;

	/* Check the type. We only support 'pattern' for now.
	 * Should add frac back eventually. */
	tmp = get_attribute(Node, "type", loc_data).value();
	if (0 == strcmp(tmp, "pattern")) {
		i = 0;

		/* Get the content string */
		tmp = Node.child_value();
		while (*tmp) {
			switch (*tmp) {
			case ' ':
			case '\t':
			case '\n':
				break;
			case 'T':
			case '1':
				if (i >= len) {
					archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
							"CB or SB depopulation is too long. It should be (length) symbols for CBs and (length+1) symbols for SBs.\n");
				}
				list[i] = true;
				++i;
				break;
			case 'F':
			case '0':
				if (i >= len) {
					archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
							"CB or SB depopulation is too long. It should be (length) symbols for CBs and (length+1) symbols for SBs.\n");
				}
				list[i] = false;
				++i;
				break;
			default:
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
						"Invalid character %c in CB or SB depopulation list.\n",
						*tmp);
			}
			++tmp;
		}
		if (i < len) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"CB or SB depopulation is too short. It should be (length) symbols for CBs and (length+1) symbols for SBs.\n");
		}
	}

	else {
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
				"'%s' is not a valid type for specifying cb and sb depopulation.\n",
				tmp);
	}
}

static void ProcessSwitches(pugi::xml_node Parent,
		struct s_arch_switch_inf **Switches, int *NumSwitches,
		const bool timing_enabled, const pugiutil::loc_data& loc_data) {
	int i, j;
	const char *type_name;
	const char *switch_name;
	const char *buf_size;

	ReqOpt has_buf_size;
	pugi::xml_node Node;
	has_buf_size = OPTIONAL;

	/* Count the children and check they are switches */
	*NumSwitches = count_children(Parent, "switch", loc_data);

	/* Alloc switch list */
	*Switches = NULL;
	if (*NumSwitches > 0) {
		(*Switches) = new s_arch_switch_inf[(*NumSwitches)];
	}

	/* Load the switches. */
	Node = get_first_child(Parent, "switch", loc_data);
	for (i = 0; i < *NumSwitches; ++i) {

		switch_name = get_attribute(Node, "name", loc_data).value();
		type_name = get_attribute(Node, "type", loc_data).value();

		/* Check for switch name collisions */
		for (j = 0; j < i; ++j) {
			if (0 == strcmp((*Switches)[j].name, switch_name)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
						"Two switches with the same name '%s' were found.\n",
						switch_name);
			}
		}
		(*Switches)[i].name = vtr::strdup(switch_name);

		/* Figure out the type of switch. */
		if (0 == strcmp(type_name, "mux")) {
			(*Switches)[i].buffered = true;
			has_buf_size = REQUIRED;
		}

		else if (0 == strcmp(type_name, "pass_trans")) {
			(*Switches)[i].buffered = false;
		}

		else if (0 == strcmp(type_name, "buffer")) {
			(*Switches)[i].buffered = true;
		}

		else {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"Invalid switch type '%s'.\n", type_name);
		}
		
		ReqOpt TIMING_ENABLE_REQD = BoolToReqOpt(timing_enabled);
		(*Switches)[i].R = get_attribute(Node, "R", loc_data,TIMING_ENABLE_REQD).as_float(0);
		(*Switches)[i].Cin = get_attribute(Node, "Cin", loc_data, TIMING_ENABLE_REQD).as_float(0);
		(*Switches)[i].Cout = get_attribute(Node, "Cout", loc_data, TIMING_ENABLE_REQD).as_float(0);
		ProcessSwitchTdel(Node, timing_enabled, i, (*Switches), loc_data);
		(*Switches)[i].buf_size = get_attribute(Node, "buf_size", loc_data,
				has_buf_size).as_float(0);
		(*Switches)[i].mux_trans_size = get_attribute(Node, "mux_trans_size", loc_data, OPTIONAL).as_float(1);
				
		buf_size = get_attribute(Node, "power_buf_size", loc_data, OPTIONAL).as_string(NULL);
		if (buf_size == NULL) {
			(*Switches)[i].power_buffer_type = POWER_BUFFER_TYPE_AUTO;
		} else if (strcmp(buf_size, "auto") == 0) {
			(*Switches)[i].power_buffer_type = POWER_BUFFER_TYPE_AUTO;
		} else {
			(*Switches)[i].power_buffer_type = POWER_BUFFER_TYPE_ABSOLUTE_SIZE;
			(*Switches)[i].power_buffer_size = (float) atof(buf_size);
		}

		/* Get next switch element */
		Node = Node.next_sibling(Node.name());
		
	}
}

/* Processes the switch delay. Switch delay can be specified in two ways. 
   First way: switch delay is specified as a constant via the property Tdel in the switch node. 
   Second way: switch delay is specified as a function of the switch fan-in. In this 
               case, multiple nodes in the form

               <Tdel num_inputs="1" delay="3e-11"/>

               are specified as children of the switch node. In this case, Tdel
               is not included as a property of the switch node (first way). */
static void ProcessSwitchTdel(pugi::xml_node Node, const bool timing_enabled,
		const int switch_index, s_arch_switch_inf *Switches, const pugiutil::loc_data& loc_data){

	float Tdel_prop_value;
	int num_Tdel_children;

	/* check if switch node has the Tdel property */
	bool has_Tdel_prop = false;
	Tdel_prop_value = get_attribute(Node, "Tdel", loc_data, OPTIONAL).as_float(UNDEFINED);
	if (Tdel_prop_value != UNDEFINED){
		has_Tdel_prop = true;
	}

	/* check if switch node has Tdel children */
	bool has_Tdel_children = false;
	num_Tdel_children = count_children(Node, "Tdel", loc_data, OPTIONAL);
	if (num_Tdel_children != 0){
		has_Tdel_children = true;
	}

	/* delay should not be specified as a Tdel property AND a Tdel child */
	if (has_Tdel_prop && has_Tdel_children){
		archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
				"Switch delay should be specified as EITHER a Tdel property OR as a child of the switch node, not both");
	}

	/* get pointer to the switch's Tdel map, then read-in delay data into this map */
	std::map<int, double> *Tdel_map = &Switches[switch_index].Tdel_map;
	if (has_Tdel_prop){
		/* delay specified as a constant */
		if (Tdel_map->count(UNDEFINED)){
            VTR_ASSERT(false);
		} else {
			(*Tdel_map)[UNDEFINED] = Tdel_prop_value;
		}
	} else if (has_Tdel_children) {
		/* Delay specified as a function of switch fan-in. 
		   Go through each Tdel child, read-in num_inputs and the delay value.
		   Insert this info into the switch delay map */
		pugi::xml_node Tdel_child = get_first_child(Node, "Tdel", loc_data);
		for (int ichild = 0; ichild < num_Tdel_children; ichild++){

			int num_inputs = get_attribute(Tdel_child, "num_inputs", loc_data).as_int(0);
			float Tdel_value = get_attribute(Tdel_child, "delay", loc_data).as_float(0.);

			if (Tdel_map->count( num_inputs ) ){
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Tdel_child),
					"Tdel node specified num_inputs (%d) that has already been specified by another Tdel node", num_inputs);
			} else {
				(*Tdel_map)[num_inputs] = Tdel_value;
			}
			Tdel_child = Tdel_child.next_sibling(Tdel_child.name());

		}
	} else {
		/* No delay info specified for switch */
		if (timing_enabled){
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"Switch should contain intrinsic delay information if timing is enabled");
		} else {
			/* set a default value */
			(*Tdel_map)[UNDEFINED] = 0;
		}
	}
}

static void ProcessDirects(pugi::xml_node Parent, t_direct_inf **Directs,
		 int *NumDirects, const struct s_arch_switch_inf *Switches, const int NumSwitches,
		 const pugiutil::loc_data& loc_data) {
	int i, j;
	const char *direct_name;
	const char *from_pin_name;
	const char *to_pin_name;
	const char *switch_name;

	pugi::xml_node Node;

	/* Count the children and check they are direct connections */
	*NumDirects = count_children(Parent, "direct", loc_data);

	/* Alloc direct list */
	*Directs = NULL;
	if (*NumDirects > 0) {
		*Directs = (t_direct_inf *) vtr::malloc(
				*NumDirects * sizeof(t_direct_inf));
		memset(*Directs, 0, (*NumDirects * sizeof(t_direct_inf)));
	}

	/* Load the directs. */
	Node = get_first_child(Parent, "direct", loc_data);
	for (i = 0; i < *NumDirects; ++i) {
		
		direct_name = get_attribute(Node, "name", loc_data).value();
		/* Check for direct name collisions */
		for (j = 0; j < i; ++j) {
			if (0 == strcmp((*Directs)[j].name, direct_name)) {
				archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
						"Two directs with the same name '%s' were found.\n",
						direct_name);
			}
		}
		(*Directs)[i].name = vtr::strdup(direct_name);

		/* Figure out the source pin and sink pin name */
		from_pin_name = get_attribute(Node, "from_pin",  loc_data).value();
		to_pin_name = get_attribute(Node, "to_pin", loc_data).value();

		/* Check that to_pin and the from_pin are not the same */
		if (0 == strcmp(to_pin_name, from_pin_name)) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"The source pin and sink pin are the same: %s.\n",
					to_pin_name);
		}
		(*Directs)[i].from_pin = vtr::strdup(from_pin_name);
		(*Directs)[i].to_pin = vtr::strdup(to_pin_name);

		(*Directs)[i].x_offset = get_attribute(Node, "x_offset", loc_data).as_int(0);
		(*Directs)[i].y_offset = get_attribute(Node, "y_offset", loc_data).as_int(0);
		(*Directs)[i].z_offset = get_attribute(Node, "z_offset", loc_data).as_int(0);

        //Set the optional switch type
        switch_name = get_attribute(Node, "switch_name", loc_data, OPTIONAL).as_string(NULL);
        if(switch_name != NULL) {
            //Look-up the user defined switch
            for(j = 0; j < NumSwitches; j++) {
                if(0 == strcmp(switch_name, Switches[j].name)) {
                    break; //Found the switch
                }
            }
            if(j >= NumSwitches) {
                archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
                        "Could not find switch named '%s' in switch list.\n", switch_name);

            }
            (*Directs)[i].switch_type = j; //Save the correct switch index
        } else {
            //If not defined, use the delayless switch by default
            //TODO: find a better way of indicating this.  Ideally, we would
            //specify the delayless switch index here, but it does not appear
            //to be defined at this point.
            (*Directs)[i].switch_type = -1; 
        }

		/* Check that the direct chain connection is not zero in both direction */
		if ((*Directs)[i].x_offset == 0 && (*Directs)[i].y_offset == 0) {
			archfpga_throw(loc_data.filename_c_str(), loc_data.line(Node),
					"The x_offset and y_offset are both zero, this is a length 0 direct chain connection.\n");
		}

		(*Directs)[i].line = loc_data.line(Node);
		/* Should I check that the direct chain offset is not greater than the chip? How? */

		/* Get next direct element */
		Node = Node.next_sibling(Node.name());
	}
}

static void ProcessPower( pugi::xml_node parent,
		t_power_arch * power_arch,
		const pugiutil::loc_data& loc_data) {
	pugi::xml_node Cur;

	/* Get the local interconnect capacitances */
	power_arch->local_interc_factor = 0.5;
	Cur = get_single_child(parent, "local_interconnect", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->C_wire_local = get_attribute(Cur, "C_wire", loc_data, OPTIONAL).as_float(0.);
		power_arch->local_interc_factor = get_attribute(Cur, "factor", loc_data, OPTIONAL).as_float(0.5);

	}

	/* Get logical effort factor */
	power_arch->logical_effort_factor = 4.0;
	Cur = get_single_child(parent, "buffers", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->logical_effort_factor = get_attribute(Cur,
				"logical_effort_factor", loc_data).as_float(0);;
	}

	/* Get SRAM Size */
	power_arch->transistors_per_SRAM_bit = 6.0;
	Cur = get_single_child(parent, "sram", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->transistors_per_SRAM_bit = get_attribute(Cur,
				"transistors_per_bit", loc_data).as_float(0);
	}

	/* Get Mux transistor size */
	power_arch->mux_transistor_size = 1.0;
	Cur = get_single_child(parent, "mux_transistor_size", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->mux_transistor_size = get_attribute(Cur,
				"mux_transistor_size", loc_data).as_float(0);
	}

	/* Get FF size */
	power_arch->FF_size = 1.0;
	Cur = get_single_child(parent, "FF_size", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->FF_size = get_attribute(Cur, "FF_size", loc_data).as_float(0);
	}

	/* Get LUT transistor size */
	power_arch->LUT_transistor_size = 1.0;
	Cur = get_single_child(parent, "LUT_transistor_size", loc_data, OPTIONAL);
	if (Cur) {
		power_arch->LUT_transistor_size = get_attribute(Cur,
				"LUT_transistor_size", loc_data).as_float(0);
	}
}

/* Get the clock architcture */
static void ProcessClocks(pugi::xml_node Parent, t_clock_arch * clocks, const pugiutil::loc_data& loc_data) {
	pugi::xml_node Node;
	int i;
	const char *tmp;

	clocks->num_global_clocks = count_children(Parent, "clock", loc_data, OPTIONAL);

	/* Alloc the clockdetails */
	clocks->clock_inf = NULL;
	if (clocks->num_global_clocks > 0) {
		clocks->clock_inf = (t_clock_network *) vtr::malloc(
				clocks->num_global_clocks * sizeof(t_clock_network));
		memset(clocks->clock_inf, 0,
				clocks->num_global_clocks * sizeof(t_clock_network));
	}

	/* Load the clock info. */
	Node = get_first_child(Parent, "clock", loc_data);
	for (i = 0; i < clocks->num_global_clocks; ++i) {

		tmp = get_attribute(Node, "buffer_size", loc_data).value();
		if (strcmp(tmp, "auto") == 0) {
			clocks->clock_inf[i].autosize_buffer = true;
		} else {
			clocks->clock_inf[i].autosize_buffer = false;
			clocks->clock_inf[i].buffer_size = (float) atof(tmp);
		}

		clocks->clock_inf[i].C_wire = get_attribute(Node, "C_wire", loc_data).as_float(0);

		/* get the next clock item */
		Node = Node.next_sibling(Node.name());
	}
}


/* Used by functions outside read_xml_util.c to gain access to arch filename */
const char* get_arch_file_name() {
	return arch_file_name;
}

bool check_model_clocks(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model) {
    //Collect the ports identified as clocks
    std::set<std::string> clocks;
    for(t_model_ports* ports : {model->inputs, model->outputs}) {
        for(t_model_ports* port = ports; port != nullptr; port = port->next) {
            if(port->is_clock) {
                clocks.insert(port->name);
            }
        }
    }

    //Check that any clock references on the ports are to identified clock ports
    for(t_model_ports* ports : {model->inputs, model->outputs}) {
        for(t_model_ports* port = ports; port != nullptr; port = port->next) {
            if(!port->clock.empty() && !clocks.count(port->clock)) {
                archfpga_throw(loc_data.filename_c_str(), loc_data.line(model_tag),
                        "No matching clock port '%s' on model '%s', required for port '%s'",
                        port->clock.c_str(), model->name, port->name);
            }
        }
    }
    return true;
}

bool check_model_combinational_sinks(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model) {
    //Outputs should have no combinational sinks
    for(t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
        if(port->combinational_sink_ports.size() != 0) {
            archfpga_throw(loc_data.filename_c_str(), loc_data.line(model_tag),
                    "Model '%s' output port '%s' can not have combinational sink ports",
                    model->name, port->name);
        }
    }

    //Record the output ports
    std::set<std::string> output_ports;
    for(t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
        output_ports.insert(port->name);
    }

    //Check that the input port combinational sinks are all outputs
    for(t_model_ports* port = model->inputs; port != nullptr; port = port->next) {
        for(std::string sink_port_name : port->combinational_sink_ports) {
            if(!output_ports.count(sink_port_name)) {
                archfpga_throw(loc_data.filename_c_str(), loc_data.line(model_tag),
                        "Model '%s' input port '%s' can not be combinationally connected to '%s' (not an output port of the model)",
                        model->name, port->name, sink_port_name.c_str());
            }
        }
    }
    return true;
}

void warn_model_missing_timing(pugi::xml_node model_tag, const pugiutil::loc_data& loc_data, const t_model* model) {
    //Check whether there are missing edges and warn the user
    std::set<std::string> comb_connected_outputs;
    for(t_model_ports* port = model->inputs; port != nullptr; port = port->next) {
        if(port->clock.empty() //Not sequential
           && port->combinational_sink_ports.empty() //Doesn't drive any combinational outputs
           && !port->is_clock //Not an input clock
          ) {
            vtr::printf_warning(loc_data.filename_c_str(), loc_data.line(model_tag),
                    "Model '%s' input port '%s' has no timing specification (no clock specified to create a sequential input port, not combinationally connected to any outputs, not a clock input)\n", model->name, port->name);
        }


        comb_connected_outputs.insert(port->combinational_sink_ports.begin(), port->combinational_sink_ports.end());
    }
     
    for(t_model_ports* port = model->outputs; port != nullptr; port = port->next) {
        if(port->clock.empty() //Not sequential
           && !comb_connected_outputs.count(port->name) //Not combinationally drivven
           && !port->is_clock //Not an output clock
           ) {
            vtr::printf_warning(loc_data.filename_c_str(), loc_data.line(model_tag),
                    "Model '%s' output port '%s' has no timing specification (no clock specified to create a sequential output port, not combinationally connected to any inputs, not a clock output)\n", model->name, port->name);
        }
    }
}

bool check_leaf_pb_model_timing_consistency(const t_pb_type* pb_type, const t_arch& arch) {
    //Normalize the blif model name to match the model name
    // by removing the leading '.' (.latch, .inputs, .names etc.)
    // by removing the leading '.subckt'
    VTR_ASSERT(pb_type->blif_model);
    std::string blif_model = pb_type->blif_model;
    if(blif_model[0] == '.') {
        blif_model = blif_model.substr(1);
    }
    std::string subckt = "subckt ";
    auto pos = blif_model.find(subckt);
    if(pos != std::string::npos) {
        blif_model = blif_model.substr(pos + subckt.size());
    }

    //Find the matching model
    const t_model* model = nullptr;



    for(const t_model* models : {arch.models, arch.model_library}) {
        for(model = models; model != nullptr; model = model->next) {
            if(std::string(model->name) == blif_model) {
                break;    
            }
        }
        if(model != nullptr) {
            break;
        }
    }
    VTR_ASSERT(model != nullptr);

    //Now that we have the model we can compare the timing annotations
     
    for(int i = 0; i < pb_type->num_annotations; ++i) {
        const t_pin_to_pin_annotation* annot = &pb_type->annotations[i];

        if(annot->type == E_ANNOT_PIN_TO_PIN_DELAY) {
            //Check that any combinational delays specified match the 'combinational_sinks_ports' in the model

            if(annot->clock) {
                //Sequential annotation, check that the clock on the specified port matches the model

                //Annotations always put the pin in the input_pins field
                VTR_ASSERT(annot->input_pins);
                for(std::string input_pin : vtr::split(annot->input_pins)) {
                    InstPort annot_port(input_pin);
                    for(std::string clock : vtr::split(annot->clock)) {
                        InstPort annot_clock(annot->clock);

                        //Find the model port
                        const t_model_ports* model_port = nullptr;
                        for(const t_model_ports* ports : {model->inputs, model->outputs}) {
                            for(const t_model_ports* port = ports; port != nullptr; port = port->next) {
                                if(port->name == annot_port.port_name()) {
                                    model_port = port;
                                    break;
                                }
                            }
                            if(model_port != nullptr) break;
                        }
                        VTR_ASSERT(model_port != nullptr);

                        //Check that the clock matches the model definition
                        std::string model_clock = model_port->clock;
                        if(model_clock.empty()) {
                            archfpga_throw(get_arch_file_name(), annot->line_num,
                                "<pb_type> timing annotation/<model> mismatch on port '%s' of model '%s', model specifies"
                                " no clock but timing annotation specifies '%s'",
                                annot_port.port_name().c_str(), model->name, annot_clock.port_name().c_str());
                        }
                        if(model_port->clock != annot_clock.port_name()) {
                            archfpga_throw(get_arch_file_name(), annot->line_num,
                                "<pb_type> timing annotation/<model> mismatch on port '%s' of model '%s', model specifies"
                                " clock as '%s' but timing annotation specifies '%s'",
                                annot_port.port_name().c_str(), model->name, model_clock.c_str(), annot_clock.port_name().c_str());
                        }
                    }
                }

            } else if (annot->input_pins && annot->output_pins) {
                //Combinational annotation
                VTR_ASSERT_MSG(!annot->clock, "Combinational annotations should have no clock");
                for(std::string input_pin : vtr::split(annot->input_pins)) {
                    InstPort annot_in(input_pin);
                    for(std::string output_pin : vtr::split(annot->output_pins)) {
                        InstPort annot_out(output_pin);

                        //Find the input model port
                        const t_model_ports* model_port = nullptr;
                        for(const t_model_ports* port = model->inputs; port != nullptr; port = port->next) {
                            if(port->name == annot_in.port_name()) {
                                model_port = port;
                                break;
                            }
                        }
                        VTR_ASSERT(model_port != nullptr);

                        //Check that the output port is listed in the model's combinational sinks
                        auto b = model_port->combinational_sink_ports.begin();
                        auto e = model_port->combinational_sink_ports.end();
                        auto iter = std::find(b, e, annot_out.port_name());
                        if(iter == e) {
                            archfpga_throw(get_arch_file_name(), annot->line_num,
                                "<pb_type> timing annotation/<model> mismatch on port '%s' of model '%s', timing annotation"
                                " specifies combinational connection to port '%s' but the connection does not exist in the model",
                                model_port->name, model->name, annot_out.port_name().c_str());
                        }
                    }
                }
            } else {
                throw ArchFpgaError("Unrecognized delay annotation");
            }
        }
    }


    return true; 
}

std::string inst_port_to_port_name(std::string inst_port) {
    auto pos = inst_port.find('.');
    if(pos != std::string::npos) {
        return inst_port.substr(pos + 1);
    }
    return inst_port;
}

static bool attribute_to_bool(const pugi::xml_node node,
                const pugi::xml_attribute attr,
                const pugiutil::loc_data& loc_data) {
    if(attr.value() == std::string("1")) {
        return true;
    } else if(attr.value() == std::string("0")) {
        return false;
    } else {
        bad_attribute_value(attr, node, loc_data, {"0", "1"});
    }

    return false;
}
