#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <cstdarg>
using namespace std;

#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_log.h"
#include "vtr_memory.h"
#include "vtr_math.h"

#include "vpr_types.h"
#include "vpr_error.h"

#include "globals.h"
#include "atom_netlist.h"
#include "read_sdc.h"
#include "read_blif.h"
#include "path_delay.h"
#include "path_delay2.h"
#include "slre.h"
#include "sdcparse.hpp"

/***************************** Summary **********************************/

/* Author: Michael Wainberg

Looks for an SDC (Synopsys Design Constraints) file called <circuitname>.sdc
(unless overridden with --sdc_file <filename.sdc> on the command-line, in which 
case it looks for that filename), and parses the timing constraints in that file. 
If it doesn't find a file with that name, it uses default timing constraints 
(which differ depending on whether the circuit has 0, 1, or multiple clocks).

The primary routine, read_sdc, populates a container structure, timing_ctx.sdc.
One of the two key output data structures within is timing_ctx.sdc->constrained_clocks, which 
associates each clock given a timing constraint with a name, fanout and whether 
it is a netlist or virtual (external) clock.  From this point on, the only clocks 
we care about are the ones in this array. During timing analysis and data output, 
clocks are accessed using the indexing of this array.

The other key data structure is the "constraint matrix" timing_ctx.sdc->domain_constraint, which 
has a timing constraint for each pair (source and sink) of clock domains. These 
generally come from finding the smallest difference between the posedges of the 
two clocks over the LCM clock period ("edge counting" - see calculate_constraint()).

Alternatively, entries in timing_ctx.sdc->domain_constraint can come from a special-case, "override 
constraint" (so named because it overrides the default behaviour of edge counting). 
Override constraints can cut paths (set_clock_groups, set_false_path commands), 
create a multicycle (set_multicycle_path) or even override a constraint with a user-
specified one (set_max_delay). These entries are stored temporarily in timing_ctx.sdc->cc_constraints 
(cc = clock to clock), which is freed once the timing_constraints echo file is 
created during process_constraints(). 

Flip-flop-level override constraints also exist and are stored in timing_ctx.sdc->cf_constraints, 
timing_ctx.sdc->fc_constraints and timing_ctx.sdc->ff_constraints (depending on whether the source, sink or neither 
of the two is a clock domain).Unlike timing_ctx.sdc->cc_constraints, they are placed on the timing 
graph during timing analysis instead of going into timing_ctx.sdc->domain_constraint, and are not 
freed until the end of VPR's execution.

I/O constraints from set_input_delay and set_output_delay are stored in constrained_
inputs and timing_ctx.sdc->constrained_outputs. These associate each I/O in the netlist given a 
constraint with the clock (often virtual, but could be in the netlist) it was 
constrained on, and the delay through the I/O in that constraint.

The remaining data structures are temporary and local to this file: netlist_clocks, 
netlist_inputs and netlist_outputs, which are used to match names of clocks and I/Os
in the SDC file to those in the netlist; sdc_clocks, which stores info on clock periods 
and offsets from create_clock commands and is the raw info used in edge counting; and 
exclusive_groups, used when parsing set_clock_groups commands into timing_ctx.sdc->cc_constraints. */

/****************** Types local to this module **************************/

struct t_sdc_clock {
	char * name;
	float period;
	float rising_edge;
	float falling_edge;
};
/* Stores the name, period and offset of each constrained clock. */

struct t_sdc_exclusive_group {
	char ** clock_names;
	int num_clock_names;
};
/* Used to temporarily separate clock names into exclusive groups when parsing the 
command set_clock_groups -exclusive. */

/****************** Variables local to this module **************************/

static FILE *sdc;
t_sdc_clock * sdc_clocks = nullptr; /* List of clock periods and offsets from create_clock commands */

int num_netlist_clocks = 0; /* number of clocks in netlist */
char ** netlist_clocks; /* [0..num_netlist_clocks - 1] array of names of clocks in netlist */

int num_netlist_ios = 0; /* number of clocks in netlist */
char ** netlist_ios; /* [0..num_netlist_clocks - 1] array of names of ios in netlist */

static std::string sdc_file_name = "<default_SDC>.sdc"; /* Name of SDC file */

/***************** Subroutines local to this module *************************/

static void alloc_and_load_netlist_clocks_and_ios();
static void use_default_timing_constraints();
static void count_netlist_clocks_as_constrained_clocks();
static void add_clock(std::string net_name);
static int find_constrained_clock(char * ptr);
static float calculate_constraint(t_sdc_clock source_domain, t_sdc_clock sink_domain);
static void add_override_constraint(char ** from_list, int num_from, char ** to_list, int num_to, 
	float constraint, int num_multicycles, bool domain_level_from, bool domain_level_to,
	bool make_copies);
static int find_cc_constraint(char * source_clock_domain, char * sink_clock_domain);
static bool regex_match (const char *string, const char *pattern);
static void count_netlist_ios_as_constrained_ios(char * clock_name, float io_delay);
static void free_io_constraint(t_io *& io_array, int num_ios);
static void free_clock_constraint(t_clock *& clock_array, int num_clocks);

static bool apply_create_clock(const sdcparse::CreateClock& sdc_create_clock, int lineno);
static bool apply_set_clock_groups(const sdcparse::SetClockGroups& sdc_set_clock_groups, int lineno);
static bool apply_set_false_path(const sdcparse::SetFalsePath& sdc_set_false_path);
static bool apply_set_min_max_delay(const sdcparse::SetMinMaxDelay& sdc_set_min_max_delay);
static bool apply_set_multicycle_path(const sdcparse::SetMulticyclePath& sdc_set_multicycle_path);
static bool apply_set_io_delay(const sdcparse::SetIoDelay& sdc_set_io_delay, int lineno);

//TODO
//static bool apply_set_clock_uncertainty(const sdcparse::SetClockUncertainty& sdc_set_clock_uncertainty);
//static bool apply_set_clock_latency(const sdcparse::SetClockLatency& sdc_set_clock_latency);
//static bool apply_set_timing_derate(const sdcparse::SetTimingDerate& sdc_set_timing_derate);

static bool is_valid_clock_name(const char* clock_name);
static bool build_from_to_lists(char ***from_list, int *num_from, bool* domain_level_from,
                            char ***to_list, int *num_to, bool* domain_level_to,
                            const sdcparse::StringGroup& from_group, const sdcparse::StringGroup& to_group);

void vpr_sdc_error(const int line_number, const std::string& near_text, const std::string& msg);

/********************* Class definitions *******************************/

class SdcCallback : public sdcparse::Callback {
    public: //sdcparse::Callback interface
        //Start of parsing
        void start_parse() override {}

        //Sets current filename
        void filename(std::string fname) override { fname_ = fname; }

        //Sets current line number
        void lineno(int line_num) override { lineno_ = line_num; }

