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

📄 path_delay.c

📁 fpga设计评估软件
💻 C
📖 第 1 页 / 共 4 页
字号:
         /* If this is a sequential block, we have two more pins: #1: the    *          * clock input (connects to the subblock output node) and #2: the   *          * sequential sink (which the subblock LUT inputs will connect to). */             sblk_pin_to_tnode[iblk][isub][clk_pin] = curr_tnode;             curr_tnode += 2;          }          else {             sblk_pin_to_tnode[iblk][isub][clk_pin] = OPEN;          }       }           }   /* End if a clb. */    else {   /* INPAD or OUTPAD */       block_pin_to_tnode[iblk][0] = curr_tnode;         /* Pad input  */       block_pin_to_tnode[iblk][1] = curr_tnode + 1;     /* Pad output */       curr_tnode += 2;       for (ipin=2;ipin<pins_per_clb;ipin++)           block_pin_to_tnode[iblk][ipin] = OPEN;       sblk_pin_to_tnode[iblk] = NULL;  /* No subblock pins */    } }  /* End for all blocks */ *sblk_pin_to_tnode_ptr = sblk_pin_to_tnode; *block_pin_to_tnode_ptr = block_pin_to_tnode; return (curr_tnode);}static void free_pin_mappings (int **block_pin_to_tnode, int           ***sblk_pin_to_tnode, int *num_subblocks_per_block) {/* Frees the arrays that map from pins to tnode coordinates. */ int iblk; free_matrix (block_pin_to_tnode, 0, num_blocks - 1, 0, sizeof (int));  for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type == CLB) {       free_matrix (sblk_pin_to_tnode[iblk], 0, num_subblocks_per_block[iblk]                      - 1, 0, sizeof (int));    } } free (sblk_pin_to_tnode);}static void alloc_and_load_fanout_counts (int ***num_uses_of_clb_ipin_ptr,          int ***num_uses_of_sblk_opin_ptr, t_subblock_data subblock_data) {/* Allocates and loads two arrays that say how many points each clb input   * * pin and each subblock output fan out to.                                 */ int iblk; int **num_uses_of_clb_ipin, **num_uses_of_sblk_opin; int *num_subblocks_per_block; t_subblock **subblock_inf; int subblock_lut_size; num_subblocks_per_block = subblock_data.num_subblocks_per_block; subblock_inf = subblock_data.subblock_inf; subblock_lut_size = subblock_data.subblock_lut_size; num_uses_of_clb_ipin = (int **) my_malloc (num_blocks * sizeof (int *)); num_uses_of_sblk_opin = (int **) my_malloc (num_blocks * sizeof (int *)); for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type != CLB) {       num_uses_of_clb_ipin[iblk] = NULL;       num_uses_of_sblk_opin[iblk] = NULL;    }    else {   /* CLB */       num_uses_of_clb_ipin[iblk] = (int *) my_calloc (pins_per_clb,                     sizeof (int));       num_uses_of_sblk_opin[iblk] = (int *) my_calloc (                    num_subblocks_per_block[iblk], sizeof (int));       load_one_clb_fanout_count (subblock_lut_size, subblock_inf[iblk],                    num_subblocks_per_block[iblk], num_uses_of_clb_ipin[iblk],                    num_uses_of_sblk_opin[iblk], iblk);    }  /* End if CLB */ }  /* End for all blocks */ *num_uses_of_clb_ipin_ptr = num_uses_of_clb_ipin; *num_uses_of_sblk_opin_ptr = num_uses_of_sblk_opin;}static void free_fanout_counts (int **num_uses_of_clb_ipin, int              **num_uses_of_sblk_opin) {/* Frees the fanout count arrays. */ int iblk;  for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type == CLB) {       free (num_uses_of_clb_ipin[iblk]);       free (num_uses_of_sblk_opin[iblk]);    } } free (num_uses_of_clb_ipin); free (num_uses_of_sblk_opin);}static void alloc_and_load_tnodes_and_net_mapping (int **num_uses_of_clb_ipin,           int **num_uses_of_sblk_opin, int **block_pin_to_tnode, int ***          sblk_pin_to_tnode, t_subblock_data subblock_data, t_timing_inf          timing_inf) {/* Does the actual allocation and building of the timing graph. */ int iblk, subblock_lut_size; int *num_subblocks_per_block; int *next_clb_ipin_edge, *next_sblk_opin_edge; t_subblock **subblock_inf; tnode = (t_tnode *) my_malloc (num_tnodes * sizeof (t_tnode)); tnode_descript = (t_tnode_descript *) my_malloc (num_tnodes *                    sizeof (t_tnode_descript)); net_to_driver_tnode = (int *) my_malloc (num_nets * sizeof (int)); next_clb_ipin_edge = (int *) my_malloc (pins_per_clb * sizeof (int)); next_sblk_opin_edge = (int *) my_malloc (subblock_data.max_subblocks_per_block                                * sizeof (int)); subblock_inf = subblock_data.subblock_inf; subblock_lut_size = subblock_data.subblock_lut_size; num_subblocks_per_block = subblock_data.num_subblocks_per_block; for (iblk=0;iblk<num_blocks;iblk++) {    switch (block[iblk].type) {    case CLB:       build_clb_tnodes (iblk, num_uses_of_clb_ipin[iblk], block_pin_to_tnode,                sblk_pin_to_tnode[iblk], subblock_lut_size,               num_subblocks_per_block[iblk], subblock_inf[iblk],               timing_inf.T_clb_ipin_to_sblk_ipin, next_clb_ipin_edge);       build_subblock_tnodes (num_uses_of_sblk_opin[iblk],                block_pin_to_tnode[iblk], sblk_pin_to_tnode[iblk],                subblock_lut_size, num_subblocks_per_block[iblk],                subblock_inf[iblk], timing_inf.T_sblk_opin_to_sblk_ipin,                timing_inf.T_sblk_opin_to_clb_opin, timing_inf.T_subblock,               next_sblk_opin_edge, iblk);       break;    case INPAD:       build_ipad_tnodes (iblk, block_pin_to_tnode, timing_inf.T_ipad,                   num_subblocks_per_block, subblock_inf);       break;    case OUTPAD:       build_opad_tnodes (block_pin_to_tnode[iblk], timing_inf.T_opad, iblk);       break;       default:       printf ("Error in alloc_and_load_tnodes_and_net_mapping:\n"               "\tUnexpected block type (%d) for block %d (%s).\n",                 block[iblk].type, iblk, block[iblk].name);       exit (1);    } }  free (next_clb_ipin_edge); free (next_sblk_opin_edge);}static void build_clb_tnodes (int iblk, int *n_uses_of_clb_ipin, int         **block_pin_to_tnode, int **sub_pin_to_tnode, int subblock_lut_size,         int num_subs, t_subblock *sub_inf, float T_clb_ipin_to_sblk_ipin,        int *next_clb_ipin_edge) {/* This routine builds the tnodes corresponding to the clb pins of this     * * block, and properly hooks them up to the rest of the graph. Note that    * * only the sblk_pin_to_tnode, etc. element for this block is passed in.    */ int isub, ipin, iedge, from_pin; int inode, to_node, num_edges; t_tedge *tedge; int clk_pin; clk_pin = subblock_lut_size + 1;/* Start by allocating the edge arrays, and for opins, loading them.    */ for (ipin=0;ipin<pins_per_clb;ipin++) {    inode = block_pin_to_tnode[iblk][ipin];    if (inode != OPEN) {   /* Pin is used -> put in graph */       if (is_opin (ipin)) {          build_block_output_tnode (inode, iblk, ipin, block_pin_to_tnode);          tnode_descript[inode].type = CLB_OPIN;       }       else {    /* CLB ipin */          next_clb_ipin_edge[ipin] = 0;            /* Reset */          num_edges = n_uses_of_clb_ipin[ipin];          tnode[inode].num_edges = num_edges;          tnode[inode].out_edges = (t_tedge *) my_chunk_malloc (num_edges *                sizeof (t_tedge), &tedge_ch_list_head, &tedge_ch_bytes_avail,               &tedge_ch_next_avail);          tnode_descript[inode].type = CLB_IPIN;       }       tnode_descript[inode].ipin = ipin;       tnode_descript[inode].isubblk = OPEN;       tnode_descript[inode].iblk = iblk;    } }/* Now load the edge arrays for the CLB input pins. Do this by looking at   * * where the subblock input and clock pins are driven from.                 */ for (isub=0;isub<num_subs;isub++) {    for (ipin=0;ipin<subblock_lut_size;ipin++) {       from_pin = sub_inf[isub].inputs[ipin];      /* Not OPEN and comes from clb ipin? */       if (from_pin != OPEN && from_pin < pins_per_clb) {           inode = block_pin_to_tnode[iblk][from_pin];          to_node = sub_pin_to_tnode[isub][ipin];          tedge = tnode[inode].out_edges;          iedge = next_clb_ipin_edge[from_pin]++;          tedge[iedge].to_node = to_node;          tedge[iedge].Tdel = T_clb_ipin_to_sblk_ipin;       }    }    from_pin = sub_inf[isub].clock;    if (from_pin != OPEN && from_pin < pins_per_clb) {        inode = block_pin_to_tnode[iblk][from_pin];       to_node = sub_pin_to_tnode[isub][clk_pin];  /* Feeds seq. output */       tedge = tnode[inode].out_edges;       iedge = next_clb_ipin_edge[from_pin]++;       tedge[iedge].to_node = to_node;/* For the earliest possible clock I want this delay to be zero, so it       * * arrives at flip flops at T = 0.  For later clocks or locally generated    * * clocks that may accumulate delay (like the clocks in a ripple counter),   * * I might want to make this delay nonzero.  Not worth bothering about now.  */       tedge[iedge].Tdel = 0.;    } }}static void build_block_output_tnode (int inode, int iblk, int ipin,        int **block_pin_to_tnode) {/* Sets the number of edges and the edge array for an output pin from a      * * block.  This pin must be hooked to something -- i.e. not OPEN.            */ int iedge, to_blk, to_pin, to_node, num_edges, inet; t_tedge *tedge;  inet = block[iblk].nets[ipin];          /* Won't be OPEN, as inode exists */ assert (inet != OPEN);                  /* Sanity check. */ net_to_driver_tnode[inet] = inode;  num_edges = net[inet].num_pins - 1; tnode[inode].num_edges = num_edges; tnode[inode].out_edges = (t_tedge *) my_chunk_malloc (num_edges *         sizeof (t_tedge), &tedge_ch_list_head, &tedge_ch_bytes_avail,         &tedge_ch_next_avail); tedge = tnode[inode].out_edges; for (iedge=0;iedge<net[inet].num_pins-1;iedge++) {    to_blk = net[inet].blocks[iedge+1];    if (block[to_blk].type == CLB)       to_pin = net[inet].blk_pin[iedge+1];    else                  /* OUTPAD */       to_pin = 0;    to_node = block_pin_to_tnode[to_blk][to_pin];    tedge[iedge].to_node = to_node;   /* Set delay from net delays with a later call */ }}static void build_subblock_tnodes (int *n_uses_of_sblk_opin,           int *blk_pin_to_tnode, int **sub_pin_to_tnode,           int subblock_lut_size, int num_subs, t_subblock *sub_inf,           float T_sblk_opin_to_sblk_ipin, float T_sblk_opin_to_clb_opin,           t_T_subblock *T_subblock, int *next_sblk_opin_edge, int iblk) {/* This routine builds the tnodes of the subblock pins within one CLB. Note * * that only the block_pin_to_tnode, etc. data for *this* block are passed  * * in.                                                                      */ int isub, ipin, inode, to_node, from_pin, to_pin, out_pin, clk_pin; int iedge, num_edges; float ipin_to_sink_Tdel; t_tedge *tedge; boolean has_inputs;  out_pin = subblock_lut_size; clk_pin = subblock_lut_size + 1;/* Allocate memory for output pins first. */ for (isub=0;isub<num_subs;isub++) {    inode = sub_pin_to_tnode[isub][out_pin];        if (inode != OPEN) {     /* Output is used -> timing node exists. */       next_sblk_opin_edge[isub] = 0;    /* Reset */       num_edges = n_uses_of_sblk_opin[isub];       tnode[inode].num_edges = num_edges;       tnode[inode].out_edges = (t_tedge *) my_chunk_malloc (num_edges *             sizeof (t_tedge), &tedge_ch_list_head, &tedge_ch_bytes_avail,            &tedge_ch_next_avail);           tnode_descript[inode].type = SUBBLK_OPIN;

⌨️ 快捷键说明

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