/**Function************************************************************* Synopsis [Create the reset latch with data=1 and init=0.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Obj_t * Io_ReadCreateResetLatch( Abc_Ntk_t * pNtk, int fBlifMv ) { Abc_Obj_t * pLatch, * pNode; Abc_Obj_t * pNetLI, * pNetLO; // create latch with 0 init value // pLatch = Io_ReadCreateLatch( pNtk, "_resetLI_", "_resetLO_" ); pNetLI = Abc_NtkCreateNet( pNtk ); pNetLO = Abc_NtkCreateNet( pNtk ); Abc_ObjAssignName( pNetLI, Abc_ObjName(pNetLI), NULL ); Abc_ObjAssignName( pNetLO, Abc_ObjName(pNetLO), NULL ); pLatch = Io_ReadCreateLatch( pNtk, Abc_ObjName(pNetLI), Abc_ObjName(pNetLO) ); // set the initial value Abc_LatchSetInit0( pLatch ); // feed the latch with constant1- node // pNode = Abc_NtkCreateNode( pNtk ); // pNode->pData = Abc_SopRegister( pNtk->pManFunc, "2\n1\n" ); pNode = Abc_NtkCreateNodeConst1( pNtk ); Abc_ObjAddFanin( Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pNode ); return pLatch; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { Abc_Ntk_t * pNtk = p->pNtkCur; Abc_Obj_t * pLatch; int ResetValue; if ( vTokens->nSize < 3 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); sprintf( p->sError, "The .latch line does not have enough tokens." ); Io_ReadBlifPrintErrorMessage( p ); return 1; } // create the latch pLatch = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[1], (char *)vTokens->pArray[2] ); // get the latch reset value if ( vTokens->nSize == 3 ) Abc_LatchSetInitDc( pLatch ); else { ResetValue = atoi((char *)vTokens->pArray[vTokens->nSize-1]); if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); sprintf( p->sError, "The .latch line has an unknown reset value (%s).", (char*)vTokens->pArray[3] ); Io_ReadBlifPrintErrorMessage( p ); return 1; } if ( ResetValue == 0 ) Abc_LatchSetInit0( pLatch ); else if ( ResetValue == 1 ) Abc_LatchSetInit1( pLatch ); else if ( ResetValue == 2 ) Abc_LatchSetInitDc( pLatch ); } return 0; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) { ProgressBar * pProgress; Vec_Ptr_t * vTokens; Abc_Ntk_t * pNtk; Abc_Obj_t * pNode, * pNet; Vec_Str_t * vString; unsigned uTruth[8]; char * pType, ** ppNames, * pString; int iLine, nNames, nDigits, fLutsPresent = 0; // allocate the empty network pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) ); // go through the lines of the file vString = Vec_StrAlloc( 100 ); pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) ); for ( iLine = 0; (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)); iLine++ ) { Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL ); if ( vTokens->nSize == 1 ) { printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // get the type of the line if ( strncmp( (char *)vTokens->pArray[0], "INPUT", 5 ) == 0 ) Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[1] ); else if ( strncmp( (char *)vTokens->pArray[0], "OUTPUT", 5 ) == 0 ) Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[1] ); else { // get the node name and the node type pType = (char *)vTokens->pArray[1]; if ( strncmp(pType, "DFF", 3) == 0 ) // works for both DFF and DFFRSE { pNode = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[2], (char *)vTokens->pArray[0] ); // Abc_LatchSetInit0( pNode ); if ( pType[3] == '0' ) Abc_LatchSetInit0( pNode ); else if ( pType[3] == '1' ) Abc_LatchSetInit1( pNode ); else Abc_LatchSetInitDc( pNode ); } else if ( strcmp(pType, "LUT") == 0 ) { fLutsPresent = 1; ppNames = (char **)vTokens->pArray + 3; nNames = vTokens->nSize - 3; // check the number of inputs if ( nNames > 8 ) { printf( "%s: Currently cannot read truth tables with more than 8 inputs (%d).\n", Extra_FileReaderGetFileName(p), nNames ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // get the hex string pString = (char *)vTokens->pArray[2]; if ( strncmp( pString, "0x", 2 ) ) { printf( "%s: The LUT signature (%s) does not look like a hexadecimal beginning with \"0x\".\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } pString += 2; // pad the string with zero's if needed nDigits = (1 << nNames) / 4; if ( nDigits == 0 ) nDigits = 1; if ( strlen(pString) < (unsigned)nDigits ) { Vec_StrFill( vString, nDigits - strlen(pString), '0' ); Vec_StrPrintStr( vString, pString ); Vec_StrPush( vString, 0 ); pString = Vec_StrArray( vString ); } // read the hex number from the string if ( !Extra_ReadHexadecimal( uTruth, pString, nNames ) ) { printf( "%s: Reading hexadecimal number (%s) has failed.\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } // check if the node is a constant node if ( Extra_TruthIsConst0(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); } else if ( Extra_TruthIsConst1(uTruth, nNames) ) { pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 ); Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); } else { // create the node pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); assert( nNames > 0 ); if ( nNames > 1 ) Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Mem_Flex_t *)pNtk->pManFunc, nNames, uTruth) ); else if ( pString[0] == '2' ) Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( pString[0] == '1' ) Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else { printf( "%s: Reading truth table (%s) of single-input node has failed.\n", Extra_FileReaderGetFileName(p), pString ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } } } else { // create a new node and add it to the network ppNames = (char **)vTokens->pArray + 2; nNames = vTokens->nSize - 2; pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames ); // assign the cover if ( strcmp(pType, "AND") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "OR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "NAND") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "XOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, nNames) ); else if ( strncmp(pType, "BUF", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strcmp(pType, "NOT") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) ); else if ( strncmp(pType, "MUX", 3) == 0 ) // Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") ); Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") ); else if ( strncmp(pType, "gnd", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) ); else if ( strncmp(pType, "vdd", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) ); else { printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) ); Vec_StrFree( vString ); Abc_NtkDelete( pNtk ); return NULL; } } } } Extra_ProgressBarStop( pProgress ); Vec_StrFree( vString ); // check if constant 0 is present if ( (pNet = Abc_NtkFindNet( pNtk, "gnd" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) Io_ReadCreateConst( pNtk, "gnd", 0 ); } if ( (pNet = Abc_NtkFindNet( pNtk, "1" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) { printf( "Io_ReadBenchNetwork(): Adding constant 0 fanin to non-driven net \"1\".\n" ); Io_ReadCreateConst( pNtk, "1", 0 ); } } // check if constant 1 is present if ( (pNet = Abc_NtkFindNet( pNtk, "vdd" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) Io_ReadCreateConst( pNtk, "vdd", 1 ); } if ( (pNet = Abc_NtkFindNet( pNtk, "2" )) ) { if ( Abc_ObjFaninNum(pNet) == 0 ) { printf( "Io_ReadBenchNetwork(): Adding constant 1 fanin to non-driven net \"2\".\n" ); Io_ReadCreateConst( pNtk, "2", 1 ); } } Abc_NtkFinalizeRead( pNtk ); // if LUTs are present, collapse the truth tables into cubes if ( fLutsPresent ) { if ( !Abc_NtkToBdd(pNtk) ) { printf( "Io_ReadBenchNetwork(): Converting to BDD has failed.\n" ); Abc_NtkDelete( pNtk ); return NULL; } if ( !Abc_NtkToSop(pNtk, 0) ) { printf( "Io_ReadBenchNetwork(): Converting to SOP has failed.\n" ); Abc_NtkDelete( pNtk ); return NULL; } } return pNtk; }