VPR-6.0

vpr/SRC/base/stats.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void routing_stats (boolean full_stats, enum e_route_type route_type, int num_switch, t_segment_inf *segment_inf, int num_segment, float R_minW_nmos, float R_minW_pmos, enum e_directionality directionality, boolean timing_analysis_enabled, float **net_slack, float **net_delay)
void print_wirelen_prob_dist (void)
void print_lambda (void)
void get_num_bends_and_length (int inet, int *bends, int *length, int *segments)

Function Documentation

void get_num_bends_and_length ( int  inet,
int *  bends_ptr,
int *  len_ptr,
int *  segments_ptr 
)

Counts and returns the number of bends, wirelength, and number of routing resource segments in net inet's routing.

Definition at line 320 of file stats.c.

{
    struct s_trace *tptr, *prevptr;
    int inode;
    t_rr_type curr_type, prev_type;
    int bends, length, segments;

    bends = 0;
    length = 0;
    segments = 0;

    prevptr = trace_head[inet]; /* Should always be SOURCE. */
    if(prevptr == NULL)
        {
            printf
                ("Error in get_num_bends_and_length:  net #%d has no traceback.\n",
                 inet);
            exit(1);
        }
    inode = prevptr->index;
    prev_type = rr_node[inode].type;

    tptr = prevptr->next;

    while(tptr != NULL)
        {
            inode = tptr->index;
            curr_type = rr_node[inode].type;

            if(curr_type == SINK)
                {               /* Starting a new segment */
                    tptr = tptr->next;  /* Link to existing path - don't add to len. */
                    if(tptr == NULL)
                        break;

                    curr_type = rr_node[tptr->index].type;
                }

            else if(curr_type == CHANX || curr_type == CHANY)
                {
                    segments++;
                    length += 1 + rr_node[inode].xhigh - rr_node[inode].xlow +
                        rr_node[inode].yhigh - rr_node[inode].ylow;

                    if(curr_type != prev_type
                       && (prev_type == CHANX || prev_type == CHANY))
                        bends++;
                }

            prev_type = curr_type;
            tptr = tptr->next;
        }

    *bends_ptr = bends;
    *len_ptr = length;
    *segments_ptr = segments;
}

Here is the caller graph for this function:

void print_lambda ( void  )

Finds the average number of input pins used per clb. Does not count inputs which are hooked to global nets (i.e. the clock when it is marked global).

Definition at line 487 of file stats.c.

{
    int bnum, ipin;
    int num_inputs_used = 0;
    int iclass, inet;
    float lambda;
    t_type_ptr type;

    for(bnum = 0; bnum < num_blocks; bnum++)
        {
            type = block[bnum].type;
            assert(type != NULL);
            if(type != IO_TYPE)
                {
                    for(ipin = 0; ipin < type->num_pins; ipin++)
                        {
                            iclass = type->pin_class[ipin];
                            if(type->class_inf[iclass].type == RECEIVER)
                                {
                                    inet = block[bnum].nets[ipin];
                                    if(inet != OPEN)    /* Pin is connected? */
                                        if(clb_net[inet].is_global == FALSE)    /* Not a global clock */
                                            num_inputs_used++;
                                }
                        }
                }
        }

    lambda = (float)num_inputs_used / (float)num_blocks;
    printf("Average lambda (input pins used per clb) is: %g\n", lambda);
}
void print_wirelen_prob_dist ( void  )

Prints out the probability distribution of the wirelength / number input pins on a net -- i.e. simulates 2-point net length probability distribution.

Definition at line 387 of file stats.c.

{

    float *prob_dist;
    float norm_fac, two_point_length;
    int inet, bends, length, segments, index;
    float av_length;
    int prob_dist_size, i, incr;

    prob_dist_size = nx + ny + 10;
    prob_dist = (float *)my_calloc(prob_dist_size, sizeof(float));
    norm_fac = 0.;

    for(inet = 0; inet < num_nets; inet++)
        {
                if(clb_net[inet].is_global == FALSE && clb_net[inet].num_sinks != 0)
                {
                    get_num_bends_and_length(inet, &bends, &length,
                                             &segments);

/*  Assign probability to two integer lengths proportionately -- i.e.  *
 *  if two_point_length = 1.9, add 0.9 of the pins to prob_dist[2] and *
 *  only 0.1 to prob_dist[1].                                          */

                    two_point_length =
                        (float)length / (float)(clb_net[inet].num_sinks);
                    index = (int)two_point_length;
                    if(index >= prob_dist_size)
                        {

                            printf
                                ("Warning: index (%d) to prob_dist exceeds its allocated size (%d)\n",
                                 index, prob_dist_size);
                            printf
                                ("Realloc'ing to increase 2-pin wirelen prob distribution array\n");
                            incr = index - prob_dist_size + 2;
                            prob_dist_size += incr;
                            prob_dist =
                                my_realloc(prob_dist,
                                           prob_dist_size * sizeof(float));
                            for(i = prob_dist_size - incr; i < prob_dist_size;
                                i++)
                                prob_dist[i] = 0.0;
                        }
                    prob_dist[index] +=
                        (clb_net[inet].num_sinks) * (1 - two_point_length +
                                                 index);

                    index++;
                    if(index >= prob_dist_size)
                        {

                            printf
                                ("Warning: index (%d) to prob_dist exceeds its allocated size (%d)\n",
                                 index, prob_dist_size);
                            printf
                                ("Realloc'ing to increase 2-pin wirelen prob distribution array\n");
                            incr = index - prob_dist_size + 2;
                            prob_dist_size += incr;
                            prob_dist =
                                my_realloc(prob_dist,
                                           prob_dist_size * sizeof(float));
                            for(i = prob_dist_size - incr; i < prob_dist_size;
                                i++)
                                prob_dist[i] = 0.0;
                        }
                    prob_dist[index] += (clb_net[inet].num_sinks) * (1 - index +
                                                                 two_point_length);

                    norm_fac += clb_net[inet].num_sinks;
                }
        }

/* Normalize so total probability is 1 and print out. */

    printf("\nProbability distribution of 2-pin net lengths:\n\n");
    printf("Length    p(Lenth)\n");

    av_length = 0;

    for(index = 0; index < prob_dist_size; index++)
        {
            prob_dist[index] /= norm_fac;
            printf("%6d  %10.6f\n", index, prob_dist[index]);
            av_length += prob_dist[index] * index;
        }

    printf("\nThe number of 2-pin nets is ;%g;\n", norm_fac);
    printf("\nExpected value of 2-pin net length (R) is ;%g;\n", av_length);
    printf("\nTotal wire length is ;%g;\n", norm_fac * av_length);

    free(prob_dist);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void routing_stats ( boolean  full_stats,
enum e_route_type  route_type,
int  num_switch,
t_segment_inf segment_inf,
int  num_segment,
float  R_minW_nmos,
float  R_minW_pmos,
enum e_directionality  directionality,
boolean  timing_analysis_enabled,
float **  net_slack,
float **  net_delay 
)

Prints out various statistics about the current routing. Both a routing and an rr_graph must exist when you call this routine.

Definition at line 32 of file stats.c.

{
    float T_crit;
        float area, used_area;
        int i, j;

    get_length_and_bends_stats();
    get_channel_occupancy_stats();

    printf("Logic Area (in minimum width transistor areas, excludes I/Os and empty grid tiles):\n");

        area = 0;
        for(i = 1; i <= nx; i++) {
                for(j = 1; j <= ny; j++) {
                        if(grid[i][j].offset == 0) {
                                if(grid[i][j].type->area == UNDEFINED) {
                                        area += grid_logic_tile_area * grid[i][j].type->height;
                                } else {
                                        area += grid[i][j].type->area;
                                }
                        }
                }
        }
        /* Todo: need to add pitch of routing to blocks with height > 3 */
    printf("Total Logic Block Area (Warning, need to add pitch of routing to blocks with height > 3): %g \n", area);

        used_area = 0;
        for(i = 0; i < num_blocks; i++) {
                if(block[i].type != IO_TYPE) {
                        if(block[i].type->area == UNDEFINED) {
                                used_area += grid_logic_tile_area * block[i].type->height;
                        } else {
                                used_area += block[i].type->area;
                        }
                }
        }
    printf("Total Used Logic Block Area: %g \n", used_area);

    if(route_type == DETAILED)
        {
            count_routing_transistors(directionality, num_switch, segment_inf,
                                      R_minW_nmos, R_minW_pmos);
            get_segment_usage_stats(num_segment, segment_inf);

            if(timing_analysis_enabled)
                {
                    load_net_delay_from_routing(net_delay, clb_net, num_nets);

#ifdef CREATE_ECHO_FILES
                    print_net_delay(net_delay, "net_delay.echo", clb_net, num_nets);
#endif /* CREATE_ECHO_FILES */

                    load_timing_graph_net_delays(net_delay);
                    T_crit = load_net_slack(net_slack, 0);

#ifdef CREATE_ECHO_FILES
                    print_timing_graph("timing_graph.echo");
                    print_net_slack("net_slack.echo", net_slack);
                    print_critical_path("critical_path.echo");
#endif /* CREATE_ECHO_FILES */

                    printf("\n");
                        if(pb_max_internal_delay == UNDEFINED || pb_max_internal_delay < T_crit) {
                                printf("Critical Path: %g (s)\n", T_crit);
                        } else {
                                printf("Critical Path: %g (s) - capped by fmax of block type %s\n", pb_max_internal_delay, pbtype_max_internal_delay->name);
                        }
                }
        }

    if(full_stats == TRUE)
        print_wirelen_prob_dist();
}

Here is the call graph for this function:

Here is the caller graph for this function: