VPR-6.0

vpr/SRC/pack/pb_type_graph.c File Reference

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "util.h"
#include "token.h"
#include "arch_types.h"
#include "vpr_types.h"
#include "globals.h"
#include "vpr_utils.h"
#include "pb_type_graph.h"
#include "pb_type_graph_annotations.h"
Include dependency graph for pb_type_graph.c:

Go to the source code of this file.

Functions

static int check_pb_graph ()
static void alloc_and_load_pb_graph (INOUTP t_pb_graph_node *pb_graph_node, INP t_pb_graph_node *parent_pb_graph_node, INP const t_pb_type *pb_type, INP int index)
static void alloc_and_load_mode_interconnect (INOUTP t_pb_graph_node *pb_graph_parent_node, INOUTP t_pb_graph_node **pb_graph_children_nodes, INP const t_mode *mode)
static boolean realloc_and_load_pb_graph_pin_ptrs_at_var (INP const t_pb_graph_node *pb_graph_parent_node, INP t_pb_graph_node **pb_graph_children_nodes, INP boolean interconnect_error_check, INP boolean is_input_to_interc, INP const t_token *tokens, INOUTP int *token_index, INOUTP int *num_pins, OUTP t_pb_graph_pin ***pb_graph_pins)
static t_pb_graph_pinget_pb_graph_pin_from_name (INP const char *port_name, INP const t_pb_graph_node *pb, INP int pin)
static void alloc_and_load_complete_interc_edges (INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)
static void alloc_and_load_direct_interc_edges (INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)
static void alloc_and_load_mux_interc_edges (INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)
static void alloc_and_load_pin_locations_from_pb_graph (t_type_descriptor *type)
static void echo_pb_rec (INP const t_pb_graph_node *pb, INP int level, INP FILE *fp)
static void echo_pb_pins (INP t_pb_graph_pin **pb_graph_pins, INP int num_ports, INP int level, INP FILE *fp)
static void free_pb_graph (INOUTP t_pb_graph_node *pb_graph_node)
void alloc_and_load_all_pb_graphs ()
void free_all_pb_graph_nodes ()
void echo_pb_graph (char *filename)
t_pb_graph_pin *** alloc_and_load_port_pin_ptrs_from_string (INP const t_pb_graph_node *pb_graph_parent_node, INP t_pb_graph_node **pb_graph_children_nodes, INP const char *port_string, OUTP int **num_ptrs, OUTP int *num_sets, INP boolean is_input_to_interc, INP boolean interconnect_error_check)
static void echo_pb_rec (const INP t_pb_graph_node *pb_graph_node, INP int level, INP FILE *fp)

Variables

static int pin_count_in_cluster
static struct s_linked_vptredges_head
static struct s_linked_vptrnum_edges_head

Detailed Description

Jason Luu July 17, 2009 pb_graph creates the internal routing edges that join together the different pb_types modes within a pb_type

Definition in file pb_type_graph.c.


Function Documentation

void alloc_and_load_all_pb_graphs ( )

Allocate memory into types and load the pb graph with interconnect edges

Definition at line 85 of file pb_type_graph.c.

                                     {
        int i, errors;
        edges_head = NULL;
        num_edges_head = NULL;
        for(i = 0; i < num_types; i++) {
                if(type_descriptors[i].pb_type) {
                        pin_count_in_cluster = 0;
                        type_descriptors[i].pb_graph_head = my_calloc(1, sizeof(t_pb_graph_node));
                        alloc_and_load_pb_graph(type_descriptors[i].pb_graph_head, NULL, type_descriptors[i].pb_type, 0);
                        type_descriptors[i].pb_graph_head->total_pb_pins = pin_count_in_cluster;
                        alloc_and_load_pin_locations_from_pb_graph(&type_descriptors[i]);
                } else {
                        type_descriptors[i].pb_graph_head = NULL;
                        assert(&type_descriptors[i] == EMPTY_TYPE);
                }
        }

        errors = check_pb_graph ();
        if(errors > 0) {
                printf("Errors in pb graph");
                exit(1);
        }
        for(i = 0; i < num_types; i++) {
                if(type_descriptors[i].pb_type) {
                        load_pb_graph_pin_to_pin_annotations(type_descriptors[i].pb_graph_head);
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_complete_interc_edges ( INP t_interconnect interconnect,
INOUTP t_pb_graph_pin ***  input_pb_graph_node_pin_ptrs,
INP int  num_input_sets,
INP int *  num_input_ptrs,
INOUTP t_pb_graph_pin ***  output_pb_graph_node_pin_ptrs,
INP int  num_output_sets,
INP int *  num_output_ptrs 
) [static]

Creates edges to connect all input pins to output pins

Definition at line 581 of file pb_type_graph.c.

                                                                                                                           {
        int i_inset, i_outset, i_inpin, i_outpin;
        int in_count, out_count;
        t_pb_graph_edge *edges;
        int i_edge;
        struct s_linked_vptr *cur;


        /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */
        in_count = out_count = 0;
        
        for(i_inset = 0; i_inset < num_input_sets; i_inset++) {
                in_count += num_input_ptrs[i_inset];
        }
        for(i_outset = 0; i_outset < num_output_sets; i_outset++) {
                out_count += num_output_ptrs[i_outset];
        }

        edges = my_calloc(in_count * out_count, sizeof(t_pb_graph_edge));
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = edges_head;
        edges_head = cur;
        cur->data_vptr = (void *)edges;
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = num_edges_head;
        num_edges_head = cur;
        cur->data_vptr = (void *)((long)in_count * out_count);
        

        for(i_inset = 0; i_inset < num_input_sets; i_inset++) {
                for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges = my_realloc(input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges, 
                                (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges + out_count) * sizeof(t_pb_graph_edge *));
                }
        }

        for(i_outset = 0; i_outset < num_output_sets; i_outset++) {
                for(i_outpin = 0; i_outpin < num_output_ptrs[i_outset]; i_outpin++) {
                        output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges = my_realloc(output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges, 
                                (output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges + in_count) * sizeof(t_pb_graph_edge *));
                }
        }

        i_edge = 0;

        /* Load connections between pins and record these updates in the edges */
        for(i_inset = 0; i_inset < num_input_sets; i_inset++) {
                for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
                        for(i_outset = 0; i_outset < num_output_sets; i_outset++) {
                                for(i_outpin = 0; i_outpin < num_output_ptrs[i_outset]; i_outpin++) {

                                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] = &edges[i_edge];
                                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++;
                                        output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges[output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges] = &edges[i_edge];
                                        output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges++;

                                        edges[i_edge].num_input_pins = 1;
                                        edges[i_edge].input_pins = my_malloc(sizeof(t_pb_graph_pin *));
                                        edges[i_edge].input_pins[0] = input_pb_graph_node_pin_ptrs[i_inset][i_inpin];
                                        edges[i_edge].num_output_pins = 1;
                                        edges[i_edge].output_pins = my_malloc(sizeof(t_pb_graph_pin *));
                                        edges[i_edge].output_pins[0] = output_pb_graph_node_pin_ptrs[i_outset][i_outpin];                                       

                                        edges[i_edge].interconnect = interconnect;
                                        edges[i_edge].driver_set = i_inset;
                                        edges[i_edge].driver_pin = i_inpin;
                                        
                                        i_edge++;
                                }
                        }
                }
        }
        assert(i_edge == in_count * out_count);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_direct_interc_edges ( INP t_interconnect interconnect,
INOUTP t_pb_graph_pin ***  input_pb_graph_node_pin_ptrs,
INP int  num_input_sets,
INP int *  num_input_ptrs,
INOUTP t_pb_graph_pin ***  output_pb_graph_node_pin_ptrs,
INP int  num_output_sets,
INP int *  num_output_ptrs 
) [static]

Definition at line 662 of file pb_type_graph.c.

                                                                                                                           {

        int i;
        t_pb_graph_edge *edges;
        struct s_linked_vptr *cur;

        /* Allocate memory for edges */
        assert(num_input_sets == 1 && num_output_sets == 1);
        if(num_input_ptrs[0] != num_output_ptrs[0]) {
                printf("input ptrs %d output ptrs %d input pin %s output pin %s input_pb_type %s output_pb_type %s\n",
                        num_input_ptrs[0], num_output_ptrs[0], input_pb_graph_node_pin_ptrs[0][0]->port->name, output_pb_graph_node_pin_ptrs[0][0]->port->name,
                        input_pb_graph_node_pin_ptrs[0][0]->parent_node->pb_type->name, output_pb_graph_node_pin_ptrs[0][0]->parent_node->pb_type->name);
        }
        assert(num_input_ptrs[0] == num_output_ptrs[0]);
        
        edges = my_calloc(num_input_ptrs[0], sizeof(t_pb_graph_edge));
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = edges_head;
        edges_head = cur;
        cur->data_vptr = (void *)edges;
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = num_edges_head;
        num_edges_head = cur;
        cur->data_vptr = (void *)((long)num_input_ptrs[0]);
        
        
        /* Reallocate memory for pins and load connections between pins and record these updates in the edges */
        for(i = 0; i < num_input_ptrs[0]; i++) {                
                input_pb_graph_node_pin_ptrs[0][i]->output_edges = my_realloc(
                        input_pb_graph_node_pin_ptrs[0][i]->output_edges, (input_pb_graph_node_pin_ptrs[0][i]->num_output_edges + 1) * sizeof(t_pb_graph_edge *));
                input_pb_graph_node_pin_ptrs[0][i]->output_edges[input_pb_graph_node_pin_ptrs[0][i]->num_output_edges] = &edges[i];
                input_pb_graph_node_pin_ptrs[0][i]->num_output_edges++;
                
                output_pb_graph_node_pin_ptrs[0][i]->input_edges = my_realloc(
                        output_pb_graph_node_pin_ptrs[0][i]->input_edges, (output_pb_graph_node_pin_ptrs[0][i]->num_input_edges + 1) * sizeof(t_pb_graph_edge *));
                output_pb_graph_node_pin_ptrs[0][i]->input_edges[output_pb_graph_node_pin_ptrs[0][i]->num_input_edges] = &edges[i];
                output_pb_graph_node_pin_ptrs[0][i]->num_input_edges++;

                edges[i].num_input_pins = 1;
                edges[i].input_pins = my_malloc(sizeof(t_pb_graph_pin *));
                edges[i].input_pins[0] = input_pb_graph_node_pin_ptrs[0][i];
                edges[i].num_output_pins = 1;
                edges[i].output_pins = my_malloc(sizeof(t_pb_graph_pin *));
                edges[i].output_pins[0] = output_pb_graph_node_pin_ptrs[0][i];

                edges[i].interconnect = interconnect;
                edges[i].driver_set = 0;
                edges[i].driver_pin = i;
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_mode_interconnect ( INOUTP t_pb_graph_node pb_graph_parent_node,
INOUTP t_pb_graph_node **  pb_graph_children_nodes,
INP const t_mode mode 
) [static]

Generate interconnect associated with a mode of operation

Parameters:
pb_graph_parent_node,:parent node of pb in mode
pb_graph_children_nodes,:[0..num_pb_type_in_mode-1][0..num_pb]
mode,:mode of operation

Definition at line 397 of file pb_type_graph.c.

                                                                                                                 {
        int i, j;
        int *num_input_pb_graph_node_pins, *num_output_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */
        int num_input_pb_graph_node_sets, num_output_pb_graph_node_sets;
        t_pb_graph_pin *** input_pb_graph_node_pins, ***output_pb_graph_node_pins;
        for(i = 0; i < mode->num_interconnect; i++) {
                /* determine the interconnect input and output pins */
                input_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(pb_graph_parent_node, 
                                                                                                                   pb_graph_children_nodes,
                                                                                                                   mode->interconnect[i].input_string,
                                                                                                                   &num_input_pb_graph_node_pins,
                                                                                                                   &num_input_pb_graph_node_sets,
                                                                                                                   TRUE,
                                                                                                                   TRUE);

                output_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(pb_graph_parent_node, 
                                                                                                                   pb_graph_children_nodes,
                                                                                                                   mode->interconnect[i].output_string,
                                                                                                                   &num_output_pb_graph_node_pins,
                                                                                                                   &num_output_pb_graph_node_sets,
                                                                                                                   FALSE,
                                                                                                                   TRUE);

                /* process the interconnect based on its type */
                switch ( mode->interconnect[i].type ) {

                        case COMPLETE_INTERC: 
                                alloc_and_load_complete_interc_edges(&mode->interconnect[i],
                                                                                                         input_pb_graph_node_pins,
                                                                                                         num_input_pb_graph_node_sets,
                                                                                                         num_input_pb_graph_node_pins,
                                                                                                         output_pb_graph_node_pins,
                                                                                                         num_output_pb_graph_node_sets,
                                                                                                         num_output_pb_graph_node_pins);

                        break;

                        case DIRECT_INTERC: 
                                alloc_and_load_direct_interc_edges(&mode->interconnect[i],
                                                                                                        input_pb_graph_node_pins,
                                                                                                        num_input_pb_graph_node_sets,
                                                                                                        num_input_pb_graph_node_pins,
                                                                                                        output_pb_graph_node_pins,
                                                                                                        num_output_pb_graph_node_sets,
                                                                                                        num_output_pb_graph_node_pins);
                        break;

                        case MUX_INTERC:
                                alloc_and_load_mux_interc_edges(&mode->interconnect[i],
                                                                                                input_pb_graph_node_pins,
                                                                                                num_input_pb_graph_node_sets,
                                                                                                num_input_pb_graph_node_pins,
                                                                                                output_pb_graph_node_pins,
                                                                                                num_output_pb_graph_node_sets,
                                                                                                num_output_pb_graph_node_pins);

                        break;

                        default : 
                                printf(ERRTAG "Unknown interconnect %d for mode %s in pb_type %s\n", mode->interconnect[i].type,
                                        mode->name, pb_graph_parent_node->pb_type->name);
                                printf("\tinput %s output %s\n", mode->interconnect[i].input_string, mode->interconnect[i].output_string);
                                exit(1);
                }
                for(j = 0; j < num_input_pb_graph_node_sets; j++) {
                        free(input_pb_graph_node_pins[j]);
                }
                free(input_pb_graph_node_pins);
                for(j = 0; j < num_output_pb_graph_node_sets; j++) {
                        free(output_pb_graph_node_pins[j]);
                }
                free(output_pb_graph_node_pins);
                free(num_input_pb_graph_node_pins);
                free(num_output_pb_graph_node_pins);
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_mux_interc_edges ( INP t_interconnect interconnect,
INOUTP t_pb_graph_pin ***  input_pb_graph_node_pin_ptrs,
INP int  num_input_sets,
INP int *  num_input_ptrs,
INOUTP t_pb_graph_pin ***  output_pb_graph_node_pin_ptrs,
INP int  num_output_sets,
INP int *  num_output_ptrs 
) [static]

Definition at line 719 of file pb_type_graph.c.

                                                                                                                           {
        int i_inset, i_inpin, i_outpin;
        t_pb_graph_edge *edges;
        struct s_linked_vptr *cur;

        /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */
        assert(num_output_sets == 1);

        edges = my_calloc(num_input_sets, sizeof(t_pb_graph_edge));
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = edges_head;
        edges_head = cur;
        cur->data_vptr = (void *)edges;
        cur = my_malloc(sizeof(struct s_linked_vptr));
        cur->next = num_edges_head;
        num_edges_head = cur;
        cur->data_vptr = (void *)((long)num_input_sets);
        

        for(i_inset = 0; i_inset < num_input_sets; i_inset++) {
                for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges = my_realloc(input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges, 
                                (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges + 1) * sizeof(t_pb_graph_edge *));
                }
        }

        for(i_outpin = 0; i_outpin < num_output_ptrs[0]; i_outpin++) {
                output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges = my_realloc(output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges, 
                        (output_pb_graph_node_pin_ptrs[0][i_outpin]->num_input_edges + num_input_sets) * sizeof(t_pb_graph_edge *));
        }

        /* Load connections between pins and record these updates in the edges */
        for(i_inset = 0; i_inset < num_input_sets; i_inset++) {
                assert(num_output_ptrs[0] == num_input_ptrs[i_inset]);
                edges[i_inset].input_pins = my_calloc(num_output_ptrs[0], sizeof(t_pb_graph_pin *));
                edges[i_inset].output_pins = my_calloc(num_output_ptrs[0], sizeof(t_pb_graph_pin *));
                edges[i_inset].num_input_pins = num_output_ptrs[0];
                edges[i_inset].num_output_pins = num_output_ptrs[0];
                for(i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] = &edges[i_inset];
                        input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++;
                        output_pb_graph_node_pin_ptrs[0][i_inpin]->input_edges[output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges] = &edges[i_inset];
                        output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges++;

                        edges[i_inset].input_pins[i_inpin] = input_pb_graph_node_pin_ptrs[i_inset][i_inpin];
                        edges[i_inset].output_pins[i_inpin] = output_pb_graph_node_pin_ptrs[0][i_inpin];
                        
                        assert(i_inpin == 0); /* current does not support bus-based routing, TODO: Support bus based routing */
                        edges[i_inset].interconnect = interconnect;
                        edges[i_inset].driver_set = i_inset;
                        edges[i_inset].driver_pin = i_inpin;
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_pb_graph ( INOUTP t_pb_graph_node pb_graph_node,
INP t_pb_graph_node parent_pb_graph_node,
INP const t_pb_type pb_type,
INP int  index 
) [static]

Definition at line 170 of file pb_type_graph.c.

                                                                                       {
        int i, j, k, i_input, i_output, i_clockport;

        pb_graph_node->placement_index = index;
        pb_graph_node->pb_type = pb_type;
        pb_graph_node->parent_pb_graph_node = parent_pb_graph_node;

        pb_graph_node->num_input_ports = 0;
        pb_graph_node->num_output_ports = 0;
        pb_graph_node->num_clock_ports = 0;

        /* Generate ports for pb graph node */
        for(i = 0; i < pb_type->num_ports; i++) {
                if(pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) {
                        pb_graph_node->num_input_ports++;
                } else if(pb_type->ports[i].type == OUT_PORT) {
                        assert(!pb_type->ports[i].is_clock);
                        pb_graph_node->num_output_ports++;
                } else {
                        assert(pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT);
                        pb_graph_node->num_clock_ports++;
                } 
        }

        pb_graph_node->num_input_pins = my_calloc(pb_graph_node->num_input_ports, sizeof(int));
        pb_graph_node->num_output_pins = my_calloc(pb_graph_node->num_output_ports, sizeof(int));
        pb_graph_node->num_clock_pins = my_calloc(pb_graph_node->num_clock_ports, sizeof(int));
        
        pb_graph_node->input_pins = my_calloc(pb_graph_node->num_input_ports, sizeof(t_pb_graph_pin*));
        pb_graph_node->output_pins = my_calloc(pb_graph_node->num_output_ports, sizeof(t_pb_graph_pin*));
        pb_graph_node->clock_pins = my_calloc(pb_graph_node->num_clock_ports, sizeof(t_pb_graph_pin*));
        
        i_input = i_output = i_clockport = 0;
        for(i = 0; i < pb_type->num_ports; i++) {
                if(pb_type->ports[i].model_port) {
                        assert(pb_type->num_modes == 0);
                } else {
                        assert(pb_type->num_modes != 0 || pb_type->ports[i].is_clock);
                }
                if(pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) {
                        pb_graph_node->input_pins[i_input] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin));
                        pb_graph_node->num_input_pins[i_input] = pb_type->ports[i].num_pins;
                        for(j = 0; j < pb_type->ports[i].num_pins; j++) {
                                pb_graph_node->input_pins[i_input][j].input_edges = NULL;
                                pb_graph_node->input_pins[i_input][j].num_input_edges = 0;
                                pb_graph_node->input_pins[i_input][j].output_edges = NULL;
                                pb_graph_node->input_pins[i_input][j].num_output_edges = 0;
                                pb_graph_node->input_pins[i_input][j].pin_number = j;
                                pb_graph_node->input_pins[i_input][j].port = &pb_type->ports[i];
                                pb_graph_node->input_pins[i_input][j].parent_node = pb_graph_node;
                                pb_graph_node->input_pins[i_input][j].pin_count_in_cluster = pin_count_in_cluster;
                                pb_graph_node->input_pins[i_input][j].type = PB_PIN_NORMAL;
                                if(pb_graph_node->pb_type->blif_model != NULL) {
                                        if(strcmp(pb_graph_node->pb_type->blif_model, ".output") == 0) {
                                                pb_graph_node->input_pins[i_input][j].type = PB_PIN_OUTPAD;
                                        } else if(pb_graph_node->num_clock_ports != 0) {
                                                pb_graph_node->input_pins[i_input][j].type = PB_PIN_SEQUENTIAL;
                                        } else {
                                                pb_graph_node->input_pins[i_input][j].type = PB_PIN_TERMINAL;
                                        }
                                }
                                pin_count_in_cluster++;
                        }
                        i_input++;
                } else if(pb_type->ports[i].type == OUT_PORT) {
                        pb_graph_node->output_pins[i_output] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin));
                        pb_graph_node->num_output_pins[i_output] = pb_type->ports[i].num_pins;
                        for(j = 0; j < pb_type->ports[i].num_pins; j++) {
                                pb_graph_node->output_pins[i_output][j].input_edges = NULL;
                                pb_graph_node->output_pins[i_output][j].num_input_edges = 0;
                                pb_graph_node->output_pins[i_output][j].output_edges = NULL;
                                pb_graph_node->output_pins[i_output][j].num_output_edges = 0;
                                pb_graph_node->output_pins[i_output][j].pin_number = j;
                                pb_graph_node->output_pins[i_output][j].port = &pb_type->ports[i];
                                pb_graph_node->output_pins[i_output][j].parent_node = pb_graph_node;
                                pb_graph_node->output_pins[i_output][j].pin_count_in_cluster = pin_count_in_cluster;
                                pb_graph_node->output_pins[i_output][j].type = PB_PIN_NORMAL;
                                if(pb_graph_node->pb_type->blif_model != NULL) {
                                        if(strcmp(pb_graph_node->pb_type->blif_model, ".input") == 0) {
                                                pb_graph_node->output_pins[i_output][j].type = PB_PIN_INPAD;
                                        } else if(pb_graph_node->num_clock_ports != 0) {
                                                pb_graph_node->output_pins[i_output][j].type = PB_PIN_SEQUENTIAL;
                                        } else {
                                                pb_graph_node->output_pins[i_output][j].type = PB_PIN_TERMINAL;
                                        }
                                }
                                pin_count_in_cluster++;                         
                        }
                        i_output++;
                } else {
                        assert(pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT);
                        pb_graph_node->clock_pins[i_clockport] = my_calloc(pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin));
                        pb_graph_node->num_clock_pins[i_clockport] = pb_type->ports[i].num_pins;
                        for(j = 0; j < pb_type->ports[i].num_pins; j++) {
                                pb_graph_node->clock_pins[i_clockport][j].input_edges = NULL;
                                pb_graph_node->clock_pins[i_clockport][j].num_input_edges = 0;
                                pb_graph_node->clock_pins[i_clockport][j].output_edges = NULL;
                                pb_graph_node->clock_pins[i_clockport][j].num_output_edges = 0;
                                pb_graph_node->clock_pins[i_clockport][j].pin_number = j;
                                pb_graph_node->clock_pins[i_clockport][j].port = &pb_type->ports[i];
                                pb_graph_node->clock_pins[i_clockport][j].parent_node = pb_graph_node;
                                pb_graph_node->clock_pins[i_clockport][j].pin_count_in_cluster = pin_count_in_cluster;
                                pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_NORMAL;                 
                                if(pb_graph_node->pb_type->blif_model != NULL) {
                                        pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_CLOCK;                  
                                }
                                pin_count_in_cluster++;
                        }
                        i_clockport++;
                } 
        }

        /* Allocate and load child nodes for each mode and create interconnect in each mode */
        pb_graph_node->child_pb_graph_nodes = my_calloc(pb_type->num_modes, sizeof(t_pb_graph_node **));
        for(i = 0; i < pb_type->num_modes; i++) {
                pb_graph_node->child_pb_graph_nodes[i] = my_calloc(pb_type->modes[i].num_pb_type_children, sizeof(t_pb_graph_node *));
                for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
                        pb_graph_node->child_pb_graph_nodes[i][j] = my_calloc(pb_type->modes[i].pb_type_children[j].num_pb, sizeof(t_pb_graph_node));
                        for(k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
                                alloc_and_load_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k],
                                                                                pb_graph_node,
                                                                                &pb_type->modes[i].pb_type_children[j],
                                                                                k);
                        }
                }
        }

        for(i = 0; i < pb_type->num_modes; i++) {
                /* Create interconnect for mode */
                alloc_and_load_mode_interconnect(pb_graph_node, pb_graph_node->child_pb_graph_nodes[i], &pb_type->modes[i]);
        }
}       

