VPR-6.0
|
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "graphics.h"
#include "read_netlist.h"
#include "check_netlist.h"
#include "print_netlist.h"
#include "draw.h"
#include "place_and_route.h"
#include "pack.h"
#include "SetupGrid.h"
#include "stats.h"
#include "path_delay.h"
#include "OptionTokens.h"
#include "ReadOptions.h"
#include "read_xml_arch_file.h"
#include "SetupVPR.h"
#include "rr_graph.h"
#include "pb_type_graph.h"
Go to the source code of this file.
static void free_complex_block_types | ( | ) | [static] |
Definition at line 448 of file main.c.
{ int i, j, k, m; free_all_pb_graph_nodes(); for(i = 0; i < num_types; i++) { if(&type_descriptors[i] == EMPTY_TYPE) { continue; } free(type_descriptors[i].name); for(j = 0; j < type_descriptors[i].height; j++) { for(k = 0; k < 4; k ++) { for(m = 0; m < type_descriptors[i].num_pin_loc_assignments[j][k]; m++) { if(type_descriptors[i].pin_loc_assignments[j][k][m]) free(type_descriptors[i].pin_loc_assignments[j][k][m]); } free(type_descriptors[i].pinloc[j][k]); free(type_descriptors[i].pin_loc_assignments[j][k]); } free(type_descriptors[i].pinloc[j]); free(type_descriptors[i].pin_loc_assignments[j]); free(type_descriptors[i].num_pin_loc_assignments[j]); } free(type_descriptors[i].pinloc); free(type_descriptors[i].pin_loc_assignments); free(type_descriptors[i].num_pin_loc_assignments); free(type_descriptors[i].pin_height); free_pb_type(type_descriptors[i].pb_type); free(type_descriptors[i].pb_type); } }
static void free_pb_type | ( | t_pb_type * | pb_type | ) | [static] |
Definition at line 481 of file main.c.
{ int i, j, k, m; struct s_linked_vptr *vptr, *prev; free(pb_type->name); if(pb_type->blif_model) free(pb_type->blif_model); for(i = 0; i < pb_type->num_modes; i++) { for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) { free_pb_type(&pb_type->modes[i].pb_type_children[j]); } free(pb_type->modes[i].pb_type_children); free(pb_type->modes[i].name); for(j = 0; j < pb_type->modes[i].num_interconnect; j++) { free(pb_type->modes[i].interconnect[j].input_string); free(pb_type->modes[i].interconnect[j].output_string); free(pb_type->modes[i].interconnect[j].name); for(k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; k++) { if(pb_type->modes[i].interconnect[j].annotations[k].clock) free(pb_type->modes[i].interconnect[j].annotations[k].clock); if(pb_type->modes[i].interconnect[j].annotations[k].input_pins) { free(pb_type->modes[i].interconnect[j].annotations[k].input_pins); } if(pb_type->modes[i].interconnect[j].annotations[k].output_pins) { free(pb_type->modes[i].interconnect[j].annotations[k].output_pins); } for(m = 0; m < pb_type->modes[i].interconnect[j].annotations[k].num_value_prop_pairs; m++) { free(pb_type->modes[i].interconnect[j].annotations[k].value[m]); } free(pb_type->modes[i].interconnect[j].annotations[k].prop); free(pb_type->modes[i].interconnect[j].annotations[k].value); } free(pb_type->modes[i].interconnect[j].annotations); } if(pb_type->modes[i].interconnect) free(pb_type->modes[i].interconnect); } if(pb_type->modes) free(pb_type->modes); for(i = 0; i < pb_type->num_annotations; i++) { for(j = 0; j < pb_type->annotations[i].num_value_prop_pairs; j++) { free(pb_type->annotations[i].value[j]); } free(pb_type->annotations[i].value); free(pb_type->annotations[i].prop); if(pb_type->annotations[i].input_pins) { free(pb_type->annotations[i].input_pins); } if(pb_type->annotations[i].output_pins) { free(pb_type->annotations[i].output_pins); } if(pb_type->annotations[i].clock) { free(pb_type->annotations[i].clock); } } if(pb_type->num_annotations > 0) { free(pb_type->annotations); } vptr = pb_type->models_contained; while(vptr) { prev = vptr; vptr = vptr->next; free(prev); } for(i = 0; i < pb_type->num_ports; i++) { free(pb_type->ports[i].name); if(pb_type->ports[i].port_class) { free(pb_type->ports[i].port_class); } } free(pb_type->ports); }
static void freeArch | ( | t_arch * | Arch | ) | [static] |
Definition at line 367 of file main.c.
{ int i; t_model *model, *prev; t_model_ports *port, *prev_port; struct s_linked_vptr *vptr, *vptr_prev; for(i = 0; i < Arch->num_switches; i++) { if(Arch->Switches->name != NULL) { free(Arch->Switches[i].name); } } free(Arch->Switches); for(i = 0; i < Arch->num_segments; i++) { if(Arch->Segments->cb != NULL) { free(Arch->Segments[i].cb); } if(Arch->Segments->sb != NULL) { free(Arch->Segments[i].sb); } } free(Arch->Segments); model = Arch->models; while(model) { port = model->inputs; while(port) { prev_port = port; port = port->next; free(prev_port->name); free(prev_port); } port = model->outputs; while(port) { prev_port = port; port = port->next; free(prev_port->name); free(prev_port); } vptr = model->pb_types; while(vptr) { vptr_prev = vptr; vptr = vptr->next; free(vptr_prev); } prev = model; model = model->next; if(prev->instances) free(prev->instances); free(prev->name); free(prev); } for(i = 0; i < 4; i++) { vptr = Arch->model_library[i].pb_types; while(vptr) { vptr_prev = vptr; vptr = vptr->next; free(vptr_prev); } } free(Arch->model_library[0].name); free(Arch->model_library[0].outputs->name); free(Arch->model_library[0].outputs); free(Arch->model_library[1].inputs->name); free(Arch->model_library[1].inputs); free(Arch->model_library[1].name); free(Arch->model_library[2].name); free(Arch->model_library[2].inputs[0].name); free(Arch->model_library[2].inputs[1].name); free(Arch->model_library[2].inputs); free(Arch->model_library[2].outputs->name); free(Arch->model_library[2].outputs); free(Arch->model_library[3].name); free(Arch->model_library[3].inputs->name); free(Arch->model_library[3].inputs); free(Arch->model_library[3].outputs->name); free(Arch->model_library[3].outputs); free(Arch->model_library); }
static void freeOptions | ( | t_options * | options | ) | [static] |
Definition at line 707 of file main.c.
{ free(options->ArchFile); free(options->CircuitName); if(options->BlifFile) free(options->BlifFile); if(options->NetFile) free(options->NetFile); if(options->PlaceFile) free(options->PlaceFile); if(options->RouteFile) free(options->RouteFile); if(options->OutFilePrefix) free(options->OutFilePrefix); if(options->PinFile) free(options->PinFile); }
static void InitArch | ( | INP t_arch | Arch | ) | [static] |
This is a modification of the init_arch function to use Arch as param.
Definition at line 567 of file main.c.
{ int *num_instances_type, *num_blocks_type; int i; int current, high, low; boolean fit; current = nint(sqrt(num_blocks)); /* current is the value of the smaller side of the FPGA */ low = 1; high = -1; num_instances_type = my_calloc(num_types, sizeof(int)); num_blocks_type = my_calloc(num_types, sizeof(int)); for(i = 0; i < num_blocks; i++) { num_blocks_type[block[i].type->index]++; } if(Arch.clb_grid.IsAuto) { /* Auto-size FPGA, perform a binary search */ while(high == -1 || low < high) { /* Generate grid */ if(Arch.clb_grid.Aspect >= 1.0) { ny = current; nx = nint(current * Arch.clb_grid.Aspect); } else { nx = current; ny = nint(current / Arch.clb_grid.Aspect); } #if DEBUG printf("Auto-sizing FPGA, try x = %d y = %d\n", nx, ny); #endif alloc_and_load_grid(num_instances_type); freeGrid(); /* Test if netlist fits in grid */ fit = TRUE; for(i = 0; i < num_types; i++) { if(num_blocks_type[i] > num_instances_type[i]) { fit = FALSE; break; } } /* get next value */ if(!fit) { /* increase size of max */ if(high == -1) { current = current * 2; if(current > MAX_SHORT) { printf(ERRTAG "FPGA required is too large for current architecture settings\n"); exit(1); } } else { if(low == current) current++; low = current; current = low + ((high - low) / 2); } } else { high = current; current = low + ((high - low) / 2); } } /* Generate grid */ if(Arch.clb_grid.Aspect >= 1.0) { ny = current; nx = nint(current * Arch.clb_grid.Aspect); } else { nx = current; ny = nint(current / Arch.clb_grid.Aspect); } alloc_and_load_grid(num_instances_type); printf("FPGA auto-sized to, x = %d y = %d\n", nx, ny); } else { nx = Arch.clb_grid.W; ny = Arch.clb_grid.H; alloc_and_load_grid(num_instances_type); } printf("The circuit will be mapped into a %d x %d array of clbs.\n", nx, ny); /* Test if netlist fits in grid */ fit = TRUE; for(i = 0; i < num_types; i++) { if(num_blocks_type[i] > num_instances_type[i]) { fit = FALSE; break; } } if(!fit) { printf(ERRTAG "Not enough physical locations for type %s, " "number of blocks is %d but number of locations is %d\n", type_descriptors[i].name, num_blocks_type[i], num_instances_type[i]); exit(1); } printf("\nResource Usage:\n"); for(i = 0; i < num_types; i++) { printf("Netlist %d\tblocks of type %s\n", num_blocks_type[i], type_descriptors[i].name); printf("Architecture %d\tblocks of type %s\n", num_instances_type[i], type_descriptors[i].name); } printf("\n"); chan_width_x = (int *)my_malloc((ny + 1) * sizeof(int)); chan_width_y = (int *)my_malloc((nx + 1) * sizeof(int)); free(num_blocks_type); free(num_instances_type); }
int main | ( | int | argc, |
char ** | argv | ||
) |
VPR program Generate FPGA architecture given architecture description Pack, place, and route circuit into FPGA architecture Electrical timing analysis on results
Overall steps
Definition at line 151 of file main.c.
{ t_options Options; t_arch Arch; t_model *user_models, *library_models; enum e_operation Operation; struct s_file_name_opts FileNameOpts; struct s_packer_opts PackerOpts; struct s_placer_opts PlacerOpts; struct s_annealing_sched AnnealSched; struct s_router_opts RouterOpts; struct s_det_routing_arch RoutingArch; t_segment_inf *Segments; t_timing_inf Timing; boolean ShowGraphics; boolean TimingEnabled; int GraphPause; clock_t begin, end; /* Print title message */ PrintTitle(); /* Print usage message if no args */ if(argc < 2) { PrintUsage(); exit(1); } /* Read in available inputs */ ReadOptions(argc, argv, &Options); /* Determine whether timing is on or off */ TimingEnabled = IsTimingEnabled(Options); /* Use inputs to configure VPR */ memset(&Arch, 0, sizeof(t_arch)); SetupVPR(Options, TimingEnabled, &FileNameOpts, &Arch, &Operation, &user_models, &library_models, &PackerOpts, &PlacerOpts, &AnnealSched, &RouterOpts, &RoutingArch, &Segments, &Timing, &ShowGraphics, &GraphPause); /* Check inputs are reasonable */ CheckOptions(Options, TimingEnabled); CheckArch(Arch, TimingEnabled); /* Verify settings don't conflict or otherwise not make sense */ CheckSetup(Operation, PlacerOpts, AnnealSched, RouterOpts, RoutingArch, Segments, Timing, Arch.Chans); fflush(stdout); /* Packing stage */ if(PackerOpts.doPacking) { begin = clock(); try_pack(&PackerOpts, &Arch, user_models, library_models); end = clock(); #ifdef CLOCKS_PER_SEC printf("Packing took %g seconds\n", (float)(end - begin) / CLOCKS_PER_SEC); #else printf("Packing took %g seconds\n", (float)(end - begin) / CLK_PER_SEC); #endif /* Free logical blocks and nets */ if(logical_block != NULL) { free_logical_blocks(); free_logical_nets(); } if(!PlacerOpts.doPlacement && !RouterOpts.doRouting) { return 0; } } /* Packing stage complete */ fflush(stdout); /* Read in netlist file for placement and routing */ if(FileNameOpts.NetFile) { read_netlist(FileNameOpts.NetFile, &Arch, &num_blocks, &block, &num_nets, &clb_net); /* This is done so that all blocks have subblocks and can be treated the same */ check_netlist(); } /* Output the current settings to console. */ ShowSetup(Options, Arch, TimingEnabled, Operation, FileNameOpts, PlacerOpts, AnnealSched, RouterOpts, RoutingArch, Segments, Timing); if(Operation == TIMING_ANALYSIS_ONLY) { do_constant_net_delay_timing_analysis( Timing, Options.constant_net_delay); return 0; } InitArch(Arch); fflush(stdout); /* Startup X graphics */ set_graphics_state(ShowGraphics, GraphPause, RouterOpts.route_type); if(ShowGraphics) { init_graphics("VPR: Versatile Place and Route for FPGAs"); alloc_draw_structs(); } /* Do placement and routing */ place_and_route(Operation, PlacerOpts, FileNameOpts.PlaceFile, FileNameOpts.NetFile, FileNameOpts.ArchFile, FileNameOpts.RouteFile, AnnealSched, RouterOpts, RoutingArch, Segments, Timing, Arch.Chans, Arch.models); fflush(stdout); /* Close down X Display */ if(ShowGraphics) close_graphics(); /* free data structures */ freeOptions(&Options); /* Free logical blocks and nets */ if(logical_block != NULL) { free_logical_blocks(); free_logical_nets(); } freeArch(&Arch); free_complex_block_types(); /* Return 0 to single success to scripts */ return 0; }
static void PrintTitle | ( | ) | [static] |
Definition at line 350 of file main.c.
{ puts(""); puts("VPR FPGA Placement and Routing."); puts("Version: Version " VPR_VERSION); puts("Compiled: " __DATE__ "."); puts("Original VPR by V. Betz."); puts("Timing-driven placement enhancements by A. Marquardt."); puts("Single-drivers enhancements by Andy Ye with additions by."); puts("Mark Fang, Jason Luu, Ted Campbell"); puts("Heterogeneous stucture support by Jason Luu and Ted Campbell."); puts("T-VPack clustering integration by Jason Luu."); puts("Area-driven AAPack added by Jason Luu."); puts("This code is licensed only for non-commercial use."); puts(""); }
static void PrintUsage | ( | ) | [static] |
Outputs usage message
Definition at line 291 of file main.c.
{ puts("Usage: vpr fpga_architecture.xml circuit_name [Options ...]"); puts(""); puts("General Options: [--nodisp] [--auto <int>] [--pack]"); puts("\t[--place] [--route] [--timing_analyze_only_with_net_delay <float>]"); puts("\t[--fast] [--full_stats] [--timing_analysis on | off] [--outfile_prefix <string>]"); puts("\t[--blif_file <string>][--net_file <string>][--place_file <string>][--route_file <string>]"); puts(""); puts("Packer Options:"); /* puts("\t[-global_clocks on|off]"); puts("\t[-hill_climbing on|off]"); puts("\t[-sweep_hanging_nets_and_inputs on|off]"); */ puts("\t[--timing_driven_clustering on|off]"); puts("\t[--cluster_seed_type timing|max_inputs] [--alpha_clustering <float>] [--beta_clustering <float>]"); /* puts("\t[-recompute_timing_after <int>] [-cluster_block_delay <float>]"); */ puts("\t[--allow_unrelated_clustering on|off]"); /* puts("\t[-allow_early_exit on|off]"); puts("\t[-intra_cluster_net_delay <float>] "); puts("\t[-inter_cluster_net_delay <float>] "); */ puts("\t[--connection_driven_clustering on|off] "); /* puts("\t[-packer_algorithm greedy|brute_force]"); puts("\t[-hack_no_legal_frac_lut]"); puts("\t[-hack_safe_latch]"); */ puts(""); puts("Placer Options:"); puts("\t[--place_algorithm bounding_box | net_timing_driven | path_timing_driven]"); puts("\t[--init_t <float>] [--exit_t <float>]"); puts("\t[--alpha_t <float>] [--inner_num <float>] [--seed <int>]"); puts("\t[--place_cost_exp <float>] [--place_cost_type linear | nonlinear]"); puts("\t[--place_chan_width <int>] [--num_regions <int>] "); puts("\t[--fix_pins random | <file.pads>]"); puts("\t[--enable_timing_computations on | off]"); puts("\t[--block_dist <int>]"); puts(""); puts("Placement Options Valid Only for Timing-Driven Placement:"); puts("\t[--timing_tradeoff <float>]"); puts("\t[--recompute_crit_iter <int>]"); puts("\t[--inner_loop_recompute_divider <int>]"); puts("\t[--td_place_exp_first <float>]"); puts("\t[--td_place_exp_last <float>]"); puts(""); puts("Router Options: [-max_router_iterations <int>] [-bb_factor <int>]"); puts("\t[--initial_pres_fac <float>] [--pres_fac_mult <float>]"); puts("\t[--acc_fac <float>] [--first_iter_pres_fac <float>]"); puts("\t[--bend_cost <float>] [--route_type global | detailed]"); puts("\t[--verify_binary_search] [--route_chan_width <int>]"); puts("\t[--router_algorithm breadth_first | timing_driven | directed_search]"); puts("\t[--base_cost_type intrinsic_delay | delay_normalized | demand_only]"); puts(""); puts("Routing options valid only for timing-driven routing:"); puts("\t[--astar_fac <float>] [--max_criticality <float>]"); puts("\t[--criticality_exp <float>]"); puts(""); }
int binary_search = -1 |
char* blif_circuit_name = NULL |
int* chan_width_x = NULL |
int* chan_width_y = NULL |
struct s_linked_vptr* circuit_p_io_removed = NULL |
int* clb_to_vpack_net_mapping = NULL |
t_type_ptr EMPTY_TYPE = NULL |
t_type_ptr FILL_TYPE = NULL |
struct s_grid_tile** grid = NULL |
float grid_logic_tile_area = 0 |
t_type_ptr IO_TYPE = NULL |
float ipin_mux_trans_size = 0 |
struct s_logical_block* logical_block = NULL |
int** net_rr_terminals = NULL |
int num_blocks = 0 |
int num_const_gen = 0 |
int num_latches = 0 |
int num_logical_blocks = 0 |
int num_logical_nets = 0 |
int num_luts = 0 |
int num_nets = 0 |
int num_p_inputs = 0 |
int num_p_outputs = 0 |
int num_rr_indexed_data = 0 |
int num_rr_nodes = 0 |
int num_saved_logical_blocks = 0 |
int num_saved_logical_nets = 0 |
int num_subckts = 0 |
int num_tnodes = 0 |
int num_types = 0 |
int nx = 0 |
float pb_max_internal_delay = UNDEFINED |
const t_pb_type* pbtype_max_internal_delay = NULL |
int** rr_blk_source = NULL |
t_rr_indexed_data* rr_indexed_data = NULL |
t_ivec*** rr_node_indices = NULL |
struct s_logical_block * saved_logical_blocks = NULL |
struct s_net * saved_logical_nets = NULL |
struct s_switch_inf* switch_inf = NULL |
struct s_trace** trace_head = NULL |
struct s_trace** trace_tail = NULL |
struct s_type_descriptor* type_descriptors = NULL |
int* vpack_to_clb_net_mapping = NULL |