📄 main.c
字号:
#include <stdio.h>#include <string.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "graphics.h"#include "read_netlist.h"#include "print_netlist.h"#include "read_arch.h"#include "draw.h"#include "place_and_route.h"#include "stats.h"#include "path_delay.h"/******************** Global variables ************************************/ /********** Netlist to be mapped stuff ****************/int num_nets, num_blocks;int num_p_inputs, num_p_outputs, num_clbs, num_globals;struct s_net *net;struct s_block *block;boolean *is_global; /* FALSE if a net is normal, TRUE if it is */ /* global. Global signals are not routed. */ /********** Physical architecture stuff ****************/int nx, ny, io_rat, pins_per_clb;/* Pinloc[0..3][0..pins_per_clb-1]. For each pin pinloc[0..3][i] is 1 if * * pin[i] exists on that side of the clb. See vpr_types.h for correspondence * * between the first index and the clb side. */int **pinloc; int *clb_pin_class; /* clb_pin_class[0..pins_per_clb-1]. Gives the class * * number of each pin on a clb. *//* TRUE if this is a global clb pin -- an input pin to which the netlist can * * connect global signals, but which does not connect into the normal * * routing via muxes etc. Marking pins like this (only clocks in my work) * * stops them from screwing up the input switch pattern in the rr_graph * * generator and from creating extra switches that the area model would * * count. */boolean *is_global_clb_pin; /* [0..pins_per_clb-1]. */struct s_class *class_inf; /* class_inf[0..num_class-1]. Provides * * information on all available classes. */int num_class; /* Number of different classes. */int *chan_width_x, *chan_width_y; /* [0..ny] and [0..nx] respectively */struct s_clb **clb; /* Physical block list */ /******** Structures defining the routing ***********//* [0..num_nets-1] of linked list start pointers. Define the routing. */struct s_trace **trace_head, **trace_tail; /**** Structures defining the FPGA routing architecture ****/int num_rr_nodes;t_rr_node *rr_node; /* [0..num_rr_nodes-1] */int num_rr_indexed_data;t_rr_indexed_data *rr_indexed_data; /* [0..num_rr_indexed_data-1] *//* Gives the rr_node indices of net terminals. */int **net_rr_terminals; /* [0..num_nets-1][0..num_pins-1]. *//* Gives information about all the switch types * * (part of routing architecture, but loaded in read_arch.c */struct s_switch_inf *switch_inf; /* [0..det_routing_arch.num_switch-1] *//* Stores the SOURCE and SINK nodes of all CLBs (not valid for pads). */int **rr_clb_source; /* [0..num_blocks-1][0..num_class-1]*//********************** Subroutines local to this module ********************/static void get_input (char *net_file, char *arch_file, int place_cost_type, int num_regions, float aspect_ratio, boolean user_sized, enum e_route_type route_type, struct s_det_routing_arch *det_routing_arch, t_segment_inf **segment_inf_ptr, t_timing_inf *timing_inf_ptr, t_subblock_data *subblock_data_ptr, t_chan_width_dist *chan_width_dist_ptr);static void parse_command (int argc, char *argv[], char *net_file, char *arch_file, char *place_file, char *route_file, enum e_operation *operation, float *aspect_ratio, boolean *full_stats, boolean *user_sized, boolean *verify_binary_search, int *gr_automode, boolean *show_graphics, struct s_annealing_sched *annealing_sched, struct s_placer_opts *placer_opts, struct s_router_opts *router_opts, boolean *timing_analysis_enabled, float *constant_net_delay);static int read_int_option (int argc, char *argv[], int iarg);static float read_float_option (int argc, char *argv[], int iarg);/************************* Subroutine definitions ***************************/int main (int argc, char *argv[]) { char title[] = "\n\nVPR FPGA Placement and Routing Program Version 4.3\n" "Original VPR by V. Betz\n" "Timing-driven placement enhancements by A. Marquardt\n" "Source completed March 25, 2000; compiled " __DATE__ ".\n" "This code is licensed only for non-commercial use.\n\n"; char net_file[BUFSIZE], place_file[BUFSIZE], arch_file[BUFSIZE]; char route_file[BUFSIZE]; float aspect_ratio; boolean full_stats, user_sized; char pad_loc_file[BUFSIZE]; enum e_operation operation; boolean verify_binary_search; boolean show_graphics; int gr_automode; struct s_annealing_sched annealing_sched; struct s_placer_opts placer_opts; struct s_router_opts router_opts; struct s_det_routing_arch det_routing_arch; t_segment_inf *segment_inf; t_timing_inf timing_inf; t_subblock_data subblock_data; t_chan_width_dist chan_width_dist; float constant_net_delay; printf("%s",title); placer_opts.pad_loc_file = pad_loc_file;/* Parse the command line. */ parse_command (argc, argv, net_file, arch_file, place_file, route_file, &operation, &aspect_ratio, &full_stats, &user_sized, &verify_binary_search, &gr_automode, &show_graphics, &annealing_sched, &placer_opts, &router_opts, &timing_inf.timing_analysis_enabled, &constant_net_delay);/* Parse input circuit and architecture */ get_input (net_file, arch_file, placer_opts.place_cost_type, placer_opts.num_regions, aspect_ratio, user_sized, router_opts.route_type, &det_routing_arch, &segment_inf, &timing_inf, &subblock_data, &chan_width_dist); if (full_stats == TRUE) print_lambda ();#ifdef DEBUG print_netlist ("net.echo", net_file, subblock_data); print_arch (arch_file, router_opts.route_type, det_routing_arch, segment_inf, timing_inf, subblock_data, chan_width_dist);#endif if (operation == TIMING_ANALYSIS_ONLY) { /* Just run the timing analyzer. */ do_constant_net_delay_timing_analysis (timing_inf, subblock_data, constant_net_delay); free_subblock_data (&subblock_data); exit (0); } set_graphics_state (show_graphics, gr_automode, router_opts.route_type); if (show_graphics) { /* Get graphics going */ init_graphics("VPR: Versatile Place and Route for FPGAs"); alloc_draw_structs (); } fflush (stdout); place_and_route (operation, placer_opts, place_file, net_file, arch_file, route_file, full_stats, verify_binary_search, annealing_sched, router_opts, det_routing_arch, segment_inf, timing_inf, &subblock_data, chan_width_dist); if (show_graphics) close_graphics(); /* Close down X Display */ exit (0);}static void parse_command (int argc, char *argv[], char *net_file, char *arch_file, char *place_file, char *route_file, enum e_operation *operation, float *aspect_ratio, boolean *full_stats, boolean *user_sized, boolean *verify_binary_search, int *gr_automode, boolean *show_graphics, struct s_annealing_sched *annealing_sched, struct s_placer_opts *placer_opts, struct s_router_opts *router_opts, boolean *timing_analysis_enabled, float *constant_net_delay) { /* Parse the command line to get the input and output files and options. */ int i; int seed; boolean do_one_nonlinear_place, bend_cost_set, base_cost_type_set; /* Set the defaults. If the user specified an option on the command * * line, the corresponding default is overwritten. */ seed = 1; /* Flag to check if place_chan_width has been specified. */ do_one_nonlinear_place = FALSE; bend_cost_set = FALSE; base_cost_type_set = FALSE; /* Allows me to see if nx and or ny have been set. */ nx = 0; ny = 0; *operation = PLACE_AND_ROUTE; annealing_sched->type = AUTO_SCHED; annealing_sched->inner_num = 10.; annealing_sched->init_t = 100.; annealing_sched->alpha_t = 0.8; annealing_sched->exit_t = 0.01; placer_opts->place_algorithm = PATH_TIMING_DRIVEN_PLACE; placer_opts->timing_tradeoff = 0.5; placer_opts->block_dist = 1; placer_opts->place_cost_exp = 1.; placer_opts->place_cost_type = LINEAR_CONG; placer_opts->num_regions = 4; /* Really 4 x 4 array */ placer_opts->place_freq = PLACE_ONCE; placer_opts->place_chan_width = 100; /* Reduces roundoff for lin. cong. */ placer_opts->pad_loc_type = FREE; placer_opts->pad_loc_file[0] = '\0'; placer_opts->recompute_crit_iter = 1; /*re-timing-analyze circuit at every temperature*/ placer_opts->enable_timing_computations = FALSE; placer_opts->inner_loop_recompute_divider = 0; /*0 acts a a flag indicating that *no inner loop recomputes be done*/ placer_opts->td_place_exp_first = 1; /*exponentiation starts at 1 */ placer_opts->td_place_exp_last = 8; /*experimental results indicate 8 is good*//* Old values for breadth first router: first_iter_pres_fac = 0, * * pres_fac_mult = 2, acc_fac = 0.2. */ router_opts->router_algorithm = TIMING_DRIVEN; router_opts->first_iter_pres_fac = 0.5; router_opts->initial_pres_fac = 0.5; router_opts->pres_fac_mult = 2; router_opts->acc_fac = 1; router_opts->base_cost_type = DEMAND_ONLY; router_opts->bend_cost = 1.; router_opts->max_router_iterations = 30; router_opts->bb_factor = 3; router_opts->route_type = DETAILED; router_opts->fixed_channel_width = NO_FIXED_CHANNEL_WIDTH; router_opts->astar_fac = 1.2; router_opts->max_criticality = 0.99; router_opts->criticality_exp = 1.; *timing_analysis_enabled = TRUE; *aspect_ratio = 1.; *full_stats = FALSE; *user_sized = FALSE; *verify_binary_search = FALSE; *show_graphics = TRUE; *gr_automode = 1; /* Wait for user input only after MAJOR updates. */ *constant_net_delay = -1;/* Start parsing the command line. First four arguments are not * * optional. */ if (argc < 5) { printf("Usage: vpr circuit.net fpga.arch placed.out routed.out " "[Options ...]\n\n"); printf("General Options: [-nodisp] [-auto <int>] [-route_only]\n"); printf("\t[-place_only] [-timing_analyze_only_with_net_delay <float>]\n"); printf("\t[-aspect_ratio <float>] [-nx <int>] [-ny <int>] [-fast]\n"); printf("\t[-full_stats] [-timing_analysis on | off]\n"); printf("\nPlacer Options: \n"); printf("\t[-place_algorithm bounding_box | net_timing_driven | path_timing_driven]\n"); printf("\t[-init_t <float>] [-exit_t <float>]\n"); printf("\t[-alpha_t <float>] [-inner_num <float>] [-seed <int>]\n"); printf("\t[-place_cost_exp <float>] [-place_cost_type linear | " "nonlinear]\n"); printf("\t[-place_chan_width <int>] [-num_regions <int>] \n"); printf("\t[-fix_pins random | <file.pads>]\n"); printf("\t[-enable_timing_computations on | off]\n"); printf("\t[-block_dist <int>]\n"); printf("\nPlacement Options Valid Only for Timing-Driven Placement:\n"); printf("\t[-timing_tradeoff <float>]\n"); printf("\t[-recompute_crit_iter <int>]\n"); printf("\t[-inner_loop_recompute_divider <int>]\n"); printf("\t[-td_place_exp_first <float>]\n"); printf("\t[-td_place_exp_last <float>]\n"); printf("\nRouter Options: [-max_router_iterations <int>] " "[-bb_factor <int>]\n"); printf("\t[-initial_pres_fac <float>] [-pres_fac_mult <float>]\n" "\t[-acc_fac <float>] [-first_iter_pres_fac <float>]\n" "\t[-bend_cost <float>] [-route_type global | detailed]\n" "\t[-verify_binary_search] [-route_chan_width <int>]\n" "\t[-router_algorithm breadth_first | timing_driven]\n" "\t[-base_cost_type intrinsic_delay | delay_normalized | " "demand_only]\n"); printf ("\nRouting options valid only for timing-driven routing:\n" "\t[-astar_fac <float>] [-max_criticality <float>]\n" "\t[-criticality_exp <float>]\n\n"); exit(1); } strncpy(net_file,argv[1],BUFSIZE); strncpy(arch_file,argv[2],BUFSIZE); strncpy(place_file,argv[3],BUFSIZE); strncpy(route_file,argv[4],BUFSIZE); i = 5;/* Now get any optional arguments. */ while (i < argc) { if (strcmp(argv[i],"-aspect_ratio") == 0) { *aspect_ratio = read_float_option (argc, argv, i); if (*aspect_ratio <= 0.) { printf("Error: Aspect ratio must be > 0.\n"); exit(1); } i += 2; continue; } if (strcmp(argv[i],"-nodisp") == 0) { *show_graphics = FALSE; i++; continue; } if (strcmp(argv[i],"-auto") == 0) { *gr_automode = read_int_option (argc, argv, i); if ((*gr_automode > 2) || (*gr_automode < 0)) { printf("Error: -auto value must be between 0 and 2.\n"); exit(1); } i += 2; continue; } if (strcmp(argv[i],"-recompute_crit_iter") == 0) { placer_opts->recompute_crit_iter = read_int_option (argc, argv, i); if (placer_opts->recompute_crit_iter < 1) { printf("Error: -recompute_crit_iter must be 1 or more \n"); exit (1); } i += 2; continue; } if (strcmp(argv[i],"-inner_loop_recompute_divider") == 0) { placer_opts->inner_loop_recompute_divider = read_int_option (argc, argv, i); if (placer_opts->inner_loop_recompute_divider < 1) { printf("Error: -inner_loop_recompute_divider must be 1 or more \n"); exit (1); } i += 2; continue; } if (strcmp(argv[i],"-fix_pins") == 0) { if (argc <= i+1) { printf("Error: -fix_pins option requires a string parameter.\n"); exit (1); } if (strcmp(argv[i+1], "random") == 0) { placer_opts->pad_loc_type = RANDOM; } else { placer_opts->pad_loc_type = USER; strncpy (placer_opts->pad_loc_file, argv[i+1], BUFSIZE); } i += 2; continue; } if (strcmp(argv[i],"-full_stats") == 0) { *full_stats = TRUE; i += 1; continue; } if (strcmp(argv[i],"-nx") == 0) { nx = read_int_option (argc, argv, i); *user_sized = TRUE; if (nx <= 0) { printf("Error: -nx value must be greater than 0.\n"); exit(1); } i += 2; continue; } if (strcmp(argv[i],"-ny") == 0) { ny = read_int_option (argc, argv, i); *user_sized = TRUE; if (ny <= 0) { printf("Error: -ny value must be greater than 0.\n"); exit(1); } i += 2; continue; } if (strcmp(argv[i],"-fast") == 0) { /* Set all parameters for fast compile. */ annealing_sched->inner_num = 1; router_opts->first_iter_pres_fac = 10000; router_opts->initial_pres_fac = 10000; router_opts->bb_factor = 0; router_opts->max_router_iterations = 10; i++; continue; } if (strcmp (argv[i],"-timing_analysis") == 0) { if (argc <= i+1) { printf ("Error: -timing_analysis option requires a string " "parameter.\n"); exit (1); } if (strcmp(argv[i+1], "on") == 0) { *timing_analysis_enabled = TRUE; } else if (strcmp(argv[i+1], "off") == 0) { *timing_analysis_enabled = FALSE; } else { printf("Error: -timing_analysis must be on or off.\n"); exit (1); } i += 2; continue; } if (strcmp(argv[i],"-timing_analyze_only_with_net_delay") == 0) { *operation = TIMING_ANALYSIS_ONLY; *constant_net_delay = read_float_option (argc, argv, i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -