/**
 General API for VPR
 Other software tools should generally call just the functions defined here
 For advanced/power users, you can call functions defined elsewhere in VPR or modify the data structures directly at your discretion but be aware that doing so can break the correctness of VPR

 Author: Jason Luu
 June 21, 2012
 */

#include <cstdio>
#include <cstring>
#include <ctime>
#include <chrono>
#include <cmath>
#include <sstream>
using namespace std;


#include "vtr_assert.h"
#include "vtr_list.h"
#include "vtr_matrix.h"
#include "vtr_math.h"
#include "vtr_log.h"
#include "vtr_version.h"
#include "vtr_time.h"
#include "vtr_path.h"
#include "vtr_cilk.h"

#include "vpr_types.h"
#include "vpr_utils.h"
#include "globals.h"
#include "atom_netlist.h"
#include "graphics.h"
#include "read_netlist.h"
#include "check_netlist.h"
#include "read_blif.h"
#include "draw.h"
#include "place_and_route.h"
#include "pack.h"
#include "place.h"
#include "SetupGrid.h"
#include "stats.h"
#include "path_delay.h"
#include "read_options.h"
#include "echo_files.h"
#include "read_xml_arch_file.h"
#include "SetupVPR.h"
#include "ShowSetup.h"
#include "CheckArch.h"
#include "CheckSetup.h"
#include "rr_graph.h"
#include "pb_type_graph.h"
#include "route_common.h"
#include "timing_place_lookup.h"
#include "route_export.h"
#include "vpr_api.h"
#include "read_sdc.h"
#include "read_sdc2.h"
#include "power.h"
#include "pack_types.h"
#include "lb_type_rr_graph.h"
#include "output_blif.h"
#include "read_activity.h"
#include "net_delay.h"
#include "AnalysisDelayCalculator.h"
#include "timing_info.h"
#include "netlist_writer.h"
#include "net_delay.h"
#include "RoutingDelayCalculator.h"
#include "check_route.h"
#include "constant_nets.h"
#include "atom_netlist_utils.h"

#include "pack_report.h"

#include "timing_graph_builder.h"
#include "timing_reports.h"
#include "tatum/echo_writer.hpp"

#include "read_route.h"
#include "read_blif.h"
#include "read_place.h"

#include "arch_util.h"

#include "log.h"

#if defined(TBB_INTERFACE_VERSION)
# include <tbb/task_scheduler_init.h>

//We need to store the scheduler object so any concurrency
//setting is persistent
std::unique_ptr<tbb::task_scheduler_init> tbb_scheduler;
#endif

/* Local subroutines */
static void free_complex_block_types();

static void free_device(const t_det_routing_arch& routing_arch);
static void free_circuit();

static void get_intercluster_switch_fanin_estimates(const t_vpr_setup& vpr_setup, const t_arch& arch, const int wire_segment_length,
        int *opin_switch_fanin, int *wire_switch_fanin, int *ipin_switch_fanin);
/* Local subroutines end */

/* Display general VPR information */
void vpr_print_title() {

    VTR_LOG("\n");
    VTR_LOG("VPR FPGA Placement and Routing.\n");
    VTR_LOG("Version: %s\n", vtr::VERSION);
    VTR_LOG("Revision: %s\n", vtr::VCS_REVISION);
    VTR_LOG("Compiled: %s\n", vtr::BUILD_TIMESTAMP);
    VTR_LOG("Compiler: %s\n", vtr::COMPILER);
    VTR_LOG("University of Toronto\n");
    VTR_LOG("vtr-users@googlegroups.com\n");
    VTR_LOG("This is free open source code under MIT license.\n");
    VTR_LOG("\n");

}

void vpr_print_args(int argc, const char** argv) {
    VTR_LOG("VPR was run with the following command-line:\n");
    for (int i = 0; i < argc; i++) {
        if (i != 0) {
            VTR_LOG(" ");
        }
        VTR_LOG("%s", argv[i]);
    }
    VTR_LOG("\n\n");
}

/* Initialize VPR
 1. Read Options
 2. Read Arch
 3. Read Circuit
 4. Sanity check all three
 */
void vpr_init(const int argc, const char **argv,
        t_options *options,
        t_vpr_setup *vpr_setup,
        t_arch *arch) {

    vtr::set_log_file("vpr_stdout.log");

    /* Print title message */
    vpr_print_title();

    /* Read in user options */
    *options = read_options(argc, argv);

    //Print out the arguments passed to VPR.
    //This provides a reference in the log file to exactly
    //how VPR was run, aiding in re-producibility
    vpr_print_args(argc, argv);

    //Set the number of parallel workers
    // We determine the number of workers in the following order:
    //  1. An explicitly specified command-line argument
    //  2. An environment variable
    //  3. The default value
    size_t num_workers;
    if (options->num_workers.provenance() == argparse::Provenance::SPECIFIED) {
        //Explicit command-line
        num_workers = options->num_workers.value();
    } else {
        const char* env_value = std::getenv("VPR_NUM_WORKERS");
        if (env_value != nullptr) {
            //VPR specific environment variable
            num_workers = vtr::atou(env_value);
        } else {
            //Command-line default value
            VTR_ASSERT(options->num_workers.provenance() == argparse::Provenance::DEFAULT);
            num_workers = options->num_workers.value();
        }
    }

#if defined(TBB_INTERFACE_VERSION)
    //Using Thread Building Blocks
    if (num_workers == 0) {
        //Use default concurrency (i.e. maximum conccurency)
        num_workers = tbb::task_scheduler_init::default_num_threads();
    }

    VTR_LOG("Using up to %zu parallel worker(s)\n", num_workers);
    tbb_scheduler = std::make_unique<tbb::task_scheduler_init>(num_workers);

#elif defined(__cilk)
    //Using cilk, set the number of workers for the run-time

    if (num_workers == 0) {
        //Use default concurrency (i.e. maximum conccurency)
        num_workers = __cilkrts_get_nworkers();
    }

    std::string num_workers_str = std::to_string(num_workers);
    VTR_LOG("Using up to %zu parallel worker(s)\n", num_workers);
    if (__cilkrts_set_param("nworkers", num_workers_str.c_str()) != 0) {
        VPR_THROW(VPR_ERROR_OTHER, "Failed to set the number of workers for cilkrts");
    }
#else
    //No parallel execution support
    if (num_workers != 1) {
        VTR_LOG_WARN(
            "VPR was compiled without parallel execution support, ignoring the specified number of workers (%zu)",
            options->num_workers.value());
    }
#endif

    vpr_setup->TimingEnabled = options->timing_analysis;
    vpr_setup->device_layout = options->device_layout;
    vpr_setup->constant_net_method = options->constant_net_method;
    vpr_setup->clock_modeling = options->clock_modeling;
    vpr_setup->exit_before_pack = options->exit_before_pack;

    VTR_LOG("\n");
    VTR_LOG("Architecture file: %s\n", options->ArchFile.value().c_str());
    VTR_LOG("Circuit name: %s\n", options->CircuitName.value().c_str());
    VTR_LOG("\n");

    /* Determine whether echo is on or off */
    setEchoEnabled(options->CreateEchoFile);

    /* Read in arch and circuit */
    SetupVPR(options,
            vpr_setup->TimingEnabled,
            true,
            &vpr_setup->FileNameOpts,
            arch,
            &vpr_setup->user_models,
            &vpr_setup->library_models,
            &vpr_setup->NetlistOpts,
            &vpr_setup->PackerOpts,
            &vpr_setup->PlacerOpts,
            &vpr_setup->AnnealSched,
            &vpr_setup->RouterOpts,
            &vpr_setup->AnalysisOpts,
            &vpr_setup->RoutingArch,
            &vpr_setup->PackerRRGraph,
            &vpr_setup->Segments,
            &vpr_setup->Timing,
            &vpr_setup->ShowGraphics,
            &vpr_setup->GraphPause,
            &vpr_setup->PowerOpts);

    /* Check inputs are reasonable */
    CheckArch(*arch);

    /* Verify settings don't conflict or otherwise not make sense */
    CheckSetup(
            vpr_setup->PackerOpts,
            vpr_setup->PlacerOpts,
            vpr_setup->RouterOpts,
            vpr_setup->RoutingArch, vpr_setup->Segments, vpr_setup->Timing,
            arch->Chans);

    /* flush any messages to user still in stdout that hasn't gotten displayed */
    fflush(stdout);

    /* Read blif file and sweep unused components */
    auto& atom_ctx = g_vpr_ctx.mutable_atom();
    atom_ctx.nlist = read_and_process_circuit(
            options->circuit_format,
            vpr_setup->PackerOpts.blif_file_name.c_str(),
            vpr_setup->user_models,
            vpr_setup->library_models,
            vpr_setup->NetlistOpts.const_gen_inference,
            vpr_setup->NetlistOpts.absorb_buffer_luts,
            vpr_setup->NetlistOpts.sweep_dangling_primary_ios,
            vpr_setup->NetlistOpts.sweep_dangling_nets,
            vpr_setup->NetlistOpts.sweep_dangling_blocks,
            vpr_setup->NetlistOpts.sweep_constant_primary_outputs,
            vpr_setup->NetlistOpts.netlist_verbosity);


    if (vpr_setup->PowerOpts.do_power) {
        //Load the net activity file for power estimation
        vtr::ScopedStartFinishTimer t("Load Activity File");
        auto& power_ctx = g_vpr_ctx.mutable_power();
        power_ctx.atom_net_power = read_activity(atom_ctx.nlist, vpr_setup->FileNameOpts.ActFile.c_str());
    }

    //Initialize timing graph and constraints
    if (vpr_setup->TimingEnabled) {
        auto& timing_ctx = g_vpr_ctx.mutable_timing();
        {
            vtr::ScopedStartFinishTimer t("Build Timing Graph");
            timing_ctx.graph = TimingGraphBuilder(atom_ctx.nlist, atom_ctx.lookup).timing_graph();
            VTR_LOG("  Timing Graph Nodes: %zu\n", timing_ctx.graph->nodes().size());
            VTR_LOG("  Timing Graph Edges: %zu\n", timing_ctx.graph->edges().size());
        }
        {
            print_netlist_clock_info(atom_ctx.nlist);
        }
        {
            vtr::ScopedStartFinishTimer t("Load Timing Constraints");
            timing_ctx.constraints = read_sdc2(vpr_setup->Timing, atom_ctx.nlist, atom_ctx.lookup, *timing_ctx.graph);
        }
    }

    fflush(stdout);

    ShowSetup(*vpr_setup);
}


bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {

    if (vpr_setup.exit_before_pack) {
        VTR_LOG_WARN( "Exiting before packing as requested.\n");
        return true;
    }

    { //Pack
        bool pack_success = vpr_pack_flow(vpr_setup, arch);

        if (!pack_success) {
            return false; //Unimplementable
        }
    }

    vpr_create_device_grid(vpr_setup, arch);

    vpr_init_graphics(vpr_setup, arch);

    { //Place
        bool place_success = vpr_place_flow(vpr_setup, arch);

        if (!place_success) {
            return false; //Unimplementable
        }
    }

    RouteStatus route_status;
    { //Route
        route_status = vpr_route_flow(vpr_setup, arch);
    }

    { //Analysis
        vpr_analysis_flow(vpr_setup, arch, route_status.success());
    }

    vpr_close_graphics(vpr_setup);

    return route_status.success();
}

/*
 * Allocs globals: chan_width_x, chan_width_y, device_ctx.grid
 * Depends on num_clbs, pins_per_clb */
void vpr_create_device_grid(const t_vpr_setup& vpr_setup, const t_arch& Arch) {
	/* Read in netlist file for placement and routing */
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& device_ctx = g_vpr_ctx.mutable_device();

    /*
     * Keep a copy of the architecture
     */
    device_ctx.arch = Arch;

    /*
     *Load the device grid
     */

    //Record the resource requirement
    std::map<t_type_ptr,size_t> num_type_instances;
    for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
        num_type_instances[cluster_ctx.clb_nlist.block_type(blk_id)]++;
    }

    //Build the device
    float target_device_utilization = vpr_setup.PackerOpts.target_device_utilization;
    device_ctx.grid = create_device_grid(vpr_setup.device_layout, Arch.grid_layouts, num_type_instances, target_device_utilization);

    /*
     *Report on the device
     */
    size_t num_grid_tiles = count_grid_tiles(device_ctx.grid);
    VTR_LOG("FPGA sized to %zu x %zu: %zu grid tiles (%s)\n", device_ctx.grid.width(), device_ctx.grid.height(), num_grid_tiles, device_ctx.grid.name().c_str());

    VTR_LOG("\n");
    VTR_LOG("Resource usage...\n");
    for (int i = 0; i < device_ctx.num_block_types; ++i) {
        auto type = &device_ctx.block_types[i];
        VTR_LOG("\tNetlist      %d\tblocks of type: %s\n",
                num_type_instances[type], type->name);
        VTR_LOG("\tArchitecture %d\tblocks of type: %s\n",
                device_ctx.grid.num_instances(type), type->name);
    }
    VTR_LOG("\n");

    float device_utilization = calculate_device_utilization(device_ctx.grid, num_type_instances);
    VTR_LOG("Device Utilization: %.2f (target %.2f)\n", device_utilization, target_device_utilization);
    for (int i = 0; i < device_ctx.num_block_types; ++i) {
        auto type = &device_ctx.block_types[i];
        float util = 0.;
        if (num_type_instances[type] != 0) {
            util = float(num_type_instances[type]) / device_ctx.grid.num_instances(type);
        }
        VTR_LOG("\tBlock Utilization: %.2f Type: %s\n", util, type->name);
    }
    VTR_LOG("\n");

    if (!device_ctx.grid.limiting_resources().empty()) {
        std::vector<std::string> limiting_block_names;
        for (auto blk_type : device_ctx.grid.limiting_resources()) {
            limiting_block_names.push_back(blk_type->name);
        }
        VTR_LOG("FPGA size limited by block type(s): %s\n", vtr::join(limiting_block_names, " ").c_str());
        VTR_LOG("\n");
    }

    /*
     * Channel setup
     */
    device_ctx.chan_width.x_max = device_ctx.chan_width.y_max = 0;
    device_ctx.chan_width.x_min = device_ctx.chan_width.y_min = 0;
    device_ctx.chan_width.x_list = (int *) vtr::malloc(device_ctx.grid.height() * sizeof (int));
    device_ctx.chan_width.y_list = (int *) vtr::malloc(device_ctx.grid.width() * sizeof (int));
}

bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
    auto& packer_opts = vpr_setup.PackerOpts;

    bool status = true;

    if (packer_opts.doPacking == STAGE_SKIP) {
        //pass
    } else {
        if (packer_opts.doPacking == STAGE_DO) {
            //Do the actual packing
            status = vpr_pack(vpr_setup, arch);

            //TODO: to be consistent with placement/routing vpr_pack should really
            //      load the netlist data structures itself, instead of re-loading
            //      the netlist from the .net file

            //Load the result from the .net file
            vpr_load_packing(vpr_setup, arch);
        } else {
            VTR_ASSERT(packer_opts.doPacking == STAGE_LOAD);
            //Load a previous packing from the .net file
            vpr_load_packing(vpr_setup, arch);
        }

        /* Sanity check the resulting netlist */
        check_netlist();

        /* Output the netlist stats to console. */
        printClusteredNetlistStats();

        if(vpr_setup.gen_netlist_as_blif) {
            char *name = (char*)vtr::malloc((strlen(vpr_setup.FileNameOpts.CircuitName.c_str()) + 16) * sizeof(char));
            sprintf(name, "%s.preplace.blif", vpr_setup.FileNameOpts.CircuitName.c_str());
            output_blif(&arch, name);
            free(name);
        }
    }

    return status;
}

bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) {
    vtr::ScopedStartFinishTimer timer("Packing");

    /* If needed, estimate inter-cluster delay. Assume the average routing hop goes out of
     a block through an opin switch to a length-4 wire, then through a wire switch to another
     length-4 wire, then through a wire-to-ipin-switch into another block. */
    int wire_segment_length = 4;

    float inter_cluster_delay = UNDEFINED;
    if (vpr_setup.PackerOpts.timing_driven
            && vpr_setup.PackerOpts.auto_compute_inter_cluster_net_delay) {

        /* We want to determine a reasonable fan-in to the opin, wire, and ipin switches, based
           on which the intercluster delays can be estimated. The fan-in of a switch influences its
           delay.

           The fan-in of the switch depends on the architecture (unidirectional/bidirectional), as
           well as Fc_in/out and Fs */
        int opin_switch_fanin, wire_switch_fanin, ipin_switch_fanin;
        get_intercluster_switch_fanin_estimates(vpr_setup, arch, wire_segment_length, &opin_switch_fanin,
                &wire_switch_fanin, &ipin_switch_fanin);


        float Tdel_opin_switch, R_opin_switch, Cout_opin_switch;
        float opin_switch_del = get_arch_switch_info(arch.Segments[0].arch_opin_switch, opin_switch_fanin,
                Tdel_opin_switch, R_opin_switch, Cout_opin_switch);

        float Tdel_wire_switch, R_wire_switch, Cout_wire_switch;
        float wire_switch_del = get_arch_switch_info(arch.Segments[0].arch_wire_switch, wire_switch_fanin,
                Tdel_wire_switch, R_wire_switch, Cout_wire_switch);

        float Tdel_wtoi_switch, R_wtoi_switch, Cout_wtoi_switch;
        float wtoi_switch_del = get_arch_switch_info(
                vpr_setup.RoutingArch.wire_to_arch_ipin_switch, ipin_switch_fanin,
                Tdel_wtoi_switch, R_wtoi_switch, Cout_wtoi_switch);

        float Rmetal = arch.Segments[0].Rmetal;
        float Cmetal = arch.Segments[0].Cmetal;

        /* The delay of a wire with its driving switch is the switch delay plus the
         product of the equivalent resistance and capacitance experienced by the wire. */

        float first_wire_seg_delay = opin_switch_del
                + (R_opin_switch + Rmetal * (float) wire_segment_length / 2)
                * (Cout_opin_switch + Cmetal * (float) wire_segment_length);
        float second_wire_seg_delay = wire_switch_del
                + (R_wire_switch + Rmetal * (float) wire_segment_length / 2)
                * (Cout_wire_switch + Cmetal * (float) wire_segment_length);
        inter_cluster_delay = 4
                * (first_wire_seg_delay + second_wire_seg_delay
                + wtoi_switch_del); /* multiply by 4 to get a more conservative estimate */
    }

    return try_pack(&vpr_setup.PackerOpts, &arch, vpr_setup.user_models,
            vpr_setup.library_models, inter_cluster_delay, vpr_setup.PackerRRGraph
#ifdef ENABLE_CLASSIC_VPR_STA
            , vpr_setup.Timing
#endif
            );
}

void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) {
    vtr::ScopedStartFinishTimer timer("Load Packing");

    VTR_ASSERT_MSG(!vpr_setup.FileNameOpts.NetFile.empty(),
            "Must have valid .net filename to load packing");

    auto& cluster_ctx = g_vpr_ctx.mutable_clustering();

    cluster_ctx.clb_nlist = read_netlist(vpr_setup.FileNameOpts.NetFile.c_str(),
                                         &arch,
                                         vpr_setup.FileNameOpts.verify_file_digests);

    process_constant_nets(cluster_ctx.clb_nlist, vpr_setup.constant_net_method);

    {
        std::ofstream ofs("packing_pin_util.rpt");
        report_packing_pin_usage(ofs, g_vpr_ctx);
    }

}

bool vpr_place_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
    const auto& placer_opts = vpr_setup.PlacerOpts;
    if (placer_opts.doPlacement == STAGE_SKIP) {
        //pass
    } else {
        if (placer_opts.doPlacement == STAGE_DO) {
            //Do the actual placement
            vpr_place(vpr_setup, arch);

        } else {
            VTR_ASSERT(placer_opts.doPlacement == STAGE_LOAD);

            //Load a previous placement
            vpr_load_placement(vpr_setup, arch);
        }

        sync_grid_to_blocks();
        post_place_sync();
    }

    return true;
}

void vpr_place(t_vpr_setup& vpr_setup, const t_arch& arch) {
    vtr::ScopedStartFinishTimer timer("Placement");

    try_place(vpr_setup.PlacerOpts,
              vpr_setup.AnnealSched,
              arch.Chans,
              vpr_setup.RouterOpts,
              &vpr_setup.RoutingArch,
              vpr_setup.Segments,
#ifdef ENABLE_CLASSIC_VPR_STA
              vpr_setup.Timing,
#endif
              arch.Directs,
              arch.num_directs);

    auto& filename_opts = vpr_setup.FileNameOpts;
    auto& cluster_ctx = g_vpr_ctx.clustering();

    print_place(filename_opts.NetFile.c_str(),
                cluster_ctx.clb_nlist.netlist_id().c_str(),
                filename_opts.PlaceFile.c_str());
}

void vpr_load_placement(t_vpr_setup& vpr_setup, const t_arch& /*arch*/) {
    vtr::ScopedStartFinishTimer timer("Load Placement");

    const auto& device_ctx = g_vpr_ctx.device();
    const auto& filename_opts = vpr_setup.FileNameOpts;

    read_place(filename_opts.NetFile.c_str(), filename_opts.PlaceFile.c_str(), filename_opts.verify_file_digests, device_ctx.grid);
}

RouteStatus vpr_route_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {

    RouteStatus route_status;

    const auto& router_opts = vpr_setup.RouterOpts;
    const auto& filename_opts = vpr_setup.FileNameOpts;

    if (router_opts.doRouting == STAGE_SKIP) {
        //Assume successful
        route_status = RouteStatus(true, -1);
    } else { //Do or load
        int chan_width = router_opts.fixed_channel_width;

        //Initialize the delay calculator
        vtr::t_chunk net_delay_ch;
        vtr::vector_map<ClusterNetId, float *> net_delay = alloc_net_delay(&net_delay_ch);

        std::shared_ptr<SetupHoldTimingInfo> timing_info = nullptr;
        std::shared_ptr<RoutingDelayCalculator> routing_delay_calc = nullptr;
        if (vpr_setup.Timing.timing_analysis_enabled) {
            auto& atom_ctx = g_vpr_ctx.atom();

            routing_delay_calc = std::make_shared<RoutingDelayCalculator>(atom_ctx.nlist, atom_ctx.lookup, net_delay);

            timing_info = make_setup_hold_timing_info(routing_delay_calc);
        }

        if (router_opts.doRouting == STAGE_DO) {
            //Do the actual routing
            if (NO_FIXED_CHANNEL_WIDTH == chan_width) {
                //Find minimum channel width
                route_status = vpr_route_min_W(vpr_setup, arch, timing_info, net_delay);
            } else {
                //Route at specified channel width
                route_status = vpr_route_fixed_W(vpr_setup, arch, chan_width, timing_info, net_delay);
            }

            //Save the routing in the .route file
            print_route(filename_opts.PlaceFile.c_str(), filename_opts.RouteFile.c_str());
        } else {
            VTR_ASSERT(router_opts.doRouting == STAGE_LOAD);

            //Load a previous routing
            route_status = vpr_load_routing(vpr_setup, arch, chan_width, timing_info, net_delay);
        }

        //Post-implementation

        std::string graphics_msg;
        if (route_status.success()) {
            //Sanity check the routing
            auto& device_ctx = g_vpr_ctx.device();
            check_route(router_opts.route_type, device_ctx.num_rr_switches);
            get_serial_num();

            //Update status
            VTR_LOG("Circuit successfully routed with a channel width factor of %d.\n", route_status.chan_width());
            graphics_msg = vtr::string_fmt("Routing succeeded with a channel width factor of %d.", route_status.chan_width());
        } else {
            //Update status
            VTR_LOG("Circuit is unroutable with a channel width factor of %d.\n", route_status.chan_width());
            graphics_msg = vtr::string_fmt("Routing failed with a channel width factor of %d. ILLEGAL routing shown.", route_status.chan_width());
        }

        //Echo files
        if (vpr_setup.Timing.timing_analysis_enabled) {
            if (isEchoFileEnabled(E_ECHO_FINAL_ROUTING_TIMING_GRAPH)) {
                auto& timing_ctx = g_vpr_ctx.timing();
                tatum::write_echo(getEchoFileName(E_ECHO_FINAL_ROUTING_TIMING_GRAPH),
                        *timing_ctx.graph, *timing_ctx.constraints, *routing_delay_calc, timing_info->analyzer());
            }

            if (isEchoFileEnabled(E_ECHO_ROUTING_SINK_DELAYS)) {
                //TODO: implement
            }
        }

        if (router_opts.switch_usage_analysis) {
            print_switch_usage();
        }

        //Update interactive graphics
        update_screen(ScreenUpdatePriority::MAJOR, graphics_msg.c_str(), ROUTING, timing_info);

        free_net_delay(net_delay, &net_delay_ch);
    }

    return route_status;
}