        //Individual commands
        void create_clock(const sdcparse::CreateClock& cmd) override { 
            got_commands_ = true;
            apply_create_clock(cmd, lineno_); 
        }
        void set_io_delay(const sdcparse::SetIoDelay& cmd) override { 
            got_commands_ = true;
            apply_set_io_delay(cmd, lineno_); 
        }
        void set_clock_groups(const sdcparse::SetClockGroups& cmd) override { 
            got_commands_ = true;
            apply_set_clock_groups(cmd, lineno_); 
        }
        void set_false_path(const sdcparse::SetFalsePath& cmd) override { 
            got_commands_ = true;
            apply_set_false_path(cmd); 
        }
        void set_min_max_delay(const sdcparse::SetMinMaxDelay& cmd) override { 
            got_commands_ = true;
            apply_set_min_max_delay(cmd);
        }
        void set_multicycle_path(const sdcparse::SetMulticyclePath& cmd) override {
            got_commands_ = true;
            apply_set_multicycle_path(cmd);
        }
        void set_clock_uncertainty(const sdcparse::SetClockUncertainty& /*cmd*/) override { 
            got_commands_ = true;
            vpr_sdc_error(lineno_, "", "set_clock_uncertainty currently unsupported"); 
        }
        void set_clock_latency(const sdcparse::SetClockLatency& /*cmd*/) override { 
            got_commands_ = true;
            vpr_sdc_error(lineno_, "", "set_clock_latency currently unsupported"); 
        }
        void set_disable_timing(const sdcparse::SetDisableTiming& /*cmd*/) override { 
            got_commands_ = true;
            vpr_sdc_error(lineno_, "", "set_disable_timing currently unsupported"); 
        }
        void set_timing_derate(const sdcparse::SetTimingDerate& /*cmd*/) override { 
            got_commands_ = true;
            vpr_sdc_error(lineno_, "", "set_timing_derate currently unsupported"); 
        }

        //End of parsing
        void finish_parse() override {}

        //Error during parsing
        void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override {
            vpr_sdc_error(curr_lineno, near_text, msg);
        }


    public:
        bool got_commands() { return got_commands_; }
    private:
        bool got_commands_ = false;
        std::string fname_;
        int lineno_ = -1;

};

/********************* Subroutine definitions *******************************/

void read_sdc(t_timing_inf timing_inf) {
	int source_clock_domain, sink_clock_domain, iinput, ioutput, icc, isource, isink;
	
    auto& timing_ctx = g_vpr_ctx.mutable_timing();

	/* Make sure we haven't called this subroutine before. */
	VTR_ASSERT(!timing_ctx.sdc);

	/* Allocate container structure for SDC constraints. */
	timing_ctx.sdc = (t_timing_constraints *) vtr::calloc(1, sizeof(t_timing_constraints));
	

#ifndef ENABLE_CLASSIC_VPR_STA
    return;
#endif
	/* If no SDC file is included or specified, or timing analysis is off,
	use default behaviour of cutting paths between domains and optimizing each clock separately */

	if (!timing_inf.timing_analysis_enabled) {
		vtr::printf_info("\n");
		vtr::printf_info("Timing analysis off; using default timing constraints.\n");
		use_default_timing_constraints();
		return;
	}
	
	if ((sdc = fopen(timing_inf.SDCFile.c_str(), "r")) == nullptr) {
		vtr::printf_info("\n");
		vtr::printf_info("SDC file '%s' blank or not found.\n", timing_inf.SDCFile.c_str());
		use_default_timing_constraints();
		return;
	}
	
	/* Now we have an SDC file. */

	/* Save name of SDC file for error outputs */
	sdc_file_name = timing_inf.SDCFile;

	/* Count how many clocks and I/Os are in the netlist. 
	Store the names of each clock and each I/O in netlist_clocks and netlist_ios. 
	The only purpose of these two lists is to compare clock names in the SDC file against them.
	As a result, they will be freed after the SDC file is parsed. */
	alloc_and_load_netlist_clocks_and_ios();

	/* Parse the file line-by-line. */
    SdcCallback sdc_callback;
    sdcparse::sdc_parse_file(sdc, sdc_callback, sdc_file_name.c_str());

	if (!sdc_callback.got_commands()) { /* blank file or only comments found */
		vtr::printf_info("\n");
		vtr::printf_info("SDC file '%s' blank or not found.\n", timing_inf.SDCFile.c_str());
		use_default_timing_constraints();
		free(netlist_clocks);
		free(netlist_ios);
		return;
	}

	/* Make sure that all virtual clocks referenced in timing_ctx.sdc->constrained_inputs and timing_ctx.sdc->constrained_outputs have been constrained. */
	for (iinput = 0; iinput < timing_ctx.sdc->num_constrained_inputs; iinput++) {
		if ((find_constrained_clock(timing_ctx.sdc->constrained_inputs[iinput].clock_name)) == -1) {
			vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), timing_ctx.sdc->constrained_inputs[iinput].file_line_number, 
					"Input %s is associated with an unconstrained clock %s.\n", 
					timing_ctx.sdc->constrained_inputs[iinput].name, 
					timing_ctx.sdc->constrained_inputs[iinput].clock_name);
		}
	}

	for (ioutput = 0; ioutput < timing_ctx.sdc->num_constrained_outputs; ioutput++) {
		if ((find_constrained_clock(timing_ctx.sdc->constrained_outputs[ioutput].clock_name)) == -1) {
			vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), timing_ctx.sdc->constrained_inputs[iinput].file_line_number,
					"Output %s is associated with an unconstrained clock %s.\n", 
					timing_ctx.sdc->constrained_outputs[ioutput].name, 
					timing_ctx.sdc->constrained_outputs[ioutput].clock_name);
		}
	}

	/* Make sure that all clocks referenced in timing_ctx.sdc->cc_constraints have been constrained. */
	for (icc = 0; icc < timing_ctx.sdc->num_cc_constraints; icc++) {
		for (isource = 0; isource < timing_ctx.sdc->cc_constraints[icc].num_source; isource++) {
			if ((find_constrained_clock(timing_ctx.sdc->cc_constraints[icc].source_list[isource])) == -1) {
				vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), timing_ctx.sdc->cc_constraints[icc].file_line_number,
						"Token %s is not a constrained clock.\n", 
						timing_ctx.sdc->cc_constraints[icc].source_list[isource]);
			}
		}
		for (isink = 0; isink < timing_ctx.sdc->cc_constraints[icc].num_sink; isink++) {
			if ((find_constrained_clock(timing_ctx.sdc->cc_constraints[icc].sink_list[isink])) == -1) {
				vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), timing_ctx.sdc->cc_constraints[icc].file_line_number, 
						"Token %s is not a constrained clock.\n",
						timing_ctx.sdc->cc_constraints[icc].sink_list[isink]);
			}
		}
	}

	/* Allocate matrix of timing constraints [0..timing_ctx.sdc->num_constrained_clocks-1][0..timing_ctx.sdc->num_constrained_clocks-1] and initialize to 0 */
    size_t num_constrained_clocks = timing_ctx.sdc->num_constrained_clocks;
	timing_ctx.sdc->domain_constraint = vtr::Matrix<float>({num_constrained_clocks, num_constrained_clocks});
	
	/* Based on the information from sdc_clocks, calculate constraints for all paths except ones with an override constraint. */
	for (source_clock_domain = 0; source_clock_domain < timing_ctx.sdc->num_constrained_clocks; source_clock_domain++) {
		for (sink_clock_domain = 0; sink_clock_domain < timing_ctx.sdc->num_constrained_clocks; sink_clock_domain++) {
			if ((icc = find_cc_constraint(timing_ctx.sdc->constrained_clocks[source_clock_domain].name, timing_ctx.sdc->constrained_clocks[sink_clock_domain].name)) != -1) {
				if (timing_ctx.sdc->cc_constraints[icc].num_multicycles == 0) {
					/* There's a special constraint from set_false_path, set_clock_groups 
					-exclusive or set_max_delay which overrides the default constraint. */
					timing_ctx.sdc->domain_constraint[source_clock_domain][sink_clock_domain] = timing_ctx.sdc->cc_constraints[icc].constraint;
				} else {
					/* There's a special constraint from set_multicycle_path which overrides the default constraint. 
					This constraint = default constraint (obtained via edge counting) + (num_multicycles - 1) * period of sink clock domain. */
					timing_ctx.sdc->domain_constraint[source_clock_domain][sink_clock_domain] = 
						calculate_constraint(sdc_clocks[source_clock_domain], sdc_clocks[sink_clock_domain]) 
						+ (timing_ctx.sdc->cc_constraints[icc].num_multicycles - 1) * sdc_clocks[sink_clock_domain].period;
				}
			} else {
				/* There's no special override constraint. */
				/* Calculate the constraint between clock domains by finding the smallest positive 
				difference between a posedge in the source domain and one in the sink domain. */
				timing_ctx.sdc->domain_constraint[source_clock_domain][sink_clock_domain] = 
					calculate_constraint(sdc_clocks[source_clock_domain], sdc_clocks[sink_clock_domain]);
			}
		}
	}

	vtr::printf_info("\n");
	vtr::printf_info("SDC file '%s' parsed successfully.\n",
			 timing_inf.SDCFile.c_str() ); 
	vtr::printf_info("%d clocks (including virtual clocks), %d inputs and %d outputs were constrained.\n", 
			 timing_ctx.sdc->num_constrained_clocks, timing_ctx.sdc->num_constrained_inputs, timing_ctx.sdc->num_constrained_outputs);
	vtr::printf_info("\n");
	
	/* Since all the information we need is stored in timing_ctx.sdc->domain_constraint, timing_ctx.sdc->constrained_clocks, 
	and constrained_ios, free other data structures used in this routine */
	for (int iclk = 0; iclk < timing_ctx.sdc->num_constrained_clocks; iclk++) {
        free(sdc_clocks[iclk].name);
    }
	free(sdc_clocks);
	free(netlist_clocks);
    for(int i = 0; i < num_netlist_ios; ++i) {
        free(netlist_ios[i]);
    }
	free(netlist_ios);

    fclose(sdc);

	return;
}

/*
 * Override the default error function in libsdcparse so that it throws
 * vpr style errors.
 */
void vpr_sdc_error(const int line_number, const std::string& /*near_text*/, const std::string& msg) {
    vpr_throw(VPR_ERROR_SDC, get_sdc_file_name(), line_number, msg.c_str());
}

static bool apply_create_clock(const sdcparse::CreateClock& sdc_create_clock, int lineno) {
    bool found;

    auto& timing_ctx = g_vpr_ctx.timing();

    if(sdc_create_clock.is_virtual) { 
        /* Store the clock's name, period and edges in the local array sdc_clocks. */
        sdc_clocks = (t_sdc_clock *) vtr::realloc(sdc_clocks, ++timing_ctx.sdc->num_constrained_clocks * sizeof(t_sdc_clock));
        sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = vtr::strdup(sdc_create_clock.name.c_str());
        sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].period = sdc_create_clock.period;
        sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].rising_edge = sdc_create_clock.rise_edge; 
        sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].falling_edge = sdc_create_clock.fall_edge; 

        /* Also store the clock's name, and the fact that it is not a netlist clock, in timing_ctx.sdc->constrained_clocks. */
        timing_ctx.sdc->constrained_clocks = (t_clock *) vtr::realloc (timing_ctx.sdc->constrained_clocks, timing_ctx.sdc->num_constrained_clocks * sizeof(t_clock));
        timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = vtr::strdup(sdc_create_clock.name.c_str());
        timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].is_netlist_clock = false;
    } else {
        VTR_ASSERT(!sdc_create_clock.is_virtual);

        for(size_t itarget = 0; itarget < sdc_create_clock.targets.strings.size(); itarget++) {

            /* See if the regular expression stored in ptr is legal and matches at least one clock net. 
            If it is not legal, it will fail during regex_match.  We check for a match using bool found. */
            found = false;
            for (int iclock = 0; iclock < num_netlist_clocks; iclock++) {
                if (regex_match(netlist_clocks[iclock], sdc_create_clock.targets.strings[itarget].c_str())) {
                    /* We've found a new clock!  (Note that we can't store ptr as the clock's 
                    name since it could be a regex, unlike the virtual clock case).*/
                    found = true;

                    /* Store the clock's name, period and edges in the local array sdc_clocks. */
                    sdc_clocks = (t_sdc_clock *) vtr::realloc(sdc_clocks, ++timing_ctx.sdc->num_constrained_clocks * sizeof(t_sdc_clock));
                    sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = netlist_clocks[iclock];
                    sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].period = sdc_create_clock.period;
                    sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].rising_edge = sdc_create_clock.rise_edge; 
                    sdc_clocks[timing_ctx.sdc->num_constrained_clocks - 1].falling_edge = sdc_create_clock.fall_edge; 

                    /* Also store the clock's name, and the fact that it is a netlist clock, in timing_ctx.sdc->constrained_clocks. */
                    timing_ctx.sdc->constrained_clocks = (t_clock *) vtr::realloc (timing_ctx.sdc->constrained_clocks, timing_ctx.sdc->num_constrained_clocks * sizeof(t_clock));
                    timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = vtr::strdup(netlist_clocks[iclock]);
                    timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].is_netlist_clock = true;
                    /* Fanout will be filled out once the timing graph has been constructed. */
                }
            }

            if (!found) {
                vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), lineno, 
                        "Clock name or regular expression does not correspond to any nets.\n"
                        "If you'd like to create a virtual clock, use the '-name' keyword.\n");
                return false;
            }
        }
        
    }
    return true;
}

