e_parse.y

来自「对于研究FPGA结构的人来说」· Y 代码 · 共 1,369 行 · 第 1/3 页

Y
1,369
字号
				ERROR("Couldn't add INOUT port named %s to hash table.\n", $3);			}			free($3);		}		else {			/* name the active port and retire to the list */			pActivePort->name = $3;			debug("Add: port %s to pPortLL\n", pActivePort->name);			ll_add(pPortLL, pActivePort);		}		pActivePort = NULL;    }    ;port_h:	| designator port_h    | direction port_h    ;direction:    '(' EP_direction NameToken ')'     {		my_assert(pActivePort==NULL);		/* Create a new active port */		if(!strcasecmp($3, "input")) {	    	debug("Alloc: input port\n");	    	pActivePort = (PORT *) malloc(sizeof(PORT));			mem_assert(pActivePort);			pActivePort->direction = in;			pActivePort->name = NULL;			pActivePort->ignore = 0;			pActivePort->pNet = 0;		} else if(!strcasecmp($3, "output")) {	    	debug("Alloc: output port\n");	    	pActivePort = (PORT *) malloc(sizeof(PORT));			mem_assert(pActivePort);			pActivePort->direction = out;			pActivePort->name = NULL;			pActivePort->ignore = 0;			pActivePort->pNet = 0;		} else if(!strcasecmp($3, "inout")) {			debug("Alloc: inout port\n");			WARN("INOUT port support has not been fully tested.\n");			pActivePort = (PORT *) malloc(sizeof(PORT));			mem_assert(pActivePort);			pActivePort->direction = inout;			pActivePort->name = NULL;			pActivePort->ignore = 0;			pActivePort->pNet = 0;		} else {	    	ERROR("Error: Unsupported port direction %s.\n", $3);	    	exit(1);		}		free($3);    }    ;contents:    '(' EP_contents contents_h ')'     ;contents_h:    | instance contents_h    | net contents_h    | comment contents_h    | userData contents_h    ;instance:    '(' EP_instance instanceNameDef viewRef instance_h ')'     {    	int i;			my_assert(pActiveInstance);		/* Declare ports */		pActiveInstance->ports = 			(NET **) malloc(pActiveInstance->pViewRef->nPorts * sizeof(NET *));		mem_assert(pActiveInstance->ports);		memset(pActiveInstance->ports, 0, sizeof(NET *) * pActiveInstance->pViewRef->nPorts);		/* Link new instance into this views instance chain for deallocation */		pActiveInstance->pNextInstance = pActiveView->pFirstInstance;		pActiveView->pFirstInstance = pActiveInstance;		/* Add instance to the instance hash table */		hash_add(pInstanceHT, pActiveInstance->name, pActiveInstance);		VERBOSE("Instance: %s of cell %s.\n", pActiveInstance->name, 			pActiveInstance->pCellRef->name);		/* Nullify active instance */		pActiveInstance = NULL;    }     | '(' EP_instance instanceNameDef viewList instance_h ')' 	{		ERROR("Error: viewList not allowed in instance %s of "			"cell %s.\n", pActiveInstance->name, pActiveCell->name); 		exit(1);    }    ;instanceNameDef:	nameDef	{		my_assert(pActiveView);		if(pActiveView->tag != netlist) {			ERROR("Error: Instances only allowed in views of type NETLIST.\n");			exit(-1);		}		my_assert(!pActiveInstance);		pActiveInstance = (INSTANCE *) malloc(sizeof(INSTANCE));		mem_assert(pActiveInstance);		pActiveInstance->name = strdup($1);		pActiveInstance->ports = NULL;		pActiveInstance->pCellRef = NULL;		pActiveInstance->pViewRef = NULL;		pActiveInstance->pNextInstance = NULL;		free($1);	}	;instance_h:    | property instance_h     | comment instance_h    | userData instance_h    ;viewList:    '(' EP_viewList     {		SKIPTAG("viewList");    }    ;viewRef:    '(' EP_viewRef nameRef ')'     {		ERROR("Error: No cellRef in viewRef tag (local view"			" references not supported yet) %s.\n", $3);		free($3);		exit(1);    }    | '(' EP_viewRef nameRef cellRef ')' 	{		NETLISTVIEW *pCurr = $4->pViewLL;		while(pCurr) {			if(!strcmp(pCurr->name, $3)) {				pActiveInstance->pCellRef = $4;				pActiveInstance->pViewRef = pCurr;				break;			}			pCurr = pCurr->pNextView;		}		if(!pCurr) {	    	ERROR("Error: Cell %s does not have a view named %s.\n", ($4)->name, $3);	    	exit(1);		}    }    ;cellRef:    '(' EP_cellRef nameRef ')' 	{		CELL *pCellDef;		pCellDef = (CELL *) hash_get(pActiveLibrary->pCellHT, $3); 		if(!pCellDef) {	    	ERROR("Error: Cell %s not found in current" 				" library %s.\n", $3, pActiveLibrary->name);	    	exit(1);		}		free($3);		$$ = pCellDef;    }    | '(' EP_cellRef nameRef libraryRef ')' 	{		CELL *pCellDef;				pCellDef = (CELL *) hash_get(($4)->pCellHT, $3);		if(!pCellDef) {	    	ERROR("Error: Cell %s not found in library %s.\n", $3, ($4)->name);	    	exit(1);		}		free($3); 		$$ = pCellDef;    }    ;libraryRef:    '(' EP_libraryRef nameRef ')' 	{		LIBRARY *pLibrary;		pLibrary = (LIBRARY *) hash_get(pLibraryHT, $3);		if(!pLibrary) {	    	ERROR("Error: library %s not found.\n", $3);	    	exit(1);		}		free($3);		$$ = pLibrary;    }    ;net:    '(' EP_net nameDef joined net_h ')'    { 		NET *pNewNet;		int i;		int nSources=0;		if(pPortRefLL->nEntries <= 1) {			if(!opt.edif_warn_once || !warning_1pin) {	    		WARN("Warning: Net %s has 1 or fewer pins.\n", $3);				warning_1pin = 1;			}		    ll_free(pPortRefLL);		} else {		   	VERBOSE("Net: %s with %d pins.\n", $3, pPortRefLL->nEntries);			/* Allocate a new net */		   	pNewNet = (NET *) malloc(sizeof(NET));			mem_assert(pNewNet);			pNewNet->name = $3;			pNewNet->ports = (PORTREF *) malloc(pPortRefLL->nEntries * sizeof(PORTREF));			mem_assert(pNewNet->ports);			/* Link it in to the de-allocation chain for this view */			pNewNet->pNextNet = pActiveView->pFirstNet;			pActiveView->pFirstNet = pNewNet;			/* Loop through each port reference, and link the net up */		    pNewNet->nPorts = 1;		    LL_LOOP(pPortRefLL) {				PORTREF *pCurrPortRef = (PORTREF *) ll_get(pPortRefLL);				/* If it is a reference to an instance */				if(pCurrPortRef->pInstance) {			   		/* If it points to a output port it's a source */			   		if(pCurrPortRef->portNum < pCurrPortRef->pInstance->pViewRef->nOutPorts) {						debug("\tSource port %d (%s) of instance %s.\n", pCurrPortRef->portNum, pCurrPortRef->pInstance->pViewRef->ports[pCurrPortRef->portNum].name, pCurrPortRef->pInstance->name);						if(nSources++) {							ERROR("Error: Too many drivers on net %s.\n", pNewNet->name);							exit(-1);						}   		 				pNewNet->ports[0] = *pCurrPortRef;			   		} 			   		/* Otherwise it's a sink */			   		else {						debug("\tSink port %d (%s) of instance %s.\n", pCurrPortRef->portNum, pCurrPortRef->pInstance->pViewRef->ports[pCurrPortRef->portNum].name, pCurrPortRef->pInstance->name);						if(pNewNet->nPorts == pPortRefLL->nEntries) {			    			ERROR("Error: No source for net %s.\n", pNewNet->name);			    			exit(1);						}						pNewNet->ports[pNewNet->nPorts++] = *pCurrPortRef;			   		}				} 				/* It's a reference to a pin of the cell */				else {			   		/* If it points to an output pin, then it's a sink */			   		if(pCurrPortRef->portNum < pActiveView->nOutPorts) {						VERBOSE("\tSink pin %d (%s) of current cell.\n", pCurrPortRef->portNum, pActiveView->ports[pCurrPortRef->portNum].name);						if(pNewNet->nPorts == pPortRefLL->nEntries) {			    			ERROR("Error: No source for net %s.\n", pNewNet->name);			    			exit(1);						}						pNewNet->ports[pNewNet->nPorts++] = *pCurrPortRef;			   		} 			   		/* Otherwise it's a source */			   		else {						VERBOSE("\tSource pin %d (%s) of current cell.\n", pCurrPortRef->portNum, pActiveView->ports[pCurrPortRef->portNum].name);						if(nSources++) {							ERROR("Error: Too many drivers on net %s.\n", pNewNet->name);							exit(-1);						}						pNewNet->ports[0] = *pCurrPortRef;			   		}				}		    }		    ll_free(pPortRefLL);	   		 	/* Attach the ports to the cells and vice-versa */   		 	for(i=0; i<pNewNet->nPorts; i++) {				INSTANCE *pInstance = pNewNet->ports[i].pInstance;				if(!pInstance) {		    		my_assert(pActiveView);		    		pActiveView->ports[pNewNet->ports[i].portNum].pNet = pNewNet;				}				else {		    		pInstance->ports[pNewNet->ports[i].portNum] = pNewNet;				}   		 	}		}		ll_free(pPortRefLL);	}	;/* PARTIAL */net_h:    | comment net_h    | userData net_h    ;joined:    '(' EP_joined joined_h ')'    ;/* PARTIAL */joined_h:    | portRef joined_h     {		/* Check if this is the first portref for the net */		if(!pPortRefLL)	    	pPortRefLL = ll_alloc(free_PORTREF);		/* Attach the portRef to the linked list */		my_assert($1);		ll_add(pPortRefLL, $1);     }    ;/* PARTIAL */portRef:    '(' EP_portRef nameRef ')'     {		PORTREF *pActivePortRef;		int i;		/* Allocate a new port reference */		pActivePortRef = (PORTREF *) malloc(sizeof(PORTREF));		mem_assert(pActivePortRef);		/* If reference to a local port, then pInstance points nowhere */		pActivePortRef->pInstance = NULL;		/* Find the port with name nameREF */		/* Is it in the inout hash table? */		if(hash_get(pInOutHT, $3)) {			ERROR("Bi-directional pins are not yet supported.\n"); 		}		for(i=0; i<pActiveView->nPorts; i++)	    	if(!strcmp($3, pActiveView->ports[i].name))	    		break;		/* Check to make sure it was found */		if(i==pActiveView->nPorts) {		    ERROR("Error: Port %s not found on active view %s.\n", 				$3, pActiveView->name);		    exit(1);		}		/* Point the port reference to this pin */		pActivePortRef->portNum = i;				/* Tidy up */		free($3);		$$ = pActivePortRef;    }    | '(' EP_portRef nameRef instanceRef ')'     {		PORTREF *pActivePortRef;		int i;		pActivePortRef = (PORTREF *) malloc(sizeof(PORTREF));		mem_assert(pActivePortRef);		pActivePortRef->pInstance = $4; 		/* Find the port with name nameRef */		for(i=0; i<$4->pViewRef->nPorts; i++)	    	if(!strcmp($3, $4->pViewRef->ports[i].name))	    		break;		/* Find the correct port on the instance */		if(i==$4->pViewRef->nPorts) {	    	ERROR("Error: Port %s not found on instance %s\n", 				pActivePortRef->pInstance->name);	    	exit(1);		}		/* Point t he port reference to the port of the instance */		pActivePortRef->portNum = i;				/* Tidy Up */		free($3);		$$ = pActivePortRef;    }    ; instanceRef:    '(' EP_instanceRef nameRef ')'    {		INSTANCE *pInstance;		pInstance = (INSTANCE *) hash_get(pInstanceHT, $3);		if(!pInstance) {		    ERROR("Error: Instance \"%s\" not found.\n", $3);		    exit(1);		}		my_assert(!strcmp($3, pInstance->name));		free($3);		$$ = pInstance;    }    ;design: '(' EP_design nameDef cellRef design_h ')'    { 		VERBOSE("Main design %s, top-level cell: %s\n", $3, $4->name);		free($3);		pTopCell = $4;    }    ;design_h:    | status design_h    | comment design_h    | property design_h    | userData design_h    ;%%#include "e_token.c"int yyerror(char *s){	error("line %d: Error '%s'\n", EP_lineno, s);	exit(1);}/*intEPyywrap(void){	return 0;}*/

⌨️ 快捷键说明

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