📄 output_clustering.c
字号:
if (free_pin_index > num_clb_pins) { printf("Error in print_clbs: cluster %d has %d clock pins.\n", icluster, free_pin_index - inputs_per_cluster - cluster_size); exit (1); }/* Remove all nets that are now routed completely within the cluster from * * the cluster input/output pins. */ for (ipin=0;ipin<num_clb_pins;ipin++) { inet = net_of_clb_pin[ipin]; if (inet != OPEN) { if (num_pins_in_cluster[inet] == net[inet].num_pins) { net_of_clb_pin[ipin] = OPEN; /* Remove. */ redundant_outputs++; if (ipin < inputs_per_cluster || ipin >= inputs_per_cluster + cluster_size) { printf("Error in print_clbs: cluster %d pin %d is not an\n", icluster, ipin); printf("output, but it has been marked as a net that doesn't\n"); printf("fanout, and will be removed. Net #%d (%s)\n", inet, net[inet].name); exit (1); } } } }/* Do the actual printout. *//* Name clb (arbitrarily) after the first block it contains. */ fprintf (fpout,".clb %s\n", block[cluster_contents[icluster][0]].name); fprintf(fpout,"pinlist: "); column = 10; /* Next column I will write to. */ for (ipin=0;ipin<num_clb_pins;ipin++) print_net_name (net_of_clb_pin[ipin], &column, fpout); fprintf(fpout, "\n"); for (iblk=0;iblk<cluster_occupancy[icluster];iblk++) { sub_blk = cluster_contents[icluster][iblk]; fprintf(fpout,"subblock: "); column = 11; print_string (block[sub_blk].name, &column, fpout); for (ipin=1;ipin<=lut_size;ipin++) { /* Inputs first. */ inet = block[sub_blk].nets[ipin]; print_subblock_ipin (inet, io_net_mapping, inputs_per_cluster, cluster_size, &column, fpout); } inet = block[sub_blk].nets[0]; /* Output */ print_subblock_opin (inet, io_net_mapping, inputs_per_cluster, net_of_clb_pin, &column, fpout, muxes_to_cluster_output_pins); inet = block[sub_blk].nets[lut_size+1]; /* Clock */ print_subblock_ipin (inet, clock_net_mapping, inputs_per_cluster, cluster_size, &column, fpout); fprintf(fpout, "\n"); } fprintf (fpout, "\n"); /* Reset the data structures in order to do the next cluster. */ for (iblk=0;iblk<cluster_occupancy[icluster];iblk++) { sub_blk = cluster_contents[icluster][iblk]; for (ipin=0;ipin<=lut_size;ipin++) { inet = block[sub_blk].nets[ipin]; if (inet != OPEN) { io_net_mapping[inet] = OPEN; num_pins_in_cluster[inet] = 0; } } inet = block[sub_blk].nets[lut_size+1]; /* Clock */ if (inet != OPEN) clock_net_mapping[inet] = OPEN; } for (ipin=0;ipin<num_clb_pins;ipin++) net_of_clb_pin[ipin] = OPEN; } used_outputs = num_blocks - num_p_inputs - num_p_outputs - redundant_outputs; total_bles = num_blocks - num_p_inputs - num_p_outputs; printf("\nAverage number of cluster outputs used outside cluster: %f\n", (float) used_outputs / (float) num_clusters); printf("Fraction outputs made local: %f\n", (float) redundant_outputs / (float) (total_bles)); printf ("Average number of used LUT inputs per BLE (excluding clocks): %f\n", (float) total_used_ble_inputs / (float) total_bles); printf ("Average fraction of BLE (LUT) inputs generated locally: %f\n", (float) total_locally_generated_ble_inputs / (float) total_used_ble_inputs); free (io_net_mapping); free (clock_net_mapping); free (num_pins_in_cluster); free (net_of_clb_pin);}static void print_subblock_ipin (int inet, int *io_net_mapping, int inputs_per_cluster, int cluster_size, int *column_ptr, FILE *fpout) {/* Prints out where a subblock gets its input pin from. */ char str[BUFSIZE]; int ble_num; if (inet == OPEN) { print_net_number (OPEN, column_ptr, fpout); } else if (io_net_mapping[inet] >= inputs_per_cluster && io_net_mapping[inet] < inputs_per_cluster + cluster_size) { /* Subblock input comes from a BLE output within this cluster. */ ble_num = io_net_mapping[inet] - inputs_per_cluster; sprintf (str, "ble_%d", ble_num); print_string (str, column_ptr, fpout); } else { /* Regular input or clock pin */ print_net_number (io_net_mapping[inet], column_ptr, 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) {/* Prints out a subblock output pin. If the net driven by this BLE is used * * only internally to the clb, then the subblock output is marked as OPEN. */ int clb_pin; if (inet == OPEN) { printf ("Error in print_subblock_opin: inet = %d.\n", inet); exit (1);/* print_net_number (OPEN, column_ptr, fpout); */ } else { clb_pin = io_net_mapping[inet]; if (net_of_clb_pin[clb_pin] == OPEN && muxes_to_cluster_output_pins) { /* Output not used outside clb and subblock output not directly * * connected to the CLB output pin. */ print_net_number (OPEN, column_ptr, fpout); } else { print_net_number (clb_pin, column_ptr, fpout); } }}void output_clustering (int **cluster_contents, int *cluster_occupancy, int cluster_size, int inputs_per_cluster, int clocks_per_cluster, int num_clusters, int lut_size, boolean global_clocks, boolean muxes_to_cluster_output_pins, boolean *is_clock, char *out_fname) {/* This routine dumps out the output netlist in a format suitable for * * input to vpr. The clb pins are in the following order: * * inputs_per_cluster inputs, cluster_size outputs, and * * clocks_per_cluster clocks. For a single LUT cluster, this reduces * * to N LUT inputs, 1 output, followed by the clock input. Pins that * * are unconnected are marked as open. If global_clocks is TRUE, all * * the clock nets (nets marked with TRUE in is_clock) will be set to * * be global. This routine also dumps out the internal structure of * * the cluster, in essentially a graph based format. For each LUT + * * FF subblock, I write out which cluster pin connects to each of the * * LUT pins. The LUT + FF pins are ordered as N LUT inputs, LUT * * output, then clock. If a pin is not connected, it is marked as * * OPEN. Otherwise, it is given the number of the cluster pin to * * which it connects -- the cluster pins begin with inputs (starting * * from 0), then list outputs, then clocks. Hence all cluster pins * * have an index from 0 to inputs_per_cluster + cluster_size + * * clocks_per_cluster - 1. * * If cluster_contents is NULL, this routine prints out an unclustered * * netlist -- i.e. it just prints out the LUT+FF logic blocks with all * * pins distint. */ FILE *fpout; int bnum, netnum, column; boolean skip_clustering; if (cluster_contents == NULL) /* No clustering was performed. */ skip_clustering = TRUE; else skip_clustering = FALSE; fpout = my_fopen (out_fname, "w", 0); if (global_clocks) { for (netnum=0;netnum<num_nets;netnum++) { if (is_clock[netnum]) fprintf(fpout,".global %s\n\n", net[netnum].name); } } /* Print out all input and output pads. */ for (bnum=0;bnum<num_blocks;bnum++) { switch (block[bnum].type) { case INPAD: fprintf(fpout,".input %s\n", block[bnum].name); netnum = block[bnum].nets[0]; fprintf(fpout,"pinlist: "); column = 10; print_net_name (netnum, &column, fpout); fprintf (fpout, "\n\n"); break; case OUTPAD: fprintf(fpout,".output %s\n", block[bnum].name); netnum = block[bnum].nets[0]; fprintf(fpout,"pinlist: "); column = 10; print_net_name (netnum, &column, fpout); fprintf (fpout, "\n\n"); break; case LUT: if (skip_clustering) { fprintf(fpout,".clb %s # Only LUT used.\n", block[bnum].name); print_pins (fpout, bnum, lut_size); print_basic_subblock (fpout, bnum, lut_size); } break; case LATCH: if (skip_clustering) { fprintf(fpout,".clb %s # Only LATCH used.\n", block[bnum].name); print_pins (fpout, bnum, lut_size); print_basic_subblock (fpout, bnum, lut_size); } break; case LUT_AND_LATCH: if (skip_clustering) { fprintf(fpout,".clb %s # Both LUT and LATCH used.\n", block[bnum].name); print_pins (fpout, bnum, lut_size); print_basic_subblock (fpout, bnum, lut_size); } break; case EMPTY: printf("Error in output_netlist -- block %d is EMPTY.\n",bnum); exit (1); break; default: printf("Error in output_netlist. Unexpected type %d for block" "%d.\n", block[bnum].type, bnum); } } if (skip_clustering == FALSE) print_clbs (fpout, cluster_occupancy, cluster_contents, lut_size, cluster_size, inputs_per_cluster, clocks_per_cluster, num_clusters, muxes_to_cluster_output_pins); fclose (fpout);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -