📄 path_delay.c
字号:
}static voidfree_pin_mappings(int **block_pin_to_tnode, int ****snode_block_pin_to_tnode, int *num_subblocks_per_block){/* Frees the arrays that map from pins to tnode coordinates. */ int isub, iblk, isubtype, num_subblocks; for(iblk = 0; iblk < num_blocks; iblk++) { num_subblocks = num_subblocks_per_block[iblk]; for(isub = 0; isub < num_subblocks; isub++) { for(isubtype = 0; isubtype < NUM_SUB_PIN_TYPES; isubtype++) { free(snode_block_pin_to_tnode[iblk][isub] [isubtype]); } } free_matrix(snode_block_pin_to_tnode[iblk], 0, num_subblocks_per_block[iblk] - 1, 0, sizeof(int *)); free(block_pin_to_tnode[iblk]); } free(block_pin_to_tnode); free(snode_block_pin_to_tnode);}static voidalloc_and_load_fanout_counts(int ***num_uses_of_fb_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 fb input * * pin and each subblock output fan out to. */ int iblk; int **num_uses_of_fb_ipin, ***num_uses_of_sblk_opin; int *num_subblocks_per_block; t_subblock **subblock_inf; num_subblocks_per_block = subblock_data.num_subblocks_per_block; subblock_inf = subblock_data.subblock_inf; num_uses_of_fb_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++) { num_uses_of_fb_ipin[iblk] = (int *)my_calloc(block[iblk].type->num_pins, sizeof(int)); num_uses_of_sblk_opin[iblk] = (int **)alloc_matrix(0, block[iblk].type->max_subblocks - 1, 0, block[iblk].type->max_subblock_outputs - 1, sizeof(int)); load_one_fb_fanout_count(subblock_inf[iblk], num_subblocks_per_block[iblk], num_uses_of_fb_ipin[iblk], num_uses_of_sblk_opin[iblk], iblk); } /* End for all blocks */ *num_uses_of_fb_ipin_ptr = num_uses_of_fb_ipin; *num_uses_of_sblk_opin_ptr = num_uses_of_sblk_opin;}static voidfree_fanout_counts(int **num_uses_of_fb_ipin, int ***num_uses_of_sblk_opin){/* Frees the fanout count arrays. */ int iblk; t_type_ptr type; for(iblk = 0; iblk < num_blocks; iblk++) { type = block[iblk].type; free(num_uses_of_fb_ipin[iblk]); free_matrix(num_uses_of_sblk_opin[iblk], 0, type->max_subblocks - 1, 0, sizeof(int)); } free(num_uses_of_fb_ipin); free(num_uses_of_sblk_opin);}static voidalloc_and_load_tnodes_and_net_mapping(int **num_uses_of_fb_ipin, int ***num_uses_of_sblk_opin, int **block_pin_to_tnode, int ****snode_block_pin_to_tnode, t_subblock_data subblock_data, t_timing_inf timing_inf){ int iblk; int *num_subblocks_per_block; 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)); subblock_inf = subblock_data.subblock_inf; num_subblocks_per_block = subblock_data.num_subblocks_per_block; for(iblk = 0; iblk < num_blocks; iblk++) { build_fb_tnodes(iblk, num_uses_of_fb_ipin[iblk], block_pin_to_tnode, snode_block_pin_to_tnode[iblk], num_subblocks_per_block[iblk], subblock_inf[iblk], block[iblk].type->type_timing_inf. T_fb_ipin_to_sblk_ipin); build_subblock_tnodes(num_uses_of_sblk_opin[iblk], block_pin_to_tnode[iblk], snode_block_pin_to_tnode[iblk], num_subblocks_per_block, subblock_inf, timing_inf, iblk); }}static voidbuild_fb_tnodes(int iblk, int *n_uses_of_fb_ipin, int **block_pin_to_tnode, int ***sub_pin_to_tnode, int num_subs, t_subblock * sub_inf, float T_fb_ipin_to_sblk_ipin){/* This routine builds the tnodes corresponding to the fb pins of this * block, and properly hooks them up to the rest of the graph. Note that * only the snode_block_pin_to_tnode, etc. element for this block is passed in. * Assumes that pins are ordered as [inputs][outputs][clk] */ int isub, ipin, iedge, from_pin, opin; int inode, to_node, num_edges; t_tedge *tedge; int clk_pin; t_type_ptr type; int *next_ipin_edge; type = block[iblk].type; next_ipin_edge = (int *)my_malloc(type->num_pins * sizeof(int)); clk_pin = 0;/* Start by allocating the edge arrays, and for opins, loading them. */ for(ipin = 0; ipin < block[iblk].type->num_pins; ipin++) { inode = block_pin_to_tnode[iblk][ipin]; if(inode != OPEN) { /* Pin is used -> put in graph */ if(is_opin(ipin, block[iblk].type)) { build_block_output_tnode(inode, iblk, ipin, block_pin_to_tnode); tnode_descript[inode].type = FB_OPIN; } else { /* FB ipin */ next_ipin_edge[ipin] = 0; /* Reset */ num_edges = n_uses_of_fb_ipin[ipin]; /* if clock pin, timing edges go to each subblock output used */ for(isub = 0; isub < num_subs; isub++) { if(sub_inf[isub].clock == ipin) { for(opin = 0; opin < type->max_subblock_outputs; opin++) { if(sub_inf[isub]. outputs[opin] != OPEN) { num_edges++; } } num_edges--; /* Remove clock_pin count, replaced by outputs */ } } 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 = FB_IPIN; } tnode_descript[inode].ipin = ipin; tnode_descript[inode].isubblk = OPEN; tnode_descript[inode].iblk = iblk; } }/* Now load the edge arrays for the FB 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 < type->max_subblock_inputs; ipin++) { from_pin = sub_inf[isub].inputs[ipin]; /* Not OPEN and comes from fb ipin? */ if(from_pin != OPEN && from_pin < block[iblk].type->num_pins) { inode = block_pin_to_tnode[iblk][from_pin]; assert(inode != OPEN); to_node = sub_pin_to_tnode[isub][SUB_INPUT][ipin]; tedge = tnode[inode].out_edges; iedge = next_ipin_edge[from_pin]++; tedge[iedge].to_node = to_node; tedge[iedge].Tdel = T_fb_ipin_to_sblk_ipin; } } from_pin = sub_inf[isub].clock; if(from_pin != OPEN && from_pin < block[iblk].type->num_pins) { inode = block_pin_to_tnode[iblk][from_pin]; to_node = sub_pin_to_tnode[isub][SUB_CLOCK][clk_pin]; /* Feeds seq. output */ /* connect to each output flip flop */ for(opin = 0; opin < type->max_subblock_outputs; opin++) { if(sub_inf[isub].outputs[opin] != OPEN) { tedge = tnode[inode].out_edges; iedge = next_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.; to_node += 2; } } } } free(next_ipin_edge);}static voidbuild_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_sinks + 1) - 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_sinks + 1) - 1; iedge++) { to_blk = net[inet].node_block[iedge + 1]; to_pin = net[inet].node_block_pin[iedge + 1]; 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 voidbuild_subblock_tnodes(int **n_uses_of_sblk_opin, int *node_block_pin_to_tnode, int ***sub_pin_to_tnode, int *num_subblocks_per_block, t_subblock ** subblock_inf, t_timing_inf timing_inf, int iblk){/* This routine builds the tnodes of the subblock pins within one FB. 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, opin, from_opin, clk_pin, used_opin_count; int num_subs, from_sub; t_subblock *sub_inf; int iedge, num_edges; float sink_delay; t_tedge *tedge; boolean has_inputs, has_outputs; int **next_sblk_opin_edge; /* [0..max_subblocks-1][0..max_subblock_outputs-1] */ int *num_opin_used_in_sblk; /* [0..max_subblocks-1] */ t_type_ptr type = block[iblk].type; sub_inf = subblock_inf[iblk]; num_subs = num_subblocks_per_block[iblk]; next_sblk_opin_edge = (int **)alloc_matrix(0, type->max_subblocks - 1, 0, type->max_subblock_outputs - 1, sizeof(int)); num_opin_used_in_sblk = (int *)my_malloc(type->max_subblocks * sizeof(int)); clk_pin = 0;/* Allocate memory for output pins first. */ for(isub = 0; isub < num_subs; isub++) { num_opin_used_in_sblk[isub] = 0; for(opin = 0; opin < type->max_subblock_outputs; opin++) { inode = sub_pin_to_tnode[isub][SUB_OUTPUT][opin]; if(inode != OPEN) { /* Output is used -> timing node exists. */ num_opin_used_in_sblk[isub]++; next_sblk_opin_edge[isub][opin] = 0; /* Reset */ num_edges = n_uses_of_sblk_opin[isub][opin]; 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); if(IO_TYPE == type) { tnode_descript[inode].type = INPAD_OPIN; tnode[inode + 1].num_edges = 1; tnode[inode + 1].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 + 1].out_edges; tedge[0].to_node = inode; /* For input pads, use sequential output for source timing delay (treat as register) */ if(is_global_clock (iblk, isub, opin, num_subblocks_per_block, subblock_inf)) tedge[0].Tdel = 0.; else tedge[0].Tdel = type->type_timing_inf. T_subblock[isub].T_seq_out[opin]; tnode_descript[inode + 1].type = INPAD_SOURCE; tnode_descript[inode + 1].ipin = OPEN; tnode_descript[inode + 1].isubblk = isub; tnode_descript[inode + 1].iblk = iblk; } else { tnode_descript[inode].type = SUBBLK_OPIN; } tnode_descript[inode].ipin = opin; tnode_descript[inode].isubblk = isub; tnode_descript[inode].iblk = iblk; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -