#include "read_sdc2.h"

#include <regex>

#include "vtr_log.h"
#include "vtr_assert.h"
#include "vtr_util.h"
#include "vtr_math.h"

#include "tatum/TimingGraph.hpp"
#include "tatum/TimingConstraints.hpp"
#include "sdcparse.hpp"

#include "vpr_error.h"
#include "atom_netlist.h"
#include "atom_netlist_utils.h"
#include "atom_lookup.h"

void apply_default_timing_constraints(const AtomNetlist& netlist,
                                      const AtomLookup& lookup,
                                      tatum::TimingConstraints& timing_constraints);

void apply_combinational_default_timing_constraints(const AtomNetlist& netlist,
                                                    const AtomLookup& lookup,
                                                    tatum::TimingConstraints& timing_constraints);

void apply_single_clock_default_timing_constraints(const AtomNetlist& netlist,
                                                   const AtomLookup& lookup,
                                                   const AtomPinId clock_driver,
                                                   tatum::TimingConstraints& timing_constraints);

void apply_multi_clock_default_timing_constraints(const AtomNetlist& netlist,
                                                  const AtomLookup& lookup,
                                                  const std::set<AtomPinId>& clock_drivers,
                                                  tatum::TimingConstraints& timing_constraints);

void mark_constant_generators(const AtomNetlist& netlist,
                              const AtomLookup& lookup,
                              tatum::TimingConstraints& tc);

void constrain_all_ios(const AtomNetlist& netlist,
                       const AtomLookup& lookup,
                       tatum::TimingConstraints& tc,
                       tatum::DomainId input_domain,
                       tatum::DomainId output_domain,
                       tatum::Time input_delay,
                       tatum::Time output_delay);

std::map<std::string,AtomPinId> find_netlist_primary_ios(const AtomNetlist& netlist);
std::string orig_blif_name(std::string name);
void print_netlist_clock_info(const AtomNetlist& netlist);

std::regex glob_pattern_to_regex(const std::string& glob_pattern);

class SdcParseCallback2 : public sdcparse::Callback {
    public:
        SdcParseCallback2(const AtomNetlist& netlist,
                          const AtomLookup& lookup,
                          tatum::TimingConstraints& timing_constraints,
                          tatum::TimingGraph& tg)
            : netlist_(netlist)
            , lookup_(lookup)
            , tc_(timing_constraints)
            , tg_(tg)
            {}
    public: //sdcparse::Callback interface
        //Start of parsing
        void start_parse() override {
            netlist_clock_drivers_ = find_netlist_logical_clock_drivers(netlist_);
            netlist_primary_ios_ = find_netlist_primary_ios(netlist_);
        }

        //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 {
            ++num_commands_;

            if(cmd.is_virtual) {
                //Create a virtual clock
                tatum::DomainId virtual_clk = tc_.create_clock_domain(cmd.name);

                if(sdc_clocks_.count(virtual_clk)) {
                    vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                              "Found duplicate virtual clock definition for clock '%s'",
                              cmd.name.c_str());
                }

