/**
 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>
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_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 "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::printf_info("\n");
    vtr::printf_info("VPR FPGA Placement and Routing.\n");
    vtr::printf_info("Version: %s\n", vtr::VERSION);
    vtr::printf_info("Revision: %s\n", vtr::VCS_REVISION);
    vtr::printf_info("Compiled: %s\n", vtr::BUILD_TIMESTAMP);
    vtr::printf_info("Compiler: %s\n", vtr::COMPILER);
    vtr::printf_info("University of Toronto\n");
    vtr::printf_info("vtr-users@googlegroups.com\n");
    vtr::printf_info("This is free open source code under MIT license.\n");
    vtr::printf_info("\n");

}

void vpr_print_args(int argc, const char** argv) {
    vtr::printf_info("VPR was run with the following command-line:\n");
    for (int i = 0; i < argc; i++) {
        if (i != 0) {
            vtr::printf_info(" ");
        }
        vtr::printf_info("%s", argv[i]);
    }
    vtr::printf_info("\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::printf("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::printf("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::printf_warning(__FILE__, __LINE__, 
            "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;

    vtr::printf_info("\n");
    vtr::printf_info("Architecture file: %s\n", options->ArchFile.value().c_str());
    vtr::printf_info("Circuit name: %s\n", options->CircuitName.value().c_str());
    vtr::printf_info("\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.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.verbose_sweep);


    if (vpr_setup->PowerOpts.do_power) {
        //Load the net activity file for power estimation
        vtr::ScopedPrintTimer 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::ScopedPrintTimer t("Build Timing Graph");
            timing_ctx.graph = TimingGraphBuilder(atom_ctx.nlist, atom_ctx.lookup).timing_graph();
            vtr::printf("  Timing Graph Nodes: %zu\n", timing_ctx.graph->nodes().size());
            vtr::printf("  Timing Graph Edges: %zu\n", timing_ctx.graph->edges().size());
        }
        {
            vtr::ScopedPrintTimer 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) {
    { //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
        }
    }

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

        if (!route_status.success()) {
            return false; //Unimplementable
        }
    }

    {
        //Analysis
        vpr_analysis(vpr_setup, arch);
    }

    vpr_close_graphics(vpr_setup);
    return true;
}

/*
 * 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
     */
    vtr::printf_info("FPGA sized to %zu x %zu (%s)\n", device_ctx.grid.width(), device_ctx.grid.height(), device_ctx.grid.name().c_str());

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

    float device_utilization = calculate_device_utilization(device_ctx.grid, num_type_instances);
    vtr::printf_info("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::printf("\tBlock Utilization: %.2f Type: %s\n", util, type->name);
    }
    vtr::printf_info("\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;

    if (packer_opts.doPacking == STAGE_SKIP) {
        //pass
    } else {
        if (packer_opts.doPacking == STAGE_DO) {
            //Do the actual packing
            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 true;
}

void vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) {
    vtr::ScopedPrintTimer 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 */
    }

    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::ScopedPrintTimer 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);
}

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::ScopedPrintTimer 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::ScopedPrintTimer 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);
        }

        //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::printf_info("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::printf_info("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::ScopedPrintTimer 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::ScopedPrintTimer 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) {
    vtr::ScopedPrintTimer 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)");
    }

    //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
    read_route(filename_opts.RouteFile.c_str(), vpr_setup.RouterOpts, filename_opts.verify_file_digests);

    return RouteStatus(true, 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,
			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) {
        init_graphics("VPR: Versatile Place and Route for FPGAs", 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_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_graph> *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);
}

void vpr_analysis(t_vpr_setup& vpr_setup, const t_arch& Arch) {
    if (vpr_setup.AnalysisOpts.doAnalysis == STAGE_SKIP) return;
    VTR_ASSERT(vpr_setup.AnalysisOpts.doAnalysis == STAGE_DO);

    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, net_delay
#ifdef ENABLE_CLASSIC_VPR_STA
            , 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::printf("\n");
        generate_hold_timing_stats(*timing_info);
        generate_setup_timing_stats(*timing_info);

        //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::printf_info("\n\nPower Estimation:\n");
    vtr::printf_info("-----------------\n");

    vtr::printf_info("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::printf_error(__FILE__, __LINE__,
                "Power initialization failed.\n");
    }

    if (!power_error) {
        float power_runtime_s;

        vtr::printf_info("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::printf_error(__FILE__, __LINE__,
                    "Power estimation failed. See power output for error details.\n");
        } else if (power_ret_code == POWER_RET_CODE_WARNINGS) {
            vtr::printf_warning(__FILE__, __LINE__,
                    "Power estimation completed with warnings. See power output for more details.\n");
        } else if (power_ret_code == POWER_RET_CODE_SUCCESS) {
        }
        vtr::printf_info("Power estimation took %g seconds\n", power_runtime_s);
    }

    /* Uninitialize power module */
    if (!power_error) {
        vtr::printf_info("Uninitializing power module\n");
        power_error = power_uninit();
        if (power_error) {
            vtr::printf_error(__FILE__, __LINE__,
                    "Power uninitialization failed.\n");
        } else {

        }
    }

    vtr::printf_info("\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::printf_error(__FILE__, __LINE__,
            "\nType: %s\nFile: %s\nLine: %d\nMessage: %s\n",
            error_type, filename.c_str(), vpr_error.line(),
            msg.c_str());
}
