VPR-6.0
|
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "util.h"
#include "arch_types.h"
#include "vpr_types.h"
#include "globals.h"
#include "vpr_utils.h"
#include "pb_type_graph.h"
#include "token.h"
#include "pb_type_graph_annotations.h"
Go to the source code of this file.
Functions | |
static void | load_critical_path_annotations (INOUTP t_pb_graph_node *pb_graph_node, INP int mode, INP enum e_pin_to_pin_annotation_format input_format, INP enum e_pin_to_pin_delay_annotations delay_type, INP char *annot_in_pins, INP char *annot_out_pins, INP char *value) |
static t_tedge * | find_edge () |
void | load_pb_graph_pin_to_pin_annotations (INOUTP t_pb_graph_node *pb_graph_node) |
static t_tedge* find_edge | ( | ) | [static] |
static void load_critical_path_annotations | ( | INOUTP t_pb_graph_node * | pb_graph_node, |
INP int | mode, | ||
INP enum e_pin_to_pin_annotation_format | input_format, | ||
INP enum e_pin_to_pin_delay_annotations | delay_type, | ||
INP char * | annot_in_pins, | ||
INP char * | annot_out_pins, | ||
INP char * | value | ||
) | [static] |
Definition at line 106 of file pb_type_graph_annotations.c.
{ int i, j, k, m, n, p, iedge; t_pb_graph_pin ***in_port, ***out_port; int *num_in_ptrs, *num_out_ptrs, num_in_sets, num_out_sets; float **delay_matrix; t_pb_graph_node **children = NULL; int count; int num_inputs, num_outputs; in_port = out_port = NULL; num_out_sets = num_in_sets = 0; num_out_ptrs = num_in_ptrs = NULL; /* Primarily 3 kinds of delays that affect critical path: 1. Intrablock interconnect delays 2. Combinational primitives (pin-to-pin delays of primitive) 3. Sequential primitives (setup and clock-to-q times) Note: Proper I/O modelling requires knowledge of the extra-chip world (eg. the load that pin is driving, drive strength, etc) For now, I/O delays are modelled as a constant in the architecture file by setting the pad-I/O block interconnect delay to be a constant I/O delay Algorithm: Intrablock and combinational primitive delays apply to edges Sequential delays apply to pins 1. Determine if delay applies to pin or edge 2. Format the delay information 3. Load delay information */ /* Determine what pins to read based on delay type */ num_inputs = num_outputs = 0; if(mode == OPEN) { children = NULL; } else { children = pb_graph_node->child_pb_graph_nodes[mode]; } if(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP) { assert(pb_graph_node->pb_type->blif_model != NULL); in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node, children, annot_in_pins, &num_in_ptrs, &num_in_sets, FALSE, FALSE); } else if (delay_type == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX) { assert(pb_graph_node->pb_type->blif_model != NULL); in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node, children, annot_in_pins, &num_in_ptrs, &num_in_sets, FALSE, FALSE); } else { assert(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_MAX); in_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node, children, annot_in_pins, &num_in_ptrs, &num_in_sets, FALSE, FALSE); out_port = alloc_and_load_port_pin_ptrs_from_string(pb_graph_node, children, annot_out_pins, &num_out_ptrs, &num_out_sets, FALSE, FALSE); } num_inputs = 0; for(i = 0; i < num_in_sets; i++) { num_inputs += num_in_ptrs[i]; } if(out_port != NULL) { num_outputs = 0; for(i = 0; i < num_out_sets; i++) { num_outputs += num_out_ptrs[i]; } } else { num_outputs = 1; } delay_matrix = my_malloc(sizeof(float*) * num_inputs); for(i = 0; i < num_inputs; i++) { delay_matrix[i] = my_malloc(sizeof(float) * num_outputs); } if(input_format == E_ANNOT_PIN_TO_PIN_MATRIX) { my_atof_2D(delay_matrix, num_inputs, num_outputs, value); } else { assert(input_format == E_ANNOT_PIN_TO_PIN_CONSTANT); for(i = 0; i < num_inputs; i++) { for(j = 0; j < num_outputs; j++) { delay_matrix[i][j] = atof(value); } } } if(delay_type == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP || delay_type == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX) { k = 0; for(i = 0; i < num_in_sets; i++) { for(j = 0; j < num_in_ptrs[i]; j++) { in_port[i][j]->tsu_tco = delay_matrix[k][0]; k++; } } } else { if(pb_graph_node->pb_type->num_modes != 0) { /* Not a primitive, find pb_graph_edge */ k = 0; for(i = 0; i < num_in_sets; i++) { for(j = 0; j < num_in_ptrs[i]; j++) { p = 0; for(m = 0; m < num_out_sets; m++) { for(n = 0; n < num_out_ptrs[m]; n++) { for(iedge = 0; iedge < in_port[i][j]->num_output_edges; iedge++) { if(in_port[i][j]->output_edges[iedge]->output_pins[0] == out_port[m][n]) { assert(in_port[i][j]->output_edges[iedge]->delay_max == 0); break; } } /* jluu Todo: This is inefficient, I know the interconnect so I know what edges exist can use this info to only annotate existing edges */ if(iedge != in_port[i][j]->num_output_edges) { in_port[i][j]->output_edges[iedge]->delay_max = delay_matrix[k][p]; } p++; } } k++; } } } else { /* Primitive, allocate appropriate nodes */ k = 0; for(i = 0; i < num_in_sets; i++) { for(j = 0; j < num_in_ptrs[i]; j++) { delay_matrix[k][0]; count = p = 0; for(m = 0; m < num_out_sets; m++) { for(n = 0; n < num_out_ptrs[m]; n++) { /* OPEN indicates that connection does not exist */ if(delay_matrix[k][p] != OPEN) { count++; } p++; } } in_port[i][j]->num_pin_timing = count; in_port[i][j]->pin_timing_del_max = my_malloc(sizeof(float) * count); in_port[i][j]->pin_timing = my_malloc(sizeof(t_pb_graph_pin*) * count); p = 0; count = 0; for(m = 0; m < num_out_sets; m++) { for(n = 0; n < num_out_ptrs[m]; n++) { if(delay_matrix[k][p] != OPEN) { in_port[i][j]->pin_timing_del_max[count] = delay_matrix[k][p]; in_port[i][j]->pin_timing[count] = out_port[m][n]; count++; } p++; } } assert(in_port[i][j]->num_pin_timing == count); k++; } } } } if(in_port != NULL) { for(i = 0; i < num_in_sets; i++) { free(in_port[i]); } free(in_port); free(num_in_ptrs); } if(out_port != NULL) { for(i = 0; i < num_out_sets; i++) { free(out_port[i]); } free(out_port); free(num_out_ptrs); } for(i = 0; i < num_inputs; i++) { free(delay_matrix[i]); } free(delay_matrix); }
void load_pb_graph_pin_to_pin_annotations | ( | INOUTP t_pb_graph_node * | pb_graph_node | ) |
Definition at line 35 of file pb_type_graph_annotations.c.
{ int i, j, k, m; const t_pb_type *pb_type; t_pin_to_pin_annotation *annotations; pb_type = pb_graph_node->pb_type; /* Load primitive critical path delays */ if(pb_type->num_modes == 0) { annotations = pb_type->annotations; for(i = 0; i < pb_type->num_annotations; i++) { if(annotations[i].type == E_ANNOT_PIN_TO_PIN_DELAY) { for(j = 0; j < annotations[i].num_value_prop_pairs; j++) { if( annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_MAX || annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX || annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP ) { load_critical_path_annotations(pb_graph_node, OPEN, annotations[i].format, annotations[i].prop[j], annotations[i].input_pins, annotations[i].output_pins, annotations[i].value[j]); } else { assert(annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_MIN || annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN || annotations[i].prop[j] == E_ANNOT_PIN_TO_PIN_DELAY_THOLD ); } } } else { /* Todo: load_hold_time_constraints_annotations(pb_graph_node); load_power_annotations(pb_graph_node); */ } } } else { /* Load interconnect delays */ for(i = 0; i < pb_type->num_modes; i++) { for(j = 0; j < pb_type->modes[i].num_interconnect; j++) { annotations = pb_type->modes[i].interconnect[j].annotations; for(k = 0; k < pb_type->modes[i].interconnect[j].num_annotations; k++) { if(annotations[k].type == E_ANNOT_PIN_TO_PIN_DELAY) { for(m = 0; m < annotations[k].num_value_prop_pairs; m++) { if( annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_MAX || annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MAX || annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_TSETUP ) { load_critical_path_annotations(pb_graph_node, i, annotations[k].format, annotations[k].prop[m], annotations[k].input_pins, annotations[k].output_pins, annotations[k].value[m]); } else { assert(annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_MIN || annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_CLOCK_TO_Q_MIN || annotations[k].prop[m] == E_ANNOT_PIN_TO_PIN_DELAY_THOLD ); } } } else { /* Todo: load_hold_time_constraints_annotations(pb_graph_node); load_power_annotations(pb_graph_node); */ } } } } } 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++) { load_pb_graph_pin_to_pin_annotations(&pb_graph_node->child_pb_graph_nodes[i][j][k]); } } } }