                //Virtual clocks should have no targets
                if(!cmd.targets.strings.empty()) {
                    vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                              "Virtual clock definition (i.e. with '-name') should not have targets");
                }

                //Save the mapping to the sdc clock info
                sdc_clocks_[virtual_clk] = cmd;
            } else {
                //Create a netlist clock for every matching netlist clock
                for(const std::string& clock_name_glob_pattern : cmd.targets.strings) {
                    bool found = false;

                    //We interpret each SDC target as glob-style pattern matches, which we
                    //convert to a regex
                    auto clock_name_regex = glob_pattern_to_regex(clock_name_glob_pattern);

                    //Look for matching netlist clocks
                    for(AtomPinId clock_pin : netlist_clock_drivers_) {
                        AtomNetId clock_net = netlist_.pin_net(clock_pin);
                        const auto& clock_name = netlist_.net_name(clock_net);

                        if(std::regex_match(clock_name, clock_name_regex)) {
                            found = true;
                            //Create netlist clock
                            tatum::DomainId netlist_clk = tc_.create_clock_domain(clock_name);

                            if(sdc_clocks_.count(netlist_clk)) {
                                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                                          "Found duplicate netlist clock definition for clock '%s' matching target pattern '%s'",
                                          clock_name.c_str(), clock_name_glob_pattern.c_str());
                            }

                            //Set the clock source
                            AtomPinId clock_driver = netlist_.net_driver(clock_net);
                            tatum::NodeId clock_source = lookup_.atom_pin_tnode(clock_driver);
                            VTR_ASSERT(clock_source);
                            tc_.set_clock_domain_source(clock_source, netlist_clk);


                            //Save the mapping to the clock info
                            sdc_clocks_[netlist_clk] = cmd;
                        }
                    }

                    if(!found) {
                        vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                                  "Clock name or pattern '%s' does not correspond to any nets."
                                  " To create a virtual clock, use the '-name' option.",
                                  clock_name_glob_pattern.c_str());
                    }
                }
            }
        }

        void set_io_delay(const sdcparse::SetIoDelay& cmd) override {
            ++num_commands_;

            tatum::DomainId domain;

            if (cmd.clock_name == "*") {
                if(netlist_clock_drivers_.size() == 1) {
                    //Support non-standard wildcard clock name for set_input_delay/set_output_delay
                    //commands, provided it is unambiguous (i.e. there is only one netlist clock)

                    AtomNetId clock_net = netlist_.pin_net(*netlist_clock_drivers_.begin());
                    std::string clock_name = netlist_.net_name(clock_net);
                    domain = tc_.find_clock_domain(clock_name);
                } else {
                    vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                              "Wildcard clock domain '%s' is ambiguous in multi-clock circuits, explicitly specify the target clock",
                              cmd.clock_name.c_str());
                }
            } else {
                //Regular look-up
                domain = tc_.find_clock_domain(cmd.clock_name);
            }

            //Error checks
            if (!domain) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                          "Failed to find clock domain '%s' for I/O constraint",
                          cmd.clock_name.c_str());
            }

            //Find all matching I/Os
            auto io_pins = get_ports(cmd.target_ports);

            if(io_pins.empty()) {
                //We treat this as a warning, since the primary I/Os in the target may have been swept away
                vtr::printf_warning( fname_.c_str(), lineno_,
                          "Found no matching primary inputs or primary outputs for %s\n",
                          (cmd.type == sdcparse::IoDelayType::INPUT) ? "set_input_delay" : "set_output_delay");
            }

            bool is_max = cmd.is_max;
            bool is_min = cmd.is_min;
            if (!is_max && !is_min) {
                //Unspecified implies both
                is_max = true;
                is_min = true;
            }

            float delay = sdc_units_to_seconds(cmd.delay);

            for(AtomPinId pin : io_pins) {
                tatum::NodeId tnode = lookup_.atom_pin_tnode(pin);
                VTR_ASSERT(tnode);

                //Set i/o constraint
                if (cmd.type == sdcparse::IoDelayType::INPUT) {


                    if(netlist_.pin_type(pin) == PinType::DRIVER) {
                        if (is_max) {
                            tc_.set_input_constraint(tnode, domain, tatum::DelayType::MAX, tatum::Time(delay));
                        }
                        if (is_min) {
                            tc_.set_input_constraint(tnode, domain, tatum::DelayType::MIN, tatum::Time(delay));
                        }
                    } else {
                        VTR_ASSERT(netlist_.pin_type(pin) == PinType::SINK);

                        AtomBlockId blk = netlist_.pin_block(pin);
                        std::string io_name = orig_blif_name(netlist_.block_name(blk));

                        vtr::printf_warning(fname_.c_str(), lineno_,
                                            "set_input_delay command matched but was not applied to primary output '%s'\n",
                                            io_name.c_str());
                    }
                } else {
                    VTR_ASSERT(cmd.type == sdcparse::IoDelayType::OUTPUT);

                    if(netlist_.pin_type(pin) == PinType::SINK) {
                        if (is_max) {
                            tc_.set_output_constraint(tnode, domain, tatum::DelayType::MAX, tatum::Time(delay));
                        }
                        if (is_min) {
                            tc_.set_output_constraint(tnode, domain, tatum::DelayType::MIN, tatum::Time(delay));
                        }

                    } else {
                        VTR_ASSERT(netlist_.pin_type(pin) == PinType::DRIVER);
                        AtomBlockId blk = netlist_.pin_block(pin);
                        std::string io_name = orig_blif_name(netlist_.block_name(blk));

                        vtr::printf_warning(fname_.c_str(), lineno_,
                                            "set_output_delay command matched but was not applied to primary input '%s'\n",
                                            io_name.c_str());
                    }
                }
            }
        }

        void set_clock_groups(const sdcparse::SetClockGroups& cmd) override {
            ++num_commands_;

            if (cmd.type != sdcparse::ClockGroupsType::EXCLUSIVE) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                        "set_clock_groups only supports -exclusive groups");
            }

            //FIXME: more efficient to collect per-group clocks once instead of at each iteration

            //Disable timing between each group of clock domains
            for (size_t src_group = 0; src_group < cmd.clock_groups.size(); ++src_group) {
                auto src_clocks = get_clocks(cmd.clock_groups[src_group]);

                for (size_t sink_group = 0; sink_group < cmd.clock_groups.size(); ++sink_group) {
                    if (src_group == sink_group) continue;

                    auto sink_clocks = get_clocks(cmd.clock_groups[sink_group]);

                    for (auto src_clock : src_clocks) {
                        for (auto sink_clock : sink_clocks) {
                            //Mark this pair of domains to be disabled
                            disabled_domain_pairs_.insert({src_clock, sink_clock});
                        }
                    }
                }
            }
        }

        void set_false_path(const sdcparse::SetFalsePath& cmd) override {
            ++num_commands_;

            auto from_clocks = get_clocks(cmd.from);
            auto to_clocks = get_clocks(cmd.to);

            if (from_clocks.empty() && to_clocks.empty()) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                        "set_false_path must specify at least one -from or -to clock");
            }

            if (from_clocks.empty()) {
                from_clocks = get_all_clocks();
            }

            if (to_clocks.empty()) {
                to_clocks = get_all_clocks();
            }

            for (auto from_clock : from_clocks) {
                for (auto to_clock : to_clocks) {
                    //Mark this domain pair to be disabled
                    disabled_domain_pairs_.insert({from_clock, to_clock});
                }
            }
        }

        void set_min_max_delay(const sdcparse::SetMinMaxDelay& cmd) override {
            ++num_commands_;

            auto from_clocks = get_clocks(cmd.from);
            auto to_clocks = get_clocks(cmd.to);

            if(from_clocks.empty() && to_clocks.empty()) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                        "set_max_path must specify at least one -from or -to clock");
            }

            if (from_clocks.empty()) {
                from_clocks = get_all_clocks();
            }

            if (to_clocks.empty()) {
                to_clocks = get_all_clocks();
            }

            float constraint = cmd.value;

            for (auto from_clock : from_clocks) {
                for (auto to_clock : to_clocks) {
                    //Mark this domain pair to be disabled
                    auto key = std::make_pair(from_clock, to_clock);

                    if(cmd.type == sdcparse::MinMaxType::MAX) {
                        setup_override_constraints_[key] = constraint;
                    } else {
                        VTR_ASSERT(cmd.type == sdcparse::MinMaxType::MIN);
                        hold_override_constraints_[key] = constraint;
                    }
                }
            }
        }

        void set_multicycle_path(const sdcparse::SetMulticyclePath& cmd) override {
            ++num_commands_;

            auto from_clocks = get_clocks(cmd.from);
            auto to_clocks = get_clocks(cmd.to);

            if(from_clocks.empty() && to_clocks.empty()) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                        "set_multicycle_path must specify at least one -from or -to clock");
            }

            if (from_clocks.empty()) {
                from_clocks = get_all_clocks();
            }

            if (to_clocks.empty()) {
                to_clocks = get_all_clocks();
            }

            int setup_mcp = cmd.mcp_value;
            int hold_mcp = cmd.mcp_value;

            bool is_setup = cmd.is_setup;
            bool is_hold = cmd.is_hold || is_setup; //Specifying a setup mcp also modifies hold
            if (!is_hold && !is_setup) {
                //Unspecified implicitly sets the setup mcp to the target value,
                //and the hold mcp to zero
                is_setup = true;
                is_hold = true;

                VTR_ASSERT(setup_mcp == cmd.mcp_value);
                hold_mcp = 0; //Default hold check is 0
            }

            for(auto from_clock : from_clocks) {
                for(auto to_clock : to_clocks) {
                    auto domain_pair = std::make_pair(from_clock, to_clock);

                    if(is_setup) {
                        setup_mcp_overrides_[domain_pair] = setup_mcp;
                    }

                    if (is_hold) {
                        hold_mcp_overrides_[domain_pair] = hold_mcp;
                    }
                }
            }

        }

        void set_clock_uncertainty(const sdcparse::SetClockUncertainty& cmd) override {
            ++num_commands_;

            auto from_clocks = get_clocks(cmd.from);
            auto to_clocks = get_clocks(cmd.to);

            if (from_clocks.empty()) {
                from_clocks = get_all_clocks();
            }

            if (to_clocks.empty()) {
                to_clocks = get_all_clocks();
            }

            float uncertainty = sdc_units_to_seconds(cmd.value);

            bool is_setup = cmd.is_setup;
            bool is_hold = cmd.is_hold;
            if (!is_hold && !is_setup) {
                //Unspecified is implicitly both setup and hold
                is_setup = true;
                is_hold = true;
            }

            for (auto from_clock : from_clocks) {
                for (auto to_clock : to_clocks) {

                    if (is_setup) {
                        tc_.set_setup_clock_uncertainty(from_clock, to_clock, tatum::Time(uncertainty));
                    }

                    if (is_hold) {
                        tc_.set_hold_clock_uncertainty(from_clock, to_clock, tatum::Time(uncertainty));
                    }
                }
            }
        }

        void set_clock_latency(const sdcparse::SetClockLatency& cmd) override {
            ++num_commands_;

            if (cmd.type != sdcparse::ClockLatencyType::SOURCE) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_, "set_clock_latency only supports specifying -source latency");
            }

            auto clocks = get_clocks(cmd.target_clocks);
            if (clocks.empty()) {
                clocks = get_all_clocks();
            }

            bool is_early = cmd.is_early;
            bool is_late = cmd.is_late;
            if (!is_early && !is_late) {
                //Unspecified is implicitly both early and late
                is_early = true;
                is_late = true;
            }

            float latency = sdc_units_to_seconds(cmd.value);

            for (auto clock : clocks) {
                if (is_early) {
                    tc_.set_source_latency(clock, tatum::ArrivalType::EARLY, tatum::Time(latency));
                }
                if (is_late) {
                    tc_.set_source_latency(clock, tatum::ArrivalType::LATE, tatum::Time(latency));
                }
            }
        }

        void set_disable_timing(const sdcparse::SetDisableTiming& cmd) override {
            ++num_commands_;

            //Collect the specified pins
            auto from_pins = get_pins(cmd.from);
            auto to_pins = get_pins(cmd.to);

            if (from_pins.empty()) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                          "Found no matching -from pins");
            }

            if (to_pins.empty()) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                          "Found no matching -to pins");
            }

            //Disable any edges between the from and to sets
            for (auto from_pin : from_pins) {
                for (auto to_pin : from_pins) {
                    tatum::NodeId from_tnode = lookup_.atom_pin_tnode(from_pin);
                    VTR_ASSERT(from_tnode);

                    tatum::NodeId to_tnode = lookup_.atom_pin_tnode(to_pin);
                    VTR_ASSERT(to_tnode);

                    //Find the edge matching these nodes
                    tatum::EdgeId edge = tg_.find_edge(from_tnode, to_tnode);

                    if (!edge) {
                        const auto& from_pin_name = netlist_.pin_name(from_pin);
                        const auto& to_pin_name = netlist_.pin_name(to_pin);

                        vtr::printf_warning(fname_.c_str(), lineno_,
                                            "set_disable_timing no timing edge found from pin '%s' to pin '%s'\n",
                                            from_pin_name.c_str(), to_pin_name.c_str());
                    }

                    //Mark the edge in the timing graph as disabled
                    tg_.disable_edge(edge);
                }
            }
        }

        void set_timing_derate(const sdcparse::SetTimingDerate& /*cmd*/) override {
            ++num_commands_;
            vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_, "set_timing_derate currently unsupported");
        }

        //End of parsing
        void finish_parse() override {
            //Mark constant generator timing nodes
            mark_constant_generators(netlist_, lookup_, tc_);

            //Determine the final clock constraints
            resolve_clock_constraints();

            //Re-levelize if needed (e.g. due to set_disable_timing)
            tg_.levelize();
        }

        //Error during parsing
        void parse_error(const int /*curr_lineno*/, const std::string& near_text, const std::string& msg) override {
            vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_, "%s near '%s'", msg.c_str(), near_text.c_str());
        }

    public:
        size_t num_commands() { return num_commands_; }
    private:
        void resolve_clock_constraints() {
            //Set the clock constraints
            for(tatum::DomainId launch_clock : tc_.clock_domains()) {
                for(tatum::DomainId capture_clock : tc_.clock_domains()) {

                    auto domain_pair = std::make_pair(launch_clock, capture_clock);

                    if(disabled_domain_pairs_.count(domain_pair)) continue;

                    //Setup
                    tatum::Time setup_constraint = calculate_setup_constraint(launch_clock, capture_clock);
                    VTR_ASSERT(setup_constraint.valid());

                    tc_.set_setup_constraint(launch_clock, capture_clock, setup_constraint);

                    //Hold
                    tatum::Time hold_constraint = calculate_hold_constraint(launch_clock, capture_clock);
                    VTR_ASSERT(hold_constraint.valid());

                    tc_.set_hold_constraint(launch_clock, capture_clock, hold_constraint);
                }
            }
        }

        //Returns the setup constraint in seconds
        tatum::Time calculate_setup_constraint(tatum::DomainId launch_domain, tatum::DomainId capture_domain) const {
            //Calculate the period-based constraint, including the effect of multi-cycle paths
            float min_launch_to_capture_time = calculate_min_launch_to_capture_edge_time(launch_domain, capture_domain);

            auto iter = sdc_clocks_.find(capture_domain);
            VTR_ASSERT(iter != sdc_clocks_.end());
            float capture_period = iter->second.period;

            //The period based constraint is the minimum launch to capture edge time + the capture period * (extra_cycles)
            //
            // Since min_launch_to_capture_time is the minimum time to the first capture edge after a launch edge, it already
            // implicitly includes one capture cycle. As a result we subtract 1 from the setup capture cycle value to determine
            // how many extra capture cycles need to be added to the constraint.
            //
            // By default the setup capture cycle 1, specifying a capture 1 cycle after launch
            int extra_cycles = setup_capture_cycle(launch_domain, capture_domain) - 1;
            float period_based_setup_constraint = min_launch_to_capture_time + capture_period * extra_cycles;

            //Warn the user if we added negative cycles
            if (extra_cycles < 0) {
                vtr::printf_warning(__FILE__, __LINE__,
                                    "Added negative (%d) additional capture clock cycles to setup constraint"
                                    " for clock '%s' to clock '%s' transfers; check your set_multicycle_path specifications\n",
                                    extra_cycles, tc_.clock_domain_name(launch_domain).c_str(), tc_.clock_domain_name(capture_domain).c_str());
            }

            //By default the period-based constraint is the constraint
            float setup_constraint = period_based_setup_constraint;

            //See if we have any other override constraints
            auto domain_pair = std::make_pair(launch_domain, capture_domain);
            auto override_iter = setup_override_constraints_.find(domain_pair);
            if (override_iter != setup_override_constraints_.end()) {
                float override_setup_constraint = override_iter->second;

                if (setup_constraint > override_setup_constraint) {
                    vtr::printf_warning(__FILE__, __LINE__,
                                        "Override setup constraint (%g) overrides a tighter default period-based constraint (%g)"
                                        " for transfers from clock '%s' to clock '%s'\n",
                                        override_setup_constraint, setup_constraint,
                                        tc_.clock_domain_name(launch_domain).c_str(),
                                        tc_.clock_domain_name(capture_domain).c_str());
                }

                //Override the constarint
                setup_constraint = override_setup_constraint;
            }

            setup_constraint = sdc_units_to_seconds(setup_constraint);

            if (setup_constraint < 0.) {
                VPR_THROW(VPR_ERROR_SDC, "Setup constraint %g for transfers from clock '%s' to clock '%s' is negative."
                                         " Requires data to arrive before launch edge (No time travelling allowed!)",
                                         setup_constraint,
                                         tc_.clock_domain_name(launch_domain).c_str(),
                                         tc_.clock_domain_name(capture_domain).c_str());
            }

            return tatum::Time(setup_constraint);
        }

        //Returns the hold constraint in seconds
        tatum::Time calculate_hold_constraint(tatum::DomainId launch_domain, tatum::DomainId capture_domain) const {
            float min_launch_to_capture_time = calculate_min_launch_to_capture_edge_time(launch_domain, capture_domain);

            auto iter = sdc_clocks_.find(capture_domain);
            VTR_ASSERT(iter != sdc_clocks_.end());
            float capture_period = iter->second.period;

            //The period based constraint is the minimum launch to capture edge time + the capture period * extra_cycles
            //
            // Since min_launch_to_capture_time is the minimum time to the first capture edge *after* a launch edge, it already
            // implicitly includes one capture cycle. As a result we subtract 1 from the hold capture cycle value to determine
            // how many extra capture cycles need to be added to the constraint.
            //
            // For the default hold check is one cycle before the setup check
            // For the default setup check (1) this means extra_cycles is -1 (i.e. the hold capture check occurs against
            // the capture edge *before* the launch edge)
            int extra_cycles = hold_capture_cycle(launch_domain, capture_domain) - 1;
            float period_based_hold_constraint = min_launch_to_capture_time + capture_period * extra_cycles;

            //By default the period-based constraint is the constraint
            float hold_constraint = period_based_hold_constraint;

            //See if we have any other override constraints
            auto domain_pair = std::make_pair(launch_domain, capture_domain);
            auto override_iter = hold_override_constraints_.find(domain_pair);
            if(override_iter != hold_override_constraints_.end()) {
                float override_hold_constraint = override_iter->second;

                if (hold_constraint < override_hold_constraint) {
                    vtr::printf_warning(__FILE__, __LINE__,
                                        "Override hold constraint (%g) overrides tighter default period-based constraint (%g)"
                                        " for transfers from clock '%s' to clock '%s'\n",
                                        override_hold_constraint, hold_constraint,
                                        tc_.clock_domain_name(launch_domain).c_str(),
                                        tc_.clock_domain_name(capture_domain).c_str());
                }

                //Override the constarint
                hold_constraint = override_hold_constraint;
            }

            hold_constraint = sdc_units_to_seconds(hold_constraint);

            return tatum::Time(hold_constraint);
        }

        //Determine the minumum time (in SDC units) between the edges of the launch and capture clocks
        float calculate_min_launch_to_capture_edge_time(tatum::DomainId launch_domain, tatum::DomainId capture_domain) const {
            constexpr int CLOCK_SCALE = 1000;

            auto launch_iter = sdc_clocks_.find(launch_domain);
            VTR_ASSERT(launch_iter != sdc_clocks_.end());
            const sdcparse::CreateClock& launch_clock = launch_iter->second;

            auto capture_iter = sdc_clocks_.find(capture_domain);
            VTR_ASSERT(capture_iter != sdc_clocks_.end());
            const sdcparse::CreateClock& capture_clock = capture_iter->second;

            VTR_ASSERT_MSG(launch_clock.period >= 0., "Clock period must be positive");
            VTR_ASSERT_MSG(capture_clock.period >= 0., "Clock period must be positive");

            float constraint = std::numeric_limits<float>::quiet_NaN();

            if (std::fabs(launch_clock.period - capture_clock.period) < EPSILON &&
                std::fabs(launch_clock.rise_edge - capture_clock.rise_edge) < EPSILON &&
                std::fabs(launch_clock.fall_edge - capture_clock.fall_edge) < EPSILON) {
                //The source and sink domains have the same period and edges, the constraint is the common clock period.

                constraint = launch_clock.period;

            } else if (launch_clock.period < EPSILON || capture_clock.period < EPSILON) {
                //If either period is 0, the constraint is 0
                constraint = 0.;

            } else {
                /*
                 * Use edge counting to find the minimum launch to capture edge time
                 */

                //Multiply periods and edges by CLOCK_SCALE and round down to the nearest
                //integer, to avoid messy decimals.
                int launch_period = static_cast<int>(launch_clock.period * CLOCK_SCALE);
                int capture_period = static_cast<int>(capture_clock.period * CLOCK_SCALE);
                int launch_rise_edge = static_cast<int>(launch_clock.rise_edge * CLOCK_SCALE);
                int capture_rise_edge = static_cast<int>(capture_clock.rise_edge * CLOCK_SCALE);

                //Find the LCM of the two periods. This determines how long it takes before
                //the pattern of the two clock's edges starts repeating.
                int lcm_period = vtr::lcm(launch_period, capture_period);

                //Create arrays of positive edges for each clock over one LCM clock period.

                //Launch edges
                int launch_rise_time = launch_rise_edge;
                std::vector<int> launch_edges;
                int num_launch_edges = lcm_period/launch_period + 1;
                for(int i = 0; i < num_launch_edges; ++i) {
                    launch_edges.push_back(launch_rise_time);
                    launch_rise_time += launch_period;
                }

                //Capture edges
                int capture_rise_time = capture_rise_edge;
                int num_capture_edges = lcm_period/capture_period + 1;
                std::vector<int> capture_edges;
                for(int i = 0; i < num_capture_edges; ++i) {
                    capture_edges.push_back(capture_rise_time);
                    capture_rise_time += capture_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 yeilds the setup time constraint.
                int scaled_constraint = std::numeric_limits<int>::max(); //Initialize to +inf, so any constraint will be less

                for(int launch_edge : launch_edges) {
                    for(int capture_edge : capture_edges) {
                        if(capture_edge >= launch_edge) { //Postive only
                            int edge_diff = capture_edge - launch_edge;
                            VTR_ASSERT(edge_diff >= 0.);

                            scaled_constraint = std::min(scaled_constraint, edge_diff);
                        }
                    }
                }

                //Rescale the constraint back to a float
                constraint = float(scaled_constraint) / CLOCK_SCALE;
            }

            return constraint;
        }

        //Returns the cycle number (after launch) where the setup check occurs
        int setup_capture_cycle(tatum::DomainId from, tatum::DomainId to) const {
            //Default: capture one cycle after launch
            int setup_path_mult = 1;

            //Any overrides
            auto key = std::make_pair(from, to);
            auto iter = setup_mcp_overrides_.find(key);
            if(iter != setup_mcp_overrides_.end()) {
                setup_path_mult = iter->second;
            }

            //The setup capture cycle is the setup mcp value
            return setup_path_mult;
        }

        //Returns the cycle number (after launch) where the hold check occurs
        int hold_capture_cycle(tatum::DomainId from, tatum::DomainId to) const {
            //Default: hold captures the cycle before setup is captured
            //For the default setup mcp this implies capturing the same
            //cycle as launch
            int hold_offset = 1;

            //Any overrides?
            auto key = std::make_pair(from, to);
            auto iter = hold_mcp_overrides_.find(key);
            if(iter != hold_mcp_overrides_.end()) {
                //Note that we add the override to the default hold_mcp of 1 to match
                //the standard SDC behaviour (e.g. N - 1) of hold multicycles.
                //
                //For details see section 8.3 'Multicycle paths' in:
                //  J. Bhasker, R. Chadha, "Static Timing Analysis for Nanometer
                //      Designs A Practical Approach", Springer, 2009
                hold_offset += iter->second;
            }

            //The hold capture cycle is the setup capture cycle minus the hold mcp value
            return setup_capture_cycle(from, to) - hold_offset;
        }

        std::set<AtomPinId> get_ports(const sdcparse::StringGroup& port_group) {
            if(port_group.type != sdcparse::StringGroupType::PORT) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                         "Expected port collection via get_ports");
            }

            std::set<AtomPinId> pins;
            for (const auto& port_pattern : port_group.strings) {
                std::regex port_regex = glob_pattern_to_regex(port_pattern);

                bool found = false;
                for(const auto& kv : netlist_primary_ios_) {

                    const std::string& io_name = kv.first;
                    if(std::regex_match(io_name, port_regex)) {
                        found = true;

                        AtomPinId pin = kv.second;

                        pins.insert(pin);
                    }
                }

                if(!found) {
                    vtr::printf_warning(fname_.c_str(), lineno_,
                                        "get_ports target name or pattern '%s' matched no ports\n",
                                        port_pattern.c_str());
                }
            }
            return pins;
        }

        std::set<tatum::DomainId> get_clocks(const sdcparse::StringGroup& clock_group) {
            std::set<tatum::DomainId> domains;

            if(clock_group.strings.empty()) {
                return domains;
            }

            if(clock_group.type != sdcparse::StringGroupType::CLOCK) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                         "Expected clock collection via get_clocks");
            }

            for (const auto& clock_glob_pattern : clock_group.strings) {
                std::regex clock_regex = glob_pattern_to_regex(clock_glob_pattern);

                bool found = false;
                for(tatum::DomainId domain : tc_.clock_domains()) {

                    const std::string& clock_name = tc_.clock_domain_name(domain);
                    if(std::regex_match(clock_name, clock_regex)) {
                        found = true;

                        domains.insert(domain);
                    }
                }

                if(!found) {
                    vtr::printf_warning(fname_.c_str(), lineno_,
                                        "get_clocks target name or pattern '%s' matched no clocks\n",
                                        clock_glob_pattern.c_str());
                }
            }

            return domains;
        }

        std::set<AtomPinId> get_pins(const sdcparse::StringGroup& pin_group) {
            std::set<AtomPinId> pins;

            if(pin_group.strings.empty()) {
                return pins;
            }

            if(pin_group.type != sdcparse::StringGroupType::PIN) {
                vpr_throw(VPR_ERROR_SDC, fname_.c_str(), lineno_,
                         "Expected pin collection via get_pins");
            }

            for (const auto& pin_pattern : pin_group.strings) {
                std::regex pin_regex = glob_pattern_to_regex(pin_pattern);

                bool found = false;
                for(AtomPinId pin : netlist_.pins()) {

                    const std::string& pin_name = netlist_.pin_name(pin);

                    if(std::regex_match(pin_name, pin_regex)) {
                        found = true;

                        pins.insert(pin);
                    }
                }

                if(!found) {
                    vtr::printf_warning(fname_.c_str(), lineno_,
                                        "get_pins target name or pattern '%s' matched no pins\n",
                                        pin_pattern.c_str());
                }
            }

            return pins;
        }

        std::set<tatum::DomainId> get_all_clocks() {
            auto domains = tc_.clock_domains();
            return std::set<tatum::DomainId>(domains.begin(), domains.end());
        }

        float sdc_units_to_seconds(float val) const {
            return val * unit_scale_;
        }

        float seconds_to_sdc_units(float val) const {
            return val / unit_scale_;
        }

    private:
        const AtomNetlist& netlist_;
        const AtomLookup& lookup_;
        tatum::TimingConstraints& tc_;
        tatum::TimingGraph& tg_;

        size_t num_commands_ = 0;
        std::string fname_;
        int lineno_ = -1;

        float unit_scale_ = 1e-9;

        std::map<tatum::DomainId,sdcparse::CreateClock> sdc_clocks_;
        std::set<AtomPinId> netlist_clock_drivers_;
        std::map<std::string,AtomPinId> netlist_primary_ios_;

        std::set<std::pair<tatum::DomainId,tatum::DomainId>> disabled_domain_pairs_;
        std::map<std::pair<tatum::DomainId,tatum::DomainId>, float> setup_override_constraints_;
        std::map<std::pair<tatum::DomainId,tatum::DomainId>, float> hold_override_constraints_;

        std::map<std::pair<tatum::DomainId,tatum::DomainId>,int> setup_mcp_overrides_;
        std::map<std::pair<tatum::DomainId,tatum::DomainId>,int> hold_mcp_overrides_;
};

std::unique_ptr<tatum::TimingConstraints> read_sdc2(const t_timing_inf& timing_inf,
                                                   const AtomNetlist& netlist,
                                                   const AtomLookup& lookup,
                                                   tatum::TimingGraph& timing_graph) {
    auto timing_constraints = std::make_unique<tatum::TimingConstraints>();

    if (!timing_inf.timing_analysis_enabled) {
		vtr::printf("\n");
		vtr::printf("Timing analysis off\n");
        apply_default_timing_constraints(netlist, lookup, *timing_constraints);
    } else {
        FILE* sdc_file = fopen(timing_inf.SDCFile.c_str(), "r");
        if (sdc_file == nullptr) {
            //No SDC file
            vtr::printf("\n");
            vtr::printf("SDC file '%s' not found\n", timing_inf.SDCFile.c_str());
            apply_default_timing_constraints(netlist, lookup, *timing_constraints);
        } else {

            VTR_ASSERT(sdc_file != nullptr);

            //Parse the file
            SdcParseCallback2 callback(netlist, lookup, *timing_constraints, timing_graph);
            sdc_parse_file(sdc_file, callback, timing_inf.SDCFile.c_str());
            fclose(sdc_file);

            if (callback.num_commands() == 0) {
                vtr::printf("\n");
                vtr::printf("SDC file '%s' contained no SDC commands\n", timing_inf.SDCFile.c_str());
                apply_default_timing_constraints(netlist, lookup, *timing_constraints);
            } else {
                vtr::printf("\n");
                vtr::printf("Applied %zu SDC commands from '%s'\n", callback.num_commands(), timing_inf.SDCFile.c_str());
            }
        }
    }
    vtr::printf("Timing constraints created %zu clocks\n", timing_constraints->clock_domains().size());
    print_netlist_clock_info(netlist);

    vtr::printf("\n");

    return timing_constraints;
}

