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

📄 path_delay.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 4 页
字号:
       tnode_descript[inode].ipin = out_pin;       tnode_descript[inode].isubblk = isub;       tnode_descript[inode].iblk = iblk;    } }/* Load the output pins edge arrays. */ for (isub=0;isub<num_subs;isub++) {    for (ipin=0;ipin<subblock_lut_size;ipin++) {  /* sblk opin to sblk ipin */       from_pin = sub_inf[isub].inputs[ipin];      /* Not OPEN and comes from local subblock output? */       if (from_pin >= pins_per_clb) {          inode = sub_pin_to_tnode[from_pin - pins_per_clb][out_pin];          to_node = sub_pin_to_tnode[isub][ipin];          tedge = tnode[inode].out_edges;          iedge = next_sblk_opin_edge[from_pin - pins_per_clb]++;          tedge[iedge].to_node = to_node;          tedge[iedge].Tdel = T_sblk_opin_to_sblk_ipin;       }    }    from_pin = sub_inf[isub].clock;    /* sblk opin to sblk clock */   /* Not OPEN and comes from local subblock output? */    if (from_pin >= pins_per_clb) {       inode = sub_pin_to_tnode[from_pin - pins_per_clb][out_pin];       to_node = sub_pin_to_tnode[isub][clk_pin];   /* Feeds seq. output */       tedge = tnode[inode].out_edges;       iedge = next_sblk_opin_edge[from_pin - pins_per_clb]++;       tedge[iedge].to_node = to_node; /* NB: Could make sblk opin to clk delay parameter; not worth it right now. */       tedge[iedge].Tdel = T_sblk_opin_to_sblk_ipin;      }    to_pin = sub_inf[isub].output;    if (to_pin != OPEN) {  /* sblk opin goes to clb opin? */             /* Check that CLB pin connects to something ->     *              * not just a mandatory BLE to CLB opin connection */       if (block[iblk].nets[to_pin] != OPEN) {          to_node = blk_pin_to_tnode[to_pin];          inode = sub_pin_to_tnode[isub][out_pin];          tedge = tnode[inode].out_edges;          iedge = next_sblk_opin_edge[isub]++;          tedge[iedge].to_node = to_node;          tedge[iedge].Tdel = T_sblk_opin_to_clb_opin;       }    } }/* Now build the subblock input pins and, if the subblock is used in        * * sequential mode (i.e. is clocked), the two clock pin nodes.              */ for (isub=0;isub<num_subs;isub++) {    if (sub_pin_to_tnode[isub][out_pin] == OPEN)    /* Empty, so skip */       continue;    if (sub_inf[isub].clock == OPEN) {  /* Combinational mode */       to_node = sub_pin_to_tnode[isub][out_pin];       ipin_to_sink_Tdel = T_subblock[isub].T_comb;    }    else {     /* Sequential mode.  Build two clock nodes. */      /* First node is the clock input pin; it feeds the sequential output */       inode = sub_pin_to_tnode[isub][clk_pin];       tnode[inode].num_edges = 1;       tnode[inode].out_edges = (t_tedge *) my_chunk_malloc ( sizeof (t_tedge),            &tedge_ch_list_head, &tedge_ch_bytes_avail, &tedge_ch_next_avail);       tedge = tnode[inode].out_edges;       tedge[0].to_node = sub_pin_to_tnode[isub][out_pin];       tedge[0].Tdel = T_subblock[isub].T_seq_out;       tnode_descript[inode].type = FF_SOURCE;       tnode_descript[inode].ipin = OPEN;       tnode_descript[inode].isubblk = isub;       tnode_descript[inode].iblk = iblk;      /* Now create the "sequential sink" -- i.e. the FF input node. */       inode++;       tnode[inode].num_edges = 0;       tnode[inode].out_edges = NULL;       tnode_descript[inode].type = FF_SINK;       tnode_descript[inode].ipin = OPEN;       tnode_descript[inode].isubblk = isub;       tnode_descript[inode].iblk = iblk;             /* Subblock inputs connect to this node. */        to_node = inode;       ipin_to_sink_Tdel = T_subblock[isub].T_seq_in;    }  /* Build and hook up subblock inputs. */    has_inputs = FALSE;    for (ipin=0;ipin<subblock_lut_size;ipin++) {       inode = sub_pin_to_tnode[isub][ipin];              if (inode != OPEN) {    /* tnode exists -> pin is used */          has_inputs = TRUE;          tnode[inode].num_edges = 1;          tnode[inode].out_edges = (t_tedge *) my_chunk_malloc ( sizeof                 (t_tedge), &tedge_ch_list_head, &tedge_ch_bytes_avail,                 &tedge_ch_next_avail);          tedge = tnode[inode].out_edges;          tedge[0].to_node = to_node;          tedge[0].Tdel = ipin_to_sink_Tdel;          tnode_descript[inode].type = SUBBLK_IPIN;          tnode_descript[inode].ipin = ipin;          tnode_descript[inode].isubblk = isub;          tnode_descript[inode].iblk = iblk;       }    }#define T_CONSTANT_GENERATOR -1000   /* Essentially -ve infinity */    if (!has_inputs) {    /* Constant generator.  Give fake input. */       inode = sub_pin_to_tnode[isub][out_pin] + 1;       tnode[inode].num_edges = 1;       tnode[inode].out_edges = (t_tedge *) my_chunk_malloc ( sizeof (t_tedge),            &tedge_ch_list_head, &tedge_ch_bytes_avail, &tedge_ch_next_avail);       tedge = tnode[inode].out_edges;       tedge[0].to_node = to_node;/* Want constants generated early so they never affect the critical path. */        tedge[0].Tdel = T_CONSTANT_GENERATOR;       tnode_descript[inode].type = CONSTANT_GEN_SOURCE;       tnode_descript[inode].ipin = OPEN;       tnode_descript[inode].isubblk = isub;       tnode_descript[inode].iblk = iblk;    } }  /* End for each subblock */}static void build_ipad_tnodes (int iblk, int **block_pin_to_tnode, float            T_ipad, int *num_subblocks_per_block, t_subblock **subblock_inf) {/* Builds the two tnodes corresponding to an input pad, and hooks them into * * the timing graph.                                                        */ int to_node, inode; t_tedge *tedge;/* First node: input node to the pad -> nothing comes into this.  Second    * * node is the output node of the pad, that has edges to CLB ipins.         */ inode = block_pin_to_tnode[iblk][0]; to_node = block_pin_to_tnode[iblk][1]; tnode[inode].num_edges = 1; tnode[inode].out_edges = (t_tedge *) my_chunk_malloc ( sizeof (t_tedge),        &tedge_ch_list_head, &tedge_ch_bytes_avail, &tedge_ch_next_avail); tedge = tnode[inode].out_edges; tedge[0].to_node =  to_node; /* By definition, global clocks from pads arrive at T = 0.  The earliest any * * clock can arrive at any flip flop is T = 0, and the fastest global clock  * * from a pad should have zero delay on its edges so it does get to the      * * flip flop clock pin at T = 0.                                             */ if (is_global_clock (iblk, num_subblocks_per_block, subblock_inf))       tedge[0].Tdel = 0.; else     tedge[0].Tdel = T_ipad; tnode_descript[inode].type = INPAD_SOURCE; tnode_descript[inode].ipin = OPEN; tnode_descript[inode].isubblk = OPEN; tnode_descript[inode].iblk = iblk;/* Now do pad output. */ build_block_output_tnode (to_node, iblk, 0, block_pin_to_tnode); tnode_descript[to_node].type = INPAD_OPIN; tnode_descript[to_node].ipin = 0; tnode_descript[to_node].isubblk = OPEN; tnode_descript[to_node].iblk = iblk;}static boolean is_global_clock (int iblk, int *num_subblocks_per_block,     t_subblock **subblock_inf) {/* Returns TRUE if the net driven by this block (which must be an INPAD) is  * * (1) a global signal, and (2) used as a clock input to at least one block. */ int inet, ipin, to_blk, to_pin, isub;  inet = block[iblk].nets[0]; if (!is_global[inet])     return (FALSE); for (ipin=1;ipin<net[inet].num_pins;ipin++) {    to_blk = net[inet].blocks[ipin];    to_pin = net[inet].blk_pin[ipin];    for (isub=0;isub<num_subblocks_per_block[to_blk];isub++) {       if (subblock_inf[to_blk][isub].clock == to_pin)          return (TRUE);    } } return (FALSE);}static void build_opad_tnodes (int *blk_pin_to_tnode, float T_opad, int iblk) {/* Builds the two tnodes in an output pad and connects them up.   */ int to_node, inode; t_tedge *tedge;/* First node: input node to the pad -> will be driven some net.  Second    * * node is the output node of the pad, which connects to nothing.           */ inode = blk_pin_to_tnode[0]; to_node = blk_pin_to_tnode[1]; tnode[inode].num_edges = 1; tnode[inode].out_edges = (t_tedge *) my_chunk_malloc ( sizeof (t_tedge),        &tedge_ch_list_head, &tedge_ch_bytes_avail, &tedge_ch_next_avail); tedge = tnode[inode].out_edges; tedge[0].to_node =  to_node;  tedge[0].Tdel = T_opad; tnode_descript[inode].type = OUTPAD_IPIN; tnode_descript[inode].ipin = 0; tnode_descript[inode].isubblk = OPEN; tnode_descript[inode].iblk = iblk; tnode[to_node].num_edges = 0; tnode[to_node].out_edges = NULL; tnode_descript[to_node].type = OUTPAD_SINK; tnode_descript[to_node].ipin = OPEN; tnode_descript[to_node].isubblk = OPEN; tnode_descript[to_node].iblk = iblk;}void load_timing_graph_net_delays (float **net_delay) {/* Sets the delays of the inter-CLB nets to the values specified by          * * net_delay[0..num_nets-1][1..num_pins-1].  These net delays should have    * * been allocated and loaded with the net_delay routines.  This routine      * * marks the corresponding edges in the timing graph with the proper delay.  */ int inet, ipin, inode; t_tedge *tedge; for (inet=0;inet<num_nets;inet++) {    inode = net_to_driver_tnode[inet];    tedge = tnode[inode].out_edges;/* Note that the edges of a tnode corresponding to a CLB or INPAD opin must  * * be in the same order as the pins of the net driven by the tnode.          */    for (ipin=1;ipin<net[inet].num_pins;ipin++)        tedge[ipin-1].Tdel = net_delay[inet][ipin]; }}void free_timing_graph (float **net_slack) {/* Frees the timing graph data. */ if (tedge_ch_list_head == NULL) {    printf ("Error in free_timing_graph: No timing graph to free.\n");    exit (1); } free_chunk_memory (tedge_ch_list_head); free (tnode); free (tnode_descript); free (net_to_driver_tnode); free_ivec_vector (tnodes_at_level, 0, num_tnode_levels - 1); free (net_slack);  tedge_ch_list_head = NULL; tedge_ch_bytes_avail = 0; tedge_ch_next_avail = NULL; tnode = NULL; tnode_descript = NULL; num_tnodes = 0; net_to_driver_tnode = NULL; tnodes_at_level = NULL; num_tnode_levels = 0;}void print_net_slack (char *fname, float **net_slack) {/* Prints the net slacks into a file.                                     */ int inet, ipin; FILE *fp; fp = my_fopen (fname, "w", 0); fprintf (fp, "Net #\tSlacks\n\n"); for (inet=0;inet<num_nets;inet++) {    fprintf (fp, "%5d", inet);    for (ipin=1;ipin<net[inet].num_pins;ipin++) {       fprintf (fp, "\t%g", net_slack[inet][ipin]);    }    fprintf (fp, "\n"); }}void print_timing_graph (char *fname) {/* Prints the timing graph into a file.           */ FILE *fp; int inode, iedge, ilevel, i; t_tedge *tedge; t_tnode_type itype; char *tnode_type_names[] = {"INPAD_SOURCE", "INPAD_OPIN",            "OUTPAD_IPIN", "OUTPAD_SINK", "CLB_IPIN", "CLB_OPIN",            "SUBBLK_IPIN", "SUBBLK_OPIN", "FF_SINK", "FF_SOURCE",

⌨️ 快捷键说明

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