static bool apply_set_clock_groups(const sdcparse::SetClockGroups& sdc_set_clock_groups, int lineno) {
    bool found;

    int iclock;
    int num_exclusive_groups = 0;
	t_sdc_exclusive_group *exclusive_groups = nullptr;

    VTR_ASSERT(sdc_set_clock_groups.clock_groups.size() >= 2); //Should have already been caught by parser
    VTR_ASSERT(sdc_set_clock_groups.type == sdcparse::ClockGroupsType::EXCLUSIVE); //Currently only form supported

    for(size_t igroup = 0; igroup < sdc_set_clock_groups.clock_groups.size(); igroup++) {
        const sdcparse::StringGroup& clock_group = sdc_set_clock_groups.clock_groups[igroup];
        
        /* Create a new entry in exclusive groups */
        exclusive_groups = (t_sdc_exclusive_group *) vtr::realloc(
            exclusive_groups, ++num_exclusive_groups * sizeof(t_sdc_exclusive_group));
        exclusive_groups[num_exclusive_groups - 1].clock_names = nullptr;
        exclusive_groups[num_exclusive_groups - 1].num_clock_names = 0;

        for(size_t iclk_name = 0; iclk_name < clock_group.strings.size(); iclk_name++) {
            const char* clk_name = clock_group.strings[iclk_name].c_str();

            /* Check the regex clk_name against each netlist clock and add it to the clock_names list if it matches. */
            found = false;
            for (iclock = 0; iclock < num_netlist_clocks; iclock++) {
                if (regex_match(netlist_clocks[iclock], clk_name)) {
                    found = true;
                    exclusive_groups[num_exclusive_groups - 1].clock_names = (char **) vtr::realloc(
                        exclusive_groups[num_exclusive_groups - 1].clock_names, ++exclusive_groups[num_exclusive_groups - 1].num_clock_names * sizeof(char *));
                    exclusive_groups[num_exclusive_groups - 1].clock_names
                        [exclusive_groups[num_exclusive_groups - 1].num_clock_names - 1] = 
                        vtr::strdup(netlist_clocks[iclock]);
                }
            }
            if (!found) {
                if(!is_valid_clock_name(clk_name)) {
                    vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), lineno, 
                            "Clock name '%s' does not match to any known clock.\n",
                            clk_name);
                } else {
                    /* The clock_name is a valid non-netlist clock (i.e. a virtual clock), so add it to the list.  */
                    exclusive_groups[num_exclusive_groups - 1].clock_names = (char **) vtr::realloc(
                        exclusive_groups[num_exclusive_groups - 1].clock_names, ++exclusive_groups[num_exclusive_groups - 1].num_clock_names * sizeof(char *));
                    exclusive_groups[num_exclusive_groups - 1].clock_names[exclusive_groups[num_exclusive_groups - 1].num_clock_names - 1] = vtr::strdup(clk_name);
                }
            }
        }
    }

    /* Finally, create two DO_NOT_ANALYSE override constraints for each pair of entries
    to cut paths bidirectionally between pairs of clock lists in different groups. 
    Set make_copies to true because we have to use the lists of names in multiple
    override constraints, and it's impossible to free them from multiple places at the
    end without a whole lot of trouble. */

    for (int i = 0; i < num_exclusive_groups; i++) {
        for (int j = 0; j < num_exclusive_groups; j++) {
            if (i != j) {
                add_override_constraint(exclusive_groups[i].clock_names, exclusive_groups[i].num_clock_names, 
                    exclusive_groups[j].clock_names, exclusive_groups[j].num_clock_names, DO_NOT_ANALYSE, 0, true, true, true);
            }
        }
    }

    /* Now that we've copied all the clock name lists
    (2 * num_exlusive_groups - 1) times, free the original lists. */
    for (int i = 0; i < num_exclusive_groups; i++) {
        for (int j = 0; j < exclusive_groups[i].num_clock_names; j++) {
            free(exclusive_groups[i].clock_names[j]);
        }
        free(exclusive_groups[i].clock_names);
    }
    free (exclusive_groups);

    return true;
}


static bool apply_set_false_path(const sdcparse::SetFalsePath& sdc_set_false_path) {
	bool domain_level_from = false, domain_level_to = false;
    int num_from = 0, num_to = 0;
    char **from_list = nullptr, **to_list = nullptr;

    build_from_to_lists(&from_list, &num_from, &domain_level_from,
                        &to_list, &num_to, &domain_level_to,
                        sdc_set_false_path.from, sdc_set_false_path.to);

    /* Create a constraint between each element in from_list and each element in to_list with value DO_NOT_ANALYSE. 
    Set make_copies to false since, as we only need to use from_list and to_list once, we can just have the
    override constraint entry point to those lists. */
    add_override_constraint(from_list, num_from, to_list, num_to, DO_NOT_ANALYSE, 0, domain_level_from, domain_level_to, false);
    
    /* Finally, set from_list and to_list to NULL since they're both 
    being pointed to by the override constraint entry we just created. */
    from_list = nullptr, to_list = nullptr;

    return true;
}

static bool apply_set_min_max_delay(const sdcparse::SetMinMaxDelay& sdc_set_min_max_delay) {
    /* Basically the same as apply_set_false_path, except we get a specific delay value for the constraint. */

	bool domain_level_from = false, domain_level_to = false;
    int num_from = 0, num_to = 0;
    char **from_list = nullptr, **to_list = nullptr;

    if(sdc_set_min_max_delay.type != sdcparse::MinMaxType::MAX) {
        vpr_sdc_error(-1, "", "Only set_max_delay currently supported");
    }

    build_from_to_lists(&from_list, &num_from, &domain_level_from,
                        &to_list, &num_to, &domain_level_to,
                        sdc_set_min_max_delay.from, sdc_set_min_max_delay.to);

    /* Create a constraint between each element in from_list and each element in to_list with value max_delay. */
    add_override_constraint(from_list, num_from, to_list, num_to, sdc_set_min_max_delay.value,
                            0, domain_level_from, domain_level_to, false);
    
    /* Finally, set from_list and to_list to NULL since they're both 
    being pointed to by the override constraint entry we just created. */
    from_list = nullptr, to_list = nullptr;

    return true;
}

static bool apply_set_multicycle_path(const sdcparse::SetMulticyclePath& sdc_set_multicycle_path) {
	bool domain_level_from = false, domain_level_to = false;
    int num_from = 0, num_to = 0;
    char **from_list = nullptr, **to_list = nullptr;

    VTR_ASSERT(sdc_set_multicycle_path.is_setup && !sdc_set_multicycle_path.is_hold); //Currently only form supported

    build_from_to_lists(&from_list, &num_from, &domain_level_from,
                        &to_list, &num_to, &domain_level_to,
                        sdc_set_multicycle_path.from, sdc_set_multicycle_path.to);

    /* Create an override constraint between from and to. Unlike the previous two commands, set_multicycle_path requires 
    information about the periods and offsets of the clock domains which from and to, which we have to fill in at the end. */
    add_override_constraint(from_list, num_from, to_list, num_to, HUGE_NEGATIVE_FLOAT /* irrelevant - never used */,
        sdc_set_multicycle_path.mcp_value, domain_level_from, domain_level_to, false);
    
    /* Finally, set from_list and to_list to NULL since they're both 
    being pointed to by the override constraint entry we just created. */
    from_list = nullptr, to_list = nullptr;

    return true;
}

