Пример #1
0
/* Initializes the block_list with info from a netlist */
void read_netlist(IN const char* net_file,
             IN int num_types,
             IN const struct s_type_descriptor block_types[],
             IN block_type_ptr IO_type,
             IN int io_ipin,
             IN int io_opin,
             OUT subblock_data_t* subblock_data_ptr,
             OUT int* num_blocks,
             OUT block_t* block_list[],
             OUT int* num_nets,
             OUT net_t* net_list[])
{
    int i, j, k, l, m;
    enum { COUNT, LOAD, MAP, STOP } pass;
    int line, prev_line;
    enum special_blk overide;
    char** block_tokens;
    char** pin_tokens;
    char** tokens;
    subblock_t** slist = NULL;
    int* scount = NULL;
    block_type_ptr type = NULL;
    FILE* infile = my_fopen(net_file, "r");
    int bcount = 0;
    block_t* blist = NULL;
    int ncount = 0;
    net_t* nlist = NULL;
    memset(subblock_data_ptr, 0, sizeof(subblock_data_t));

    /* Multi-pass load
     * COUNT
     *->count blocks
     *->count nets
     *
     * LOAD
     *->alloc num_subblocks_per_block list
     *->allocate s_block list at start
     *->allocate s_net list at start
     *->count subblocks per block
     *->sets block names
     *->sets block types
     *->allocs block net lists
     *->sets net names
     *
     * MAP
     *->fills in s_block:nets list
     *->fills in subblocks */

    for (pass = 0; pass < STOP; ++pass) {
        rewind(infile);
        line = 0;
        i = 0;
        j = 0;
        overide = NORMAL;

        /* Alloc the lists */
        if (LOAD == pass) {
            blist = (block_t*)my_malloc(sizeof(block_t) *
                                           bcount);
            memset(blist, 0, (sizeof(block_t) * bcount));

            nlist = (net_t*)my_malloc(sizeof(net_t) *
                                         ncount);
            memset(nlist, 0, (sizeof(net_t) * ncount));

            slist = (subblock_t**) my_malloc(sizeof(subblock_t*) *
                                         bcount);
            memset(slist, 0, (sizeof(subblock_t*) * bcount));

            scount = (int*)my_malloc(sizeof(int) * bcount);
            memset(scount, 0, (sizeof(int) * bcount));
        }

        /* Read file line by line */
        block_tokens = ReadLineTokens(infile, &line);
        prev_line = line;

        while (block_tokens) {
            /* .global directives have special meaning */
            if (0 == strcmp(block_tokens[0], ".global")) {
                if (MAP == pass) {
                    for (l = 0; l < ncount; ++l) {
                        if (0 == strcmp(nlist[l].name, block_tokens[1])) {
                            nlist[l].is_global = TRUE;
                            break;
                        }
                    }

                    if (l == ncount) {
                        printf(ERRTAG
                               "'%s':%d - '.global' specified an invalid net\n",
                               net_file, prev_line);
                        exit(1);
                    }
                }

                /* Don't do any more processing on this */
                FreeTokens(&block_tokens);
                block_tokens = ReadLineTokens(infile, &line);
                prev_line = line;
                continue;
            }

            pin_tokens = ReadLineTokens(infile, &line);

            if (CountTokens(block_tokens) != 2) {
                printf(ERRTAG "'%s':%d - block type line should "
                       "be in form '.type_name block_name'\n",
                       net_file, prev_line);
                exit(1);
            }

            if (NULL == pin_tokens) {
                printf(ERRTAG
                       "'%s':%d - blocks must be follow by a 'pinlist:' line\n",
                       net_file, line);
                exit(1);
            }

            if (0 != strcmp("pinlist:", pin_tokens[0])) {
                printf(ERRTAG
                       "'%s':%d - 'pinlist:' line must follow "
                       "block type line\n", net_file, line);
                exit(1);
            }

            type =
                get_type_by_name(block_tokens[0], num_types,
                                 block_types, IO_type, net_file,
                                 prev_line, &overide);

            /* Check if we are overiding the pinlist format for this block */
            if (overide) {
                if (CountTokens(pin_tokens) != 2) {
                    /* 'pinlist:' and name */
                    printf(ERRTAG
                           "'%s':%d - pinlist for .input and .output should "
                           "only have one item.\n", net_file,
                           line);
                    exit(1);
                }

                /* Make a new faked token list with 'pinlist:' and then pin mappings and a null */
                tokens = (char**)my_malloc(sizeof(char*) *
                                             (type->num_type_pins + 2));
                l = strlen(pinlist_str) + 1;
                k = strlen(pin_tokens[1]) + 1;
                tokens[0] = (char*)my_malloc(sizeof(char) * (k + l));
                memcpy(tokens[0], pinlist_str, l * sizeof(char));
                memcpy(tokens[0] + l, pin_tokens[1],
                       k * sizeof(char));

                /* Set all other pins to open */
                for (k = 0; k < type->num_type_pins; ++k) {
                    tokens[1 + k] = "open"; /* free wont be called on this so is safe */
                }

                tokens[1 + k] = NULL;   /* End of token list marker */

                /* Set the one pin with the value given */
                for (k = 0; k < type->num_type_pins; ++k) {
                    switch (overide) {
                        case INPAD:
                            tokens[1 + io_opin] = (tokens[0] + l);
                            break;

                        case OUTPAD:
                            tokens[1 + io_ipin] = (tokens[0] + l);
                            break;
                    }
                }

                FreeTokens(&pin_tokens);
                pin_tokens = tokens;
                tokens = NULL;
            }

            if (CountTokens(pin_tokens) != (type->num_type_pins + 1)) {
                printf(ERRTAG
                       "'%s':%d - 'pinlist:' line has %d pins instead of "
                       "expect %d pins.\n", net_file, line,
                       CountTokens(pin_tokens) - 1, type->num_type_pins);
                exit(1);
            }

            /* Load block name and type and alloc net list */
            if (LOAD == pass) {
                blist[i].name = my_strdup(block_tokens[1]);
                blist[i].block_type = type;

                blist[i].nets = (int*)my_malloc(sizeof(int) * type->num_type_pins);
                for (k = 0; k < type->num_type_pins; ++k) {
                    blist[i].nets[k] = OPEN;
                }
            }

            /* Examine pin list to determine nets */
            for (k = 0; k < type->num_type_pins; ++k) {
                if (0 != strcmp("open", pin_tokens[1 + k])) {
                    if (DRIVER == type->class_inf[type->pin_class[k]].type) {
                        if (LOAD == pass) {
                            nlist[j].name = my_strdup(pin_tokens[1 + k]);
                        }

                        if (MAP == pass) {
                            blist[i].nets[k] = j;   /* If we are net source we don't need to search */
                        }

                        ++j;    /* This was an active netlist */
                    } else {
                        if (MAP == pass) {
                            /* Map sinks by doing a linear search to find the net */
                            blist[i].nets[k] = OPEN;

                            for (l = 0; l < ncount; ++l) {
                                if (0 == strcmp(nlist[l].name,
                                                pin_tokens[1 + k])) {
                                    blist[i].nets[k] = l;
                                    break;
                                }
                            }

                            if (OPEN == blist[i].nets[k]) {
                                printf(ERRTAG
                                       "'%s':%d - Net '%s' not found\n",
                                       net_file,
                                       line,
                                       pin_tokens
                                       [1 + k]);
                                exit(1);
                            }
                        }
                    }
                }
            }

            /* Allocating subblocks */
            if (MAP == pass) {
                /* All blocks internally have subblocks but I/O subblocks are
                allocated and loaded elsewhere */
                if (scount[i] > 0) {
                    slist[i] = (subblock_t*)
                               my_malloc(sizeof(subblock_t) * scount[i]);

                    for (k = 0; k < scount[i]; ++k) {
                        slist[i][k].name = NULL;
                        slist[i][k].clock = OPEN;
                        slist[i][k].inputs =
                            (int*)my_malloc(sizeof(int) *
                                            type->max_subblock_inputs);

                        for (l = 0; l < type->max_subblock_inputs; ++l) {
                            slist[i][k].inputs[l] = OPEN;
                        }

                        slist[i][k].outputs =
                            (int*)my_malloc(sizeof(int) * type->max_subblock_outputs);

                        for (l = 0; l < type->max_subblock_outputs; ++l) {
                            slist[i][k].outputs[l] = OPEN;
                        }
                    }
                }
            }

            /* Ignore subblock data */
            tokens = ReadLineTokens(infile, &line);
            prev_line = line;
            m = 0;

            while (tokens && (0 == strcmp(tokens[0], "subblock:"))) {
                if (CountTokens(tokens) != (type->max_subblock_inputs + type->max_subblock_outputs + 1 + /* clocks */
                                            2)) {
                    /* 'subblock:', name */
                    printf("subblock wrong pin count, netlist has %d, architecture as %d on line %d \n" ,
                           CountTokens(tokens) - 2, (type->max_subblock_inputs + type->max_subblock_outputs + 1),
                           line);
                    exit(1);
                }

                /* Count subblocks given */
                if (LOAD == pass) {
                    scount[i]++;
                }

                /* Load subblock name */
                if (MAP == pass) {
                    assert(i < bcount);
                    assert(m < scount[i]);
                    slist[i][m].name = my_strdup(tokens[1]);

                    for (k = 0; k < type->max_subblock_inputs; ++k) {
                        /* Check prefix and load pin num */
                        l = 2 + k;

                        if (0 == strncmp("ble_", tokens[l], 4)) {
                            /* Skip the 'ble_' part */
                            slist[i][m].inputs[k] = type->num_type_pins + my_atoi(tokens[l] + 4);
                        } else if (0 != strcmp("open", tokens[l])) {
                            slist[i][m].inputs[k] = my_atoi(tokens[l]);
                        }
                    }

                    for (k = 0; k < type->max_subblock_outputs; ++k) {
                        l = 2 + type->max_subblock_inputs + k;

                        if (0 != strcmp("open", tokens[l])) {
                            slist[i][m].outputs[k] = my_atoi(tokens[l]);
                        }
                    }

                    l = 2 + type->max_subblock_inputs + type->max_subblock_outputs;

                    if (0 != strcmp("open", tokens[l])) {
                        slist[i][m].clock = my_atoi(tokens[l]);
                    }
                }

                ++m;    /* Next subblock */
                FreeTokens(&tokens);
                tokens = ReadLineTokens(infile, &line);
                prev_line = line;
            }

            if (pass > COUNT) {
                /* Check num of subblocks read */
                if (scount[i] > type->max_subblocks) {
                    printf("too many subblocks on block [%d] %s\n", i, blist[i].name);
                    exit(1);
                }
            }

            ++i;    /* End of this block */
            FreeTokens(&block_tokens);
            FreeTokens(&pin_tokens);
            block_tokens = tokens;
        }

        /* Save counts */
        if (COUNT == pass) {
            bcount = i;
            ncount = j;
        }
    }

    fclose(infile);
    /* Builds mappings from each netlist to the blocks contained */
    sync_nets_to_blocks(bcount, blist, ncount, nlist);
    /* Send values back to caller */
    *num_blocks = bcount;
    *block_list = blist;
    *num_nets = ncount;
    *net_list = nlist;
    subblock_data_ptr->subblock_inf = slist;
    subblock_data_ptr->num_subblocks_per_block = scount;
}
Пример #2
0
void read_trace_file(char *trace_file) {

	FILE *infile;
	char **tokens, *coord;
	int line, i, error;
	int cur_net, skip_cur_net;
	struct s_trace *trace, *next;
	char str[256];
	t_rr_type rr_type, prev_rr_type;

	int x, y, pin, class, pad, track, xhigh, yhigh;

	trace_head = (struct s_trace **) my_malloc(
			num_nets * sizeof(struct s_trace *));
	trace_tail = (struct s_trace **) my_malloc(
			num_nets * sizeof(struct s_trace *));

	infile = fopen(trace_file, "r");
	line = 0;

	/* Check first line match */
	tokens = ReadLineTokens(infile, &line);
	error = 0;
	if (NULL == tokens) {
		error = 1;
	}
	for (i = 0; i < 7; ++i) {
		if (!error) {
			if (NULL == tokens[i]) {
				error = 1;
				break;
			}
		}
	}
	if (!error) {
		if ((0 != strcmp(tokens[0], "Array"))
				|| (0 != strcmp(tokens[1], "size:"))
				|| (0 != strcmp(tokens[3], "x"))
				|| (0 != strcmp(tokens[5], "logic"))
				|| (0 != strcmp(tokens[6], "blocks."))) {
			error = 1;
		};
		if (nx != atoi(tokens[2]) || ny != atoi(tokens[4]))
			error = 1;
	}

	tokens = ReadLineTokens(infile, &line);
	if (NULL == tokens) {
		error = 1;
	}
	for (i = 0; i < 4; ++i) {
		if (!error) {
			if (NULL == tokens[i]) {
				error = 1;
				break;
			}
		}
	}
	if (!error) {
		if ((0 != strcmp(tokens[0], "T_crit:"))
				|| (0 != strcmp(tokens[2], "Width_fac:"))) {
			error = 1;
		};
		T_critical_path = atof(tokens[1]);
		fixed_chan_width = atoi(tokens[3]);
	}

	tokens = ReadLineTokens(infile, &line);
	if (NULL == tokens || 0 != strcmp(tokens[0], "Routing:"))
		error = 1;

	if (error) {
		printf(
				ERRTAG
				"'%s' - Bad FPGA size/T_crit/width specification line or header line in routing file\n",
				trace_file);
		exit(1);
	}

	build_route(fixed_chan_width);

	/* Begin parsing traces
	 * */
	cur_net = OPEN;
	while (1) {
		tokens = ReadLineTokens(infile, &line);
		if (tokens == NULL) {
			/* Set last net trace_tail */
			if (cur_net != OPEN) {
				trace->next = NULL;
				trace_tail[cur_net] = trace;
			}
			break;
		}
		if (0 == strcmp(tokens[0], "Net")) {
			skip_cur_net = 0;
			/* Set previous net trace_tail */
			if (cur_net != OPEN) {
				trace->next = NULL;
				trace_tail[cur_net] = trace;
			}

			cur_net = atoi(tokens[1]);

			trace = (struct s_trace *) my_malloc(sizeof(struct s_trace));
			trace_head[cur_net] = trace;

			strcpy(str, "(");
			strcat(str, clb_net[cur_net].name);
			strcat(str, ")\0");
			if (0 != strcmp(tokens[2], str)
					&& 0 == strcmp(tokens[3], "global")) {
				skip_cur_net = 1;
				trace_head[cur_net] = NULL;
				trace_tail[cur_net] = NULL;
				cur_net = OPEN;
				free(trace);
			}
		} else if (!skip_cur_net) {
			/* rr_resource node of the current net */
			if (0 == strcmp(tokens[0], "SOURCE")) {

				/* SOURCE (x,y) Class: class*/
				/* tokens[1] gives coordinates of the routing resource*/
				rr_type = SOURCE;
				coord = strtok(tokens[1], "(,)");
				x = atoi(coord);
				coord = strtok(NULL, "(,)");
				y = atoi(coord);

				if (0 == (strcmp(tokens[2], "Class:"))) {
					class = atoi(tokens[3]);
					trace->index = get_rr_node_index(x, y, rr_type, class,
							rr_node_indices);
				} else if (0 == (strcmp(tokens[2], "Pad:"))) {
					pad = atoi(tokens[3]);
					trace->index = get_rr_node_index(x, y, rr_type, pad,
							rr_node_indices);
				} else if (0 == (strcmp(tokens[4], "Class:"))) {
					class = atoi(tokens[5]);
					trace->index = get_rr_node_index(x, y, rr_type, class,
							rr_node_indices);
				} else {
					assert(0 == (strcmp(tokens[4], "Pad:")));
					pad = atoi(tokens[5]);
					trace->index = get_rr_node_index(x, y, rr_type, pad,
							rr_node_indices);
				}
				prev_rr_type = SOURCE;
				continue;

			} else if (0 == strcmp(tokens[0], "OPIN")) {
Пример #3
0
void
read_place(IN const char *place_file,
	   IN const char *arch_file,
	   IN const char *net_file,
	   IN int nx,
	   IN int ny,
	   IN int num_blocks,
	   INOUT struct s_block block_list[])
{

    FILE *infile;
    char **tokens;
    int line;
    int i;
    int error;
    struct s_block *cur_blk;

    infile = my_fopen(place_file, "r");

    /* Check filenames in first line match */
    tokens = ReadLineTokens(infile, &line);
    error = 0;
    if(NULL == tokens)
	{
	    error = 1;
	}
    for(i = 0; i < 6; ++i)
	{
	    if(!error)
		{
		    if(NULL == tokens[i])
			{
			    error = 1;
			}
		}
	}
    if(!error)
	{
	    if((0 != strcmp(tokens[0], "Netlist")) ||
	       (0 != strcmp(tokens[1], "file:")) ||
	       (0 != strcmp(tokens[3], "Architecture")) ||
	       (0 != strcmp(tokens[4], "file:")))
		{
		    error = 1;
		};
	}
    if(error)
	{
	    printf(ERRTAG
		   "'%s' - Bad filename specification line in placement file\n",
		   place_file);
	    exit(1);
	}
    if(0 != strcmp(tokens[2], arch_file))
	{
	    printf(ERRTAG
		   "'%s' - Architecture file that generated placement (%s) does "
		   "not match current architecture file (%s)\n", place_file,
		   tokens[2], arch_file);
	    exit(1);
	}
    if(0 != strcmp(tokens[5], net_file))
	{
	    printf(ERRTAG
		   "'%s' - Netlist file that generated placement (%s) does "
		   "not match current netlist file (%s)\n", place_file,
		   tokens[5], net_file);
	    exit(1);
	}

    /* Check array size in second line matches */
    tokens = ReadLineTokens(infile, &line);
    error = 0;
    if(NULL == tokens)
	{
	    error = 1;
	}
    for(i = 0; i < 7; ++i)
	{
	    if(!error)
		{
		    if(NULL == tokens[i])
			{
			    error = 1;
			}
		}
	}
    if(!error)
	{
	    if((0 != strcmp(tokens[0], "Array")) ||
	       (0 != strcmp(tokens[1], "size:")) ||
	       (0 != strcmp(tokens[3], "x")) ||
	       (0 != strcmp(tokens[5], "logic")) ||
	       (0 != strcmp(tokens[6], "blocks")))
		{
		    error = 1;
		};
	}
    if(error)
	{
	    printf(ERRTAG
		   "'%s' - Bad fpga size specification line in placement file\n",
		   place_file);
	    exit(1);
	}
    if((my_atoi(tokens[2]) != nx) || (my_atoi(tokens[4]) != ny))
	{
	    printf(ERRTAG
		   "'%s' - Current FPGA size (%d x %d) is different from "
		   "size when placement generated (%d x %d)\n", place_file,
		   nx, ny, my_atoi(tokens[2]), my_atoi(tokens[4]));
	    exit(1);
	}

    tokens = ReadLineTokens(infile, &line);
    while(tokens)
	{
	    /* Linear search to match pad to netlist */
	    cur_blk = NULL;
	    for(i = 0; i < num_blocks; ++i)
		{
		    if(0 == strcmp(block_list[i].name, tokens[0]))
			{
			    cur_blk = (block_list + i);
			    break;
			}
		}

	    /* Error if invalid block */
	    if(NULL == cur_blk)
		{
		    printf(ERRTAG "'%s':%d - Block in placement file does "
			   "not exist in netlist\n", place_file, line);
		    exit(1);
		}

	    /* Set pad coords */
	    cur_blk->x = my_atoi(tokens[1]);
	    cur_blk->y = my_atoi(tokens[2]);
	    cur_blk->z = my_atoi(tokens[3]);

	    /* Get next line */
	    assert(*tokens);
	    free(*tokens);
	    free(tokens);
	    tokens = ReadLineTokens(infile, &line);
	}

    fclose(infile);
}