//Apply the default timing constraints (i.e. if there are no user specified constraints)
//appropriate to the type of circuit.
void apply_default_timing_constraints(const AtomNetlist& netlist,
                                      const AtomLookup& lookup,
                                      tatum::TimingConstraints& tc) {
    std::set<AtomPinId> netlist_clock_drivers = find_netlist_logical_clock_drivers(netlist);

    if(netlist_clock_drivers.size() == 0) {
        apply_combinational_default_timing_constraints(netlist, lookup, tc);

    } else if (netlist_clock_drivers.size() == 1) {
        apply_single_clock_default_timing_constraints(netlist, lookup, *netlist_clock_drivers.begin(), tc);

    } else {
        VTR_ASSERT(netlist_clock_drivers.size() > 1);

        apply_multi_clock_default_timing_constraints(netlist, lookup, netlist_clock_drivers, tc);
    }

}

//Apply the default timing constraints for purely combinational circuits which have
//no explicit netlist clock
void apply_combinational_default_timing_constraints(const AtomNetlist& netlist,
                                                    const AtomLookup& lookup,
                                                    tatum::TimingConstraints& tc) {
    std::string clock_name = "virtual_io_clock";

    vtr::printf("Setting default timing constraints:\n");
    vtr::printf("   * constrain all primay inputs and primary outputs on a virtual external clock '%s'\n", clock_name.c_str());
    vtr::printf("   * optimize virtual clock to run as fast as possible\n");

    //Create a virtual clock, with 0 period
    tatum::DomainId domain = tc.create_clock_domain(clock_name);
    tc.set_setup_constraint(domain, domain, tatum::Time(0.));
    tc.set_hold_constraint(domain, domain, tatum::Time(0.));

    //Constrain all I/Os with zero input/output delay
    constrain_all_ios(netlist, lookup, tc, domain, domain, tatum::Time(0.), tatum::Time(0.));

    //Mark constant generator timing nodes
    mark_constant_generators(netlist, lookup, tc);
}