Here is the call graph for this function:

Here is the caller graph for this function:

static void alloc_and_load_pin_locations_from_pb_graph ( t_type_descriptor type) [static]

Definition at line 1037 of file pb_type_graph.c.

                                                                                {
        int i, j, k, m, icapacity;
        int num_sides;
        int side_index;
        int pin_num;
        int count;

        int *num_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */
        int num_pb_graph_node_sets;
        t_pb_graph_pin*** pb_graph_node_pins;

        num_sides = 2 * (type->height + 1);
        side_index = 0;
        count = 0;
        
        if(type->pin_location_distribution == E_SPREAD_PIN_DISTR) {
                pin_num = 0;
                /* evenly distribute pins starting at bottom left corner */
                for(j = 0; j < 4; j++) {
                        for(i = 0; i < type->height; i++) {
                                if(j == TOP && i != type->height - 1) {
                                        continue;
                                }
                                if(j == BOTTOM && i != 0) {
                                        continue;
                                }
                                for(k = 0; k < (type->num_pins / num_sides) + 1; k++) {
                                        pin_num = side_index + k * num_sides;
                                        if(pin_num < type->num_pins) {
                                                type->pinloc[i][j][pin_num] = 1;
                                                type->pin_height[pin_num] = i;
                                                count++;
                                        }
                                }
                                side_index++;
                        }
                }
                assert(side_index == num_sides);
                assert(count == type->num_pins);
        } else {
                assert(type->pin_location_distribution == E_CUSTOM_PIN_DISTR);
                for(i = 0; i < type->height; i++) {
                        for(j = 0; j < 4; j++) {                        
                                if(j == TOP && i != type->height - 1) {
                                        continue;
                                }
                                if(j == BOTTOM && i != 0) {
                                        continue;
                                }
                                for(k = 0; k < type->num_pin_loc_assignments[i][j]; k++) {
                                        pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(type->pb_graph_head, 
                                                                                                   type->pb_graph_head->child_pb_graph_nodes[0],
                                                                                                   type->pin_loc_assignments[i][j][k],
                                                                                                   &num_pb_graph_node_pins,
                                                                                                   &num_pb_graph_node_sets,
                                                                                                   FALSE,
                                                                                                   FALSE);
                                        assert(num_pb_graph_node_sets == 1);                                    


                                        for(m = 0; m < num_pb_graph_node_pins[0]; m++) {
                                                pin_num = pb_graph_node_pins[0][m]->pin_count_in_cluster;
                                                assert(pin_num < type->num_pins / type->capacity);
                                                for(icapacity = 0; icapacity < type->capacity; icapacity++) {
                                                        type->pinloc[i][j][pin_num + icapacity * type->num_pins / type->capacity] = 1;
                                                        type->pin_height[pin_num] = i;
                                                        assert(count < type->num_pins);
                                                }                                               
                                        }
                                        free(pb_graph_node_pins[0]);
                                        free(pb_graph_node_pins);
                                        free(num_pb_graph_node_pins);
                                }
                        }
                }       
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

t_pb_graph_pin*** alloc_and_load_port_pin_ptrs_from_string ( INP const t_pb_graph_node pb_graph_parent_node,
INP t_pb_graph_node **  pb_graph_children_nodes,
INP const char *  port_string,
OUTP int **  num_ptrs,
OUTP int *  num_sets,
INP boolean  is_input_to_interc,
INP boolean  interconnect_error_check 
)

creates an array of pointers to the pb graph node pins in order from the port string

Returns:
t_pb_graph_pin ptr indexed by [0..num_sets_in_port - 1][0..num_ptrs - 1]

Definition at line 480 of file pb_type_graph.c.

                                                                                                                                                                        {
        t_token * tokens;
        int num_tokens, curr_set;
        int i;
        boolean in_squig_bracket, success;
        
        t_pb_graph_pin ***pb_graph_pins;

        num_tokens = 0;
        tokens = GetTokensFromString(port_string, &num_tokens);
        *num_sets = 0;
        in_squig_bracket = FALSE;
        
        /* count the number of sets available */
        for(i = 0; i < num_tokens; i++) {
                assert(tokens[i].type != TOKEN_NULL);
                if(tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) {
                        if(in_squig_bracket) {
                                printf(ERRTAG "{ inside { in port %s\n", port_string);
                                exit(1);
                        }
                        in_squig_bracket = TRUE;
                } else if(tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) {
                        if(!in_squig_bracket) {
                                (*num_sets)++;
                                printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string);
                                exit(1);
                        }
                        in_squig_bracket = FALSE;
                } else if(tokens[i].type == TOKEN_DOT) {
                        if(!in_squig_bracket) {
                                (*num_sets)++;
                        }               
                }
        }

        if(in_squig_bracket) {
                (*num_sets)++;
                printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string);
                exit(1);
        }

        pb_graph_pins = my_calloc(*num_sets, sizeof(t_pb_graph_pin**));
        *num_ptrs = my_calloc(*num_sets, sizeof(int));


        curr_set = 0;
        for(i = 0; i < num_tokens; i++) {
                assert(tokens[i].type != TOKEN_NULL);
                if(tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) {
                        if(in_squig_bracket) {
                                printf(ERRTAG "{ inside { in port %s\n", port_string);
                                exit(1);
                        }
                        in_squig_bracket = TRUE;
                } else if(tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) {
                        if((*num_ptrs)[curr_set] == 0) {
                                printf(ERRTAG "No data contained in {} in port %s\n", port_string);
                                exit(1);
                        }
                        if(!in_squig_bracket) {
                                curr_set++;
                                printf(ERRTAG "No matching '{' for '}' in port %s\n", port_string);
                                exit(1);
                        }
                        in_squig_bracket = FALSE;
                } else if(tokens[i].type == TOKEN_STRING) {

                        success = realloc_and_load_pb_graph_pin_ptrs_at_var(pb_graph_parent_node,
                                                                                                                pb_graph_children_nodes,
                                                                                                                interconnect_error_check,
                                                                                                                is_input_to_interc,
                                                                                                                tokens,
                                                                                                                &i,
                                                                                                                &((*num_ptrs)[curr_set]),
                                                                                                                &pb_graph_pins[curr_set]);

                        if(!success) {
                                printf(ERRTAG "syntax error processing port string %s\n", port_string);
                                exit(1);
                        }

                        if(!in_squig_bracket) {
                                curr_set++;
                        }               
                }
        }
        assert(curr_set == *num_sets);
        freeTokens(tokens, num_tokens);
        return pb_graph_pins;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_pb_graph ( ) [static]

check pb_type graph and return the number of errors

Definition at line 156 of file pb_type_graph.c.

                             {
        int num_errors;
        /* TODO: Error checks to do 
                1.  All pin and edge connections are bidirectional and match each other
                2.  All pb_type names are unique in a namespace
                3.  All ports are unique in a pb_type
                4.  Number of pb of a pb_type in graph is the same as requested number
                5.  All pins are connected to edges
        */
        num_errors = 0;

        return num_errors;
}

Here is the caller graph for this function:

void echo_pb_graph ( char *  filename)

Print out the pb_type graph

Definition at line 134 of file pb_type_graph.c.

                                     {
        FILE *fp;
    int i;

    fp = my_fopen(filename, "w", 0);

    fprintf(fp, "Physical Blocks Graph\n");
        fprintf(fp, "--------------------------------------------\n\n");

    for(i = 0; i < num_types; i++)
        {
                fprintf(fp, "type %s\n", type_descriptors[i].name);
                if(type_descriptors[i].pb_graph_head)
                        echo_pb_rec(type_descriptors[i].pb_graph_head, 1, fp);
        }

    fclose(fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void echo_pb_pins ( INP t_pb_graph_pin **  pb_graph_pins,
INP int  num_ports,
INP int  level,
INP FILE *  fp 
) [static]

Definition at line 1150 of file pb_type_graph.c.

                                                                                                              {
        int i, j, k, m;
        t_port *port;

        print_tabs(fp, level);
        
        for(i = 0; i < num_ports; i++) {
                port = pb_graph_pins[i][0].port;
                print_tabs(fp, level);
                fprintf(fp, "Port \"%s\": num_pins %d type %d parent name \"%s\"\n", 
                        port->name, port->num_pins, port->type, port->parent_pb_type->name);    

                for(j = 0; j < port->num_pins; j++) {
                        print_tabs(fp, level + 1);
                        assert(j == pb_graph_pins[i][j].pin_number);
                        assert(pb_graph_pins[i][j].port == port);
                        fprintf(fp, "Pin %d port name \"%s\" num input edges %d num output edges %d parent type \"%s\" parent index %d\n", 
                                pb_graph_pins[i][j].pin_number, pb_graph_pins[i][j].port->name, pb_graph_pins[i][j].num_input_edges, pb_graph_pins[i][j].num_output_edges,
                                pb_graph_pins[i][j].parent_node->pb_type->name, pb_graph_pins[i][j].parent_node->placement_index);      
                        for(k = 0; k < pb_graph_pins[i][j].num_input_edges; k++) {
                                print_tabs(fp, level + 2);
                                fprintf(fp, "Input edge %d num inputs %d num outputs %d\n", 
                                        k, pb_graph_pins[i][j].input_edges[k]->num_input_pins, pb_graph_pins[i][j].input_edges[k]->num_output_pins);    
                                print_tabs(fp, level + 3);
                                fprintf(fp, "Input edge inputs\n");
                                for(m = 0; m < pb_graph_pins[i][j].input_edges[k]->num_input_pins; m++) {
                                        print_tabs(fp, level + 3);
                                        fprintf(fp, "pin number %d port_name \"%s\"\n",
                                                pb_graph_pins[i][j].input_edges[k]->input_pins[m]->pin_number, pb_graph_pins[i][j].input_edges[k]->input_pins[m]->port->name);  
                                }
                                print_tabs(fp, level + 3);
                                fprintf(fp, "Input edge outputs\n");
                                for(m = 0; m < pb_graph_pins[i][j].input_edges[k]->num_output_pins; m++) {
                                        print_tabs(fp, level + 3);
                                        fprintf(fp, "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n",
                                                pb_graph_pins[i][j].input_edges[k]->output_pins[m]->pin_number, pb_graph_pins[i][j].input_edges[k]->output_pins[m]->port->name,
                                                pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->pb_type->name,
                                                pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->placement_index);      
                                }
                        }
                        for(k = 0; k < pb_graph_pins[i][j].num_output_edges; k++) {
                                print_tabs(fp, level + 2);
                                fprintf(fp, "Output edge %d num inputs %d num outputs %d\n", 
                                        k, pb_graph_pins[i][j].output_edges[k]->num_input_pins, pb_graph_pins[i][j].output_edges[k]->num_output_pins);  
                                print_tabs(fp, level + 3);
                                fprintf(fp, "Output edge inputs\n");
                                for(m = 0; m < pb_graph_pins[i][j].output_edges[k]->num_input_pins; m++) {
                                        print_tabs(fp, level + 3);
                                        fprintf(fp, "pin number %d port_name \"%s\"\n",
                                                pb_graph_pins[i][j].output_edges[k]->input_pins[m]->pin_number, pb_graph_pins[i][j].output_edges[k]->input_pins[m]->port->name);        
                                }
                                print_tabs(fp, level + 3);
                                fprintf(fp, "Output edge outputs\n");
                                for(m = 0; m < pb_graph_pins[i][j].output_edges[k]->num_output_pins; m++) {
                                        print_tabs(fp, level + 3);
                                        fprintf(fp, "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n",
                                                pb_graph_pins[i][j].output_edges[k]->output_pins[m]->pin_number, pb_graph_pins[i][j].output_edges[k]->output_pins[m]->port->name,
                                                pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->pb_type->name,
                                                pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->placement_index);     
                                }
                        }
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void echo_pb_rec ( INP const t_pb_graph_node pb,
INP int  level,
INP FILE *  fp 
) [static]

Here is the caller graph for this function:

static void echo_pb_rec ( const INP t_pb_graph_node pb_graph_node,
INP int  level,
INP FILE *  fp 
) [static]

Definition at line 1115 of file pb_type_graph.c.

                                                                                               {
        int i, j, k;

        print_tabs(fp, level);
        fprintf(fp, "Physical Block: type \"%s\"  index %d  num_children %d\n", 
                pb_graph_node->pb_type->name, pb_graph_node->placement_index, pb_graph_node->pb_type->num_pb);

        if(pb_graph_node->parent_pb_graph_node) {
                print_tabs(fp, level + 1);
                fprintf(fp, "Parent Block: type \"%s\" index %d \n", pb_graph_node->parent_pb_graph_node->pb_type->name,
                        pb_graph_node->parent_pb_graph_node->placement_index);
        }
        
        print_tabs(fp, level);
        fprintf(fp, "Input Ports: total ports %d\n", pb_graph_node->num_input_ports);
        echo_pb_pins(pb_graph_node->input_pins, pb_graph_node->num_input_ports, level, fp);
        print_tabs(fp, level);
        fprintf(fp, "Output Ports: total ports %d\n", pb_graph_node->num_output_ports);
        echo_pb_pins(pb_graph_node->output_pins, pb_graph_node->num_output_ports, level, fp);
        print_tabs(fp, level);
        fprintf(fp, "Clock Ports: total ports %d\n", pb_graph_node->num_clock_ports);
        echo_pb_pins(pb_graph_node->clock_pins, pb_graph_node->num_clock_ports, level, fp);
        if(pb_graph_node->pb_type->num_modes > 0) {
                print_tabs(fp, level);
                fprintf(fp, "Children:\n");
        }
        for(i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
                for(j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children; j++) {
                        for(k = 0; k < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb; k++) {
                                echo_pb_rec(&pb_graph_node->child_pb_graph_nodes[i][j][k], level + 1, fp);
                        }
                }
        }
}

Here is the call graph for this function:

void free_all_pb_graph_nodes ( )

Free pb graph

Definition at line 118 of file pb_type_graph.c.

                                {
        int i;
        for(i = 0; i < num_types; i++) {
                if(type_descriptors[i].pb_type) {
                        pin_count_in_cluster = 0;
                        if(type_descriptors[i].pb_graph_head) {
                                free_pb_graph(type_descriptors[i].pb_graph_head);
                        }
                }
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_pb_graph ( INOUTP t_pb_graph_node pb_graph_node) [static]

Definition at line 307 of file pb_type_graph.c.

                                                                 {
        int i, j, k;
        const t_pb_type *pb_type;
        struct s_linked_vptr *cur, *cur_num;
        t_pb_graph_edge *edges;

        pb_type = pb_graph_node->pb_type;
        
        /* Free ports for pb graph node */
        for(i = 0; i < pb_graph_node->num_input_ports; i++) {
                for(j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
                        if(pb_graph_node->input_pins[i][j].pin_timing)
                                free(pb_graph_node->input_pins[i][j].pin_timing);
                        if(pb_graph_node->input_pins[i][j].pin_timing_del_max)
                                free(pb_graph_node->input_pins[i][j].pin_timing_del_max);
                        if(pb_graph_node->input_pins[i][j].input_edges)
                                free(pb_graph_node->input_pins[i][j].input_edges);

                        if(pb_graph_node->input_pins[i][j].output_edges)
                                free(pb_graph_node->input_pins[i][j].output_edges);
                }
                free(pb_graph_node->input_pins[i]);             
        }
        for(i = 0; i < pb_graph_node->num_output_ports; i++) {
                for(j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
                        if(pb_graph_node->output_pins[i][j].pin_timing)
                                free(pb_graph_node->output_pins[i][j].pin_timing);
                        if(pb_graph_node->output_pins[i][j].pin_timing_del_max)
                                free(pb_graph_node->output_pins[i][j].pin_timing_del_max);
                        if(pb_graph_node->output_pins[i][j].input_edges)
                                free(pb_graph_node->output_pins[i][j].input_edges);
                        if(pb_graph_node->output_pins[i][j].output_edges)
                                free(pb_graph_node->output_pins[i][j].output_edges);
                }
                free(pb_graph_node->output_pins[i]);            
        }
        for(i = 0; i < pb_graph_node->num_clock_ports; i++) {
                for(j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
                        if(pb_graph_node->clock_pins[i][j].pin_timing)
                                free(pb_graph_node->clock_pins[i][j].pin_timing);
                        if(pb_graph_node->clock_pins[i][j].pin_timing_del_max)
                                free(pb_graph_node->clock_pins[i][j].pin_timing_del_max);
                        if(pb_graph_node->clock_pins[i][j].input_edges)
                                free(pb_graph_node->clock_pins[i][j].input_edges);
                        if(pb_graph_node->clock_pins[i][j].output_edges)
                                free(pb_graph_node->clock_pins[i][j].output_edges);
                }
                free(pb_graph_node->clock_pins[i]);             
        }
        free(pb_graph_node->input_pins);
        free(pb_graph_node->output_pins);
        free(pb_graph_node->clock_pins);

        free(pb_graph_node->num_input_pins);
        free(pb_graph_node->num_output_pins);
        free(pb_graph_node->num_clock_pins);
        
        for(i = 0; i < pb_type->num_modes; i++) {
                for(j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
                        for(k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
                                free_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k]);
                        }
                        free(pb_graph_node->child_pb_graph_nodes[i][j]);
                }               
                free(pb_graph_node->child_pb_graph_nodes[i]);
        }
        free(pb_graph_node->child_pb_graph_nodes);

        while(edges_head != NULL) {
                cur = edges_head;
                cur_num = num_edges_head;
                edges = (t_pb_graph_edge*) cur->data_vptr;
                for(i = 0; i < (long) cur_num->data_vptr; i++) {
                        free(edges[i].input_pins);
                        free(edges[i].output_pins);
                }
                edges_head = edges_head->next;
                num_edges_head = num_edges_head->next;
                free(edges);
                free(cur_num);
                free(cur);
        }
}       

Here is the caller graph for this function:

static t_pb_graph_pin * get_pb_graph_pin_from_name ( INP const char *  port_name,
INP const t_pb_graph_node pb,
INP int  pin 
) [static]

Definition at line 1004 of file pb_type_graph.c.

                                                                                                                            {
        int i;
        
        for(i = 0; i < pb->num_input_ports; i++) {
                if(0 == strcmp(port_name, pb->input_pins[i][0].port->name)) {
                        if(pin < pb->input_pins[i][0].port->num_pins) {
                                return &pb->input_pins[i][pin];
                        } else {
                                return NULL;
                        }
                }
        }
        for(i = 0; i < pb->num_output_ports; i++) {
                if(0 == strcmp(port_name, pb->output_pins[i][0].port->name)) {
                        if(pin < pb->output_pins[i][0].port->num_pins) {
                                return &pb->output_pins[i][pin];
                        } else {
                                return NULL;
                        }
                }
        }
        for(i = 0; i < pb->num_clock_ports; i++) {
                if(0 == strcmp(port_name, pb->clock_pins[i][0].port->name)) {
                        if(pin < pb->clock_pins[i][0].port->num_pins) {
                                return &pb->clock_pins[i][pin];
                        } else {
                                return NULL;
                        }
                }
        }
        return NULL;
}

Here is the caller graph for this function:

static boolean realloc_and_load_pb_graph_pin_ptrs_at_var ( INP const t_pb_graph_node pb_graph_parent_node,
INP t_pb_graph_node **  pb_graph_children_nodes,
INP boolean  interconnect_error_check,
INP boolean  is_input_to_interc,
INP const t_token tokens,
INOUTP int *  token_index,
INOUTP int *  num_pins,
OUTP t_pb_graph_pin ***  pb_graph_pins 
) [static]

populate array of pb graph pins for a single variable of type pb_type[int:int].port[int:int]

Parameters:
pb_graph_pins,:pointer to array from [0..num_port_pins] of pb_graph_pin pointers
tokens,:array of tokens to scan
num_pins,:current number of pins in pb_graph_pin array

Definition at line 787 of file pb_type_graph.c.

                                                                                                                                              {

        int i, j, ipin, ipb;
        int pb_msb, pb_lsb;
        int pin_msb, pin_lsb;
        const t_pb_graph_node *pb_node_array;
        char *port_name;
        t_port *iport;
        int add_or_subtract_pb, add_or_subtract_pin;
        boolean found;
        t_mode *mode = NULL;

        assert(tokens[*token_index].type == TOKEN_STRING);
        pb_node_array = NULL;


        if(pb_graph_children_nodes) 
                mode = pb_graph_children_nodes[0][0].pb_type->parent_mode;

        pb_msb = pb_lsb = OPEN;
        pin_msb = pin_lsb = OPEN;

        /* parse pb */
        found = FALSE;
        if(0 == strcmp(pb_graph_parent_node->pb_type->name, tokens[*token_index].data)) {
                pb_node_array = pb_graph_parent_node;
                pb_msb = pb_lsb = 0;
                found = TRUE;
                (*token_index)++;
                if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
                        (*token_index)++;
                        if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                        pb_msb = my_atoi(tokens[*token_index].data);
                        (*token_index)++;
                        if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 
                                if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) {
                                        return FALSE; 
                                }
                                pb_lsb = pb_msb;
                                (*token_index)++;
                        } else {
                                (*token_index)++;
                                if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                                pb_lsb= my_atoi(tokens[*token_index].data);
                                (*token_index)++;
                                if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; }                                 
                                (*token_index)++;
                        }
                        /* Check to make sure indices from user match internal data structures for the indices of the parent */
                        if((pb_lsb != pb_msb) &&  (pb_lsb != pb_graph_parent_node->placement_index)) {
                                printf(ERRTAG "Incorrect placement index for %s, expected index %d\n", 
                                        tokens[0].data, pb_graph_parent_node->placement_index);
                                return FALSE;
                        }
                        pb_lsb = pb_msb = 0; /* Internal representation of parent is always 0 */
                }
        } else {
                if(mode == NULL) {
                        printf(ERRTAG "pb_graph_parent_node %s failed\n", pb_graph_parent_node->pb_type->name);
                }
                assert(mode);
                for(i = 0; i < mode->num_pb_type_children; i++) {
                        assert(&mode->pb_type_children[i] == pb_graph_children_nodes[i][0].pb_type);
                        if(0 == strcmp(mode->pb_type_children[i].name, tokens[*token_index].data)) {
                                pb_node_array = pb_graph_children_nodes[i];
                                found = TRUE;
                                (*token_index)++;

                                if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
                                        (*token_index)++;
                                        if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                                        pb_msb = my_atoi(tokens[*token_index].data);
                                        (*token_index)++;
                                        if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 
                                                if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) {
                                                        return FALSE; 
                                                }
                                                pb_lsb = pb_msb;
                                                (*token_index)++;
                                        } else {
                                                (*token_index)++;
                                                if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                                                pb_lsb= my_atoi(tokens[*token_index].data);
                                                (*token_index)++;
                                                if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; }                                 
                                                (*token_index)++;
                                        }
                                } else {
                                        pb_msb = pb_node_array[0].pb_type->num_pb - 1;
                                        pb_lsb = 0;
                                }
                                break;
                        }
                }
        }

        if(!found) {
                printf(ERRTAG "Unknown pb_type name %s, not defined in namespace of mode %s\n", tokens[*token_index].data, mode->name);
                return FALSE;
        }

        found = FALSE;

        if(!checkTokenType(tokens[*token_index], TOKEN_DOT)) { return FALSE; }
        (*token_index)++;
        if(!checkTokenType(tokens[*token_index], TOKEN_STRING)) { return FALSE; }
        
        /* parse ports and port pins of pb */
        port_name = tokens[*token_index].data;

        (*token_index)++;
        if(tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
                (*token_index)++;
                if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                pin_msb = my_atoi(tokens[*token_index].data);
                (*token_index)++;
                if(!checkTokenType(tokens[*token_index], TOKEN_COLON)) { 
                        if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) {
                                return FALSE; 
                        }
                        pin_lsb = pin_msb;
                        (*token_index)++;
                } else {
                        (*token_index)++;
                        if(!checkTokenType(tokens[*token_index], TOKEN_INT)) { return FALSE; }
                        pin_lsb= my_atoi(tokens[*token_index].data);
                        (*token_index)++;
                        if(!checkTokenType(tokens[*token_index], TOKEN_CLOSE_SQUARE_BRACKET)) { return FALSE; }                                 
                        (*token_index)++;
                }
        } else {
                if(get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb], 0) == NULL) {
                        printf("failed to find port name %s\n", port_name);
                        exit(1);
                }
                iport = get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb], 0)->port;
                pin_msb = iport->num_pins - 1;
                pin_lsb = 0;
        }
        (*token_index)--;

        if(pb_msb < pb_lsb) {
                add_or_subtract_pb = -1;
        } else {
                add_or_subtract_pb = 1;
        }

        if(pin_msb < pin_lsb) {
                add_or_subtract_pin = -1;
        } else {
                add_or_subtract_pin = 1;
        }
        *num_pins += (abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1);
        *pb_graph_pins = my_calloc(*num_pins, sizeof(t_pb_graph_pin *));
        i = j = 0;

        ipb = pb_lsb;
        
        while(ipb != pb_msb + add_or_subtract_pin) {
                ipin = pin_lsb;
                j = 0;
                while(ipin != pin_msb + add_or_subtract_pin) {
                        (*pb_graph_pins)[i*(abs(pin_msb - pin_lsb) + 1) + j] = get_pb_graph_pin_from_name(port_name, &pb_node_array[ipb], ipin);
                        iport = (*pb_graph_pins)[i*(abs(pin_msb - pin_lsb) + 1) + j]->port;
                        if(!iport) { return FALSE; }    

                        /* Error checking before assignment */
                        if(interconnect_error_check) {
                                if(pb_node_array == pb_graph_parent_node) {
                                        if(is_input_to_interc) {
                                                if(iport->type != IN_PORT) {
                                                        printf(ERRTAG "input to interconnect from parent is not an input or clock pin\n");
                                                        return FALSE;
                                                }
                                        } else {
                                                if(iport->type != OUT_PORT) {
                                                        printf(ERRTAG "output from interconnect from parent is not an input or clock pin\n");
                                                        return FALSE;
                                                }
                                        }
                                } else {
                                        if(is_input_to_interc) {
                                                if(iport->type != OUT_PORT) {
                                                        printf(ERRTAG "output from interconnect from parent is not an input or clock pin\n");
                                                        return FALSE;
                                                }
                                        } else {
                                                if(iport->type != IN_PORT) {
                                                        printf(ERRTAG "input to interconnect from parent is not an input or clock pin\n");
                                                        return FALSE;
                                                }
                                        }
                                }
                        }       


                        /* load pb_graph_pin for pin */

                        ipin += add_or_subtract_pin;
                        j++;
                }
                i++;
                ipb += add_or_subtract_pb;
        }

        assert((abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1) == i * j);

        return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct s_linked_vptr* edges_head [static]

Definition at line 25 of file pb_type_graph.c.

struct s_linked_vptr* num_edges_head [static]

Definition at line 26 of file pb_type_graph.c.

int pin_count_in_cluster [static]

variable global to this section that indexes each pb graph pin within a cluster

Definition at line 24 of file pb_type_graph.c.