blob: dae4edf9994e9d2c046f099d32e2e9a17e37b59f [file] [log] [blame]
// Tool to output FASM from placed and routed design via metadata tagging.
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>
using namespace std;
#include "vtr_error.h"
#include "vtr_memory.h"
#include "vtr_log.h"
#include "tatum/error.hpp"
#include "vpr_error.h"
#include "vpr_api.h"
#include "vpr_signal_handler.h"
#include "globals.h"
#include "net_delay.h"
#include "RoutingDelayCalculator.h"
#include "fasm.h"
/*
* Exit codes to signal success/failure to scripts
* calling vpr
*/
constexpr int SUCCESS_EXIT_CODE = 0; //Everything OK
constexpr int ERROR_EXIT_CODE = 1; //Something went wrong internally
constexpr int UNIMPLEMENTABLE_EXIT_CODE = 2; //Could not implement (e.g. unroutable)
constexpr int INTERRUPTED_EXIT_CODE = 3; //VPR was interrupted by the user (e.g. SIGINT/ctr-C)
/*
* Writes FASM file based on the netlist name by walking the netlist.
*/
static bool write_fasm() {
auto& atom_ctx = g_vpr_ctx.atom();
std::string fasm_filename = atom_ctx.nlist.netlist_name() + ".fasm";
vtr::printf("Writing Implementation FASM: %s\n", fasm_filename.c_str());
std::ofstream fasm_os(fasm_filename);
fasm::FasmWriterVisitor visitor(fasm_os);
NetlistWalker nl_walker(visitor);
nl_walker.walk();
return true;
}
/*
* Generate FASM utility.
*
* 1. Loads pack, place and route files
* 2. Walks netlist and outputs FASM.
* 3. Cleans up and exits.
*
*/
int main(int argc, const char **argv) {
t_options Options = t_options();
t_arch Arch = t_arch();
t_vpr_setup vpr_setup = t_vpr_setup();
clock_t entire_flow_begin, entire_flow_end;
entire_flow_begin = clock();
try {
vpr_install_signal_handler();
/* Read options, architecture, and circuit netlist */
vpr_init(argc, argv, &Options, &vpr_setup, &Arch);
vpr_setup.PackerOpts.doPacking = STAGE_LOAD;
vpr_setup.PlacerOpts.doPlacement = STAGE_LOAD;
vpr_setup.RouterOpts.doRouting = STAGE_LOAD;
vpr_setup.AnalysisOpts.doAnalysis = STAGE_SKIP;
bool flow_succeeded = false;
flow_succeeded = vpr_flow(vpr_setup, Arch);
/* Actually write output FASM file. */
flow_succeeded = write_fasm();
if (!flow_succeeded) {
return UNIMPLEMENTABLE_EXIT_CODE;
}
entire_flow_end = clock();
vtr::printf_info("The entire flow of VPR took %g seconds.\n",
(float) (entire_flow_end - entire_flow_begin) / CLOCKS_PER_SEC);
/* free data structures */
vpr_free_all(Arch, vpr_setup);
} catch (const tatum::Error& tatum_error) {
vtr::printf_error(__FILE__, __LINE__, "STA Engine: %s\n", tatum_error.what());
return ERROR_EXIT_CODE;
} catch (const VprError& vpr_error) {
vpr_print_error(vpr_error);
if (vpr_error.type() == VPR_ERROR_INTERRUPTED) {
return INTERRUPTED_EXIT_CODE;
} else {
return ERROR_EXIT_CODE;
}
} catch (const vtr::VtrError& vtr_error) {
vtr::printf_error(__FILE__, __LINE__, "%s:%d %s\n", vtr_error.filename_c_str(), vtr_error.line(), vtr_error.what());
return ERROR_EXIT_CODE;
}
/* Signal success to scripts */
return SUCCESS_EXIT_CODE;
}