//Apply the default timing constraints for circuits with a single netlist clock
void apply_single_clock_default_timing_constraints(const AtomNetlist& netlist,
                                                   const AtomLookup& lookup,
                                                   const AtomPinId clock_driver,
                                                   tatum::TimingConstraints& tc) {
    AtomNetId clock_net = netlist.pin_net(clock_driver);
    std::string clock_name = netlist.net_name(clock_net);

    vtr::printf("Setting default timing constraints:\n");
    vtr::printf("   * constrain all primay inputs and primary outputs on netlist clock '%s'\n", clock_name.c_str());
    vtr::printf("   * optimize netlist clock to run as fast as possible\n");

    //Create the netlist clock with period 0
    tatum::DomainId domain = tc.create_clock_domain(clock_name);
    tc.set_setup_constraint(domain, domain, tatum::Time(0.));
    tc.set_hold_constraint(domain, domain, tatum::Time(0.));

    //Mark the clock domain source
    AtomPinId clock_driver_pin = netlist.net_driver(clock_net);
    tatum::NodeId clock_source = lookup.atom_pin_tnode(clock_driver_pin);
    VTR_ASSERT(clock_source);
    tc.set_clock_domain_source(clock_source, domain);

    //Constrain all I/Os with zero input/output delay
    constrain_all_ios(netlist, lookup, tc, domain, domain, tatum::Time(0.), tatum::Time(0.));

    //Mark constant generator timing nodes
    mark_constant_generators(netlist, lookup, tc);
}

