#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 AtomNetId clock_net,
                                                   tatum::TimingConstraints& timing_constraints);

void apply_multi_clock_default_timing_constraints(const AtomNetlist& netlist,
                                                  const AtomLookup& lookup,
                                                  const std::set<AtomNetId>& clock_nets,
                                                  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_nets_ = find_netlist_clocks(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(AtomNetId clock_net : netlist_clock_nets_) {
                        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_nets_.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)

                    std::string clock_name = netlist_.net_name(*netlist_clock_nets_.begin());
                    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<AtomNetId> netlist_clock_nets_;
        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<AtomNetId> netlist_clocks = find_netlist_clocks(netlist); 

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

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

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

        apply_multi_clock_default_timing_constraints(netlist, lookup, netlist_clocks, 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 AtomNetId clock_net,
                                                   tatum::TimingConstraints& tc) {
    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<AtomNetId>& clock_nets,
                                                  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(AtomNetId clock_net : clock_nets) {

        //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
        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, 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<AtomNetId> netlist_clocks = find_netlist_clocks(netlist); 
    vtr::printf("Netlist contains %zu clocks\n", netlist_clocks.size());

    //Print out pin/block fanout info for each block
    for (auto net_id : netlist_clocks) {
        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);
}

