16 #define LINELENGTH 1024
25 for (i = 0; i < num_tabs; i++) {
30 static void print_string(
const char *str_ptr,
int *column,
int num_tabs, FILE * fpout) {
38 len = strlen(str_ptr);
40 vpr_printf(TIO_MESSAGE_ERROR,
"in print_string: String %s is too long for desired maximum line length.\n", str_ptr);
50 fprintf(fpout,
"%s ", str_ptr);
54 static void print_net_name(
int inet,
int *column,
int num_tabs, FILE * fpout) {
84 int prev_node, prev_edge;
95 &&
rr_node[inode].pb_graph_pin->port->parent_pb_type->num_modes
102 if (
rr_node[prev_node].pb_graph_pin->port->parent_pb_type->depth
107 rr_node[prev_node].pb_graph_pin->parent_node->pb_type->name)
111 rr_node[prev_node].pb_graph_pin->port->name)
113 / 10 + strlen(name) + 11;
114 str_ptr = (
char*)
my_malloc(len *
sizeof(
char));
115 sprintf(str_ptr,
"%s[%d].%s[%d]->%s ",
116 rr_node[prev_node].pb_graph_pin->parent_node->pb_type->name,
123 rr_node[prev_node].pb_graph_pin->parent_node->pb_type->name)
125 rr_node[prev_node].pb_graph_pin->port->name)
127 / 10 + strlen(name) + 8;
128 str_ptr = (
char*)
my_malloc(len *
sizeof(
char));
129 sprintf(str_ptr,
"%s.%s[%d]->%s ",
130 rr_node[prev_node].pb_graph_pin->parent_node->pb_type->name,
142 int pb_index,
boolean is_used,
int tab_depth, FILE * fpout) {
145 const t_pb_type * pb_type, *child_pb_type;
147 int prev_edge, prev_node;
149 int mode_of_edge, port_index, node_index;
153 pb_type = pb_graph_node->
pb_type;
160 for (i = 0; i < pb_type->
num_ports; i++) {
174 mode == NULL || &pb_type->
modes[mode_of_edge] == mode);
175 mode = &pb_type->
modes[mode_of_edge];
182 assert(mode != NULL && mode_of_edge !=
UNDEFINED);
184 "<block name=\"open\" instance=\"%s[%d]\" mode=\"%s\">\n",
188 fprintf(fpout,
"\t<inputs>\n");
190 for (i = 0; i < pb_type->
num_ports; i++) {
194 fprintf(fpout,
"\t\t<port name=\"%s\">",
202 fprintf(fpout,
"</port>\n");
207 fprintf(fpout,
"\t</inputs>\n");
211 fprintf(fpout,
"\t<outputs>\n");
213 for (i = 0; i < pb_type->
num_ports; i++) {
216 fprintf(fpout,
"\t\t<port name=\"%s\">",
225 fprintf(fpout,
"</port>\n");
230 fprintf(fpout,
"\t</outputs>\n");
232 column = tab_depth * TAB_LENGTH + 8;
234 fprintf(fpout,
"\t<clocks>\n");
236 for (i = 0; i < pb_type->
num_ports; i++) {
240 fprintf(fpout,
"\t\t<port name=\"%s\">",
248 fprintf(fpout,
"</port>\n");
253 fprintf(fpout,
"\t</clocks>\n");
261 for (k = 0; k < child_pb_type->
num_ports && !is_used; k++) {
277 j, is_used, tab_depth + 1, fpout);
283 fprintf(fpout,
"</block>\n");
285 fprintf(fpout,
"<block name=\"open\" instance=\"%s[%d]\"/>\n",
290 static void print_pb(FILE *fpout,
t_pb * pb,
int pb_index,
int tab_depth) {
294 const t_pb_type *pb_type, *child_pb_type;
297 int port_index, node_index;
306 fprintf(fpout,
"<block name=\"%s\" instance=\"%s[%d]\">\n", pb->
name,
307 pb_type->
name, pb_index);
309 fprintf(fpout,
"<block name=\"%s\" instance=\"%s[%d]\" mode=\"%s\">\n",
314 fprintf(fpout,
"\t<inputs>\n");
316 for (i = 0; i < pb_type->
num_ports; i++) {
319 fprintf(fpout,
"\t\t<port name=\"%s\">",
332 fprintf(fpout,
"</port>\n");
337 fprintf(fpout,
"\t</inputs>\n");
339 column = tab_depth * TAB_LENGTH + 8;
341 fprintf(fpout,
"\t<outputs>\n");
343 for (i = 0; i < pb_type->
num_ports; i++) {
347 fprintf(fpout,
"\t\t<port name=\"%s\">",
354 fprintf(fpout,
"</port>\n");
359 fprintf(fpout,
"\t</outputs>\n");
361 column = tab_depth * TAB_LENGTH + 8;
363 fprintf(fpout,
"\t<clocks>\n");
365 for (i = 0; i < pb_type->
num_ports; i++) {
368 fprintf(fpout,
"\t\t<port name=\"%s\">",
381 fprintf(fpout,
"</port>\n");
386 fprintf(fpout,
"\t</clocks>\n");
400 for (k = 0; k < child_pb_type->
num_ports && !is_used; k++) {
416 j, is_used, tab_depth + 1, fpout);
422 fprintf(fpout,
"</block>\n");
432 for (icluster = 0; icluster < num_clusters; icluster++) {
437 print_pb(fpout, clb[icluster].pb, icluster, 1);
446 int ipin, icluster, itype, inet;
448 int total_nets_absorbed;
449 boolean * nets_absorbed;
451 int *num_clb_types, *num_clb_inputs_used, *num_clb_outputs_used;
453 nets_absorbed = NULL;
454 num_clb_types = num_clb_inputs_used = num_clb_outputs_used = NULL;
463 nets_absorbed[inet] =
TRUE;
470 unabsorbable_ffs = 0;
482 vpr_printf(TIO_MESSAGE_INFO,
"%d FFs in input netlist not absorbable (ie. impossible to form BLE).\n", unabsorbable_ffs);
487 for (icluster = 0; icluster < num_clusters; icluster++) {
488 for (ipin = 0; ipin < clb[icluster].
type->
num_pins; ipin++) {
489 if (clb[icluster].nets[ipin] !=
OPEN) {
490 nets_absorbed[clb[icluster].
nets[ipin]] =
FALSE;
493 num_clb_inputs_used[clb[icluster].
type->
index]++;
494 }
else if (clb[icluster].type->class_inf[clb[icluster].
type->
pin_class[ipin]].
type
496 num_clb_outputs_used[clb[icluster].
type->
index]++;
500 num_clb_types[clb[icluster].
type->
index]++;
503 for (itype = 0; itype <
num_types; itype++) {
504 if (num_clb_types[itype] == 0) {
505 vpr_printf(TIO_MESSAGE_INFO,
"\t%s: # blocks: %d, average # input + clock pins used: %g, average # output pins used: %g\n",
508 vpr_printf(TIO_MESSAGE_INFO,
"\t%s: # blocks: %d, average # input + clock pins used: %g, average # output pins used: %g\n",
510 (
float) num_clb_inputs_used[itype] / (
float) num_clb_types[itype],
511 (
float) num_clb_outputs_used[itype] / (
float) num_clb_types[itype]);
515 total_nets_absorbed = 0;
517 if (nets_absorbed[inet] ==
TRUE) {
518 total_nets_absorbed++;
521 vpr_printf(TIO_MESSAGE_INFO,
"Absorbed logical nets %d out of %d nets, %d nets not absorbed.\n",
522 total_nets_absorbed, num_logical_nets, num_logical_nets - total_nets_absorbed);
525 free(num_clb_inputs_used);
526 free(num_clb_outputs_used);
531 boolean * is_clock,
char *out_fname,
boolean skip_clustering) {
539 int bnum, netnum, column;
541 fpout = fopen(out_fname,
"w");
543 fprintf(fpout,
"<block name=\"%s\" instance=\"FPGA_packed_netlist[0]\">\n",
545 fprintf(fpout,
"\t<inputs>\n\t\t");
553 fprintf(fpout,
"\n\t</inputs>\n");
554 fprintf(fpout,
"\n\t<outputs>\n\t\t");
562 fprintf(fpout,
"\n\t</outputs>\n");
566 fprintf(fpout,
"\n\t<clocks>\n\t\t");
569 if (is_clock[netnum]) {
573 fprintf(fpout,
"\n\t</clocks>\n\n");
584 if (skip_clustering) {
590 vpr_printf(TIO_MESSAGE_ERROR,
"in output_netlist: logical_block %d is VPACK_EMPTY.\n",
596 vpr_printf(TIO_MESSAGE_ERROR,
"in output_netlist: Unexpected type %d for logical_block %d.\n",
601 if (skip_clustering ==
FALSE)
604 fprintf(fpout,
"</block>\n\n");
t_pb_graph_pin ** clock_pins
static void print_interconnect(int inode, int *column, int num_tabs, FILE *fpout)
static void print_clusters(t_block *clb, int num_clusters, FILE *fpout)
struct s_pb_type * pb_type_children
struct s_rr_node * rr_graph
struct s_pb_graph_edge ** output_edges
static void print_string(const char *str_ptr, int *column, int num_tabs, FILE *fpout)
void * my_calloc(size_t nelem, size_t size)
t_pb_graph_pin ** output_pins
static void print_stats(t_block *clb, int num_clusters)
t_interconnect * interconnect
static void * my_malloc(int ibytes)
void output_clustering(t_block *clb, int num_clusters, boolean global_clocks, boolean *is_clock, char *out_fname, boolean skip_clustering)
static void print_pb(FILE *fpout, t_pb *pb, int pb_index, int tab_depth)
struct s_pb_graph_node * parent_node
struct s_pb_graph_node *** child_pb_graph_nodes
static void print_open_pb_graph_node(t_pb_graph_node *pb_graph_node, int pb_index, boolean is_used, int tab_depth, FILE *fpout)
struct s_pb_type * pb_type
struct s_pb_type * parent_pb_type
t_pb_graph_pin * pb_graph_pin
struct s_type_descriptor * type_descriptors
static void print_tabs(FILE *fpout, int num_tabs)
static void print_net_name(int inet, int *column, int num_tabs, FILE *fpout)
t_pb_graph_node * pb_graph_node
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block