//Apply the default timing constraints for circuits with multiple netlist clocks
void apply_multi_clock_default_timing_constraints(const AtomNetlist& netlist,
                                                  const AtomLookup& lookup,
                                                  const std::set<AtomPinId>& clock_drivers,
                                                  tatum::TimingConstraints& tc) {
    std::string virtual_clock_name = "virtual_io_clock";
    vtr::printf("Setting default timing constraints:\n");
    vtr::printf("   * constrain all primay inputs and primary outputs on a virtual external clock '%s'\n", virtual_clock_name.c_str());
    vtr::printf("   * optimize all netlist and virtual clocks to run as fast as possible\n");
    vtr::printf("   * ignore cross netlist clock domain timing paths\n");

    //Create a virtual clock, with 0 period
    tatum::DomainId virtual_clock = tc.create_clock_domain(virtual_clock_name);
    tc.set_setup_constraint(virtual_clock, virtual_clock, tatum::Time(0.));
    tc.set_hold_constraint(virtual_clock, virtual_clock, tatum::Time(0.));

    //Constrain all I/Os with zero input/output delay t the virtual clock
    constrain_all_ios(netlist, lookup, tc, virtual_clock, virtual_clock, tatum::Time(0.), tatum::Time(0.));

    //Create each of the netlist clocks, and constrain it to period 0. Do not analyze cross-domain paths
    for(AtomPinId clock_driver : clock_drivers) {
        AtomNetId clock_net = netlist.pin_net(clock_driver);

        //Create the clock
        std::string clock_name = netlist.net_name(clock_net);
        tatum::DomainId clock = tc.create_clock_domain(clock_name);

        //Mark the clock domain source
        tatum::NodeId clock_source = lookup.atom_pin_tnode(clock_driver);
        VTR_ASSERT(clock_source);
        tc.set_clock_domain_source(clock_source, clock);

        //Do not analyze cross-domain timing paths (except to/from virtual clock)
        tc.set_setup_constraint(clock, clock, tatum::Time(0.)); //Intra-domain
        tc.set_setup_constraint(clock, virtual_clock, tatum::Time(0.)); //netlist to virtual
        tc.set_setup_constraint(virtual_clock, clock, tatum::Time(0.)); //virtual to netlist

        tc.set_hold_constraint(clock, clock, tatum::Time(0.)); //Intra-domain
        tc.set_hold_constraint(clock, virtual_clock, tatum::Time(0.)); //netlist to virtual
        tc.set_hold_constraint(virtual_clock, clock, tatum::Time(0.)); //virtual to netlist
    }

    //Mark constant generator timing nodes
    mark_constant_generators(netlist, lookup, tc);
}

