From 588122dc72932aa56e0f1810a8a3ea3c1f62f679 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 11 Sep 2023 09:44:22 +0700 Subject: [PATCH] Writing an interface module when dumping Verilog. --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaAiger.c | 9 ++-- src/aig/gia/giaMan.c | 109 +++++++++++++++++++++++++++++++++++------ src/base/abci/abc.c | 11 +++-- src/base/wln/wlnCom.c | 2 +- 5 files changed, 111 insertions(+), 22 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index fed64b1ad..d4edc1237 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1527,7 +1527,7 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose ) extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs ); extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew ); extern void Gia_ManPrintNpnClasses( Gia_Man_t * p ); -extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs ); +extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter ); /*=== giaMem.c ===========================================================*/ extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax ); extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose ); diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index aafe311b1..e3967e0ed 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -953,9 +953,12 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi } } pInit[i] = 0; - pNew = Gia_ManDupZeroUndc( pTemp = pNew, pInit, 0, fGiaSimple, 1 ); - pNew->nConstrs = pTemp->nConstrs; pTemp->nConstrs = 0; - Gia_ManStop( pTemp ); + if ( !fSkipStrash ) + { + pNew = Gia_ManDupZeroUndc( pTemp = pNew, pInit, 0, fGiaSimple, 1 ); + pNew->nConstrs = pTemp->nConstrs; pTemp->nConstrs = 0; + Gia_ManStop( pTemp ); + } ABC_FREE( pInit ); } Vec_IntFreeP( &vInits ); diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 6a3f2c458..e8f9bca32 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -1241,6 +1241,90 @@ void Gia_ManDfsSlacksPrint( Gia_Man_t * p ) } +/**Function************************************************************* + + Synopsis [Dump interface module] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManWriteNamesInter( FILE * pFile, char c, int n, int Start, int Skip, int nRegs ) +{ + int Length = Start, i, fFirst = 1; + char pName[100]; + for ( i = 0; i < n-nRegs; i++ ) + { + sprintf( pName, "%c[%d]", c, i ); + Length += strlen(pName) + 2; + if ( Length > 60 ) + { + fprintf( pFile, ",\n " ); + Length = Skip; + fFirst = 1; + } + fprintf( pFile, "%s%s", fFirst ? "":", ", pName ); + fFirst = 0; + } + for ( i = n-nRegs; i < n; i++ ) + { + sprintf( pName, "%c%c[%d]", c, c, i ); + Length += strlen(pName) + 2; + if ( Length > 60 ) + { + fprintf( pFile, ",\n " ); + Length = Skip; + fFirst = 1; + } + fprintf( pFile, "%s%s", fFirst ? "":", ", pName ); + fFirst = 0; + }} +void Gia_ManDumpModuleName( FILE * pFile, char * pName ) +{ + int i; + for ( i = 0; i < (int)strlen(pName); i++ ) + if ( isalpha(pName[i]) || isdigit(pName[i]) ) + fprintf( pFile, "%c", pName[i] ); + else + fprintf( pFile, "_" ); +} +void Gia_ManDumpInterface( Gia_Man_t * p, FILE * pFile ) +{ + int fPrintClk = 0; + fprintf( pFile, "module " ); + Gia_ManDumpModuleName( pFile, p->pName ); + fprintf( pFile, "_wrapper" ); + fprintf( pFile, " (%s i, o );\n\n", fPrintClk && Gia_ManRegNum(p) ? " clk," : "" ); + if ( fPrintClk && Gia_ManRegNum(p) ) + fprintf( pFile, " input clk;\n" ); + fprintf( pFile, " input [%d:0] i;\n", Gia_ManPiNum(p)-1 ); + fprintf( pFile, " output [%d:0] o;\n\n", Gia_ManPoNum(p)-1 ); + + if ( Gia_ManRegNum(p) ) { + fprintf( pFile, " wire [%d:%d] ii;\n", Gia_ManCiNum(p)-1, Gia_ManPiNum(p) ); + fprintf( pFile, " wire [%d:%d] oo;\n\n", Gia_ManCoNum(p)-1, Gia_ManPoNum(p) ); + fprintf( pFile, " always @ (posedge %s)\n ii <= oo;\n\n", fPrintClk ? "clk" : "i[0]" ); + } + + fprintf( pFile, " " ); + Gia_ManDumpModuleName( pFile, p->pName ); + fprintf( pFile, " " ); + Gia_ManDumpModuleName( pFile, p->pName ); + fprintf( pFile, "_inst" ); + + fprintf( pFile, " (\n " ); + Gia_ManWriteNamesInter( pFile, 'i', Gia_ManCiNum(p), 4, 4, Gia_ManRegNum(p) ); + fprintf( pFile, ",\n " ); + Gia_ManWriteNamesInter( pFile, 'o', Gia_ManCoNum(p), 4, 4, Gia_ManRegNum(p) ); + fprintf( pFile, "\n );\n\n" ); + + fprintf( pFile, "endmodule\n\n" ); +} + + /**Function************************************************************* Synopsis [Compute arrival/required times.] @@ -1323,38 +1407,33 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta fFirst = 0; } } -void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs ) +void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter ) { - FILE * pFile; Gia_Obj_t * pObj; Vec_Bit_t * vInvs, * vUsed; int nDigits = Abc_Base10Log( Gia_ManObjNum(p) ); int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) ); int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) ); - int i, k, iObj; - if ( Gia_ManRegNum(p) ) - { - printf( "Currently cannot write sequential AIG.\n" ); - return; - } - pFile = fopen( pFileName, "wb" ); + int i, k, iObj, nRegs = Gia_ManRegNum(p); + FILE * pFile = fopen( pFileName, "wb" ); if ( pFile == NULL ) { printf( "Cannot open output file \"%s\".\n", pFileName ); return; } + if ( fInter || nRegs ) + Gia_ManDumpInterface( p, pFile ); + //Gia_ManSetRegNum( p, 0 ); + p->nRegs = 0; + vInvs = Gia_ManGenUsed( p, 0 ); vUsed = Gia_ManGenUsed( p, 1 ); //fprintf( pFile, "// This Verilog file is written by ABC on %s\n\n", Extra_TimeStamp() ); fprintf( pFile, "module " ); - for ( i = 0; i < (int)strlen(p->pName); i++ ) - if ( isalpha(p->pName[i]) || isdigit(p->pName[i]) ) - fprintf( pFile, "%c", p->pName[i] ); - else - fprintf( pFile, "_" ); + Gia_ManDumpModuleName( pFile, p->pName ); if ( fVerBufs ) { @@ -1505,6 +1584,8 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int Vec_BitFree( vInvs ); Vec_BitFree( vUsed ); + + Gia_ManSetRegNum( p, nRegs ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index d821647a8..e86667882 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -31761,13 +31761,14 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nArgcNew; int fUnique = 0; int fVerilog = 0; + int fInter = 0; int fVerBufs = 0; int fMiniAig = 0; int fMiniLut = 0; int fWriteNewLine = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "upbmlnvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "upibmlnvh" ) ) != EOF ) { switch ( c ) { @@ -31777,6 +31778,9 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'p': fVerilog ^= 1; break; + case 'i': + fInter ^= 1; + break; case 'b': fVerBufs ^= 1; break; @@ -31818,7 +31822,7 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManStop( pGia ); } else if ( fVerilog ) - Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL, fVerBufs ); + Gia_ManDumpVerilog( pAbc->pGia, pFileName, NULL, fVerBufs, fInter ); else if ( fMiniAig ) Gia_ManWriteMiniAig( pAbc->pGia, pFileName ); else if ( fMiniLut ) @@ -31828,10 +31832,11 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &w [-upbmlnvh] \n" ); + Abc_Print( -2, "usage: &w [-upibmlnvh] \n" ); Abc_Print( -2, "\t writes the current AIG into the AIGER file\n" ); Abc_Print( -2, "\t-u : toggle writing canonical AIG structure [default = %s]\n", fUnique? "yes" : "no" ); Abc_Print( -2, "\t-p : toggle writing Verilog with 'and' and 'not' [default = %s]\n", fVerilog? "yes" : "no" ); + Abc_Print( -2, "\t-i : toggle writing the interface module in Verilog [default = %s]\n", fInter? "yes" : "no" ); Abc_Print( -2, "\t-b : toggle writing additional buffers in Verilog [default = %s]\n", fVerBufs? "yes" : "no" ); Abc_Print( -2, "\t-m : toggle writing MiniAIG rather than AIGER [default = %s]\n", fMiniAig? "yes" : "no" ); Abc_Print( -2, "\t-l : toggle writing MiniLUT rather than AIGER [default = %s]\n", fMiniLut? "yes" : "no" ); diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 09cbe90f3..06e4392c9 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -206,7 +206,7 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: %%yosys [-T ] [-D ] [-bismcvh] \n" ); Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); - Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); + Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\")\n" ); Abc_Print( -2, "\t-D : specify defines to be used by Yosys (default \"not used\")\n" ); Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" ); Abc_Print( -2, "\t-i : toggle inverting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" );