RouteStatus vpr_route_fixed_W(t_vpr_setup& vpr_setup, const t_arch& arch, int fixed_channel_width, std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *>& net_delay) {
    vtr::ScopedStartFinishTimer timer("Routing");

    if (NO_FIXED_CHANNEL_WIDTH == fixed_channel_width || fixed_channel_width <= 0) {
        VPR_THROW(VPR_ERROR_ROUTE, "Fixed channel width must be specified when routing at fixed channel width (was %d)", fixed_channel_width);
    }

#ifdef ENABLE_CLASSIC_VPR_STA
    t_slack *slacks = alloc_and_load_timing_graph(vpr_setup.Timing);
#endif

    bool status = try_route(fixed_channel_width,
                            vpr_setup.RouterOpts,
                            &vpr_setup.RoutingArch,
                            vpr_setup.Segments,
                            net_delay,
#ifdef ENABLE_CLASSIC_VPR_STA
                            slacks,
                            vpr_setup.Timing,
#endif
                            timing_info,
                            arch.Chans,
                            arch.Directs, arch.num_directs,
                            ScreenUpdatePriority::MAJOR);


    return RouteStatus(status, fixed_channel_width);
}

RouteStatus vpr_route_min_W(t_vpr_setup& vpr_setup, const t_arch& arch, std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *>& net_delay) {
    vtr::ScopedStartFinishTimer timer("Routing");

    auto& router_opts = vpr_setup.RouterOpts;
    int min_W = binary_search_place_and_route(vpr_setup.PlacerOpts,
                                              vpr_setup.FileNameOpts,
                                              &arch,
                                              router_opts.verify_binary_search,
                                              router_opts.min_channel_width_hint,
                                              vpr_setup.AnnealSched,
                                              router_opts,
                                              &vpr_setup.RoutingArch,
                                              vpr_setup.Segments,
                                              net_delay,
#ifdef ENABLE_CLASSIC_VPR_STA
                                              vpr_setup.Timing,
#endif
                                              timing_info);

    bool status = (min_W > 0);
    return RouteStatus(status, min_W);
}

RouteStatus vpr_load_routing(t_vpr_setup& vpr_setup, const t_arch& arch, int fixed_channel_width, std::shared_ptr<SetupHoldTimingInfo> timing_info, vtr::vector_map<ClusterNetId, float *>& net_delay) {
    vtr::ScopedStartFinishTimer timer("Load Routing");
    if (NO_FIXED_CHANNEL_WIDTH == fixed_channel_width) {
        VPR_THROW(VPR_ERROR_ROUTE, "Fixed channel width must be specified when loading routing (was %d)", fixed_channel_width);
    }

    //Create the routing resource graph
    vpr_create_rr_graph(vpr_setup, arch, fixed_channel_width);

    auto& filename_opts = vpr_setup.FileNameOpts;

    //Load the routing from a file
    bool is_legal = read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests);

    if (vpr_setup.Timing.timing_analysis_enabled) {
        //Update timing info
        load_net_delay_from_routing(net_delay);

        timing_info->update();
    }

    return RouteStatus(is_legal, fixed_channel_width);
}