//Look through the netlist to find any constant generators, and mark them as
//constant generators in the timing constraints
void mark_constant_generators(const AtomNetlist& netlist,
                              const AtomLookup& lookup,
                              tatum::TimingConstraints& tc) {

    for(AtomPinId pin : netlist.pins()) {
        if(netlist.pin_is_constant(pin)) {
            tatum::NodeId tnode = lookup.atom_pin_tnode(pin);
            VTR_ASSERT(tnode);

            tc.set_constant_generator(tnode);
        }
    }
}


//Constrain all primary inputs and primary outputs to the specifed clock domains and delays
void constrain_all_ios(const AtomNetlist& netlist,
                       const AtomLookup& lookup,
                       tatum::TimingConstraints& tc,
                       tatum::DomainId input_domain,
                       tatum::DomainId output_domain,
                       tatum::Time input_delay,
                       tatum::Time output_delay) {

    for (AtomBlockId blk : netlist.blocks()) {
        AtomBlockType type = netlist.block_type(blk);

        if (type == AtomBlockType::INPAD || type == AtomBlockType::OUTPAD) {
            //Get the pin
            if (netlist.block_pins(blk).size() == 1) {
                AtomPinId pin = *netlist.block_pins(blk).begin();

                //Find the associated tnode
                tatum::NodeId tnode = lookup.atom_pin_tnode(pin);

                //Constrain it
                if (type == AtomBlockType::INPAD) {
                    tc.set_input_constraint(tnode, input_domain, tatum::DelayType::MAX, input_delay);
                    tc.set_input_constraint(tnode, input_domain, tatum::DelayType::MIN, input_delay);
                } else {
                    VTR_ASSERT(type == AtomBlockType::OUTPAD);
                    tc.set_output_constraint(tnode, output_domain, tatum::DelayType::MAX, output_delay);
                    tc.set_output_constraint(tnode, output_domain, tatum::DelayType::MIN, output_delay);
                }
            } else {
                VTR_ASSERT_MSG(netlist.block_pins(blk).size() == 0, "Unconnected I/O");
            }
        }
    }
}