static bool apply_set_io_delay(const sdcparse::SetIoDelay& sdc_set_io_delay, int lineno) {
    bool found;
    const char* io_type;

    const char* clock_name = sdc_set_io_delay.clock_name.c_str();

    //Support for non-standard wildcard clock name for set_input_delay/set_output_dealy
    //commands, provided it is unambiguous (i.e. there is only one netlist clock)
    if(num_netlist_clocks == 1 && strcmp(clock_name, "*") == 0) {
        clock_name = netlist_clocks[0]; 
    }

    //Verify that the provided clock name is valid
    if(!is_valid_clock_name(clock_name)) {
        vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), lineno, 
                "Clock name '%s' does not match to any known clock.\n",
                clock_name);
    }
    
    /* 
     * Add each regular expression match we find to the list of constrained 
     * inputs (outputs) and give each entry the appropraite clock name and 
     * max_delay 
     */
    
    auto& timing_ctx = g_vpr_ctx.timing();

    const sdcparse::StringGroup& port_group = sdc_set_io_delay.target_ports;
    for (size_t iport = 0; iport < port_group.strings.size(); iport++) {

        found = false;

        for (int iio = 0; iio < num_netlist_ios; iio++) {
            /* See if the regular expression  is legal and matches at least one input port. 
            If it is not legal, it will fail during regex_match.  We check for a match using bool found. */
            if (regex_match(netlist_ios[iio], port_group.strings[iport].c_str())) {
                if(sdc_set_io_delay.type == sdcparse::IoDelayType::INPUT) {
                    /* We've found a new input! */
                    timing_ctx.sdc->num_constrained_inputs++;
                    found = true;

                    /* Fill in input information in the permanent array timing_ctx.sdc->constrained_inputs. */
                    timing_ctx.sdc->constrained_inputs = (t_io *) vtr::realloc (timing_ctx.sdc->constrained_inputs, timing_ctx.sdc->num_constrained_inputs * sizeof(t_io));
                    timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].name = vtr::strdup(netlist_ios[iio]);
                    timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].clock_name = vtr::strdup(clock_name);
                    timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].delay = sdc_set_io_delay.delay;
                    timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].file_line_number = lineno;
                } else {
                    VTR_ASSERT(sdc_set_io_delay.type == sdcparse::IoDelayType::OUTPUT);
					/* We've found a new output! */
					timing_ctx.sdc->num_constrained_outputs++;
					found = true;

					/* Fill in output information in the permanent array timing_ctx.sdc->constrained_outputs. */
					timing_ctx.sdc->constrained_outputs = (t_io *) vtr::realloc (timing_ctx.sdc->constrained_outputs, timing_ctx.sdc->num_constrained_outputs * sizeof(t_io));
					timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].name = vtr::strdup(netlist_ios[iio]);
					timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].clock_name = vtr::strdup(clock_name);
					timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].delay = sdc_set_io_delay.delay;
					timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].file_line_number = lineno;
                }
            }
        }

        if (!found) {
            if(sdc_set_io_delay.type == sdcparse::IoDelayType::INPUT) {
                io_type = "Input";
            } else {
                VTR_ASSERT(sdc_set_io_delay.type == sdcparse::IoDelayType::OUTPUT);
                io_type = "Output";
            }

            vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), lineno, 
                    "%s name or regular expression \"%s\" does not correspond to any nets.\n", io_type, port_group.strings[iport].c_str());
            return false;
        }
    }
    return true;
}

static bool is_valid_clock_name(const char* clock_name) {
    auto& timing_ctx = g_vpr_ctx.timing();

    bool found = false;
    for(int iclk = 0; iclk < timing_ctx.sdc->num_constrained_clocks; iclk++) {
        if(strcmp(timing_ctx.sdc->constrained_clocks[iclk].name, clock_name) == 0) {
            found = true;
            break;
        }
    }
    return found;
}

static bool build_from_to_lists(char ***from_list, int *num_from, bool* domain_level_from,
                            char ***to_list, int *num_to, bool* domain_level_to,
                            const sdcparse::StringGroup& from_group, const sdcparse::StringGroup& to_group) {
    /*
     * Source 'from' objects/clocks
     */

    //Are we working with a set of clock domains?
    if(from_group.type == sdcparse::StringGroupType::CLOCK) {
        *domain_level_from = true;
    }
    for(size_t i = 0; i < from_group.strings.size(); i++) {
        /* Keep adding clock names to from_list */
        (*from_list) = (char **) vtr::realloc((*from_list), ++(*num_from) * sizeof(**from_list));
        (*from_list)[(*num_from) - 1] = vtr::strdup(from_group.strings[i].c_str());
    }

    /*
     * Target 'to' object/clocsk
     */
    
    //Are we working with a set of clock domains?

    if(to_group.type == sdcparse::StringGroupType::CLOCK) {
        *domain_level_to = true;
    }
    for(size_t i = 0; i < to_group.strings.size(); i++) {
        /* Keep adding clock names to to_list */
        (*to_list) = (char **) vtr::realloc((*to_list), ++(*num_to) * sizeof(**to_list));
        (*to_list)[(*num_to) - 1] = vtr::strdup(to_group.strings[i].c_str());
    }

    return true;
}

static void use_default_timing_constraints() {

	int source_clock_domain, sink_clock_domain;

    auto& timing_ctx = g_vpr_ctx.timing();
	
	/* Find all netlist clocks and add them as constrained clocks. */
	count_netlist_clocks_as_constrained_clocks();

	/* We'll use separate defaults for multi-clock and single-clock/combinational circuits. */

	if (timing_ctx.sdc->num_constrained_clocks <= 1) {
		/* Create one constrained clock with period 0... */
		timing_ctx.sdc->domain_constraint = vtr::Matrix<float>({1,1});
		timing_ctx.sdc->domain_constraint[0][0] = 0.;
		
        vtr::printf_info("\n");

		if (timing_ctx.sdc->num_constrained_clocks == 0) {
			/* We need to create a virtual clock to constrain I/Os on. */
			timing_ctx.sdc->num_constrained_clocks = 1;
			timing_ctx.sdc->constrained_clocks = (t_clock *) vtr::malloc(sizeof(t_clock));
			timing_ctx.sdc->constrained_clocks[0].name = vtr::strdup("virtual_io_clock");
			timing_ctx.sdc->constrained_clocks[0].is_netlist_clock = false;

            /* Constrain all I/Os on the virtual clock, with I/O delay 0. */
            count_netlist_ios_as_constrained_ios(timing_ctx.sdc->constrained_clocks[0].name, 0.);

			vtr::printf_info("Defaulting to: constrain all %d inputs and %d outputs on a virtual external clock.\n", 
					timing_ctx.sdc->num_constrained_inputs, timing_ctx.sdc->num_constrained_outputs);
			vtr::printf_info("Optimize this virtual clock to run as fast as possible.\n");
		} else {
            /* Constrain all I/Os on the single netlist clock, with I/O delay 0. */
            count_netlist_ios_as_constrained_ios(timing_ctx.sdc->constrained_clocks[0].name, 0.);

			vtr::printf_info("Defaulting to: constrain all %d inputs and %d outputs on the netlist clock.\n", 
					timing_ctx.sdc->num_constrained_inputs, timing_ctx.sdc->num_constrained_outputs);
			vtr::printf_info("Optimize this clock to run as fast as possible.\n");
		}
	} else { /* Multiclock circuit */

		/* Constrain all I/Os on a separate virtual clock. Cut paths between all netlist
		 clocks, but analyse all paths between the virtual I/O clock and netlist clocks
		 and optimize all clocks to go as fast as possible. */

		timing_ctx.sdc->constrained_clocks = (t_clock *) vtr::realloc (timing_ctx.sdc->constrained_clocks, ++timing_ctx.sdc->num_constrained_clocks * sizeof(t_clock));
		timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = vtr::strdup("virtual_io_clock");
		timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].is_netlist_clock = false;
		count_netlist_ios_as_constrained_ios(timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name, 0.);

		/* Allocate matrix of timing constraints [0..timing_ctx.sdc->num_constrained_clocks-1][0..timing_ctx.sdc->num_constrained_clocks-1] */
        size_t num_constrained_clocks = timing_ctx.sdc->num_constrained_clocks;
		timing_ctx.sdc->domain_constraint = vtr::Matrix<float>({num_constrained_clocks, num_constrained_clocks});

		for (source_clock_domain = 0; source_clock_domain < timing_ctx.sdc->num_constrained_clocks; source_clock_domain++) {
			for (sink_clock_domain = 0; sink_clock_domain < timing_ctx.sdc->num_constrained_clocks; sink_clock_domain++) {
				if (source_clock_domain == sink_clock_domain || source_clock_domain == timing_ctx.sdc->num_constrained_clocks - 1 
					|| sink_clock_domain == timing_ctx.sdc->num_constrained_clocks - 1) {
					timing_ctx.sdc->domain_constraint[source_clock_domain][sink_clock_domain] = 0.;
				} else {
					timing_ctx.sdc->domain_constraint[source_clock_domain][sink_clock_domain] = DO_NOT_ANALYSE;
				}
			}
		}
		
		vtr::printf_info("\n");
		vtr::printf_info("Defaulting to: constrain all %d inputs and %d outputs on a virtual external clock;\n",
				timing_ctx.sdc->num_constrained_inputs, timing_ctx.sdc->num_constrained_outputs);
		vtr::printf_info("\tcut paths between netlist clock domains; and\n");
		vtr::printf_info("\toptimize all clocks to run as fast as possible.\n");
	}
}

