void free_ivec_matrix3(struct s_ivec ***ivec_matrix3, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax) { /* Frees a 3D matrix of integer vectors (ivecs). */ int i, j, k; for(i = nrmin; i <= nrmax; i++) { for(j = ncmin; j <= ncmax; j++) { for(k = ndmin; k <= ndmax; k++) { if(ivec_matrix3[i][j][k].nelem != 0) { free(ivec_matrix3[i][j][k].list); } } } } free_matrix3(ivec_matrix3, nrmin, nrmax, ncmin, ncmax, ndmin, sizeof(struct s_ivec)); }
void free_matrix4(void *vptr, int nrmin, int nrmax, int ncmin, int ncmax, int ndmin, int ndmax, int nemin, size_t elsize) { int i; char ****cptr; cptr = (char ****) vptr; for (i = nrmin; i <= nrmax; i++) { free_matrix3 (cptr[i], ncmin, ncmax, ndmin, ndmax, nemin, elsize); } free(cptr + nrmin); }
static void restore_original_device(void) { free_matrix(clb, 0, nx + 1, 0, sizeof(struct s_clb)); clb = clb_backup; free_matrix3(stage_clb, 0, num_stage - 1, 0, nx + 1, 0, sizeof(struct s_clb)); stage_clb = stage_clb_backup; }
void build_rr_graph (enum e_route_type route_type, struct s_det_routing_arch det_routing_arch, struct s_segment_inf *segment_inf, t_timing_inf timing_inf) { /* Builds the routing resource graph needed for routing. Does all the * * necessary allocation and initialization. If route_type is DETAILED * * then the routing graph built is for detailed routing, otherwise it is * * for GLOBAL routing. */ int nodes_per_clb, nodes_per_pad, nodes_per_chan; int **rr_node_indices; int Fc_output, Fc_input, Fc_pad; int **pads_to_tracks; struct s_ivec **tracks_to_clb_ipin, *tracks_to_pads; /* [0..pins_per_clb-1][0..3][0..Fc_output-1]. List of tracks this pin * * connects to. Second index is the side number (see pr.h). If a pin * * is not an output or input, respectively, or doesn't connect to * * anything on this side, the [ipin][iside][0] element is OPEN. */ int ***clb_opin_to_tracks, ***clb_ipin_to_tracks; t_seg_details *seg_details_x, *seg_details_y; /* [0 .. nodes_per_chan-1] */ nodes_per_clb = num_class + pins_per_clb; nodes_per_pad = 4 * io_rat; /* SOURCE, SINK, OPIN, and IPIN */ if (route_type == GLOBAL) { nodes_per_chan = 1; } else { nodes_per_chan = chan_width_x[0]; } seg_details_x = alloc_and_load_seg_details (nodes_per_chan, segment_inf, det_routing_arch.num_segment, nx); seg_details_y = alloc_and_load_seg_details (nodes_per_chan, segment_inf, det_routing_arch.num_segment, ny); #ifdef DEBUG dump_seg_details (seg_details_x, nodes_per_chan, "x.echo"); dump_seg_details (seg_details_y, nodes_per_chan, "y.echo"); #endif /* To set up the routing graph I need to choose an order for the rr_indices. * * For each (i,j) slot in the FPGA, the index order is [source+sink]/pins/ * * chanx/chany. The dummy source and sink are ordered by class number or pad * * number; the pins are ordered by pin number or pad number, and the channel * * segments are ordered by track number. Track 1 is closest to the "owning" * * block; i.e. it is towards the left of y-chans and the bottom of x-chans. * * * * The maximize cache effectiveness, I put all the rr_nodes associated with * * a block together (this includes the "owned" channel segments). I start * * at (0,0) (empty), go to (1,0), (2,0) ... (0,1) and so on. */ /* NB: Allocates data structures for fast index computations -- more than * * just rr_node_indices are allocated by this routine. */ rr_node_indices = alloc_and_load_rr_node_indices (nodes_per_clb, nodes_per_pad, nodes_per_chan, seg_details_x, seg_details_y); num_rr_nodes = rr_node_indices[nx+1][ny+1]; if (det_routing_arch.Fc_type == ABSOLUTE) { Fc_output = min (det_routing_arch.Fc_output, nodes_per_chan); Fc_input = min (det_routing_arch.Fc_input, nodes_per_chan); Fc_pad = min (det_routing_arch.Fc_pad, nodes_per_chan); } else { /* FRACTIONAL */ Fc_output = nint (nodes_per_chan * det_routing_arch.Fc_output); Fc_output = max (1, Fc_output); Fc_input = nint (nodes_per_chan * det_routing_arch.Fc_input); Fc_input = max (1, Fc_input); Fc_pad = nint (nodes_per_chan * det_routing_arch.Fc_pad); Fc_pad = max (1, Fc_pad); } alloc_and_load_switch_block_conn (nodes_per_chan, det_routing_arch.switch_block_type); clb_opin_to_tracks = alloc_and_load_clb_pin_to_tracks (DRIVER, nodes_per_chan, Fc_output); clb_ipin_to_tracks = alloc_and_load_clb_pin_to_tracks (RECEIVER, nodes_per_chan, Fc_input); tracks_to_clb_ipin = alloc_and_load_tracks_to_clb_ipin (nodes_per_chan, Fc_input, clb_ipin_to_tracks); pads_to_tracks = alloc_and_load_pads_to_tracks (nodes_per_chan, Fc_pad); tracks_to_pads = alloc_and_load_tracks_to_pads (pads_to_tracks, nodes_per_chan, Fc_pad); rr_edge_done = (boolean *) my_calloc (num_rr_nodes, sizeof (boolean)); alloc_and_load_rr_graph (rr_node_indices, clb_opin_to_tracks, tracks_to_clb_ipin, pads_to_tracks, tracks_to_pads, Fc_output, Fc_input, Fc_pad, nodes_per_chan, route_type, det_routing_arch, seg_details_x, seg_details_y); free (rr_edge_done); free_rr_node_indices (rr_node_indices); free_matrix3 (clb_opin_to_tracks, 0, pins_per_clb-1, 0, 3, 0, sizeof(int)); free_matrix3 (clb_ipin_to_tracks, 0, pins_per_clb-1, 0, 3, 0, sizeof(int)); free_ivec_matrix (tracks_to_clb_ipin, 0, nodes_per_chan-1, 0, 3); free_ivec_vector (tracks_to_pads, 0, nodes_per_chan-1); free_matrix (pads_to_tracks, 0, io_rat-1, 0, sizeof(int)); free_switch_block_conn (nodes_per_chan); free_edge_list_hard (&free_edge_list_head); save_segment_type_and_length_info (seg_details_x, nodes_per_chan, seg_details_y, nodes_per_chan); free_seg_details (seg_details_x, nodes_per_chan); free_seg_details (seg_details_y, nodes_per_chan); add_rr_graph_C_from_switches (timing_inf.ipin_cblock_C); /* dump_rr_graph ("rr_graph.echo"); */ check_rr_graph (route_type, det_routing_arch.num_switch); }