diff options
-rw-r--r-- | src/aig/gia/giaIf.c | 5 | ||||
-rw-r--r-- | src/base/io/io.c | 11 | ||||
-rw-r--r-- | src/base/io/ioAbc.h | 2 | ||||
-rw-r--r-- | src/base/io/ioWriteBlif.c | 298 |
4 files changed, 299 insertions, 17 deletions
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 0c0f2442..aec6ae01 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -506,7 +506,8 @@ Gia_Man_t * Gia_ManFromIf( If_Man_t * pIfMan ) // which participate as leaves of some cuts used in the mapping // such nodes are marked here and skipped when mapping is derived Counter = Gia_ManMarkDangling(pNew); - if ( pIfMan->pPars->fVerbose && Counter ) +// if ( pIfMan->pPars->fVerbose && Counter ) + if ( Counter ) printf( "GIA after mapping has %d dangling nodes.\n", Counter ); // create mapping @@ -568,7 +569,7 @@ Gia_Man_t * Gia_ManFromIf( If_Man_t * pIfMan ) pNew->pMapping[iOffset-k-1]--; continue; } - assert( FaninId != GiaId ); + assert( FaninId < GiaId ); pNew->pMapping[iOffset++] = FaninId; } pNew->pMapping[iOffset++] = GiaId; diff --git a/src/base/io/io.c b/src/base/io/io.c index b7c3234c..86e9dc80 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1654,9 +1654,10 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv ) char * pFileName; char * pLutStruct = NULL; int c, fSpecial = 0; + int fUseHie = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Sjh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Sjah" ) ) != EOF ) { switch ( c ) { @@ -1677,6 +1678,9 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv ) case 'j': fSpecial ^= 1; break; + case 'a': + fUseHie ^= 1; + break; case 'h': goto usage; default: @@ -1694,16 +1698,17 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv ) pFileName = argv[globalUtilOptind]; // call the corresponding file writer if ( fSpecial || pLutStruct ) - Io_WriteBlifSpecial( pAbc->pNtkCur, pFileName, pLutStruct ); + Io_WriteBlifSpecial( pAbc->pNtkCur, pFileName, pLutStruct, fUseHie ); else Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BLIF ); return 0; usage: - fprintf( pAbc->Err, "usage: write_blif [-S str] [-jh] <file>\n" ); + fprintf( pAbc->Err, "usage: write_blif [-S str] [-jah] <file>\n" ); fprintf( pAbc->Err, "\t writes the network into a BLIF file\n" ); fprintf( pAbc->Err, "\t-S str : string representing the LUT structure [default = %s]\n", pLutStruct ? pLutStruct : "not used" ); fprintf( pAbc->Err, "\t-j : enables special BLIF writing [default = %s]\n", fSpecial? "yes" : "no" );; + fprintf( pAbc->Err, "\t-a : enables hierarchical BLIF writing for LUT structures [default = %s]\n", fUseHie? "yes" : "no" );; fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .blif)\n" ); return 1; diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index 039f53c0..efac1212 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -106,7 +106,7 @@ extern void Io_WriteBblif( Abc_Ntk_t * pNtk, char * pFileName ); extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches ); extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches, int fBb2Wb, int fSeq ); extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk ); -extern void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ); +extern void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie ); /*=== abcWriteBlifMv.c ==========================================================*/ extern void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteBench.c =========================================================*/ diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index e13037db..bd7d9819 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -514,6 +514,68 @@ void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) fprintf( pFile, " %s", pName ); } +/**Function************************************************************* + + Synopsis [Writes the primary input list.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_NtkWriteSubcktFanins( FILE * pFile, Abc_Obj_t * pNode ) +{ + Abc_Obj_t * pNet; + int LineLength; + int AddedLength; + int NameCounter; + char * pName; + int i; + + LineLength = 6; + NameCounter = 0; + + // get the output name + pName = Abc_ObjName(Abc_ObjFanout0(pNode)); + // get the line length after the output name is written + AddedLength = strlen(pName) + 1; + fprintf( pFile, " m%d", Abc_ObjId(pNode) ); + + // get the input names + Abc_ObjForEachFanin( pNode, pNet, i ) + { + // get the fanin name + pName = Abc_ObjName(pNet); + // get the line length after the fanin name is written + AddedLength = strlen(pName) + 3; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, " \\\n" ); + // reset the line length + LineLength = 0; + NameCounter = 0; + } + fprintf( pFile, " %c=%s", 'a'+i, pName ); + LineLength += AddedLength; + NameCounter++; + } + + // get the output name + pName = Abc_ObjName(Abc_ObjFanout0(pNode)); + // get the line length after the output name is written + AddedLength = strlen(pName) + 3; + if ( NameCounter && LineLength + AddedLength > 75 ) + { // write the line extender + fprintf( pFile, " \\\n" ); + // reset the line length + LineLength = 0; + NameCounter = 0; + } + fprintf( pFile, " %c=%s", 'o', pName ); +} + /**Function************************************************************* @@ -586,6 +648,26 @@ int Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length ) /**Function************************************************************* + Synopsis [Write the node into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_NtkWriteNodeSubckt( FILE * pFile, Abc_Obj_t * pNode, int Length ) +{ + int RetValue = 0; + fprintf( pFile, ".subckt" ); + Io_NtkWriteSubcktFanins( pFile, pNode ); + fprintf( pFile, "\n" ); + return RetValue; +} + +/**Function************************************************************* + Synopsis [Writes the timing info.] Description [] @@ -1022,6 +1104,182 @@ void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCov /**Function************************************************************* + Synopsis [Write the node into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_NtkWriteModelIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCover, char * pStr ) +{ + Abc_Obj_t * pNet; + int nLeaves = Abc_ObjFaninNum(pNode); + int i, nLutLeaf, nLutLeaf2, nLutRoot, Length; + + // write the header + fprintf( pFile, "\n" ); + fprintf( pFile, ".model m%d\n", Abc_ObjId(pNode) ); + fprintf( pFile, ".inputs" ); + for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ ) + fprintf( pFile, " %c", 'a' + i ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs o\n" ); + + // quit if parameters are wrong + Length = strlen(pStr); + if ( Length != 2 && Length != 3 ) + { + printf( "Wrong LUT struct (%s)\n", pStr ); + return; + } + for ( i = 0; i < Length; i++ ) + if ( pStr[i] - '0' < 3 || pStr[i] - '0' > 6 ) + { + printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", pStr[i] - '0' ); + return; + } + + nLutLeaf = pStr[0] - '0'; + nLutLeaf2 = ( Length == 3 ) ? pStr[1] - '0' : 0; + nLutRoot = pStr[Length-1] - '0'; + if ( nLeaves > nLutLeaf - 1 + (nLutLeaf2 ? nLutLeaf2 - 1 : 0) + nLutRoot ) + { + printf( "The node size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr ); + return; + } + + // consider easy case + if ( nLeaves <= Abc_MaxInt( nLutLeaf2, Abc_MaxInt(nLutLeaf, nLutRoot) ) ) + { + // write the .names line + fprintf( pFile, ".names" ); + Abc_ObjForEachFanin( pNode, pNet, i ) + fprintf( pFile, " %c", 'a' + i ); + // get the output name + fprintf( pFile, " %s\n", "o" ); + // write the cubes + fprintf( pFile, "%s", (char*)Abc_ObjData(pNode) ); + fprintf( pFile, ".end\n" ); + return; + } + else + { + extern int If_CluMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars ); + + static word TruthStore[16][1<<10] = {{0}}, * pTruths[16]; + word pCube[1<<10], pRes[1<<10], Func0, Func1, Func2; + char pLut0[32], pLut1[32], pLut2[32] = {0}, * pSop; +// int nVarsMin[3], pVars[3][20]; + + if ( TruthStore[0][0] == 0 ) + { + static word Truth6[6] = { + 0xAAAAAAAAAAAAAAAA, + 0xCCCCCCCCCCCCCCCC, + 0xF0F0F0F0F0F0F0F0, + 0xFF00FF00FF00FF00, + 0xFFFF0000FFFF0000, + 0xFFFFFFFF00000000 + }; + int nVarsMax = 16; + int nWordsMax = (1 << 10); + int i, k; + assert( nVarsMax <= 16 ); + for ( i = 0; i < nVarsMax; i++ ) + pTruths[i] = TruthStore[i]; + for ( i = 0; i < 6; i++ ) + for ( k = 0; k < nWordsMax; k++ ) + pTruths[i][k] = Truth6[i]; + for ( i = 6; i < nVarsMax; i++ ) + for ( k = 0; k < nWordsMax; k++ ) + pTruths[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0; + } + + // collect variables +// Abc_ObjForEachFanin( pNode, pNet, i ) +// pVars[0][i] = pVars[1][i] = pVars[2][i] = i; + + // derive truth table + Abc_SopToTruthBig( (char*)Abc_ObjData(pNode), nLeaves, pTruths, pCube, pRes ); + if ( Kit_TruthIsConst0((unsigned *)pRes, nLeaves) || Kit_TruthIsConst1((unsigned *)pRes, nLeaves) ) + { + fprintf( pFile, ".names %s\n %d\n", "o", Kit_TruthIsConst1((unsigned *)pRes, nLeaves) ); + fprintf( pFile, ".end\n" ); + return; + } + +// Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " ); +// Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" ); + + // perform decomposition + if ( Length == 2 ) + { + if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) ) + { + Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " ); + Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" ); + printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) ); + return; + } + } + else + { + if ( !If_CluCheckExt3( NULL, pRes, nLeaves, nLutLeaf, nLutLeaf2, nLutRoot, pLut0, pLut1, pLut2, &Func0, &Func1, &Func2 ) ) + { + Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " ); + Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" ); + printf( "Node \"%s\" is not decomposable. Writing BLIF has failed.\n", Abc_ObjName(Abc_ObjFanout0(pNode)) ); + return; + } + } + + // write leaf node + fprintf( pFile, ".names" ); + for ( i = 0; i < pLut1[0]; i++ ) + fprintf( pFile, " %c", 'a' + pLut1[2+i] ); + fprintf( pFile, " lut1\n" ); + // write SOP + pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func1, pLut1[0], vCover ); + fprintf( pFile, "%s", pSop ); + + if ( Length == 3 && pLut2[0] > 0 ) + { + // write leaf node + fprintf( pFile, ".names" ); + for ( i = 0; i < pLut2[0]; i++ ) + if ( pLut2[2+i] == nLeaves ) + fprintf( pFile, " lut1" ); + else + fprintf( pFile, " %c", 'a' + pLut2[2+i] ); + fprintf( pFile, " lut2\n" ); + // write SOP + pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func2, pLut2[0], vCover ); + fprintf( pFile, "%s", pSop ); + } + + // write root node + fprintf( pFile, ".names" ); + for ( i = 0; i < pLut0[0]; i++ ) + if ( pLut0[2+i] == nLeaves ) + fprintf( pFile, " lut1" ); + else if ( pLut0[2+i] == nLeaves+1 ) + fprintf( pFile, " lut2" ); + else + fprintf( pFile, " %c", 'a' + pLut0[2+i] ); + fprintf( pFile, " %s\n", "o" ); + // write SOP + pSop = Io_NtkDeriveSop( (Mem_Flex_t *)Abc_ObjNtk(pNode)->pManFunc, Func0, pLut0[0], vCover ); + fprintf( pFile, "%s", pSop ); + fprintf( pFile, ".end\n" ); + } +} + + +/**Function************************************************************* + Synopsis [Write the network into a BLIF file with the given name.] Description [] @@ -1031,7 +1289,7 @@ void Io_NtkWriteNodeIntStruct( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vCov SeeAlso [] ***********************************************************************/ -void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ) +void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie ) { FILE * pFile; Vec_Int_t * vCover; @@ -1063,18 +1321,33 @@ void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ) Io_NtkWriteLatch( pFile, pLatch ); if ( Abc_NtkLatchNum(pNtk) ) fprintf( pFile, "\n" ); - // write each internal node + // write the hierarchy vCover = Vec_IntAlloc( (1<<16) ); - Abc_NtkForEachNode( pNtk, pNode, i ) + if ( fUseHie ) { - if ( pLutStruct ) - Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct ); - else - Io_NtkWriteNodeInt( pFile, pNode, vCover ); + // write each internal node + fprintf( pFile, "\n" ); + Abc_NtkForEachNode( pNtk, pNode, i ) + Io_NtkWriteNodeSubckt( pFile, pNode, 0 ); + fprintf( pFile, ".end\n\n" ); + // write models + Abc_NtkForEachNode( pNtk, pNode, i ) + Io_NtkWriteModelIntStruct( pFile, pNode, vCover, pLutStruct ); + fprintf( pFile, "\n" ); + } + else + { + // write each internal node + Abc_NtkForEachNode( pNtk, pNode, i ) + { + if ( pLutStruct ) + Io_NtkWriteNodeIntStruct( pFile, pNode, vCover, pLutStruct ); + else + Io_NtkWriteNodeInt( pFile, pNode, vCover ); + } + fprintf( pFile, ".end\n\n" ); } Vec_IntFree( vCover ); - // write the end - fprintf( pFile, ".end\n\n" ); fclose( pFile ); } @@ -1089,7 +1362,7 @@ void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ) SeeAlso [] ***********************************************************************/ -void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ) +void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct, int fUseHie ) { Abc_Ntk_t * pNtkTemp; assert( Abc_NtkIsLogic(pNtk) ); @@ -1101,7 +1374,10 @@ void Io_WriteBlifSpecial( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct ) fprintf( stdout, "Writing BLIF has failed.\n" ); return; } - Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct ); + if ( pLutStruct && fUseHie ) + Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 1 ); + else + Io_WriteBlifInt( pNtkTemp, FileName, pLutStruct, 0 ); Abc_NtkDelete( pNtkTemp ); } |