static void alloc_and_load_netlist_clocks_and_ios() {
    std::map<const t_model*,std::vector<const t_model_ports*>> clock_gen_ports; //Records info about clock generating ports

	/* Count how many clocks and I/Os are in the netlist. 
	Store the names of each clock and each I/O in netlist_clocks and netlist_ios. */
    auto& atom_ctx = g_vpr_ctx.atom();

    for(auto blk_id : atom_ctx.nlist.blocks()) {

        AtomBlockType type = atom_ctx.nlist.block_type(blk_id);
        if(type == AtomBlockType::BLOCK) {

            //Save any clock generating ports on this model type
            const t_model* model = atom_ctx.nlist.block_model(blk_id);
            VTR_ASSERT(model);
            auto iter = clock_gen_ports.find(model);
            if(iter == clock_gen_ports.end()) {
                //First time seen, record any ports which could generate clocks
                for(const t_model_ports* model_port = model->outputs; model_port; model_port = model_port->next) {
                    VTR_ASSERT(model_port->dir == OUT_PORT);
                    if(model_port->is_clock) {
                        //Clock generator
                        clock_gen_ports[model].push_back(model_port);
                    }
                }
            }

            //Look for connected input clocks
            for(auto pin_id : atom_ctx.nlist.block_clock_pins(blk_id)) {
                AtomNetId clk_net_id = atom_ctx.nlist.pin_net(pin_id);
                VTR_ASSERT(clk_net_id);

                std::string name = atom_ctx.nlist.net_name(clk_net_id);
                /* Now that we've found a clock, let's see if we've counted it already */
                bool found = false;
                for (int i = 0; !found && i < num_netlist_clocks; i++) {
                    if (netlist_clocks[i] == name) {
                        found = true;
                    }
                }
                if (!found) {
                    /* If we get here, the clock is new and so we dynamically grow the array netlist_clocks by one. */
                    netlist_clocks = (char **) vtr::realloc (netlist_clocks, ++num_netlist_clocks * sizeof(char *));
                    netlist_clocks[num_netlist_clocks - 1] = vtr::strdup(name.c_str());
                }
            }

            //Look for any generated clocks
            if(clock_gen_ports.count(model)) {
                //This is a clock generator

                //Check all the clock generating ports
                for(const t_model_ports* model_port : clock_gen_ports[model]) {
                    AtomPortId clk_gen_port = atom_ctx.nlist.find_atom_port(blk_id, model_port);

                    for(AtomPinId pin_id : atom_ctx.nlist.port_pins(clk_gen_port)) {
                        AtomNetId clk_net_id = atom_ctx.nlist.pin_net(pin_id);
                        VTR_ASSERT(clk_net_id);

                        std::string name = atom_ctx.nlist.net_name(clk_net_id);
                        /* Now that we've found a clock, let's see if we've counted it already */
                        bool found = false;
                        for (int i = 0; !found && i < num_netlist_clocks; i++) {
                            if (netlist_clocks[i] == name) {
                                found = true;
                            }
                        }
                        if (!found) {
                            /* If we get here, the clock is new and so we dynamically grow the array netlist_clocks by one. */
                            netlist_clocks = (char **) vtr::realloc (netlist_clocks, ++num_netlist_clocks * sizeof(char *));
                            netlist_clocks[num_netlist_clocks - 1] = vtr::strdup(name.c_str());
                        }
                    }
                }
            }
		} else if (type == AtomBlockType::INPAD || type == AtomBlockType::OUTPAD) {

            std::string name = atom_ctx.nlist.block_name(blk_id);
			/* Now that we've found an I/O, let's see if we've counted it already */
			bool found = false;
			for (int i = 0; !found && i < num_netlist_ios; i++) {
				if (netlist_ios[i] == name) {
					found = true;
				}
			}
			if (!found) {
                const char* trimmed_name = (type == AtomBlockType::OUTPAD) ? name.c_str() + 4 : name.c_str();
				/* the + 4 removes the prefix "out:" automatically prepended to outputs */

				/* If we get here, the I/O is new and so we dynamically grow the array netlist_ios by one. */
				netlist_ios = (char **) vtr::realloc (netlist_ios, ++num_netlist_ios * sizeof(char *));
				netlist_ios[num_netlist_ios - 1] = vtr::strdup(trimmed_name); 
			}
		}
	}
}

static void count_netlist_clocks_as_constrained_clocks() {
	/* Counts how many clocks are in the netlist, and adds them to the array timing_ctx.sdc->constrained_clocks. */
    auto& timing_ctx = g_vpr_ctx.timing();
    auto& atom_ctx = g_vpr_ctx.atom();

	timing_ctx.sdc->num_constrained_clocks = 0;
	
    for(auto blk_id : atom_ctx.nlist.blocks()) {
        //Check for input clocks
        for(auto pin_id : atom_ctx.nlist.block_clock_pins(blk_id)) {
            AtomNetId clk_net_id = atom_ctx.nlist.pin_net(pin_id);
            VTR_ASSERT(clk_net_id);

            std::string name = atom_ctx.nlist.net_name(clk_net_id);
            add_clock(name);
        }

        //Check for generated clocks
        for(AtomPortId port : atom_ctx.nlist.block_output_ports(blk_id)) {
            const t_model_ports* port_model = atom_ctx.nlist.port_model(port);
            VTR_ASSERT(port_model->dir == OUT_PORT);

            if(port_model->is_clock) {
                //This is a clock generator
                for(AtomPinId pin : atom_ctx.nlist.port_pins(port)) {
                    AtomNetId net = atom_ctx.nlist.pin_net(pin);
                    std::string net_name = atom_ctx.nlist.net_name(net);
                    add_clock(net_name);
                }
            }
        }
	}
}

static void add_clock(std::string net_name) {
    /* Now that we've found a clock, let's see if we've counted it already */
    auto& timing_ctx = g_vpr_ctx.timing();

    bool found = false;
    for (int i = 0; !found && i < timing_ctx.sdc->num_constrained_clocks; i++) {
        if (timing_ctx.sdc->constrained_clocks[i].name == net_name) {
            found = true;
        }
    }
    if (!found) {
        /* If we get here, the clock is new and so we dynamically grow the array timing_ctx.sdc->constrained_clocks by one. */
        timing_ctx.sdc->constrained_clocks = (t_clock *) vtr::realloc (timing_ctx.sdc->constrained_clocks, ++timing_ctx.sdc->num_constrained_clocks * sizeof(t_clock));
        timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].name = vtr::strdup(net_name.c_str());
        timing_ctx.sdc->constrained_clocks[timing_ctx.sdc->num_constrained_clocks - 1].is_netlist_clock = true;
        /* Fanout will be filled out once the timing graph has been constructed. */
    }
}

static void count_netlist_ios_as_constrained_ios(char * clock_name, float io_delay) {
	/* Count how many I/Os are in the netlist, adds them to the arrays timing_ctx.sdc->constrained_inputs/
	timing_ctx.sdc->constrained_outputs with an I/O delay of 0 and constrains them to clock clock_name. */

    auto& atom_ctx = g_vpr_ctx.atom();
    auto& timing_ctx = g_vpr_ctx.timing();

    for(auto blk_id : atom_ctx.nlist.blocks()) {
        AtomBlockType type = atom_ctx.nlist.block_type(blk_id);

		if (type == AtomBlockType::INPAD) {
            std::string name = atom_ctx.nlist.block_name(blk_id);
			/* Now that we've found an I/O, let's see if we've counted it already */
			bool found = false;
			for (int iinput = 0; !found && iinput < timing_ctx.sdc->num_constrained_inputs; iinput++) {
				if (timing_ctx.sdc->constrained_inputs[iinput].name == name) {
					found = true;
				}
			}
			if (!found) {
				/* If we get here, the input is new and so we add it to timing_ctx.sdc->constrained_inputs. */
				timing_ctx.sdc->constrained_inputs = (t_io *) vtr::realloc (timing_ctx.sdc->constrained_inputs, ++timing_ctx.sdc->num_constrained_inputs * sizeof(t_io));
				timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].name = vtr::strdup(name.c_str()); 
				timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].clock_name = vtr::strdup(clock_name);
				timing_ctx.sdc->constrained_inputs[timing_ctx.sdc->num_constrained_inputs - 1].delay = io_delay;
			}
		} else if (type == AtomBlockType::OUTPAD) {
            std::string name = atom_ctx.nlist.block_name(blk_id);
			/* Now that we've found an I/O, let's see if we've counted it already */
			bool found = false;
			for (int ioutput = 0; !found && ioutput < timing_ctx.sdc->num_constrained_outputs; ioutput++) {
				if (timing_ctx.sdc->constrained_outputs[ioutput].name == name) {
					found = true;
				}
			}
			if (!found) {
				/* If we get here, the output is new and so we add it to timing_ctx.sdc->constrained_outputs. */
				timing_ctx.sdc->constrained_outputs = (t_io *) vtr::realloc (timing_ctx.sdc->constrained_outputs, ++timing_ctx.sdc->num_constrained_outputs * sizeof(t_io));
				timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].name = vtr::strdup(name.c_str() + 4); 
				/* the + 4 removes the prefix "out:" automatically prepended to outputs */
				timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].clock_name = vtr::strdup(clock_name);
				timing_ctx.sdc->constrained_outputs[timing_ctx.sdc->num_constrained_outputs - 1].delay = io_delay;
			}
		}
	}
}

static int find_constrained_clock(char * ptr) {
/* Given a string ptr, find whether it's the name of a clock in the array timing_ctx.sdc->constrained_clocks.  *
 * if it is, return the clock's index in timing_ctx.sdc->constrained_clocks; if it's not, return -1. */
    auto& timing_ctx = g_vpr_ctx.timing();

	int index;
	for (index = 0; index < timing_ctx.sdc->num_constrained_clocks; index++) {
		if (strcmp(ptr, timing_ctx.sdc->constrained_clocks[index].name) == 0) {
			return index;
		}
	}
	return -1;
}

static int find_cc_constraint(char * source_clock_name, char * sink_clock_name) {
	/* Given a pair of source and sink clock domains, find out if there's an override constraint between them.
	If there is, return the index in timing_ctx.sdc->cc_constraints; if there is not, return -1. */
    auto& timing_ctx = g_vpr_ctx.timing();

	int icc, isource, isink;

	for (icc = 0; icc < timing_ctx.sdc->num_cc_constraints; icc++) {
		for (isource = 0; isource < timing_ctx.sdc->cc_constraints[icc].num_source; isource++) {
			if (strcmp(timing_ctx.sdc->cc_constraints[icc].source_list[isource], source_clock_name) == 0) {
				for (isink = 0; isink < timing_ctx.sdc->cc_constraints[icc].num_sink; isink++) {
					if (strcmp(timing_ctx.sdc->cc_constraints[icc].sink_list[isink], sink_clock_name) == 0) {
						return icc;
					}
				}
			}
		}
	}
	return -1;
}

static void add_override_constraint(char ** from_list, int num_from, char ** to_list, int num_to, 
	float constraint, int num_multicycles, bool domain_level_from, bool domain_level_to,
	bool make_copies) {
	/* Add a special-case constraint to override the default, calculated timing constraint, 
	to one of four arrays depending on whether it's coming from/to a flip-flop or an entire clock domain. 

	If make_copies is true, we make a copy of from_list and to_list for this override constraint entry; 
	if false, we just set the override constraint entry to point to the existing list. The latter is 
	more efficient, but it's almost impossible to free multiple identical pointers without freeing
	the same thing twice and causing an error. */
    auto& timing_ctx = g_vpr_ctx.timing();

	t_override_constraint ** constraint_array; 
	/* Because we are reallocating the array and possibly changing 
	its	address, we need to modify it through a reference. */

	int num_constraints, i;

	if (domain_level_from) {
		if (domain_level_to) { /* Clock-to-clock constraint */
			constraint_array = &timing_ctx.sdc->cc_constraints;
			num_constraints = ++timing_ctx.sdc->num_cc_constraints;
		} else { /* Clock-to-flipflop constraint */
			constraint_array = &timing_ctx.sdc->cf_constraints;
			num_constraints = ++timing_ctx.sdc->num_cf_constraints;
		}
	} else {
		if (domain_level_to) { /* Flipflop-to-clock constraint */
			constraint_array = &timing_ctx.sdc->fc_constraints;
			num_constraints = ++timing_ctx.sdc->num_fc_constraints;
		} else { /* Flipflop-to-flipflop constraint */
			constraint_array = &timing_ctx.sdc->ff_constraints;
			num_constraints = ++timing_ctx.sdc->num_ff_constraints;
		}
	}

	*constraint_array = (t_override_constraint *) vtr::realloc(*constraint_array, num_constraints * sizeof(t_override_constraint));
	
	if (make_copies) {
		/* Copy from_list and to_list to constraint_array[num_constraints - 1].source_list and .sink_list. */
		(*constraint_array)[num_constraints - 1].source_list = (char **) vtr::malloc(num_from * sizeof(char *));
		(*constraint_array)[num_constraints - 1].sink_list = (char **) vtr::malloc(num_to * sizeof(char *));
		for (i = 0; i < num_from; i++) {
			(*constraint_array)[num_constraints - 1].source_list[i] = vtr::strdup(from_list[i]);
		}
		for (i = 0; i < num_to; i++) {
			(*constraint_array)[num_constraints - 1].sink_list[i] = vtr::strdup(to_list[i]);
		}
	} else {
		/* Just set constraint array to point to from_list and to_list. */
		(*constraint_array)[num_constraints - 1].source_list = from_list;
		(*constraint_array)[num_constraints - 1].sink_list = to_list;
	}
	(*constraint_array)[num_constraints - 1].num_source = num_from;	
	(*constraint_array)[num_constraints - 1].num_sink = num_to;	
	(*constraint_array)[num_constraints - 1].constraint = constraint;
	(*constraint_array)[num_constraints - 1].num_multicycles = num_multicycles;
	(*constraint_array)[num_constraints - 1].file_line_number = vtr::get_file_line_number_of_last_opened_file(); /* global var */
}

static float calculate_constraint(t_sdc_clock source_domain, t_sdc_clock sink_domain) {
	/* Given information from the SDC file about the period and offset of two clocks, *
	 * determine the implied setup-time constraint between them via edge counting.    */

	int source_period, sink_period, source_rising_edge, sink_rising_edge, lcm_period, num_source_edges, num_sink_edges, 
		* source_edges, * sink_edges, i, j, time, constraint_as_int;
	float constraint;

	/* If the source and sink domains have the same period and edges, the constraint is just the common clock period. */
	if (fabs(source_domain.period - sink_domain.period) < EPSILON && 
		fabs(source_domain.rising_edge - sink_domain.rising_edge) < EPSILON &&
		fabs(source_domain.falling_edge - sink_domain.falling_edge) < EPSILON) {
		return source_domain.period; /* or, equivalently, sink_domain.period */
	}

	/* If either period is 0, the constraint is 0. */
	if (source_domain.period < EPSILON || sink_domain.period < EPSILON) {
		return 0.;
	}
	
	 /* Multiply periods and edges by 1000 and round down  *				  
	  * to the nearest integer, to avoid messy decimals.   */

	source_period = static_cast<int>(source_domain.period * 1000);
	sink_period = static_cast<int>(sink_domain.period * 1000);
	source_rising_edge = static_cast<int>(source_domain.rising_edge * 1000);
	sink_rising_edge = static_cast<int>(sink_domain.rising_edge * 1000);	

	/* If we get here, we have to use edge counting.  Find the LCM of the two periods.		   *
	* This determines how long it takes before the pattern of the two clocks starts repeating. */
    lcm_period = vtr::lcm(source_period, sink_period);

	/* Create an array of positive edges for each clock over one LCM clock period. */

	num_source_edges = lcm_period/source_period + 1; 
	num_sink_edges = lcm_period/sink_period + 1;

	source_edges = (int *) vtr::malloc((num_source_edges + 1) * sizeof(int));
	sink_edges = (int *) vtr::malloc((num_sink_edges + 1) * sizeof(int));
	
	for (i = 0, time = source_rising_edge; i < num_source_edges + 1; i++) {
		source_edges[i] = time;
		time += source_period;
	}

	for (i = 0, time = sink_rising_edge; i < num_sink_edges + 1; i++) {
		sink_edges[i] = time;
		time += sink_period;
	}

	/* Compare every edge in source_edges with every edge in sink_edges.			 *
	 * The lowest STRICTLY POSITIVE difference between a sink edge and a source edge *
	 * gives us the set-up time constraint.											 */

	constraint_as_int = INT_MAX; /* constraint starts off at +ve infinity so that everything will be less than it */

	for (i = 0; i < num_source_edges + 1; i++) {
		for (j = 0; j < num_sink_edges + 1; j++) {
			if (sink_edges[j] > source_edges[i]) {
				constraint_as_int = min(constraint_as_int, sink_edges[j] - source_edges[i]);
			}
		}
	}

	/* Divide by 1000 again and turn the constraint back into a float, and clean up memory. */

	constraint = constraint_as_int / 1000.;

	free(source_edges);
	free(sink_edges);

	return constraint;
}

static bool regex_match (const char * string, const char * regular_expression) {
	/* Given a string and a regular expression, return true if there's a match, 
	false if not. Print an error and exit if regular_expression is invalid. */

	const char * error;
	
	VTR_ASSERT(string && regular_expression);

	/* The regex library reports a match if regular_expression is a substring of string
	AND not equal to string. This is not appropriate for our purposes. For example, 
	we'd get both "clock" and "clock2" matching the regular expression "clock".  
	We have to manually return that there's no match in this special case. */
	if (strstr(string, regular_expression) && strcmp(string, regular_expression) != 0)
		return false;

	if (strcmp(regular_expression, "*") == 0)
		return true; /* The regex library hangs if it is fed "*" as a regular expression. */

	error = slre_match((enum slre_option) 0, regular_expression, string, strlen(string));

	if (!error) 
		return true;
	else if (strcmp(error, "No match") == 0) 
		return false;
	else {
		vpr_throw(VPR_ERROR_SDC, sdc_file_name.c_str(), vtr::get_file_line_number_of_last_opened_file(), 
				"Error matching regular expression \"%s\".\n", regular_expression);
		return false;
	}
}

void free_sdc_related_structs() {
    auto& timing_ctx = g_vpr_ctx.mutable_timing();

	if (!timing_ctx.sdc) return;

	free_override_constraint(timing_ctx.sdc->cc_constraints, timing_ctx.sdc->num_cc_constraints); 
	/* Should already have been freed in process_constraints() */

	free_override_constraint(timing_ctx.sdc->cf_constraints, timing_ctx.sdc->num_cf_constraints);
	free_override_constraint(timing_ctx.sdc->fc_constraints, timing_ctx.sdc->num_fc_constraints);
	free_override_constraint(timing_ctx.sdc->ff_constraints, timing_ctx.sdc->num_ff_constraints);
	free_io_constraint(timing_ctx.sdc->constrained_inputs, timing_ctx.sdc->num_constrained_inputs);
	free_io_constraint(timing_ctx.sdc->constrained_outputs, timing_ctx.sdc->num_constrained_outputs);
	free_clock_constraint(timing_ctx.sdc->constrained_clocks, timing_ctx.sdc->num_constrained_clocks);
	free(timing_ctx.sdc);
	timing_ctx.sdc = nullptr;
}

void free_override_constraint(t_override_constraint *& constraint_array, int num_constraints) {
	int i, j;

	if (!constraint_array) return;

	for (i = 0; i < num_constraints; i++) {
		for (j = 0; j < constraint_array[i].num_source; j++) {
			free(constraint_array[i].source_list[j]);
			constraint_array[i].source_list[j] = nullptr;
		}
		for (j = 0; j < constraint_array[i].num_sink; j++) {
			free(constraint_array[i].sink_list[j]);
			constraint_array[i].sink_list[j] = nullptr;
		}
		free(constraint_array[i].source_list);
		free(constraint_array[i].sink_list);
	}
	free(constraint_array);
	constraint_array = nullptr;
}

static void free_io_constraint(t_io *& io_array, int num_ios) {
	int i;

	for (i = 0; i < num_ios; i++) {
		free(io_array[i].name);
		free(io_array[i].clock_name);
	}
	free(io_array);
	io_array = nullptr;
}

static void free_clock_constraint(t_clock *& clock_array, int num_clocks) {
	int i;

	for (i = 0; i < num_clocks; i++) {
		free(clock_array[i].name);
	}
	free(clock_array);
	clock_array = nullptr;
}

const char * get_sdc_file_name(){
	return sdc_file_name.c_str();
}

