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 + -
显示快捷键?