std::map<std::string,AtomPinId> find_netlist_primary_ios(const AtomNetlist& netlist) {
    std::map<std::string,AtomPinId> primary_inputs;

    for(AtomBlockId blk : netlist.blocks()) {
        auto type = netlist.block_type(blk);
        if(type == AtomBlockType::INPAD || type == AtomBlockType::OUTPAD) {
            VTR_ASSERT(netlist.block_pins(blk).size() == 1);
            AtomPinId pin = *netlist.block_pins(blk).begin();

            std::string orig_name = orig_blif_name(netlist.block_name(blk));

            VTR_ASSERT(!primary_inputs.count(orig_name));

            primary_inputs[orig_name] = pin;
        }
    }

    return primary_inputs;
}

//Trim off the prefix added to blif names to make outputs unique
std::string orig_blif_name(std::string name) {
    constexpr const char* BLIF_UNIQ_PREFIX = "out:";

    if(name.find(BLIF_UNIQ_PREFIX) == 0) { //Starts with prefix
        name = vtr::replace_first(name, BLIF_UNIQ_PREFIX, ""); //Remove prefix
    }

    return name;
}

//Print informatino about clocks
void print_netlist_clock_info(const AtomNetlist& netlist) {

    std::set<AtomPinId> netlist_clock_drivers = find_netlist_logical_clock_drivers(netlist);
    vtr::printf("Netlist contains %zu clocks\n", netlist_clock_drivers.size());

    //Print out pin/block fanout info for each block
    for (auto clock_driver : netlist_clock_drivers) {
        AtomNetId net_id = netlist.pin_net(clock_driver);
        auto sinks = netlist.net_sinks(net_id);
        size_t fanout = sinks.size();
        std::set<AtomBlockId> clk_blks;
        for (auto pin_id : sinks) {
            auto blk_id = netlist.pin_block(pin_id);
            clk_blks.insert(blk_id);
        }
        vtr::printf("  Netlist Clock '%s' Fanout: %zu pins (%.1f%), %zu blocks (%.1f%)\n", netlist.net_name(net_id).c_str(), fanout, 100. * float(fanout) / netlist.pins().size(), clk_blks.size(), 100 * float(clk_blks.size()) / netlist.blocks().size());
    }

}

//Converts a glob pattern to a std::regex
std::regex glob_pattern_to_regex(const std::string& glob_pattern) {
    //In glob (i.e. unix-shell style):
    //   '*' is a wildcard match of zero or more instances of any characters
    //
    //In regex:
    //   '*' matches zero or more of the preceeding character
    //   '.' matches any character
    //
    //To convert a glob to a regex we need to:
    //   Convert '.' to "\.", so literal '.' in glob is treated as literal in the regex
    //   Convert '*' to ".*" so literal '*' in glob matches any sequence

    std::string regex_str = vtr::replace_all(glob_pattern, ".", "\\.");
    regex_str = vtr::replace_all(regex_str, "*", ".*");

    return std::regex(regex_str, std::regex::grep);
}

