From 0d10253bd061132fe61b0c0c04ac1b1d22c1633c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 6 Sep 2024 06:27:53 -0700 Subject: [PATCH] Another way of writing primary outputs in Verilog. --- src/base/abci/abc.c | 2 +- src/base/io/io.c | 22 ++++++----- src/base/io/ioAbc.h | 2 +- src/base/io/ioUtil.c | 4 +- src/base/io/ioWriteVerilog.c | 76 ++++++++++++++++++++++++++++-------- 5 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 8324c67d9b..29b418fa34 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32738,7 +32738,7 @@ int Abc_CommandAbc9WriteVer( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } Abc_NtkInsertHierarchyGia( pNtkSpec, pAbc->pNtkCur, fVerbose ); - Io_WriteVerilog( pNtkSpec, pFileName, 0 ); + Io_WriteVerilog( pNtkSpec, pFileName, 0, 0 ); Abc_NtkDelete( pNtkSpec ); return 0; diff --git a/src/base/io/io.c b/src/base/io/io.c index 9d456839eb..3327a9dfd8 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -3599,13 +3599,13 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) ***********************************************************************/ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) { - extern void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules ); + extern void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules, int fNewInterface ); char * pFileName; - int c, fFixed = 0, fOnlyAnds = 0, fNoModules = 0; + int c, fFixed = 0, fOnlyAnds = 0, fNoModules = 0, fNewInterface = 0; int nLutSize = -1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Kfamh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Kfamnh" ) ) != EOF ) { switch ( c ) { @@ -3629,6 +3629,9 @@ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) case 'm': fNoModules ^= 1; break; + case 'n': + fNewInterface ^= 1; + break; case 'h': goto usage; default: @@ -3647,27 +3650,26 @@ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) // get the output file name pFileName = argv[globalUtilOptind]; // call the corresponding file writer - if ( fOnlyAnds ) + if ( nLutSize >= 2 && nLutSize <= 6 ) + Io_WriteVerilogLut( pAbc->pNtkCur, pFileName, nLutSize, fFixed, fNoModules, fNewInterface ); + else { Abc_Ntk_t * pNtkTemp = Abc_NtkToNetlist( pAbc->pNtkCur ); if ( !Abc_NtkHasAig(pNtkTemp) && !Abc_NtkHasMapping(pNtkTemp) ) Abc_NtkToAig( pNtkTemp ); - Io_WriteVerilog( pNtkTemp, pFileName, 1 ); + Io_WriteVerilog( pNtkTemp, pFileName, fOnlyAnds, fNewInterface ); Abc_NtkDelete( pNtkTemp ); } - else if ( nLutSize >= 2 && nLutSize <= 6 ) - Io_WriteVerilogLut( pAbc->pNtkCur, pFileName, nLutSize, fFixed, fNoModules ); - else - Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_VERILOG ); return 0; usage: - fprintf( pAbc->Err, "usage: write_verilog [-K num] [-famh] \n" ); + fprintf( pAbc->Err, "usage: write_verilog [-K num] [-famnh] \n" ); fprintf( pAbc->Err, "\t writes the current network in Verilog format\n" ); fprintf( pAbc->Err, "\t-K num : write the network using instances of K-LUTs (2 <= K <= 6) [default = not used]\n" ); fprintf( pAbc->Err, "\t-f : toggle using fixed format [default = %s]\n", fFixed? "yes":"no" ); fprintf( pAbc->Err, "\t-a : toggle writing expressions with only ANDs (without XORs and MUXes) [default = %s]\n", fOnlyAnds? "yes":"no" ); fprintf( pAbc->Err, "\t-m : toggle writing additional modules [default = %s]\n", !fNoModules? "yes":"no" ); + fprintf( pAbc->Err, "\t-n : toggle writing generic PO names and assign-statements [default = %s]\n", fNewInterface? "yes":"no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); return 1; diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index 9a0d82098a..cf30196f2c 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -137,7 +137,7 @@ extern int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteSmv.c ===========================================================*/ extern int Io_WriteSmv( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteVerilog.c =======================================================*/ -extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName, int fOnlyAnds ); +extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName, int fOnlyAnds, int fNewInterface ); /*=== abcUtil.c ===============================================================*/ extern Io_FileType_t Io_ReadFileType( char * pFileName ); extern Io_FileType_t Io_ReadLibType( char * pFileName ); diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index 87c256561c..52cadc274f 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -465,7 +465,7 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ) { if ( !Abc_NtkHasAig(pNtkTemp) && !Abc_NtkHasMapping(pNtkTemp) ) Abc_NtkToAig( pNtkTemp ); - Io_WriteVerilog( pNtkTemp, pFileName, 0 ); + Io_WriteVerilog( pNtkTemp, pFileName, 0, 0 ); } else fprintf( stderr, "Unknown file format.\n" ); @@ -593,7 +593,7 @@ void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName ) if ( !Abc_NtkHasAig(pNtkResult) && !Abc_NtkHasMapping(pNtkResult) ) Abc_NtkToAig( pNtkResult ); } - Io_WriteVerilog( pNtkResult, pFileName, 0 ); + Io_WriteVerilog( pNtkResult, pFileName, 0, 0 ); } else if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV ) { diff --git a/src/base/io/ioWriteVerilog.c b/src/base/io/ioWriteVerilog.c index 5e4438a5dc..acddb75511 100644 --- a/src/base/io/ioWriteVerilog.c +++ b/src/base/io/ioWriteVerilog.c @@ -29,9 +29,10 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ); +static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds, int fNewInterface ); static void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); -static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); +static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start, int fNewInterface ); +static void Io_WriteVerilogAssigns( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk ); @@ -54,11 +55,12 @@ static char * Io_WriteVerilogGetName( char * pName ); SeeAlso [] ***********************************************************************/ -void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds ) +void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds, int fNewInterface ) { Abc_Ntk_t * pNetlist; FILE * pFile; int i; + // can only write nodes represented using local AIGs if ( !Abc_NtkIsAigNetlist(pNtk) && !Abc_NtkIsMappedNetlist(pNtk) ) { @@ -81,7 +83,7 @@ void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds ) if ( pNtk->pDesign ) { // write the network first - Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds ); + Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds, fNewInterface ); // write other things Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNetlist, i ) { @@ -89,12 +91,12 @@ void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds ) if ( pNetlist == pNtk ) continue; fprintf( pFile, "\n" ); - Io_WriteVerilogInt( pFile, pNetlist, fOnlyAnds ); + Io_WriteVerilogInt( pFile, pNetlist, fOnlyAnds, fNewInterface ); } } else { - Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds ); + Io_WriteVerilogInt( pFile, pNtk, fOnlyAnds, fNewInterface ); } fprintf( pFile, "\n" ); @@ -112,7 +114,7 @@ void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fOnlyAnds ) SeeAlso [] ***********************************************************************/ -void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) +void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds, int fNewInterface ) { // write inputs and outputs // fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) ); @@ -128,7 +130,7 @@ void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) fprintf( pFile, ",\n " ); } if ( Abc_NtkPoNum(pNtk) > 0 ) - Io_WriteVerilogPos( pFile, pNtk, 3 ); + Io_WriteVerilogPos( pFile, pNtk, 3, fNewInterface ); fprintf( pFile, " );\n" ); // add the clock signal if it does not exist if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 ) @@ -144,7 +146,7 @@ void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) if ( Abc_NtkPoNum(pNtk) > 0 ) { fprintf( pFile, " output" ); - Io_WriteVerilogPos( pFile, pNtk, 5 ); + Io_WriteVerilogPos( pFile, pNtk, 5, fNewInterface ); fprintf( pFile, ";\n" ); } // if this is not a blackbox, write internal signals @@ -168,6 +170,8 @@ void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk, int fOnlyAnds ) if ( Abc_NtkLatchNum(pNtk) > 0 ) Io_WriteVerilogLatches( pFile, pNtk ); } + if ( fNewInterface ) + Io_WriteVerilogAssigns( pFile, pNtk ); // finalize the file fprintf( pFile, "endmodule\n\n" ); } @@ -222,9 +226,10 @@ void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) SeeAlso [] ***********************************************************************/ -void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) +void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start, int fNewInterface ) { Abc_Obj_t * pTerm, * pNet, * pSkip; + char Name[100], * pName = Name; int LineLength; int AddedLength; int NameCounter; @@ -252,7 +257,11 @@ void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) } // get the line length after this name is written - AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2; + if ( fNewInterface ) + sprintf( Name, "po_username%d", i ); + else + pName = Abc_ObjName(pNet); + AddedLength = strlen(Io_WriteVerilogGetName(pName)) + 2; if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) { // write the line extender fprintf( pFile, "\n " ); @@ -260,7 +269,7 @@ void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) LineLength = 3; NameCounter = 0; } - fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (i==Abc_NtkPoNum(pNtk)-1)? "" : "," ); + fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pName), (i==Abc_NtkPoNum(pNtk)-1)? "" : "," ); LineLength += AddedLength; NameCounter++; } @@ -274,6 +283,37 @@ void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) } +/**Function************************************************************* + + Synopsis [Writes the primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogAssigns( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pTerm, * pNet, * pSkip; + int i; + Abc_NtkForEachPo( pNtk, pTerm, i ) + { + pNet = Abc_ObjFanin0(pTerm); + if ( Abc_ObjIsPi(Abc_ObjFanin0(pNet)) ) + { + // Skip this output since it is a feedthrough -- the same + // name will appear as an input and an output which other + // tools reading verilog do not like. + + pSkip = pNet; // save an example of skipped net + continue; + } + fprintf( pFile, " assign po_username%d = %s;\n", i, Abc_ObjName(pNet) ); + } +} + /**Function************************************************************* Synopsis [Writes the wires.] @@ -816,7 +856,7 @@ void Io_WriteVerilogObjectsLut( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, in fprintf( pFile, "}, %*s );\n", Length, Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) ); } } -void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed ) +void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fFixed, int fNewInterface ) { // write inputs and outputs // fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) ); @@ -832,7 +872,7 @@ void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fF fprintf( pFile, ",\n " ); } if ( Abc_NtkPoNum(pNtk) > 0 ) - Io_WriteVerilogPos( pFile, pNtk, 3 ); + Io_WriteVerilogPos( pFile, pNtk, 3, fNewInterface ); fprintf( pFile, " );\n\n" ); // add the clock signal if it does not exist if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 ) @@ -848,7 +888,7 @@ void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fF if ( Abc_NtkPoNum(pNtk) > 0 ) { fprintf( pFile, " output" ); - Io_WriteVerilogPos( pFile, pNtk, 5 ); + Io_WriteVerilogPos( pFile, pNtk, 5, fNewInterface ); fprintf( pFile, ";\n\n" ); } // if this is not a blackbox, write internal signals @@ -875,10 +915,12 @@ void Io_WriteVerilogLutInt( FILE * pFile, Abc_Ntk_t * pNtk, int nLutSize, int fF Io_WriteVerilogLatches( pFile, pNtk ); } } + if ( fNewInterface ) + Io_WriteVerilogAssigns( pFile, pNtk ); // finalize the file fprintf( pFile, "\nendmodule\n\n" ); } -void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules ) +void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int fFixed, int fNoModules, int fNewInterface ) { FILE * pFile; Abc_Ntk_t * pNtkTemp; @@ -917,7 +959,7 @@ void Io_WriteVerilogLut( Abc_Ntk_t * pNtk, char * pFileName, int nLutSize, int f } pNtkTemp = Abc_NtkToNetlist( pNtk ); Abc_NtkToSop( pNtkTemp, -1, ABC_INFINITY ); - Io_WriteVerilogLutInt( pFile, pNtkTemp, nLutSize, fFixed ); + Io_WriteVerilogLutInt( pFile, pNtkTemp, nLutSize, fFixed, fNewInterface ); Abc_NtkDelete( pNtkTemp ); fprintf( pFile, "\n" );