void vpr_create_rr_graph(t_vpr_setup& vpr_setup, const t_arch& arch, int chan_width) {
    auto& device_ctx = g_vpr_ctx.mutable_device();
    auto det_routing_arch = &vpr_setup.RoutingArch;
    auto& router_opts = vpr_setup.RouterOpts;

    init_chan(chan_width, arch.Chans);

    t_graph_type graph_type;
    if (router_opts.route_type == GLOBAL) {
        graph_type = GRAPH_GLOBAL;
    } else {
        graph_type = (det_routing_arch->directionality == BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
    }

    int warnings = 0;

    //Clean-up any previous RR graph
    free_rr_graph();

    //Create the RR graph
	create_rr_graph(graph_type,
            device_ctx.num_block_types, device_ctx.block_types,
            device_ctx.grid,
			&device_ctx.chan_width,
			device_ctx.num_arch_switches,
            det_routing_arch,
            vpr_setup.Segments,
			router_opts.base_cost_type,
			router_opts.trim_empty_channels,
			router_opts.trim_obs_channels,
            router_opts.lookahead_type,
			arch.Directs, arch.num_directs,
			&device_ctx.num_rr_switches,
			&warnings);

    //Initialize drawing, now that we have an RR graph
    init_draw_coords(chan_width);

}

void vpr_init_graphics(const t_vpr_setup& vpr_setup, const t_arch& arch) {
    /* Startup X graphics */
    init_graphics_state(vpr_setup.ShowGraphics, vpr_setup.GraphPause,
            vpr_setup.RouterOpts.route_type);
    if (vpr_setup.ShowGraphics) {
        std::stringstream msg;
        msg << "VPR: Versatile Place and Route for FPGAs";
        msg << " (" << vtr::getcwd() << ")";
        init_graphics(msg.str().c_str(), WHITE);
        alloc_draw_structs(&arch);
    }
}

void vpr_close_graphics(const t_vpr_setup& vpr_setup) {
    /* Close down X Display */
    if (vpr_setup.ShowGraphics)
        close_graphics();
    free_draw_structs();
}

/* Since the parameters of a switch may change as a function of its fanin,
   to get an estimation of inter-cluster delays we need a reasonable estimation
   of the fan-ins of switches that connect clusters together. These switches are
        1) opin to wire switch
        2) wire to wire switch
        3) wire to ipin switch
   We can estimate the fan-in of these switches based on the Fc_in/Fc_out of
   a logic block, and the switch block Fs value */
static void get_intercluster_switch_fanin_estimates(const t_vpr_setup& vpr_setup, const t_arch& arch, const int wire_segment_length,
        int *opin_switch_fanin, int *wire_switch_fanin, int *ipin_switch_fanin) {
    e_directionality directionality;
    int Fs;
    float Fc_in, Fc_out;
    int W = 100; //W is unknown pre-packing, so *if* we need W here, we will assume a value of 100

    directionality = vpr_setup.RoutingArch.directionality;
    Fs = vpr_setup.RoutingArch.Fs;
    Fc_in = 0, Fc_out = 0;

    //Build a dummy 10x10 device to determine the 'best' block type to use
    auto grid = create_device_grid(vpr_setup.device_layout, arch.grid_layouts, 10, 10);

    auto type = find_most_common_block_type(grid);
    /* get Fc_in/out for most common block (e.g. logic blocks) */
    VTR_ASSERT(type->fc_specs.size() > 0);

    //Estimate the maximum Fc_in/Fc_out

    for (const t_fc_specification& fc_spec : type->fc_specs) {
        float Fc = fc_spec.fc_value;

        if (fc_spec.fc_value_type == e_fc_value_type::ABSOLUTE) {
            //Convert to estimated fractional
            Fc /= W;
        }
        VTR_ASSERT_MSG(Fc >= 0 && Fc <= 1., "Fc should be fractional");

        for (int ipin : fc_spec.pins) {
            int iclass = type->pin_class[ipin];
            e_pin_type pin_type = type->class_inf[iclass].type;

            if (pin_type == DRIVER) {
                Fc_out = std::max(Fc, Fc_out);
            } else {
                VTR_ASSERT(pin_type == RECEIVER);
                Fc_in = std::max(Fc, Fc_in);
            }
        }
    }

    /* Estimates of switch fan-in are done as follows:
       1) opin to wire switch:
            2 CLBs connect to a channel, each with #opins/4 pins. Each pin has Fc_out*W
            switches, and then we assume the switches are distributed evenly over the W wires.
            In the unidirectional case, all these switches are then crammed down to W/wire_segment_length wires.

                    Unidirectional: 2 * #opins_per_side * Fc_out * wire_segment_length
                    Bidirectional:  2 * #opins_per_side * Fc_out

       2) wire to wire switch
            A wire segment in a switchblock connects to Fs other wires. Assuming these connections are evenly
            distributed, each target wire receives Fs connections as well. In the unidirectional case,
            source wires can only connect to W/wire_segment_length wires.

                    Unidirectional: Fs * wire_segment_length
                    Bidirectional:  Fs

       3) wire to ipin switch
            An input pin of a CLB simply receives Fc_in connections.

                    Unidirectional: Fc_in
                    Bidirectional:  Fc_in
     */


    /* Fan-in to opin/ipin/wire switches depends on whether the architecture is unidirectional/bidirectional */
    (*opin_switch_fanin) = 2 * type->num_drivers / 4 * Fc_out;
    (*wire_switch_fanin) = Fs;
    (*ipin_switch_fanin) = Fc_in;
    if (directionality == UNI_DIRECTIONAL) {
        /* adjustments to opin-to-wire and wire-to-wire switch fan-ins */
        (*opin_switch_fanin) *= wire_segment_length;
        (*wire_switch_fanin) *= wire_segment_length;
    } else if (directionality == BI_DIRECTIONAL) {
        /* no adjustments need to be made here */
    } else {
        vpr_throw(VPR_ERROR_PACK, __FILE__, __LINE__, "Unrecognized directionality: %d\n", (int) directionality);
    }
}

/* Free architecture data structures */
void free_device(const t_det_routing_arch& routing_arch) {
    auto& device_ctx = g_vpr_ctx.mutable_device();

    vtr::free(device_ctx.chan_width.x_list);
    vtr::free(device_ctx.chan_width.y_list);

    device_ctx.chan_width.x_list = device_ctx.chan_width.y_list = nullptr;
    device_ctx.chan_width.max = device_ctx.chan_width.x_max = device_ctx.chan_width.y_max = device_ctx.chan_width.x_min = device_ctx.chan_width.y_min = 0;

    for (int iswitch : {routing_arch.delayless_switch, routing_arch.global_route_switch}) {
        if (device_ctx.arch_switch_inf[iswitch].name) {
            vtr::free(device_ctx.arch_switch_inf[iswitch].name);
            device_ctx.arch_switch_inf[iswitch].name = nullptr;
        }
    }
    delete[] device_ctx.arch_switch_inf;
    device_ctx.arch_switch_inf = nullptr;
    free_complex_block_types();
    free_chunk_memory_trace();
}

static void free_complex_block_types() {

    auto& device_ctx = g_vpr_ctx.mutable_device();

    free_type_descriptors(device_ctx.block_types, device_ctx.num_block_types);
    free_pb_graph_edges();
}

void free_circuit() {
	//Free new net structures
	auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
	for (auto blk_id : cluster_ctx.clb_nlist.blocks())
		cluster_ctx.clb_nlist.remove_block(blk_id);

	cluster_ctx.clb_nlist = ClusteredNetlist();
}

void vpr_free_vpr_data_structures(t_arch& Arch,
        t_vpr_setup& vpr_setup) {

    free_all_lb_type_rr_graph(vpr_setup.PackerRRGraph);
    free_circuit();
    free_arch(&Arch);
    free_device(vpr_setup.RoutingArch);
    free_echo_file_info();
    free_timing_stats();
    free_sdc_related_structs();
}

void vpr_free_all(t_arch& Arch,
        t_vpr_setup& vpr_setup) {

    free_rr_graph();
    if (vpr_setup.RouterOpts.doRouting) {
        free_route_structs();
    }
    free_trace_structs();
    vpr_free_vpr_data_structures(Arch, vpr_setup);
}


/****************************************************************************************************
 * Advanced functions
 *  Used when you need fine-grained control over VPR that the main VPR operations do not enable
 ****************************************************************************************************/

/* Read in user options */
void vpr_read_options(const int argc, const char **argv, t_options * options) {
    *options = read_options(argc, argv);
}

/* Read in arch and circuit */
void vpr_setup_vpr(t_options *Options, const bool TimingEnabled,
        const bool readArchFile, t_file_name_opts *FileNameOpts,
        t_arch * Arch,
        t_model ** user_models, t_model ** library_models,
        t_netlist_opts* NetlistOpts,
        t_packer_opts *PackerOpts,
        t_placer_opts *PlacerOpts,
        t_annealing_sched *AnnealSched,
        t_router_opts *RouterOpts,
        t_analysis_opts* AnalysisOpts,
        t_det_routing_arch *RoutingArch,
        vector <t_lb_type_rr_node> **PackerRRGraph,
        t_segment_inf ** Segments, t_timing_inf * Timing,
        bool * ShowGraphics, int *GraphPause,
        t_power_opts * PowerOpts) {
    SetupVPR(Options, TimingEnabled, readArchFile, FileNameOpts, Arch,
            user_models, library_models, NetlistOpts, PackerOpts, PlacerOpts,
            AnnealSched, RouterOpts, AnalysisOpts, RoutingArch, PackerRRGraph, Segments, Timing,
            ShowGraphics, GraphPause, PowerOpts);
}

void vpr_check_arch(const t_arch& Arch) {
    CheckArch(Arch);
}

/* Verify settings don't conflict or otherwise not make sense */
void vpr_check_setup(
        const t_packer_opts PackerOpts,
        const t_placer_opts PlacerOpts,
        const t_router_opts RouterOpts,
        const t_det_routing_arch RoutingArch, const t_segment_inf * Segments,
        const t_timing_inf Timing, const t_chan_width_dist Chans) {
    CheckSetup(PackerOpts, PlacerOpts, RouterOpts, RoutingArch,
            Segments, Timing, Chans);
}

/* Show current setup */
void vpr_show_setup(const t_vpr_setup& vpr_setup) {
    ShowSetup(vpr_setup);
}

bool vpr_analysis_flow(t_vpr_setup& vpr_setup, const t_arch& Arch, bool implementation_legal) {
    auto& analysis_opts = vpr_setup.AnalysisOpts;

    if (analysis_opts.doAnalysis == STAGE_SKIP) return true; //Skipped

    if (analysis_opts.doAnalysis == STAGE_AUTO && !implementation_legal) return false; //Not run

    VTR_ASSERT_MSG(analysis_opts.doAnalysis == STAGE_DO
                   || (analysis_opts.doAnalysis == STAGE_AUTO && implementation_legal),
                   "Analysis should run only if forced, or implementation legal");

    if (!implementation_legal) {
        VTR_LOG("\n");
        VTR_LOG("*****************************************************************************************\n");
        VTR_LOG_WARN( "The following analysis results are for an illegal circuit implementation\n");
        VTR_LOG("*****************************************************************************************\n");
    }

    vpr_analysis(vpr_setup, Arch);

    return true;
}

void vpr_analysis(t_vpr_setup& vpr_setup, const t_arch& Arch) {
    auto& route_ctx = g_vpr_ctx.routing();
    auto& device_ctx = g_vpr_ctx.mutable_device();
    auto& atom_ctx = g_vpr_ctx.atom();

	//Check the first index to see if a pointer exists
	//TODO: Implement a better error check
    if (route_ctx.trace_head.size() == 0) {
        VPR_THROW(VPR_ERROR_ANALYSIS, "No routing loaded -- can not perform post-routing analysis");
    }


	vtr::vector_map<ClusterNetId, float *> net_delay;
    vtr::t_chunk net_delay_ch;
#ifdef ENABLE_CLASSIC_VPR_STA
    t_slack* slacks = nullptr;
#endif
    if (vpr_setup.TimingEnabled) {
        //Load the net delays
        net_delay = alloc_net_delay(&net_delay_ch);
        load_net_delay_from_routing(net_delay);

#ifdef ENABLE_CLASSIC_VPR_STA
        slacks = alloc_and_load_timing_graph(vpr_setup.Timing);
#endif
    }

    routing_stats(vpr_setup.RouterOpts.full_stats, vpr_setup.RouterOpts.route_type,
            device_ctx.num_rr_switches, vpr_setup.Segments,
            vpr_setup.RoutingArch.num_segment,
            vpr_setup.RoutingArch.R_minW_nmos,
            vpr_setup.RoutingArch.R_minW_pmos,
            Arch.grid_logic_tile_area,
            vpr_setup.RoutingArch.directionality,
            vpr_setup.RoutingArch.wire_to_rr_ipin_switch,
            vpr_setup.TimingEnabled
#ifdef ENABLE_CLASSIC_VPR_STA
            , net_delay, slacks, vpr_setup.Timing
#endif
            );

    if (vpr_setup.TimingEnabled) {

        //Do final timing analysis
        auto analysis_delay_calc = std::make_shared<AnalysisDelayCalculator>(atom_ctx.nlist, atom_ctx.lookup, net_delay);
        auto timing_info = make_setup_hold_timing_info(analysis_delay_calc);
        timing_info->update();

        if (isEchoFileEnabled(E_ECHO_ANALYSIS_TIMING_GRAPH)) {
            auto& timing_ctx = g_vpr_ctx.timing();
            tatum::write_echo(getEchoFileName(E_ECHO_ANALYSIS_TIMING_GRAPH),
                    *timing_ctx.graph, *timing_ctx.constraints, *analysis_delay_calc, timing_info->analyzer());
        }

#ifdef ENABLE_CLASSIC_VPR_STA
        do_timing_analysis(slacks, vpr_setup.Timing, false, true);
#endif

        //Timing stats
        VTR_LOG("\n");
        generate_hold_timing_stats(*timing_info, *analysis_delay_calc, vpr_setup.AnalysisOpts);
        generate_setup_timing_stats(*timing_info, *analysis_delay_calc, vpr_setup.AnalysisOpts);

        //Write the post-syntesis netlist
        if (vpr_setup.AnalysisOpts.gen_post_synthesis_netlist) {
            netlist_writer(atom_ctx.nlist.netlist_name().c_str(), analysis_delay_calc);
        }

        //Do power analysis
        if (vpr_setup.PowerOpts.do_power) {

            vpr_power_estimation(vpr_setup, Arch, *timing_info);
        }

        //Clean-up the net delays
        free_net_delay(net_delay, &net_delay_ch);

#ifdef ENABLE_CLASSIC_VPR_STA
        free_timing_graph(slacks);
#endif
    }
}

/* This function performs power estimation, and must be called
 * after packing, placement AND routing. Currently, this
 * will not work when running a partial flow (ex. only routing). */
void vpr_power_estimation(const t_vpr_setup& vpr_setup, const t_arch& Arch, const SetupTimingInfo& timing_info) {
	/* Ensure we are only using 1 clock */
	if(timing_info.critical_paths().size() != 1) {
        VPR_THROW(VPR_ERROR_POWER, "Power analysis only supported on single-clock circuits");
    }

    auto& power_ctx = g_vpr_ctx.mutable_power();

    /* Get the critical path of this clock */
    power_ctx.solution_inf.T_crit = timing_info.least_slack_critical_path().delay();
    VTR_ASSERT(power_ctx.solution_inf.T_crit > 0.);

    VTR_LOG("\n\nPower Estimation:\n");
    VTR_LOG("-----------------\n");

    VTR_LOG("Initializing power module\n");

    /* Initialize the power module */
    bool power_error = power_init(vpr_setup.FileNameOpts.PowerFile.c_str(),
            vpr_setup.FileNameOpts.CmosTechFile.c_str(), &Arch, &vpr_setup.RoutingArch);
    if (power_error) {
        VTR_LOG_ERROR(
                "Power initialization failed.\n");
    }

    if (!power_error) {
        float power_runtime_s;

        VTR_LOG("Running power estimation\n");

        /* Run power estimation */
        e_power_ret_code power_ret_code = power_total(&power_runtime_s, vpr_setup,
                &Arch, &vpr_setup.RoutingArch);

        /* Check for errors/warnings */
        if (power_ret_code == POWER_RET_CODE_ERRORS) {
            VTR_LOG_ERROR(
                    "Power estimation failed. See power output for error details.\n");
        } else if (power_ret_code == POWER_RET_CODE_WARNINGS) {
            VTR_LOG_WARN(
                    "Power estimation completed with warnings. See power output for more details.\n");
        } else if (power_ret_code == POWER_RET_CODE_SUCCESS) {
        }
        VTR_LOG("Power estimation took %g seconds\n", power_runtime_s);
    }

    /* Uninitialize power module */
    if (!power_error) {
        VTR_LOG("Uninitializing power module\n");
        power_error = power_uninit();
        if (power_error) {
            VTR_LOG_ERROR(
                    "Power uninitialization failed.\n");
        } else {

        }
    }

    VTR_LOG("\n");
}

void vpr_print_error(const VprError& vpr_error){
	/* Determine the type of VPR error, To-do: can use some enum-to-string mechanism */
    char* error_type = nullptr;
    try {
        switch (vpr_error.type()) {
            case VPR_ERROR_UNKNOWN:
                error_type = vtr::strdup("Unknown");
                break;
            case VPR_ERROR_ARCH:
                error_type = vtr::strdup("Architecture file");
                break;
            case VPR_ERROR_PACK:
                error_type = vtr::strdup("Packing");
                break;
            case VPR_ERROR_PLACE:
                error_type = vtr::strdup("Placement");
                break;
            case VPR_ERROR_ROUTE:
                error_type = vtr::strdup("Routing");
                break;
            case VPR_ERROR_TIMING:
                error_type = vtr::strdup("Timing");
                break;
            case VPR_ERROR_SDC:
                error_type = vtr::strdup("SDC file");
                break;
            case VPR_ERROR_NET_F:
                error_type = vtr::strdup("Netlist file");
                break;
            case VPR_ERROR_BLIF_F:
                error_type = vtr::strdup("Blif file");
                break;
            case VPR_ERROR_PLACE_F:
                error_type = vtr::strdup("Placement file");
                break;
            case VPR_ERROR_IMPL_NETLIST_WRITER:
                error_type = vtr::strdup("Implementation Netlist Writer");
                break;
            case VPR_ERROR_ATOM_NETLIST:
                error_type = vtr::strdup("Atom Netlist");
                break;
            case VPR_ERROR_POWER:
                error_type = vtr::strdup("Power");
                break;
            case VPR_ERROR_ANALYSIS:
                error_type = vtr::strdup("Analysis");
                break;
            case VPR_ERROR_OTHER:
                error_type = vtr::strdup("Other");
                break;
            case VPR_ERROR_INTERRUPTED:
                error_type = vtr::strdup("Interrupted");
                break;
            default:
                error_type = vtr::strdup("Unrecognized Error");
                break;
        }
    } catch (const vtr::VtrError& e) {
        error_type = nullptr;
    }

    //We can't pass std::string's through va_args functions,
    //so we need to copy them and pass via c_str()
    std::string msg = vpr_error.what();
    std::string filename = vpr_error.filename();

    VTR_LOG_ERROR(
            "\nType: %s\nFile: %s\nLine: %d\nMessage: %s\n",
            error_type, filename.c_str(), vpr_error.line(),
            msg.c_str());
}
