VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
path_delay2.c File Reference
#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "path_delay2.h"
#include "read_xml_arch_file.h"
+ Include dependency graph for path_delay2.c:

Go to the source code of this file.

Functions

static int * alloc_and_load_tnode_fanin_and_check_edges (int *num_sinks_ptr)
 
static void show_combinational_cycle_candidates ()
 
int alloc_and_load_timing_graph_levels (void)
 
void check_timing_graph (int num_sinks)
 
float print_critical_path_node (FILE *fp, t_linked_int *critical_path_node)
 

Variables

int num_tnode_levels
 
struct s_ivectnodes_at_level
 

Function Documentation

int alloc_and_load_timing_graph_levels ( void  )

Definition at line 81 of file path_delay2.c.

81  {
82 
83  /* Does a breadth-first search through the timing graph in order to levelize *
84  * it. This allows subsequent traversals to be done topologically for speed. *
85  * Also returns the number of sinks in the graph (nodes with no fanout). */
86 
87  t_linked_int *free_list_head, *nodes_at_level_head;
88  int inode, num_at_level, iedge, to_node, num_edges, num_sinks, num_levels,
89  i;
90  t_tedge *tedge;
91 
92  /* [0..num_tnodes-1]. # of in-edges to each tnode that have not yet been *
93  * seen in this traversal. */
94 
95  int *tnode_fanin_left;
96 
97  tnode_fanin_left = alloc_and_load_tnode_fanin_and_check_edges(&num_sinks);
98 
99  free_list_head = NULL;
100  nodes_at_level_head = NULL;
101 
102  /* Very conservative -> max number of levels = num_tnodes. Realloc later. *
103  * Temporarily need one extra level on the end because I look at the first *
104  * empty level. */
105 
106  tnodes_at_level = (struct s_ivec *) my_malloc(
107  (num_tnodes + 1) * sizeof(struct s_ivec));
108 
109  /* Scan through the timing graph, putting all the primary input nodes (no *
110  * fanin) into level 0 of the level structure. */
111 
112  num_at_level = 0;
113 
114  for (inode = 0; inode < num_tnodes; inode++) {
115  if (tnode_fanin_left[inode] == 0) {
116  num_at_level++;
117  nodes_at_level_head = insert_in_int_list(nodes_at_level_head, inode,
118  &free_list_head);
119  }
120  }
121 
122  alloc_ivector_and_copy_int_list(&nodes_at_level_head, num_at_level,
123  &tnodes_at_level[0], &free_list_head);
124 
125  num_levels = 0;
126 
127  while (num_at_level != 0) { /* Until there's nothing in the queue. */
128  num_levels++;
129  num_at_level = 0;
130 
131  for (i = 0; i < tnodes_at_level[num_levels - 1].nelem; i++) {
132  inode = tnodes_at_level[num_levels - 1].list[i];
133  tedge = tnode[inode].out_edges;
134  num_edges = tnode[inode].num_edges;
135 
136  for (iedge = 0; iedge < num_edges; iedge++) {
137  to_node = tedge[iedge].to_node;
138  tnode_fanin_left[to_node]--;
139 
140  if (tnode_fanin_left[to_node] == 0) {
141  num_at_level++;
142  nodes_at_level_head = insert_in_int_list(
143  nodes_at_level_head, to_node, &free_list_head);
144  }
145  }
146  }
147 
148  alloc_ivector_and_copy_int_list(&nodes_at_level_head, num_at_level,
149  &tnodes_at_level[num_levels], &free_list_head);
150  }
151 
153  num_levels * sizeof(struct s_ivec));
154  num_tnode_levels = num_levels;
155 
156  free(tnode_fanin_left);
157  free_int_list(&free_list_head);
158  return (num_sinks);
159 }
struct s_ivec * tnodes_at_level
Definition: path_delay2.c:12
int num_tnodes
Definition: path_delay.c:144
static int * alloc_and_load_tnode_fanin_and_check_edges(int *num_sinks_ptr)
Definition: path_delay2.c:27
int * list
Definition: util.h:49
t_linked_int * insert_in_int_list(t_linked_int *head, int data, t_linked_int **free_list_head_ptr)
Definition: util.c:319
void alloc_ivector_and_copy_int_list(t_linked_int **list_head_ptr, int num_items, struct s_ivec *ivec, t_linked_int **free_list_head_ptr)
Definition: util.c:359
int num_edges
Definition: vpr_types.h:342
int num_tnode_levels
Definition: path_delay2.c:10
static void * my_malloc(int ibytes)
Definition: graphics.c:499
t_tnode * tnode
Definition: path_delay.c:143
int nelem
Definition: util.h:48
void free_int_list(t_linked_int **int_list_head_ptr)
Definition: util.c:341
Definition: util.h:47
t_tedge * out_edges
Definition: vpr_types.h:336
static void * my_realloc(void *memblk, int ibytes)
Definition: graphics.c:512
int to_node
Definition: vpr_types.h:296

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int * alloc_and_load_tnode_fanin_and_check_edges ( int *  num_sinks_ptr)
static

Definition at line 27 of file path_delay2.c.

27  {
28 
29  /* Allocates an array and fills it with the number of in-edges (inputs) to *
30  * each tnode. While doing this it also checks that each edge in the timing *
31  * graph points to a valid tnode. Also counts the number of sinks. */
32 
33  int inode, iedge, to_node, num_edges, error, num_sinks;
34  int *tnode_num_fanin;
35  t_tedge *tedge;
36 
37  tnode_num_fanin = (int *) my_calloc(num_tnodes, sizeof(int));
38  error = 0;
39  num_sinks = 0;
40 
41  for (inode = 0; inode < num_tnodes; inode++) {
42  num_edges = tnode[inode].num_edges;
43 
44  if (num_edges > 0) {
45  tedge = tnode[inode].out_edges;
46  for (iedge = 0; iedge < num_edges; iedge++) {
47  to_node = tedge[iedge].to_node;
48  if (to_node < 0 || to_node >= num_tnodes) {
49  vpr_printf(TIO_MESSAGE_ERROR, "in alloc_and_load_tnode_fanin_and_check_edges:\n");
50  vpr_printf(TIO_MESSAGE_ERROR, "\ttnode #%d edge #%d goes to illegal node #%d.\n",
51  inode, iedge, to_node);
52  error++;
53  }
54 
55  tnode_num_fanin[to_node]++;
56  }
57  }
58 
59  else if (num_edges == 0) {
60  num_sinks++;
61  }
62 
63  else {
64  vpr_printf(TIO_MESSAGE_ERROR, "in alloc_and_load_tnode_fanin_and_check_edges:\n");
65  vpr_printf(TIO_MESSAGE_ERROR, "\ttnode #%d has %d edges.\n",
66  inode, num_edges);
67  error++;
68  }
69 
70  }
71 
72  if (error != 0) {
73  vpr_printf(TIO_MESSAGE_ERROR, "Found %d Errors in the timing graph. Aborting.\n", error);
74  exit(1);
75  }
76 
77  *num_sinks_ptr = num_sinks;
78  return (tnode_num_fanin);
79 }
int num_tnodes
Definition: path_delay.c:144
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
int num_edges
Definition: vpr_types.h:342
t_tnode * tnode
Definition: path_delay.c:143
t_tedge * out_edges
Definition: vpr_types.h:336
int to_node
Definition: vpr_types.h:296
messagelogger vpr_printf
Definition: util.c:17

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void check_timing_graph ( int  num_sinks)

Definition at line 161 of file path_delay2.c.

161  {
162 
163  /* Checks the timing graph to see that: (1) all the tnodes have been put *
164  * into some level of the timing graph; */
165 
166  /* Addition error checks that need to be done but not yet implemented: (2) the number of primary inputs *
167  * to the timing graph is equal to the number of input pads + the number of *
168  * constant generators; and (3) the number of sinks (nodes with no fanout) *
169  * equals the number of output pads + the number of flip flops. */
170 
171  int num_tnodes_check, ilevel, error;
172 
173  error = 0;
174  num_tnodes_check = 0;
175 
176  /* TODO: Rework error checks for I/Os*/
177 
178  for (ilevel = 0; ilevel < num_tnode_levels; ilevel++)
179  num_tnodes_check += tnodes_at_level[ilevel].nelem;
180 
181  if (num_tnodes_check != num_tnodes) {
182  vpr_printf(TIO_MESSAGE_ERROR, "Error in check_timing_graph: %d tnodes appear in the tnode level structure. Expected %d.\n",
183  num_tnodes_check, num_tnodes);
184  vpr_printf(TIO_MESSAGE_INFO, "Check the netlist for combinational cycles.\n");
185  if (num_tnodes > num_tnodes_check) {
187  }
188  error++;
189  }
190  /* Todo: Add error checks that # of flip-flops, memories, and other
191  black boxes match # of sinks/sources*/
192 
193  if (error != 0) {
194  vpr_printf(TIO_MESSAGE_ERROR, "Found %d Errors in the timing graph. Aborting.\n", error);
195  exit(1);
196  }
197 }
struct s_ivec * tnodes_at_level
Definition: path_delay2.c:12
int num_tnodes
Definition: path_delay.c:144
static void show_combinational_cycle_candidates()
Definition: path_delay2.c:266
int num_tnode_levels
Definition: path_delay2.c:10
int nelem
Definition: util.h:48
messagelogger vpr_printf
Definition: util.c:17

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float print_critical_path_node ( FILE *  fp,
t_linked_int critical_path_node 
)

Definition at line 199 of file path_delay2.c.

199  {
200 
201  /* Prints one tnode on the critical path out to fp. Returns the delay to the next node. */
202 
203  int inode, iblk, inet, downstream_node;
204  t_pb_graph_pin * pb_graph_pin;
205  e_tnode_type type;
206  static const char *tnode_type_names[] = { "TN_INPAD_SOURCE", "TN_INPAD_OPIN",
207  "TN_OUTPAD_IPIN", "TN_OUTPAD_SINK", "TN_CB_IPIN", "TN_CB_OPIN",
208  "TN_INTERMEDIATE_NODE", "TN_PRIMITIVE_IPIN", "TN_PRIMITIVE_OPIN", "TN_FF_IPIN",
209  "TN_FF_OPIN", "TN_FF_SINK", "TN_FF_SOURCE", "TN_FF_CLOCK", "TN_CONSTANT_GEN_SOURCE" };
210 
211  t_linked_int *next_crit_node;
212  float Tdel;
213 
214  inode = critical_path_node->data;
215  type = tnode[inode].type;
216  iblk = tnode[inode].block;
217  pb_graph_pin = tnode[inode].pb_graph_pin;
218 
219  fprintf(fp, "Node: %d %s Block #%d (%s)\n", inode, tnode_type_names[type],
220  iblk, block[iblk].name);
221 
222  if (pb_graph_pin == NULL) {
223  assert(
224  type == TN_INPAD_SOURCE || type == TN_OUTPAD_SINK || type == TN_FF_SOURCE || type == TN_FF_SINK);
225  }
226 
227  if (pb_graph_pin != NULL) {
228  fprintf(fp, "Pin: %s.%s[%d] pb (%s)", pb_graph_pin->parent_node->pb_type->name,
229  pb_graph_pin->port->name, pb_graph_pin->pin_number, block[iblk].pb->rr_node_to_pb_mapping[pb_graph_pin->pin_count_in_cluster]->name);
230  }
231  if (type != TN_INPAD_SOURCE && type != TN_OUTPAD_SINK) {
232  fprintf(fp, "\n");
233  }
234 
235  fprintf(fp, "T_arr: %g T_req: %g ", tnode[inode].T_arr,
236  tnode[inode].T_req);
237 
238  next_crit_node = critical_path_node->next;
239  if (next_crit_node != NULL) {
240  downstream_node = next_crit_node->data;
241  Tdel = tnode[downstream_node].T_arr - tnode[inode].T_arr;
242  fprintf(fp, "Tdel: %g\n", Tdel);
243  } else { /* last node, no Tdel. */
244  Tdel = 0.;
245  fprintf(fp, "\n");
246  }
247 
248  if (type == TN_CB_OPIN) {
249  inet =
250  block[iblk].pb->rr_graph[pb_graph_pin->pin_count_in_cluster].net_num;
251  inet = vpack_to_clb_net_mapping[inet];
252  fprintf(fp, "External-to-Block Net: #%d (%s). Pins on net: %d.\n",
253  inet, clb_net[inet].name, (clb_net[inet].num_sinks + 1));
254  } else if (pb_graph_pin != NULL) {
255  inet =
256  block[iblk].pb->rr_graph[pb_graph_pin->pin_count_in_cluster].net_num;
257  fprintf(fp, "Internal Net: #%d (%s). Pins on net: %d.\n", inet,
258  vpack_net[inet].name, (vpack_net[inet].num_sinks + 1));
259  }
260 
261  fprintf(fp, "\n");
262  return (Tdel);
263 }
char * name
Definition: vpr_types.h:179
int net_num
Definition: vpr_types.h:917
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
int data
Definition: util.h:40
float T_arr
Definition: vpr_types.h:343
e_tnode_type
Definition: vpr_types.h:300
struct s_pb ** rr_node_to_pb_mapping
Definition: vpr_types.h:189
int block
Definition: vpr_types.h:346
t_tnode * tnode
Definition: path_delay.c:143
int * vpack_to_clb_net_mapping
Definition: globals.c:34
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
char * name
struct s_pb_graph_node * parent_node
t_pb_graph_pin * pb_graph_pin
Definition: vpr_types.h:358
struct s_pb_type * pb_type
t_pb * pb
Definition: vpr_types.h:567
struct s_linked_int * next
Definition: util.h:41
e_tnode_type type
Definition: vpr_types.h:335
struct s_net * vpack_net
Definition: globals.c:19

+ Here is the caller graph for this function:

static void show_combinational_cycle_candidates ( )
static

Definition at line 266 of file path_delay2.c.

266  {
267  boolean *found_tnode;
268  int ilevel, i, inode;
269 
270  found_tnode = (boolean*) my_calloc(num_tnodes, sizeof(boolean));
271 
272  for (ilevel = 0; ilevel < num_tnode_levels; ilevel++) {
273  for (i = 0; i < tnodes_at_level[ilevel].nelem; i++) {
274  inode = tnodes_at_level[ilevel].list[i];
275  found_tnode[inode] = TRUE;
276  }
277  }
278 
279  vpr_printf(TIO_MESSAGE_INFO, "\tProblematic nodes:\n");
280  for (i = 0; i < num_tnodes; i++) {
281  if (found_tnode[i] == FALSE) {
282  vpr_printf(TIO_MESSAGE_INFO, "\t\ttnode %d ", i);
283  if (tnode[i].pb_graph_pin == NULL) {
284  vpr_printf(TIO_MESSAGE_INFO, "block %s port %d pin %d\n", logical_block[tnode[i].block].name, tnode[i].prepacked_data->model_port, tnode[i].prepacked_data->model_pin);
285  } else {
286  vpr_printf(TIO_MESSAGE_INFO, "\n");
287  }
288  }
289  }
290 
291  free(found_tnode);
292 }
struct s_ivec * tnodes_at_level
Definition: path_delay2.c:12
int num_tnodes
Definition: path_delay.c:144
int * list
Definition: util.h:49
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
t_prepacked_tnode_data * prepacked_data
Definition: vpr_types.h:361
Definition: util.h:12
int num_tnode_levels
Definition: path_delay2.c:10
t_tnode * tnode
Definition: path_delay.c:143
struct s_block * block
Definition: globals.c:31
int nelem
Definition: util.h:48
messagelogger vpr_printf
Definition: util.c:17
struct s_logical_block * logical_block
Definition: globals.c:20
Definition: util.h:12

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

int num_tnode_levels

Definition at line 10 of file path_delay2.c.

struct s_ivec* tnodes_at_level

Definition at line 12 of file path_delay2.c.