Example #1
0
static int check_for_duplicate_block_names (void) {

/* Checks that all blocks have duplicate names.  Returns the number of     *
 * duplicate names.                                                        */

 int error, iblk;
 struct s_hash **block_hash_table, *h_ptr;
 struct s_hash_iterator hash_iterator;

 error = 0;
 block_hash_table = alloc_hash_table ();

 for (iblk=0;iblk<num_blocks;iblk++)
    h_ptr = insert_in_hash_table (block_hash_table, block[iblk].name, iblk);

 hash_iterator = start_hash_table_iterator ();
 h_ptr = get_next_hash (block_hash_table, &hash_iterator);

 while (h_ptr != NULL) {
    if (h_ptr->count != 1) {
       printf ("Error:  %d blocks are named %s.  Block names must be unique."
               "\n", h_ptr->count, h_ptr->name);
       error++;
    }
    h_ptr = get_next_hash (block_hash_table, &hash_iterator);
 }

 free_hash_table (block_hash_table);
 return (error);
}
Example #2
0
/**
 * Find all packing patterns in architecture 
 * [0..num_packing_patterns-1]
 *
 * Limitations: Currently assumes that forced pack nets must be single-fanout as this covers all the reasonable architectures we wanted.
 More complicated structures should probably be handled either downstream (general packing) or upstream (in tech mapping)
 *              If this limitation is too constraining, code is designed so that this limitation can be removed
 */
t_pack_patterns *alloc_and_load_pack_patterns(OUTP int *num_packing_patterns) {
	int i, j, ncount;
	int L_num_blocks;
	struct s_hash **nhash;
	t_pack_patterns *list_of_packing_patterns;
	t_pb_graph_edge *expansion_edge;

	/* alloc and initialize array of packing patterns based on architecture complex blocks */
	nhash = alloc_hash_table();
	ncount = 0;
	for (i = 0; i < num_types; i++) {
		discover_pattern_names_in_pb_graph_node(
				type_descriptors[i].pb_graph_head, nhash, &ncount);
	}

	list_of_packing_patterns = alloc_and_init_pattern_list_from_hash(ncount,
			nhash);

	/* load packing patterns by traversing the edges to find edges belonging to pattern */
	for (i = 0; i < ncount; i++) {
		for (j = 0; j < num_types; j++) {
			expansion_edge = find_expansion_edge_of_pattern(i,
					type_descriptors[j].pb_graph_head);
			if (expansion_edge == NULL) {
				continue;
			}
			L_num_blocks = 0;
			list_of_packing_patterns[i].base_cost = 0;
			backward_expand_pack_pattern_from_edge(expansion_edge,
					list_of_packing_patterns, i, NULL, NULL, &L_num_blocks);
			list_of_packing_patterns[i].num_blocks = L_num_blocks;
			break;
		}
	}

	free_hash_table(nhash);

	*num_packing_patterns = ncount;
	return list_of_packing_patterns;
}
Example #3
0
void
read_user_pad_loc(char *pad_loc_file)
{

/* Reads in the locations of the IO pads from a file. */

    struct s_hash **hash_table, *h_ptr;
    int iblk, i, j, xtmp, ytmp, bnum, k;
    FILE *fp;
    char buf[BUFSIZE], bname[BUFSIZE], *ptr;

    printf("\nReading locations of IO pads from %s.\n", pad_loc_file);
    linenum = 0;
    fp = my_fopen(pad_loc_file, "r");

    hash_table = alloc_hash_table();
    for(iblk = 0; iblk < num_blocks; iblk++)
	{
	    if(block[iblk].type == IO_TYPE)
		{
		    h_ptr =
			insert_in_hash_table(hash_table, block[iblk].name,
					     iblk);
		    block[iblk].x = OPEN;	/* Mark as not seen yet. */
		}
	}

    for(i = 0; i <= nx + 1; i++)
	{
	    for(j = 0; j <= ny + 1; j++)
		{
		    if(grid[i][j].type == IO_TYPE)
			{
			    for(k = 0; k < IO_TYPE->capacity; k++)
				grid[i][j].blocks[k] = OPEN;	/* Flag for err. check */
			}
		}
	}

    ptr = my_fgets(buf, BUFSIZE, fp);

    while(ptr != NULL)
	{
	    ptr = my_strtok(buf, TOKENS, fp, buf);
	    if(ptr == NULL)
		{
		    ptr = my_fgets(buf, BUFSIZE, fp);
		    continue;	/* Skip blank or comment lines. */
		}

	    strcpy(bname, ptr);

	    ptr = my_strtok(NULL, TOKENS, fp, buf);
	    if(ptr == NULL)
		{
		    printf("Error:  line %d is incomplete.\n", linenum);
		    exit(1);
		}
	    sscanf(ptr, "%d", &xtmp);

	    ptr = my_strtok(NULL, TOKENS, fp, buf);
	    if(ptr == NULL)
		{
		    printf("Error:  line %d is incomplete.\n", linenum);
		    exit(1);
		}
	    sscanf(ptr, "%d", &ytmp);

	    ptr = my_strtok(NULL, TOKENS, fp, buf);
	    if(ptr == NULL)
		{
		    printf("Error:  line %d is incomplete.\n", linenum);
		    exit(1);
		}
	    sscanf(ptr, "%d", &k);

	    ptr = my_strtok(NULL, TOKENS, fp, buf);
	    if(ptr != NULL)
		{
		    printf("Error:  extra characters at end of line %d.\n",
			   linenum);
		    exit(1);
		}

	    h_ptr = get_hash_entry(hash_table, bname);
	    if(h_ptr == NULL)
		{
		    printf("Error:  block %s on line %d: no such IO pad.\n",
			   bname, linenum);
		    exit(1);
		}
	    bnum = h_ptr->index;
	    i = xtmp;
	    j = ytmp;

	    if(block[bnum].x != OPEN)
		{
		    printf
			("Error:  line %d.  Block %s listed twice in pad file.\n",
			 linenum, bname);
		    exit(1);
		}

	    if(i < 0 || i > nx + 1 || j < 0 || j > ny + 1)
		{
		    printf("Error:  block #%d (%s) location\n", bnum, bname);
		    printf("(%d,%d) is out of range.\n", i, j);
		    exit(1);
		}

	    block[bnum].x = i;	/* Will be reloaded by initial_placement anyway. */
	    block[bnum].y = j;	/* I need to set .x only as a done flag.         */

	    if(grid[i][j].type != IO_TYPE)
		{
		    printf("Error:  attempt to place IO block %s in \n",
			   bname);
		    printf("an illegal location (%d, %d).\n", i, j);
		    exit(1);
		}

	    if(k >= IO_TYPE->capacity || k < 0)
		{
		    printf
			("Error:  Block %s subblock number (%d) on line %d is out of "
			 "range.\n", bname, k, linenum);
		    exit(1);
		}
	    grid[i][j].blocks[k] = bnum;
	    grid[i][j].usage++;

	    ptr = my_fgets(buf, BUFSIZE, fp);
	}

    for(iblk = 0; iblk < num_blocks; iblk++)
	{
	    if(block[iblk].type == IO_TYPE && block[iblk].x == OPEN)
		{
		    printf
			("Error:  IO block %s location was not specified in "
			 "the pad file.\n", block[iblk].name);
		    exit(1);
		}
	}

    fclose(fp);
    free_hash_table(hash_table);
    printf("Successfully read %s.\n\n", pad_loc_file);
}
Example #4
0
void setup (void)
{
  test_hash_table = alloc_hash_table();
}
Example #5
0
static void init_parse(int doall) {

/* Allocates and initializes the data structures needed for the parse. */

 int i, j, len, nindex, pin_count;
 int *tmp_ptr;
 struct s_hash_iterator hash_iterator;
 struct s_hash *h_ptr;


 if (!doall) {  /* Initialization before first (counting) pass */
    num_nets = 0;  
    hash_table = alloc_hash_table ();

#define INITIAL_BLOCK_STORAGE 2000
    temp_block_storage = INITIAL_BLOCK_STORAGE;
    num_subblocks_per_block = my_malloc (INITIAL_BLOCK_STORAGE *
             sizeof(int));

    ch_subblock_bytes_avail = 0;
    ch_subblock_next_avail_mem = NULL;
    ch_subblock_head_ptr = NULL;
 }

/* Allocate memory for second (load) pass */ 

 else {   
    net = (struct s_net *) my_malloc (num_nets*sizeof(struct s_net));
    block = (struct s_block *) my_malloc (num_blocks*
        sizeof(struct s_block));   
    is_global = (boolean *) my_calloc (num_nets, sizeof(boolean));
    num_driver = (int *) my_malloc (num_nets * sizeof(int));
    temp_num_pins = (int *) my_malloc (num_nets * sizeof(int));

    for (i=0;i<num_nets;i++) {
       num_driver[i] = 0;
       net[i].num_pins = 0;
    }

/* Allocate block pin connection storage.  Some is wasted for io blocks. *
 * Method used below "chunks" the malloc of a bunch of small things to   *
 * reduce the memory housekeeping overhead of malloc.                    */

    tmp_ptr = (int *) my_malloc (pins_per_clb * num_blocks * sizeof(int));
    for (i=0;i<num_blocks;i++) 
       block[i].nets = tmp_ptr + i * pins_per_clb;

/* I use my_chunk_malloc for some storage locations below.  my_chunk_malloc  *
 * avoids the 12 byte or so overhead incurred by malloc, but since I call it *
 * with a NULL head_ptr, it will not keep around enough information to ever  *
 * free these data arrays.  If you ever have compatibility problems on a     *
 * non-SPARC architecture, just change all the my_chunk_malloc calls to      *
 * my_malloc calls.                                                          */

    hash_iterator = start_hash_table_iterator ();
    h_ptr = get_next_hash (hash_table, &hash_iterator);
    
    while (h_ptr != NULL) {
       nindex = h_ptr->index;
       pin_count = h_ptr->count;
       net[nindex].blocks = (int *) my_chunk_malloc(pin_count *
               sizeof(int), NULL, &chunk_bytes_avail, &chunk_next_avail_mem);

       net[nindex].blk_pin = (int *) my_chunk_malloc (pin_count * 
               sizeof(int), NULL, &chunk_bytes_avail, &chunk_next_avail_mem);

/* For avoiding assigning values beyond end of pins array. */

       temp_num_pins[nindex] = pin_count;

       len = strlen (h_ptr->name);
       net[nindex].name = (char *) my_chunk_malloc ((len + 1) *
            sizeof(char), NULL, &chunk_bytes_avail, &chunk_next_avail_mem);
       strcpy (net[nindex].name, h_ptr->name);
       h_ptr = get_next_hash (hash_table, &hash_iterator);
    }

/* Allocate storage for subblock info. (what's in each logic block) */

   num_subblocks_per_block = (int *) my_realloc (num_subblocks_per_block,
                  num_blocks * sizeof (int));
   subblock_inf = (t_subblock **) my_malloc (num_blocks * 
                        sizeof(t_subblock *));

   for (i=0;i<num_blocks;i++) {
      if (num_subblocks_per_block[i] == 0) 
         subblock_inf[i] = NULL;
      else {
         subblock_inf[i] = (t_subblock *) my_chunk_malloc (
              num_subblocks_per_block[i] * sizeof (t_subblock), 
              &ch_subblock_head_ptr, &ch_subblock_bytes_avail, 
              &ch_subblock_next_avail_mem);
         for (j=0;j<num_subblocks_per_block[i];j++) 
            subblock_inf[i][j].inputs = (int *) my_chunk_malloc
                 (subblock_lut_size * sizeof(int), &ch_subblock_head_ptr, 
                 &ch_subblock_bytes_avail, &ch_subblock_next_avail_mem);
      }
   }
 }

/* Initializations for both passes. */

 linenum = 0;
 num_p_inputs = 0;
 num_p_outputs = 0;
 num_clbs = 0;
 num_blocks = 0;
 num_globals = 0;
}