OpenFPGA/vpr7_x2p/vpr/SRC/pack/pack.c

166 lines
5.7 KiB
C

#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);
}