#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();
}

