⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_delay.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Allocates a new rc_node, from the free list if possible, from the free   * * store otherwise.                                                         */ t_rc_node *rc_node; rc_node = *rc_node_free_list_ptr; if (rc_node != NULL) {    *rc_node_free_list_ptr = rc_node->u.next; } else {    rc_node = (t_rc_node *) my_malloc (sizeof (t_rc_node)); } return (rc_node);}static void free_rc_node (t_rc_node *rc_node, t_rc_node            **rc_node_free_list_ptr) {/* Adds rc_node to the proper free list.          */ rc_node->u.next = *rc_node_free_list_ptr; *rc_node_free_list_ptr = rc_node;}static t_linked_rc_edge *alloc_linked_rc_edge (t_linked_rc_edge             **rc_edge_free_list_ptr) {/* Allocates a new linked_rc_edge, from the free list if possible, from the  * * free store otherwise.                                                     */ t_linked_rc_edge *linked_rc_edge; linked_rc_edge = *rc_edge_free_list_ptr; if (linked_rc_edge != NULL) {    *rc_edge_free_list_ptr = linked_rc_edge->next; } else {    linked_rc_edge = (t_linked_rc_edge *) my_malloc (sizeof                       (t_linked_rc_edge)); } return (linked_rc_edge);}static void free_linked_rc_edge (t_linked_rc_edge *rc_edge, t_linked_rc_edge              **rc_edge_free_list_ptr) {/* Adds the rc_edge to the rc_edge free list.                       */ rc_edge->next = *rc_edge_free_list_ptr; *rc_edge_free_list_ptr = rc_edge;}static float load_rc_tree_C (t_rc_node *rc_node) {/* Does a post-order traversal of the rc tree to load each node's           * * C_downstream with the proper sum of all the downstream capacitances.     * * This routine calls itself recursively to perform the traversal.          */ t_linked_rc_edge *linked_rc_edge; t_rc_node *child_node; int inode; short iswitch; float C, C_downstream;  linked_rc_edge = rc_node->u.child_list; inode = rc_node->inode; C = rr_node[inode].C; while (linked_rc_edge != NULL) {            /* For all children */    iswitch = linked_rc_edge->iswitch;    child_node = linked_rc_edge->child;    C_downstream = load_rc_tree_C (child_node);    if (switch_inf[iswitch].buffered == FALSE)       C += C_downstream;    linked_rc_edge = linked_rc_edge->next; } rc_node->C_downstream = C; return (C);}static void load_rc_tree_T (t_rc_node *rc_node, float T_arrival) {/* This routine does a pre-order depth-first traversal of the rc tree to    * * compute the Tdel to each node in the rc tree.  The T_arrival is the time * * at which the signal hits the input to this node.  This routine calls     * * itself recursively to perform the traversal.                             */ float Tdel, Rmetal, Tchild; t_linked_rc_edge *linked_rc_edge; t_rc_node *child_node; short iswitch; int inode; Tdel = T_arrival; inode = rc_node->inode;   Rmetal = rr_node[inode].R;/* NB:  rr_node[inode].C gives the capacitance of this node, while          * * rc_node->C_downstream gives the unbuffered downstream capacitance rooted * * at this node, including the C of the node itself.  I want to multiply    * * the C of this node by 0.5 Rmetal, since it's a distributed RC line.      * * Hence 0.5 Rmetal * Cnode is a pessimistic estimate of delay (i.e. end to * * end).  For the downstream capacitance rooted at this node (not including * * the capacitance of the node itself), I assume it is, on average,         * * connected halfway along the line, so I also multiply by 0.5 Rmetal.  To  * * be totally pessimistic I would multiply the downstream part of the       * * capacitance by Rmetal.  Play with this equation if you like.             *//* Rmetal is distributed so x0.5 */ Tdel += 0.5 * rc_node->C_downstream * Rmetal;   rc_node->Tdel = Tdel;/* Now expand the children of this node to load their Tdel values.       */ linked_rc_edge = rc_node->u.child_list; while (linked_rc_edge != NULL) {          /* For all children */    iswitch = linked_rc_edge->iswitch;    child_node = linked_rc_edge->child;    Tchild = Tdel + switch_inf[iswitch].R * child_node->C_downstream;    Tchild += switch_inf[iswitch].Tdel;   /* Intrinsic switch delay. */    load_rc_tree_T (child_node, Tchild);    linked_rc_edge = linked_rc_edge->next; }}static void load_one_net_delay (float **net_delay, int inet, t_linked_rc_ptr               *rr_node_to_rc_node) {/* Loads the net delay array for net inet.  The rc tree for that net must  * * have already been completely built and loaded.                          */ int ipin, inode; float Tmax; t_rc_node *rc_node; t_linked_rc_ptr *linked_rc_ptr, *next_ptr; for (ipin=1;ipin<net[inet].num_pins;ipin++) {    inode = net_rr_terminals[inet][ipin];     linked_rc_ptr = rr_node_to_rc_node[inode].next;    rc_node = rr_node_to_rc_node[inode].rc_node;    Tmax = rc_node->Tdel;   /* If below only executes when one net connects several times to the      *    * same SINK.  In this case, I can't tell which net pin each connection   *    * to this SINK corresponds to (I can just choose arbitrarily).  To make  *    * sure the timing behaviour converges, I pessimistically set the delay   *    * for all of the connections to this SINK by this net to be the max. of  *    * the delays from this net to this SINK.  NB:  This code only occurs     *    * when a net connect more than once to the same pin class on the same    *    * logic block.  Only a weird architecture would allow this.              */    if (linked_rc_ptr != NULL) {   /* The first time I hit a multiply-used SINK, I choose the largest delay  *    * from this net to this SINK and use it for every connection to this     *    * SINK by this net.                                                      */       do {          rc_node = linked_rc_ptr->rc_node;          if (rc_node->Tdel > Tmax) {             Tmax = rc_node->Tdel;             rr_node_to_rc_node[inode].rc_node = rc_node;          }          next_ptr = linked_rc_ptr->next;          free (linked_rc_ptr);          linked_rc_ptr = next_ptr;       } while (linked_rc_ptr != NULL);   /* End do while */           rr_node_to_rc_node[inode].next = NULL;    }   /* End of if multiply-used SINK */    net_delay[inet][ipin] = Tmax; }}static void load_one_constant_net_delay (float **net_delay, int inet, float       delay_value) {/* Sets each entry of the net_delay array for net inet to delay_value.     */ int ipin;  for (ipin=1;ipin<net[inet].num_pins;ipin++)     net_delay[inet][ipin] = delay_value;}static void free_rc_tree (t_rc_node *rc_root, t_rc_node            **rc_node_free_list_ptr, t_linked_rc_edge **rc_edge_free_list_ptr) {/* Puts the rc tree pointed to by rc_root back on the free list.  Depth-     * * first post-order traversal via recursion.                                 */ t_rc_node *rc_node, *child_node; t_linked_rc_edge *rc_edge, *next_edge; rc_node = rc_root; rc_edge = rc_node->u.child_list; while (rc_edge != NULL) {     /* For all children */    child_node = rc_edge->child;    free_rc_tree (child_node, rc_node_free_list_ptr, rc_edge_free_list_ptr);    next_edge = rc_edge->next;    free_linked_rc_edge (rc_edge, rc_edge_free_list_ptr);    rc_edge = next_edge; } free_rc_node (rc_node, rc_node_free_list_ptr);}static void reset_rr_node_to_rc_node (t_linked_rc_ptr *rr_node_to_rc_node, int             inet) {/* Resets the rr_node_to_rc_node mapping entries that were set during       * * construction of the RC tree for net inet.  Any extra linked list entries * * added to deal with a SINK being connected to multiple times have already * * been freed by load_one_net_delay.                                        */ struct s_trace *tptr; int inode; tptr = trace_head[inet]; while (tptr != NULL) {    inode = tptr->index;    rr_node_to_rc_node[inode].rc_node = NULL;    tptr = tptr->next; }}static void free_rc_node_free_list (t_rc_node *rc_node_free_list) {/* Really frees (i.e. calls free()) all the rc_nodes on the free list.   */ t_rc_node *rc_node, *next_node; rc_node = rc_node_free_list; while (rc_node != NULL) {    next_node = rc_node->u.next;    free (rc_node);    rc_node = next_node; }}static void free_rc_edge_free_list (t_linked_rc_edge *rc_edge_free_list) {/* Really frees (i.e. calls free()) all the rc_edges on the free list.   */ t_linked_rc_edge *rc_edge, *next_edge; rc_edge = rc_edge_free_list; while (rc_edge != NULL) {    next_edge = rc_edge->next;    free (rc_edge);    rc_edge = next_edge; }}void print_net_delay (float **net_delay, char *fname) {/* Dumps the net delays into file fname.   */ FILE *fp; int inet, ipin; fp = my_fopen (fname, "w", 0);  for (inet=0;inet<num_nets;inet++) {    fprintf (fp, "Net: %d.\n", inet);    fprintf (fp, "Delays:");        for (ipin=1;ipin<net[inet].num_pins;ipin++)        fprintf (fp, " %g", net_delay[inet][ipin]);        fprintf (fp, "\n\n"); } fclose (fp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -