⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_netlist.c

📁 用于学术研究的FPGA布局布线软件VPR
💻 C
字号:
#include <stdio.h>#include <string.h>#include <assert.h>#include "util.h"#include "hash.h"#include "vpr_types.h"#include "vpr_utils.h"#include "ReadLine.h"#include "globals.h"static char *pinlist_str = "pinlist:";enum special_blk{ NORMAL = 0, INPAD, OUTPAD };static t_type_ptr get_type_by_name(IN const char *name,				   IN int num_types,				   IN const struct s_type_descriptor				   block_types[],				   IN t_type_ptr IO_type,				   IN const char *net_file,				   IN int line,				   OUT enum special_blk *overide);/* Initializes the block_list with info from a netlist */voidread_netlist(IN const char *net_file,	     IN int num_types,	     IN const struct s_type_descriptor block_types[],	     IN t_type_ptr IO_type,	     IN int io_ipin,	     IN int io_opin,	     OUT t_subblock_data * subblock_data_ptr,	     OUT int *num_blocks,	     OUT struct s_block *block_list[],	     OUT int *num_nets,	     OUT struct s_net *net_list[]){    FILE *infile;    int bcount;    struct s_block *blist;    int ncount;    struct s_net *nlist;    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;    t_subblock **slist = NULL;    int *scount = NULL;    t_type_ptr type = NULL;    infile = my_fopen(net_file, "r");    bcount = 0;    blist = NULL;    ncount = 0;    nlist = NULL;    memset(subblock_data_ptr, 0, sizeof(t_subblock_data));    /* 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 =			(struct s_block *)my_malloc(sizeof(struct s_block) *						    bcount);		    memset(blist, 0, (sizeof(struct s_block) * bcount));		    nlist =			(struct s_net *)my_malloc(sizeof(struct s_net) *						  ncount);		    memset(nlist, 0, (sizeof(struct s_net) * ncount));		    slist =			(t_subblock **) my_malloc(sizeof(t_subblock *) *						  bcount);		    memset(slist, 0, (sizeof(t_subblock *) * 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_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_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_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_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_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].type = type;			    blist[i].nets =				(int *)my_malloc(sizeof(int) *						 type->num_pins);			    for(k = 0; k < type->num_pins; ++k)				{				    blist[i].nets[k] = OPEN;				}			}		    /* Examine pin list to determine nets */		    for(k = 0; k < type->num_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] = (t_subblock *)					my_malloc(sizeof(t_subblock) * 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))						{						    slist[i][m].inputs[k] = type->num_pins + my_atoi(tokens[l] + 4);	/* Skip the 'ble_' part */						}					    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;}static t_type_ptrget_type_by_name(IN const char *name,		 IN int num_types,		 IN const struct s_type_descriptor block_types[],		 IN t_type_ptr IO_type,		 IN const char *net_file,		 IN int line,		 OUT enum special_blk *overide){    /* Just does a simple linear search for now */    int i;    /* pin_overide is used to specify that the .input and .output     * blocks only have one pin specified and should be treated      * as if used as a .io with a full pin spec */    *overide = NORMAL;    /* .input and .output are special names that map to the basic IO type */    if(0 == strcmp(".input", name))	{	    *overide = INPAD;	    return IO_type;	}    if(0 == strcmp(".output", name))	{	    *overide = OUTPAD;	    return IO_type;	}    /* Linear type search. Don't really expect to have too many      * types for it to be a problem */    for(i = 0; i < num_types; ++i)	{	    if(0 == strcmp(block_types[i].name, name))		{		    return (block_types + i);		}	}    /* No type matched */    printf(ERRTAG "'%s':%d - Invalid block type '%s'\n",	   net_file, line, name);    exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -