/**CFile**************************************************************** FileName [ioWriteBlifMv.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Command processing package.] Synopsis [Procedures to write BLIF-MV files.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: ioWriteBlifMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "ioAbc.h" #include "base/main/main.h" #include "map/mio/mio.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvAsserts( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteBlifMvNodeFanins( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch ); static void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteBlifMvValues( FILE * pFile, Abc_Obj_t * pNode ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Write the network into a BLIF file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName ) { FILE * pFile; Abc_Ntk_t * pNtkTemp; int i; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_NtkHasBlifMv(pNtk) ); // start writing the file pFile = fopen( FileName, "w" ); if ( pFile == NULL ) { fprintf( stdout, "Io_WriteBlifMv(): Cannot open the output file.\n" ); return; } fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); // write the master network Io_NtkWriteBlifMv( pFile, pNtk ); // write the remaining networks if ( pNtk->pDesign ) { Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i ) { if ( pNtkTemp == pNtk ) continue; fprintf( pFile, "\n\n" ); Io_NtkWriteBlifMv( pFile, pNtkTemp ); } } fclose( pFile ); } /**Function************************************************************* Synopsis [Write the network into a BLIF file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk ) { assert( Abc_NtkIsNetlist(pNtk) ); // write the model name fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) ); // write the network Io_NtkWriteBlifMvOne( pFile, pNtk ); // write EXDC network if it exists if ( Abc_NtkExdc(pNtk) ) printf( "Io_NtkWriteBlifMv(): EXDC is not written.\n" ); // finalize the file fprintf( pFile, ".end\n\n\n" ); } /**Function************************************************************* Synopsis [Write one network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk ) { ProgressBar * pProgress; Abc_Obj_t * pNode, * pTerm, * pLatch; int i; // write the PIs fprintf( pFile, ".inputs" ); Io_NtkWriteBlifMvPis( pFile, pNtk ); fprintf( pFile, "\n" ); // write the POs fprintf( pFile, ".outputs" ); Io_NtkWriteBlifMvPos( pFile, pNtk ); fprintf( pFile, "\n" ); // write the MV directives fprintf( pFile, "\n" ); Abc_NtkForEachCi( pNtk, pTerm, i ) if ( Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) ); Abc_NtkForEachCo( pNtk, pTerm, i ) if ( Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanin0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) ); // write the blackbox if ( Abc_NtkHasBlackbox( pNtk ) ) { fprintf( pFile, ".blackbox\n" ); return; } // write the timing info // Io_WriteTimingInfo( pFile, pNtk ); // write the latches if ( !Abc_NtkIsComb(pNtk) ) { fprintf( pFile, "\n" ); Abc_NtkForEachLatch( pNtk, pLatch, i ) Io_NtkWriteBlifMvLatch( pFile, pLatch ); fprintf( pFile, "\n" ); } /* // write the subcircuits assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); if ( Abc_NtkBlackboxNum(pNtk) > 0 ) { fprintf( pFile, "\n" ); Abc_NtkForEachBlackbox( pNtk, pNode, i ) Io_NtkWriteBlifMvSubckt( pFile, pNode ); fprintf( pFile, "\n" ); } */ if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 ) { fprintf( pFile, "\n" ); Abc_NtkForEachBox( pNtk, pNode, i ) { if ( Abc_ObjIsLatch(pNode) ) continue; Io_NtkWriteBlifMvSubckt( pFile, pNode ); } fprintf( pFile, "\n" ); } // write each internal node pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); Io_NtkWriteBlifMvNode( pFile, pNode ); } Extra_ProgressBarStop( pProgress ); } /**Function************************************************************* Synopsis [Writes the primary input list.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pTerm, * pNet; int LineLength; int AddedLength; int NameCounter; int i; LineLength = 7; NameCounter = 0; Abc_NtkForEachPi( pNtk, pTerm, i ) { pNet = Abc_ObjFanout0(pTerm); // get the line length after this name is written AddedLength = strlen(Abc_ObjName(pNet)) + 1; 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, " %s", Abc_ObjName(pNet) ); LineLength += AddedLength; NameCounter++; } } /**Function************************************************************* Synopsis [Writes the primary input list.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pTerm, * pNet; int LineLength; int AddedLength; int NameCounter; int i; LineLength = 8; NameCounter = 0; Abc_NtkForEachPo( pNtk, pTerm, i ) { pNet = Abc_ObjFanin0(pTerm); // get the line length after this name is written AddedLength = strlen(Abc_ObjName(pNet)) + 1; 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, " %s", Abc_ObjName(pNet) ); LineLength += AddedLength; NameCounter++; } } /**Function************************************************************* Synopsis [Write the latch into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch ) { Abc_Obj_t * pNetLi, * pNetLo; int Reset; pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) ); pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) ); Reset = (int)(ABC_PTRUINT_T)Abc_ObjData( pLatch ); // write the latch line fprintf( pFile, ".latch" ); fprintf( pFile, " %10s", Abc_ObjName(pNetLi) ); fprintf( pFile, " %10s", Abc_ObjName(pNetLo) ); fprintf( pFile, "\n" ); // write the reset node fprintf( pFile, ".reset %s\n", Abc_ObjName(pNetLo) ); fprintf( pFile, "%d\n", Reset-1 ); } /**Function************************************************************* Synopsis [Write the latch into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode ) { Abc_Ntk_t * pModel = (Abc_Ntk_t *)pNode->pData; Abc_Obj_t * pTerm; int i; // write the MV directives fprintf( pFile, "\n" ); Abc_ObjForEachFanin( pNode, pTerm, i ) if ( Abc_ObjMvVarNum(pTerm) > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) ); Abc_ObjForEachFanout( pNode, pTerm, i ) if ( Abc_ObjMvVarNum(pTerm) > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) ); // write the subcircuit fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) ); // write pairs of the formal=actual names Abc_NtkForEachPi( pModel, pTerm, i ) { fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); pTerm = Abc_ObjFanin( pNode, i ); fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); } Abc_NtkForEachPo( pModel, pTerm, i ) { fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); pTerm = Abc_ObjFanout( pNode, i ); fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); } fprintf( pFile, "\n" ); } /**Function************************************************************* Synopsis [Write the node into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode ) { Abc_Obj_t * pFanin; char * pCur; int nValues, iFanin, i; // write .mv directives for the fanins fprintf( pFile, "\n" ); Abc_ObjForEachFanin( pNode, pFanin, i ) { // nValues = atoi(pCur); nValues = Abc_ObjMvVarNum( pFanin ); if ( nValues > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pFanin), nValues ); // while ( *pCur++ != ' ' ); } // write .mv directives for the node // nValues = atoi(pCur); nValues = Abc_ObjMvVarNum( Abc_ObjFanout0(pNode) ); if ( nValues > 2 ) fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), nValues ); // while ( *pCur++ != '\n' ); // write the .names line fprintf( pFile, ".table" ); Io_NtkWriteBlifMvNodeFanins( pFile, pNode ); fprintf( pFile, "\n" ); // write the cubes pCur = (char *)Abc_ObjData(pNode); if ( *pCur == 'd' ) { fprintf( pFile, ".default " ); pCur++; } // write the literals for ( ; *pCur; pCur++ ) { fprintf( pFile, "%c", *pCur ); if ( *pCur != '=' ) continue; // get the number iFanin = atoi( pCur+1 ); fprintf( pFile, "%s", Abc_ObjName(Abc_ObjFanin(pNode,iFanin)) ); // scroll on to the next symbol while ( *pCur != ' ' && *pCur != '\n' ) pCur++; pCur--; } } /**Function************************************************************* Synopsis [Writes the primary input list.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteBlifMvNodeFanins( FILE * pFile, Abc_Obj_t * pNode ) { Abc_Obj_t * pNet; int LineLength; int AddedLength; int NameCounter; char * pName; int i; LineLength = 6; NameCounter = 0; 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) + 1; 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, " %s", 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) + 1; if ( NameCounter && LineLength + AddedLength > 75 ) { // write the line extender fprintf( pFile, " \\\n" ); // reset the line length LineLength = 0; NameCounter = 0; } fprintf( pFile, " %s", pName ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END