Commit 7ecea8d4 by Alan Mishchenko

Added hierarchical BLIF output for mapping with LUT structures (write_blif -a -S <XYZ>).

parent e9e8f179
......@@ -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;
......
......@@ -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;
......
......@@ -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 =========================================================*/
......
......@@ -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,8 +1321,23 @@ 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) );
if ( fUseHie )
{
// 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 )
......@@ -1072,9 +1345,9 @@ void Io_WriteBlifInt( Abc_Ntk_t * pNtk, char * FileName, char * pLutStruct )
else
Io_NtkWriteNodeInt( pFile, pNode, vCover );
}
Vec_IntFree( vCover );
// write the end
fprintf( pFile, ".end\n\n" );
}
Vec_IntFree( vCover );
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 );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment