| #include <stdio.h> | |
| #include <assert.h> | |
| #include <string.h> | |
| #include "read_xml_arch_file.h" | |
| #include "util.h" | |
| #include "vpr_types.h" | |
| #include "globals.h" | |
| #include "prepack.h" | |
| #include "pack.h" | |
| #include "read_blif.h" | |
| #include "cluster.h" | |
| #include "output_clustering.h" | |
| #include "ReadOptions.h" | |
| /* #define DUMP_PB_GRAPH 1 */ | |
| /* #define DUMP_BLIF_INPUT 1 */ | |
| static boolean *alloc_and_load_is_clock(boolean global_clocks); | |
| void try_pack(INP struct s_packer_opts *packer_opts, INP const t_arch * arch, | |
| INP t_model *user_models, INP t_model *library_models, t_timing_inf timing_inf, float interc_delay) { | |
| boolean *is_clock; | |
| int num_models; | |
| t_model *cur_model; | |
| t_pack_patterns *list_of_packing_patterns; | |
| int num_packing_patterns; | |
| t_pack_molecule *list_of_pack_molecules, * cur_pack_molecule; | |
| int num_pack_molecules; | |
| vpr_printf(TIO_MESSAGE_INFO, "Begin packing '%s'.\n", packer_opts->blif_file_name); | |
| /* determine number of models in the architecture */ | |
| num_models = 0; | |
| cur_model = user_models; | |
| while (cur_model) { | |
| num_models++; | |
| cur_model = cur_model->next; | |
| } | |
| cur_model = library_models; | |
| while (cur_model) { | |
| num_models++; | |
| cur_model = cur_model->next; | |
| } | |
| is_clock = alloc_and_load_is_clock(packer_opts->global_clocks); | |
| vpr_printf(TIO_MESSAGE_INFO, "\n"); | |
| vpr_printf(TIO_MESSAGE_INFO, "After removing unused inputs...\n"); | |
| vpr_printf(TIO_MESSAGE_INFO, "\ttotal blocks: %d, total nets: %d, total inputs: %d, total outputs: %d\n", | |
| num_logical_blocks, num_logical_nets, num_p_inputs, num_p_outputs); | |
| vpr_printf(TIO_MESSAGE_INFO, "Begin prepacking.\n"); | |
| list_of_packing_patterns = alloc_and_load_pack_patterns( | |
| &num_packing_patterns); | |
| list_of_pack_molecules = alloc_and_load_pack_molecules( | |
| list_of_packing_patterns, num_packing_patterns, | |
| &num_pack_molecules); | |
| vpr_printf(TIO_MESSAGE_INFO, "Finish prepacking.\n"); | |
| if(packer_opts->auto_compute_inter_cluster_net_delay) { | |
| packer_opts->inter_cluster_net_delay = interc_delay; | |
| vpr_printf(TIO_MESSAGE_INFO, "Using inter-cluster delay: %g\n", packer_opts->inter_cluster_net_delay); | |
| } | |
| /* Uncomment line below if you want a dump of compressed netlist. */ | |
| /* if (getEchoEnabled()){ | |
| echo_input (packer_opts->blif_file_name, packer_opts->lut_size, "packed.echo"); | |
| }else; */ | |
| if (packer_opts->skip_clustering == FALSE) { | |
| do_clustering(arch, list_of_pack_molecules, num_models, | |
| packer_opts->global_clocks, is_clock, | |
| packer_opts->hill_climbing_flag, packer_opts->output_file, | |
| packer_opts->timing_driven, packer_opts->cluster_seed_type, | |
| packer_opts->alpha, packer_opts->beta, | |
| packer_opts->recompute_timing_after, packer_opts->block_delay, | |
| packer_opts->intra_cluster_net_delay, | |
| packer_opts->inter_cluster_net_delay, packer_opts->aspect, | |
| packer_opts->allow_unrelated_clustering, | |
| packer_opts->allow_early_exit, packer_opts->connection_driven, | |
| packer_opts->packer_algorithm, timing_inf); | |
| } else { | |
| vpr_printf(TIO_MESSAGE_ERROR, "Skip clustering no longer supported.\n"); | |
| exit(1); | |
| } | |
| free(is_clock); | |
| /*free list_of_pack_molecules*/ | |
| free_list_of_pack_patterns(list_of_packing_patterns, num_packing_patterns); | |
| cur_pack_molecule = list_of_pack_molecules; | |
| while (cur_pack_molecule != NULL){ | |
| if (cur_pack_molecule->logical_block_ptrs != NULL) | |
| free(cur_pack_molecule->logical_block_ptrs); | |
| cur_pack_molecule = list_of_pack_molecules->next; | |
| free(list_of_pack_molecules); | |
| list_of_pack_molecules = cur_pack_molecule; | |
| } | |
| vpr_printf(TIO_MESSAGE_INFO, "\n"); | |
| vpr_printf(TIO_MESSAGE_INFO, "Netlist conversion complete.\n"); | |
| vpr_printf(TIO_MESSAGE_INFO, "\n"); | |
| } | |
| float get_switch_info(short switch_index, float &Tdel_switch, float &R_switch, float &Cout_switch) { | |
| /* Fetches delay, resistance and output capacitance of the switch at switch_index. | |
| Returns the total delay through the switch. Used to calculate inter-cluster net delay. */ | |
| Tdel_switch = switch_inf[switch_index].Tdel; /* Delay when unloaded */ | |
| R_switch = switch_inf[switch_index].R; | |
| Cout_switch = switch_inf[switch_index].Cout; | |
| /* The delay through a loaded switch is its intrinsic (unloaded) | |
| delay plus the product of its resistance and output capacitance. */ | |
| return Tdel_switch + R_switch * Cout_switch; | |
| } | |
| boolean *alloc_and_load_is_clock(boolean global_clocks) { | |
| /* Looks through all the logical_block to find and mark all the clocks, by setting * | |
| * the corresponding entry in is_clock to true. global_clocks is used * | |
| * only for an error check. */ | |
| int num_clocks, bnum, clock_net; | |
| boolean * is_clock; | |
| num_clocks = 0; | |
| is_clock = (boolean *) my_calloc(num_logical_nets, sizeof(boolean)); | |
| /* Want to identify all the clock nets. */ | |
| for (bnum = 0; bnum < num_logical_blocks; bnum++) { | |
| if (logical_block[bnum].type == VPACK_LATCH) { | |
| clock_net = logical_block[bnum].clock_net; | |
| assert(clock_net != OPEN); | |
| if (is_clock[clock_net] == FALSE) { | |
| is_clock[clock_net] = TRUE; | |
| num_clocks++; | |
| } | |
| } else { | |
| if (logical_block[bnum].clock_net != OPEN) { | |
| clock_net = logical_block[bnum].clock_net; | |
| if (is_clock[clock_net] == FALSE) { | |
| is_clock[clock_net] = TRUE; | |
| num_clocks++; | |
| } | |
| } | |
| } | |
| } | |
| /* If we have multiple clocks and we're supposed to declare them global, * | |
| * print a warning message, since it looks like this circuit may have * | |
| * locally generated clocks. */ | |
| if (num_clocks > 1 && global_clocks) { | |
| vpr_printf(TIO_MESSAGE_WARNING, "Circuit contains %d clocks. All clocks will be marked global.\n", num_clocks); | |
| } | |
| return (is_clock); | |
| } | |