diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2007-02-11 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2007-02-11 08:01:00 -0800 |
commit | 5f3e4c0fe21ba5e24db0c187a616a28afc0dabae (patch) | |
tree | 30a84432ebcd370992d24ffced01ac0034072f30 /src/base/io/ioReadVerilog.c | |
parent | b9e0c95b690cf363f99b182ba8e7688aef091d95 (diff) | |
download | abc-5f3e4c0fe21ba5e24db0c187a616a28afc0dabae.tar.gz abc-5f3e4c0fe21ba5e24db0c187a616a28afc0dabae.tar.bz2 abc-5f3e4c0fe21ba5e24db0c187a616a28afc0dabae.zip |
Version abc70211
Diffstat (limited to 'src/base/io/ioReadVerilog.c')
-rw-r--r-- | src/base/io/ioReadVerilog.c | 720 |
1 files changed, 20 insertions, 700 deletions
diff --git a/src/base/io/ioReadVerilog.c b/src/base/io/ioReadVerilog.c index 4550d286..eda2d0b0 100644 --- a/src/base/io/ioReadVerilog.c +++ b/src/base/io/ioReadVerilog.c @@ -6,7 +6,7 @@ PackageName [Command processing package.] - Synopsis [Procedures to read a subset of structural Verilog from IWLS 2005 benchmark.] + Synopsis [Procedure to read network from file.] Author [Alan Mishchenko] @@ -24,99 +24,7 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct Io_ReadVer_t_ Io_ReadVer_t; // all reading info -struct Io_ReadVer_t_ -{ - // general info about file - char * pFileName; // the name of the file - Extra_FileReader_t* pReader; // the input file reader - // current processing info - st_table * tKeywords; // mapping of keywords into codes - Abc_Ntk_t * pNtk; // the primary network - // the error message - FILE * Output; // the output stream - char sError[1000]; // the error string generated during parsing - int LineCur; // the line currently being parsed - Vec_Ptr_t * vSkipped; // temporary storage for skipped objects -}; - -// verilog keyword types -typedef enum { - VER_NONE = 0, - VER_MODULE = -1, - VER_ENDMODULE = -2, - VER_INPUT = -3, - VER_OUTPUT = -4, - VER_INOUT = -5, - VER_WIRE = -6, - VER_ASSIGN = -7 -} Ver_KeywordType_t; - -// the list of verilog keywords -static char * s_Keywords[10] = -{ - NULL, // unused - "module", // -1 - "endmodule", // -2 - "input", // -3 - "output", // -4 - "inout", // -5 - "wire", // -6 - "assign" // -7 -}; - -// the list of gates in the Cadence library -static char * s_CadenceGates[40][5] = -{ - { "INVX1", "1", "1", "0 1\n", NULL }, // 0 - { "INVX2", "1", "1", "0 1\n", NULL }, // 1 - { "INVX4", "1", "1", "0 1\n", NULL }, // 2 - { "INVX8", "1", "1", "0 1\n", NULL }, // 3 - { "BUFX1", "1", "1", "1 1\n", NULL }, // 4 - { "BUFX3", "1", "1", "1 1\n", NULL }, // 5 - { "NOR2X1", "2", "1", "00 1\n", NULL }, // 6 - { "NOR3X1", "3", "1", "000 1\n", NULL }, // 7 - { "NOR4X1", "4", "1", "0000 1\n", NULL }, // 8 - { "NAND2X1", "2", "1", "11 0\n", NULL }, // 9 - { "NAND2X2", "2", "1", "11 0\n", NULL }, // 10 - { "NAND3X1", "3", "1", "111 0\n", NULL }, // 11 - { "NAND4X1", "4", "1", "1111 0\n", NULL }, // 12 - { "OR2X1", "2", "1", "00 0\n", NULL }, // 13 - { "OR4X1", "4", "1", "0000 0\n", NULL }, // 14 - { "AND2X1", "2", "1", "11 1\n", NULL }, // 15 - { "XOR2X1", "2", "1", "01 1\n10 1\n", NULL }, // 16 - { "MX2X1", "3", "1", "01- 1\n1-1 1\n", NULL }, // 17 - { "OAI21X1", "3", "1", "00- 1\n--0 1\n", NULL }, // 18 - { "OAI22X1", "4", "1", "00-- 1\n--00 1\n", NULL }, // 19 - { "OAI33X1", "6", "1", "000--- 1\n---000 1\n", NULL }, // 20 - { "AOI21X1", "3", "1", "11- 0\n--1 0\n", NULL }, // 21 - { "AOI22X1", "4", "1", "11-- 0\n--11 0\n", NULL }, // 22 - { "CLKBUFX1", "1", "1", "1 1\n", NULL }, // 23 - { "CLKBUFX2", "1", "1", "1 1\n", NULL }, // 24 - { "CLKBUFX3", "1", "1", "1 1\n", NULL }, // 25 - { "ADDHX1", "2", "2", "11 1\n", "01 1\n10 1\n" }, // 26 - { "ADDFX1", "3", "2", "11- 1\n-11 1\n1-1 1\n", "001 1\n010 1\n100 1\n111 1\n" }, // 27 - { "DFFSRX1", "1", "1", NULL, NULL }, // 28 - { "DFFX1", "1", "1", NULL, NULL }, // 29 - { "SDFFSRX1", "1", "1", NULL, NULL }, // 30 - { "TLATSRX1", "1", "1", NULL, NULL }, // 31 - { "TLATX1", "1", "1", NULL, NULL }, // 32 - { "TBUFX1", "1", "1", NULL, NULL }, // 33 - { "TBUFX2", "1", "1", NULL, NULL }, // 34 - { "TBUFX4", "1", "1", NULL, NULL }, // 35 - { "TBUFX8", "1", "1", NULL, NULL }, // 36 - { "TINVX1", "1", "1", NULL, NULL } // 37 -}; - -static Io_ReadVer_t * Io_ReadVerFile( char * pFileName ); -static Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p ); -static bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens ); -static bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ); -static bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ); -static bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ); -static bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens ); -static void Io_ReadVerPrintErrorMessage( Io_ReadVer_t * p ); -static void Io_ReadVerFree( Io_ReadVer_t * p ); +extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck, int fUseMemMan ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -124,44 +32,7 @@ static void Io_ReadVerFree( Io_ReadVer_t * p ); /**Function************************************************************* - Synopsis [Reads the network from a Verilog file.] - - Description [Works only for IWLS 2005 benchmarks.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ) -{ - Io_ReadVer_t * p; - Abc_Ntk_t * pNtk; - - // start the file - p = Io_ReadVerFile( pFileName ); - if ( p == NULL ) - return NULL; - - // read the network - pNtk = Io_ReadVerNetwork( p ); - Io_ReadVerFree( p ); - if ( pNtk == NULL ) - return NULL; - - // make sure that everything is okay with the network structure - if ( fCheck && !Abc_NtkCheckRead( pNtk ) ) - { - printf( "Io_ReadVerilog: The network check has failed.\n" ); - Abc_NtkDelete( pNtk ); - return NULL; - } - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Starts the reading data structure.] + Synopsis [Reads hierarchical design from the Verilog file.] Description [] @@ -170,583 +41,32 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ) SeeAlso [] ***********************************************************************/ -Io_ReadVer_t * Io_ReadVerFile( char * pFileName ) -{ - Extra_FileReader_t * pReader; - Io_ReadVer_t * p; - int i; - - // start the reader - pReader = Extra_FileReaderAlloc( pFileName, "/", ";", " \t\r\n,()" ); - if ( pReader == NULL ) - return NULL; - - // start the reading data structure - p = ALLOC( Io_ReadVer_t, 1 ); - memset( p, 0, sizeof(Io_ReadVer_t) ); - p->pFileName = pFileName; - p->pReader = pReader; - p->Output = stdout; - p->vSkipped = Vec_PtrAlloc( 100 ); - - // insert the keywords and gate names into the hash table - p->tKeywords = st_init_table(strcmp, st_strhash); - for ( i = 0; i < 10; i++ ) - if ( s_Keywords[i] ) - st_insert( p->tKeywords, (char *)s_Keywords[i], (char *)-i ); - for ( i = 0; i < 40; i++ ) - if ( s_CadenceGates[i][0] ) - st_insert( p->tKeywords, (char *)s_CadenceGates[i][0], (char *)i ); - return p; -} - -/**Function************************************************************* - - Synopsis [Frees the data structure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Io_ReadVerFree( Io_ReadVer_t * p ) -{ - Extra_FileReaderFree( p->pReader ); - Vec_PtrFree( p->vSkipped ); - st_free_table( p->tKeywords ); - FREE( p ); -} - -/**Function************************************************************* - - Synopsis [Prints the error message including the file name and line number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Io_ReadVerPrintErrorMessage( Io_ReadVer_t * p ) -{ - if ( p->LineCur == 0 ) // the line number is not given - fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError ); - else // print the error message with the line number - fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError ); -} - -/**Function************************************************************* - - Synopsis [Reads the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p ) +Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck ) { - char Buffer[1000]; - ProgressBar * pProgress; - Ver_KeywordType_t LineType; - Vec_Ptr_t * vTokens; Abc_Ntk_t * pNtk; - char * pModelName; - int i; + Abc_Lib_t * pDesign; - // read the model name - vTokens = Extra_FileReaderGetTokens( p->pReader ); - if ( vTokens == NULL || strcmp( vTokens->pArray[0], "module" ) ) - { - p->LineCur = 0; - sprintf( p->sError, "Wrong input file format." ); - Io_ReadVerPrintErrorMessage( p ); + // parse the verilog file + pDesign = Ver_ParseFile( pFileName, NULL, 1, fCheck ); + if ( pDesign == NULL ) return NULL; - } - pModelName = vTokens->pArray[1]; - // allocate the empty network - pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 ); - pNtk->pName = Extra_UtilStrsav( pModelName ); - pNtk->pSpec = Extra_UtilStrsav( p->pFileName ); + // extract the master network + pNtk = Vec_PtrEntryLast( pDesign->vModules ); + pNtk->pDesign = pDesign; + pDesign->pManFunc = NULL; - // create constant nodes and nets - Abc_NtkFindOrCreateNet( pNtk, "1'b0" ); - Abc_NtkFindOrCreateNet( pNtk, "1'b1" ); - Io_ReadCreateConst( pNtk, "1'b0", 0 ); - Io_ReadCreateConst( pNtk, "1'b1", 1 ); - - // read the inputs/outputs - pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) ); - for ( i = 0; vTokens = Extra_FileReaderGetTokens(p->pReader); i++ ) + // verify the design for cyclic dependence + assert( Vec_PtrSize(pDesign->vModules) > 0 ); + if ( Vec_PtrSize(pDesign->vModules) == 1 ) { - Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL ); - - // get the line type - if ( !st_lookup( p->tKeywords, vTokens->pArray[0], (char **)&LineType ) ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "The first token \"%s\" cannot be recognized.", vTokens->pArray[0] ); - Io_ReadVerPrintErrorMessage( p ); - return NULL; - } - // consider Verilog directives - if ( LineType < 0 ) - { - if ( LineType == VER_ENDMODULE ) - break; - if ( LineType == VER_ASSIGN ) - { - if ( !Io_ReadVerNetworkAssign( p, pNtk, vTokens ) ) - return NULL; - continue; - } - if ( !Io_ReadVerNetworkSignal( p, pNtk, vTokens, LineType ) ) - return NULL; - continue; - } - // proces single output gates - if ( LineType < 26 ) - { - if ( !Io_ReadVerNetworkGateSimple( p, pNtk, vTokens, LineType ) ) - return NULL; - continue; - } - // process complex gates - if ( LineType < 28 ) - { - if ( !Io_ReadVerNetworkGateComplex( p, pNtk, vTokens, LineType ) ) - return NULL; - continue; - - } - // process the latches - if ( LineType < 33 ) - { - if ( !Io_ReadVerNetworkLatch( p, pNtk, vTokens ) ) - return NULL; - continue; - } - // add the tri-state element to the skipped ones - sprintf( Buffer, "%s %s", vTokens->pArray[0], vTokens->pArray[1] ); - Vec_PtrPush( p->vSkipped, Extra_UtilStrsav(Buffer) ); - } - Extra_ProgressBarStop( pProgress ); - - if ( p->vSkipped->nSize > 0 ) - { - printf( "IoReadVerilog() skipped %d tri-state elements:\n", p->vSkipped->nSize ); - for ( i = 0; i < p->vSkipped->nSize; i++ ) - { - if ( i < 2 ) - printf( "%s,\n", p->vSkipped->pArray[i] ); - else - { - printf( "%s, etc.\n", p->vSkipped->pArray[i] ); - break; - } - } - for ( i = 0; i < p->vSkipped->nSize; i++ ) - free( p->vSkipped->pArray[i] ); - } - Abc_NtkFinalizeRead( pNtk ); - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Reads one assign directive in the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens ) -{ - assert( strcmp( vTokens->pArray[0], "assign" ) == 0 ); - // make sure the driving variable exists - if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[3] ) ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\". The assign operator is handled only for assignment to a variable and a constant.", vTokens->pArray[3] ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - // make sure the driven variable exists - if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[1] ) ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", vTokens->pArray[1] ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - // create a buffer - Io_ReadCreateBuf( pNtk, vTokens->pArray[3], vTokens->pArray[1] ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Reads one signal the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ) -{ - Abc_Obj_t * pNet; - char Buffer[1000]; - char * pToken; - int nSignals, k, Start, s; - - nSignals = 0; - pToken = vTokens->pArray[1]; - if ( pToken[0] == '[' ) - { - nSignals = atoi(pToken + 1) + 1; - if ( nSignals < 1 || nSignals > 1024 ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Incorrect number of signals in the expression \"%s\".", pToken ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - if ( nSignals == 1 ) - nSignals = 0; - Start = 2; + printf( "Warning: The design is not hierarchical.\n" ); + Abc_LibFree( pDesign, pNtk ); + pNtk->pDesign = NULL; } else - Start = 1; - for ( k = Start; k < vTokens->nSize; k++ ) - { - pToken = vTokens->pArray[k]; - // print the signal name - if ( nSignals ) - { - for ( s = 0; s < nSignals; s++ ) - { - sprintf( Buffer, "%s[%d]", pToken, s ); - if ( LineType == VER_INPUT || LineType == VER_INOUT ) - Io_ReadCreatePi( pNtk, Buffer ); - if ( LineType == VER_OUTPUT || LineType == VER_INOUT ) - Io_ReadCreatePo( pNtk, Buffer ); - if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT ) - pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer ); - } - } - else - { - if ( LineType == VER_INPUT || LineType == VER_INOUT ) - Io_ReadCreatePi( pNtk, pToken ); - if ( LineType == VER_OUTPUT || LineType == VER_INOUT ) - Io_ReadCreatePo( pNtk, pToken ); - if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT ) - pNet = Abc_NtkFindOrCreateNet( pNtk, pToken ); - } - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Reads a simple gate from the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ) -{ - Abc_Obj_t * pNet, * pNode; - char * pToken; - int nFanins, k; - - // create the node - pNode = Abc_NtkCreateNode( pNtk ); - // add the fanin nets - nFanins = s_CadenceGates[LineType][1][0] - '0'; - // skip the gate type and gate name - for ( k = 2; k < vTokens->nSize - 1; k++ ) - { - pToken = vTokens->pArray[k]; - if ( pToken[0] == '.' ) - continue; - pNet = Abc_NtkFindNet( pNtk, pToken ); - if ( pNet ) - { - Abc_ObjAddFanin( pNode, pNet ); - continue; - } - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", pToken ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - if ( Abc_ObjFaninNum(pNode) != nFanins ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Gate \"%s\" has a wrong number of inputs.", vTokens->pArray[1] ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - - // add the fanout net - pToken = vTokens->pArray[vTokens->nSize - 1]; - if ( pToken[0] == '.' ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Gate \"%s\" does not have a fanout.", vTokens->pArray[1] ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - pNet = Abc_NtkFindNet( pNtk, pToken ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", pToken ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Abc_ObjAddFanin( pNet, pNode ); - // set the function - Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Reads a complex gate from the verilog file.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType ) -{ - Abc_Obj_t * pNode1, * pNode2, * pNet; - char * pToken, * pToken1, * pToken2; - int nFanins, k; - - // create the nodes - pNode1 = Abc_NtkCreateNode( pNtk ); - pNode2 = Abc_NtkCreateNode( pNtk ); - // skip the gate type and gate name - // add the fanin nets - nFanins = s_CadenceGates[LineType][1][0] - '0'; - for ( k = 2; k < vTokens->nSize; k++ ) - { - pToken = vTokens->pArray[k]; - if ( pToken[0] == '.' ) - continue; - pNet = Abc_NtkFindNet( pNtk, pToken ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", pToken ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Abc_ObjAddFanin( pNode1, pNet ); - Abc_ObjAddFanin( pNode2, pNet ); - if ( Abc_ObjFaninNum(pNode1) == nFanins ) - { - k++; - break; - } - } - // find the tokens corresponding to the output - pToken1 = pToken2 = NULL; - for ( ; k < vTokens->nSize; k++ ) - { - pToken = vTokens->pArray[k]; - if ( pToken[0] == '.' ) - continue; - if ( pToken1 == NULL ) - pToken1 = pToken; - else - pToken2 = pToken; - } - // quit if one of the tokens is not given - if ( pToken1 == NULL || pToken2 == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "An output of a two-output gate \"%s\" is not specified.", vTokens->pArray[1] ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - - // add the fanout net - pNet = Abc_NtkFindNet( pNtk, pToken1 ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", pToken1 ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Abc_ObjAddFanin( pNet, pNode1 ); - - // add the fanout net - pNet = Abc_NtkFindNet( pNtk, pToken2 ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find net \"%s\".", pToken2 ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Abc_ObjAddFanin( pNet, pNode2 ); - Abc_ObjSetData( pNode1, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) ); - Abc_ObjSetData( pNode2, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][4]) ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Reads a latch from the verilog file.] - - Description [This procedure treats T-latch as if it were D-latch.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens ) -{ - Abc_Obj_t * pLatch, * pNet; - char * pLatchName; - char * pToken, * pToken2, * pTokenRN, * pTokenSN, * pTokenSI, * pTokenSE, * pTokenD, * pTokenQ, * pTokenQN; - int k, fRN1, fSN1; - - // get the latch name - pLatchName = vTokens->pArray[1]; - - // collect the FF signals - pTokenRN = pTokenSN = pTokenSI = pTokenSE = pTokenD = pTokenQ = pTokenQN = NULL; - for ( k = 2; k < vTokens->nSize-1; k++ ) - { - pToken = vTokens->pArray[k]; - pToken2 = vTokens->pArray[k+1]; - if ( pToken[1] == 'R' && pToken[2] == 'N' && pToken[3] == 0 ) - pTokenRN = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'S' && pToken[2] == 'N' && pToken[3] == 0 ) - pTokenSN = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'S' && pToken[2] == 'I' && pToken[3] == 0 ) - pTokenSI = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'S' && pToken[2] == 'E' && pToken[3] == 0 ) - pTokenSE = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'D' && pToken[2] == 0 ) - pTokenD = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'Q' && pToken[2] == 0 ) - pTokenQ = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'Q' && pToken[2] == 'N' && pToken[3] == 0 ) - pTokenQN = (pToken2[0] == '.')? NULL : pToken2; - else if ( pToken[1] == 'C' && pToken[2] == 'K' && pToken[3] == 0 ) {} - else - assert( 0 ); - if ( pToken2[0] != '.' ) - k++; - } - - if ( pTokenD == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 ); - sprintf( p->sError, "Cannot read pin D of the latch \"%s\".", pLatchName ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - if ( pTokenQ == NULL && pTokenQN == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 ); - sprintf( p->sError, "Cannot read pins Q/QN of the latch \"%s\".", pLatchName ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - if ( (pTokenRN == NULL) ^ (pTokenSN == NULL) ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 ); - sprintf( p->sError, "Cannot read pins RN/SN of the latch \"%s\".", pLatchName ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - if ( Abc_NtkFindNet( pNtk, pTokenD ) == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find latch input net \"%s\".", pTokenD ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - - // create the latch - pLatch = Io_ReadCreateLatch( pNtk, pTokenD, pLatchName ); - - // create the buffer if Q signal is available - if ( pTokenQ ) - { - pNet = Abc_NtkFindNet( pNtk, pTokenQ ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find latch output net \"%s\".", pTokenQ ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Io_ReadCreateBuf( pNtk, pLatchName, pTokenQ ); - } - if ( pTokenQN ) - { - pNet = Abc_NtkFindNet( pNtk, pTokenQN ); - if ( pNet == NULL ) - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot find latch output net \"%s\".", pTokenQN ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - Io_ReadCreateInv( pNtk, pLatchName, pTokenQN ); - } - - // set the initial value - if ( pTokenRN == NULL && pTokenSN == NULL ) - Abc_LatchSetInitDc( pLatch ); - else - { - fRN1 = (strcmp( pTokenRN, "1'b1" ) == 0); - fSN1 = (strcmp( pTokenSN, "1'b1" ) == 0); - if ( fRN1 && fSN1 ) - Abc_LatchSetInitDc( pLatch ); - else if ( fRN1 ) - Abc_LatchSetInit1( pLatch ); - else if ( fSN1 ) - Abc_LatchSetInit0( pLatch ); - else - { - p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 ); - sprintf( p->sError, "Cannot read the initial value of latch \"%s\".", pLatchName ); - Io_ReadVerPrintErrorMessage( p ); - return 0; - } - } - return 1; + Abc_NtkIsAcyclicHierarchy( pNtk ); + return pNtk; } //////////////////////////////////////////////////////////////////////// |