📄 output_clustering.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "util.h"#include "vpack.h"#include "globals.h"#include "output_clustering.h"#define LINELENGTH 80/****************** Subroutines local to this module ************************/static void print_subblock_ipin (int inet, int *io_net_mapping, int inputs_per_cluster, int cluster_size, int *column_ptr, FILE *fpout); static void print_subblock_opin (int inet, int *io_net_mapping, int inputs_per_cluster, int *net_of_clb_pin, int *column_ptr, FILE *fpout, boolean muxes_to_cluster_output_pins); /**************** Subroutine definitions ************************************/static void print_string (char *str_ptr, int *column, FILE *fpout) {/* Prints string without making any lines longer than LINELENGTH. Column * * points to the column in which the next character will go (both used and * * updated), and fpout points to the output file. */ int len; len = strlen(str_ptr); if (len + 3 > LINELENGTH) { printf("Error in print_string: String %s is too long for desired\n" "maximum line length.\n", str_ptr); exit(1); } if (*column + len + 2 > LINELENGTH) { fprintf(fpout,"\\\n"); *column = 1; } fprintf(fpout,"%s ",str_ptr); *column += len + 1;}static void print_net_name (int inet, int *column, FILE *fpout) {/* This routine prints out the net name (or open) and limits the * * length of a line to LINELENGTH characters by using \ to continue * * lines. net_num is the index of the net to be printed, while * * column points to the current printing column (column is both * * used and updated by this routine). fpout is the output file * * pointer. */ char *str_ptr; if (inet == OPEN) str_ptr = "open"; else str_ptr = net[inet].name; print_string (str_ptr, column, fpout);}static void print_net_number (int inet, int *column, FILE *fpout) {/* Prints out either a number or "open". */ char str[BUFSIZE]; if (inet == OPEN) sprintf (str, "open"); else sprintf (str, "%d", inet); print_string (str, column, fpout);}static void print_pins (FILE *fpout, int bnum, int lut_size) {/* This routine is used only for netlists that have NOT been clustered. * * It prints out the pinlist for a clb that contains either a LUT, a * * LATCH or both, assuming that each LUT input needs its own pin, and * * the output cannot be fed back to inputs via local routing. It prints * * the LUT inputs and output in the order below so that the net ordering * * when parsed will be the same as that of the old combinational blif * * parsing in vpr. This allows the routing serial numbers to be compared.*/ int ipin, column, netnum; fprintf(fpout,"pinlist: "); column = 10; /* Next column I will write to. */ /* LUT inputs first. */ for (ipin=1;ipin<=lut_size;ipin++) { netnum = block[bnum].nets[ipin]; print_net_name (netnum, &column, fpout); } /* Output next. */ netnum = block[bnum].nets[0]; print_net_name (netnum, &column, fpout); /* Clock last. */ netnum = block[bnum].nets[lut_size+1]; print_net_name (netnum, &column, fpout); fprintf(fpout,"\n");}static void print_basic_subblock (FILE *fpout, int bnum, int lut_size) {/* Prints out the subblock connectivity. Used only when * * the -no_clustering option is selected -- prints out * * basically redundant connection info for a LUT + FF * * logic block. */ int inet, ipin, column; fprintf(fpout, "subblock: "); column = 11; print_string (block[bnum].name, &column, fpout); for (ipin=1;ipin<=lut_size;ipin++) { /* Inputs first. */ inet = block[bnum].nets[ipin]; if (inet == OPEN) print_net_number (OPEN, &column, fpout); else print_net_number (ipin-1, &column, fpout); } print_net_number (lut_size, &column, fpout); /* Output next */ inet = block[bnum].nets[lut_size+1]; if (inet == OPEN) print_net_number (OPEN, &column, fpout); else print_net_number (lut_size+1, &column, fpout); fprintf (fpout, "\n\n");}static void print_clbs (FILE *fpout, int *cluster_occupancy, int **cluster_contents, int lut_size, int cluster_size, int inputs_per_cluster, int clocks_per_cluster, int num_clusters, boolean muxes_to_cluster_output_pins) {/* Prints out one cluster (clb). Both the external pins and the * * internal connections are printed out. */ int ipin, icluster, sub_blk, num_clb_pins, inet, free_pin_index; int column, iblk; int redundant_outputs, used_outputs, total_used_ble_inputs; int total_locally_generated_ble_inputs, total_bles;/* [0..num_nets-1]. Which clb pin connects to this net? Need * * separate data structures for input or output pins and clocks, * * because a clock net could connect to both a clb output and a * * clock input. */ int *io_net_mapping, *clock_net_mapping, *num_pins_in_cluster;/* [0..num_cluster_pins]. Net connected to this clb pin. */ int *net_of_clb_pin; io_net_mapping = (int *) my_malloc (num_nets * sizeof (int)); clock_net_mapping = (int *) my_malloc (num_nets * sizeof (int)); num_pins_in_cluster = (int *) my_malloc (num_nets * sizeof (int)); for (inet=0;inet<num_nets;inet++) { io_net_mapping[inet] = OPEN; clock_net_mapping[inet] = OPEN; num_pins_in_cluster[inet] = 0; }/* Counters used only for statistics purposes. */ redundant_outputs = 0; total_used_ble_inputs = 0; total_locally_generated_ble_inputs = 0; num_clb_pins = inputs_per_cluster + cluster_size + clocks_per_cluster; net_of_clb_pin = my_malloc (num_clb_pins * sizeof(int)); for (ipin=0;ipin<num_clb_pins;ipin++) net_of_clb_pin[ipin] = OPEN; for (icluster=0;icluster<num_clusters;icluster++) {/* First I have to get a list of the pins that have to be routed to * * this cluster's inputs. Also need to know which pin will supply * * each net needed by the LUTs of this cluster. Start with the * * cluster output nets, as nets generated in the cluster don't need * * to be routed here as inputs. */ for (iblk=0;iblk<cluster_occupancy[icluster];iblk++) { sub_blk = cluster_contents[icluster][iblk]; inet = block[sub_blk].nets[0]; /* Output */ net_of_clb_pin[inputs_per_cluster + iblk] = inet; if (io_net_mapping[inet] != OPEN) { printf("Error in print_clbs. Net #%d (%s) in cluster %d\n", inet, net[inet].name, icluster); printf("appears to be driven by two outputs.\n"); exit (1); } io_net_mapping[inet] = inputs_per_cluster + iblk; num_pins_in_cluster[inet]++; } /* Now do the input pins. */ free_pin_index = 0; for (iblk=0;iblk<cluster_occupancy[icluster];iblk++) { sub_blk = cluster_contents[icluster][iblk]; for (ipin=1;ipin<=lut_size;ipin++) { inet = block[sub_blk].nets[ipin]; if (inet != OPEN) { num_pins_in_cluster[inet]++; total_used_ble_inputs++; /* Used LUT inputs;doesn't include clk */ if (io_net_mapping[inet] == OPEN) { /* Must get from CLB IPIN */ io_net_mapping[inet] = free_pin_index; net_of_clb_pin[free_pin_index] = inet; free_pin_index++; } else if (io_net_mapping[inet] >= inputs_per_cluster) { /* Input is locally generated (output of a BLE). */ total_locally_generated_ble_inputs++; } } } } if (free_pin_index > inputs_per_cluster) { printf("Error in print_clbs: cluster %d has %d input pins.\n", icluster, free_pin_index); exit (1); }/* Now do the clocks. */ free_pin_index = inputs_per_cluster + cluster_size; for (iblk=0;iblk<cluster_occupancy[icluster];iblk++) { sub_blk = cluster_contents[icluster][iblk]; inet = block[sub_blk].nets[lut_size + 1]; if (inet != OPEN) {/* No internal output - clock connection, so don't increment num_pins_in * * _cluster so that I can guarantee that all clock inputs and outputs * * that generate clocks do come out to the cluster pins. */ if (clock_net_mapping[inet] == OPEN) { clock_net_mapping[inet] = free_pin_index; net_of_clb_pin[free_pin_index] = inet; free_pin_index++; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -