📄 path_delay.c
字号:
/* 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 + -