diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2005-12-22 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2005-12-22 08:01:00 -0800 |
commit | 457e243e588e7ed5f39251784335e254a0c9e711 (patch) | |
tree | 751d7b416e66e416983760d0b95d79bb24371309 /src/base/io | |
parent | 37f19d8dfb17605abab38110beec5fc17413e635 (diff) | |
download | abc-457e243e588e7ed5f39251784335e254a0c9e711.tar.gz abc-457e243e588e7ed5f39251784335e254a0c9e711.tar.bz2 abc-457e243e588e7ed5f39251784335e254a0c9e711.zip |
Version abc51222
Diffstat (limited to 'src/base/io')
-rw-r--r-- | src/base/io/io.c | 65 | ||||
-rw-r--r-- | src/base/io/io.h | 2 | ||||
-rw-r--r-- | src/base/io/ioReadBench.c | 2 | ||||
-rw-r--r-- | src/base/io/ioReadBlif.c | 2 | ||||
-rw-r--r-- | src/base/io/ioReadEdif.c | 2 | ||||
-rw-r--r-- | src/base/io/ioWriteVerilog.c | 445 |
6 files changed, 515 insertions, 3 deletions
diff --git a/src/base/io/io.c b/src/base/io/io.c index 1330d114..69b60000 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -44,6 +44,7 @@ static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -81,6 +82,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "write_verilog", IoCommandWriteVerilog, 0 ); } /**Function************************************************************* @@ -1383,6 +1385,69 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + Abc_Ntk_t * pNtk, * pNtkTemp; + char * FileName; + int c; + + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + + pNtk = pAbc->pNtkCur; + if ( pNtk == NULL ) + { + fprintf( pAbc->Out, "Empty network.\n" ); + return 0; + } + + if ( argc != util_optind + 1 ) + { + goto usage; + } + // get the input file name + FileName = argv[util_optind]; + + // derive the netlist + pNtkTemp = Abc_NtkLogicToNetlist(pNtk); + if ( pNtkTemp == NULL ) + { + fprintf( pAbc->Out, "Writing PLA has failed.\n" ); + return 0; + } + Io_WriteVerilog( pNtkTemp, FileName ); + Abc_NtkDelete( pNtkTemp ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: write_verilog [-h] <file>\n" ); + fprintf( pAbc->Err, "\t write a very special subset of Verilog\n" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); + return 1; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/io.h b/src/base/io/io.h index cb8678b3..286b570c 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -90,6 +90,8 @@ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ); extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); /*=== abcWritePla.c ==========================================================*/ extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName ); +/*=== abcWriteVerilog.c ==========================================================*/ +extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName ); //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c index 510167a8..d8ad8f71 100644 --- a/src/base/io/ioReadBench.c +++ b/src/base/io/ioReadBench.c @@ -127,7 +127,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, nNames ); // assign the cover if ( strcmp(pType, "AND") == 0 ) - Abc_ObjSetData( pNode, Abc_SopCreateAnd(pNtk->pManFunc, nNames) ); + Abc_ObjSetData( pNode, Abc_SopCreateAnd(pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "OR") == 0 ) Abc_ObjSetData( pNode, Abc_SopCreateOr(pNtk->pManFunc, nNames, NULL) ); else if ( strcmp(pType, "NAND") == 0 ) diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index e23bfdb7..b8a2ed01 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -504,7 +504,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens ) Vec_StrAppend( p->vCubes, vTokens->pArray[0] ); // check the char Char = ((char *)vTokens->pArray[1])[0]; - if ( Char != '0' && Char != '1' ) + if ( Char != '0' && Char != '1' && Char != 'x' && Char != 'n' ) { p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0); sprintf( p->sError, "The output character in the constant cube is wrong." ); diff --git a/src/base/io/ioReadEdif.c b/src/base/io/ioReadEdif.c index 63345fd7..a2a2f527 100644 --- a/src/base/io/ioReadEdif.c +++ b/src/base/io/ioReadEdif.c @@ -191,7 +191,7 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p ) Abc_NtkForEachNode( pNtk, pObj, i ) { if ( strncmp( pObj->pData, "And", 3 ) == 0 ) - Abc_ObjSetData( pObj, Abc_SopCreateAnd(pNtk->pManFunc, Abc_ObjFaninNum(pObj)) ); + Abc_ObjSetData( pObj, Abc_SopCreateAnd(pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( pObj->pData, "Or", 2 ) == 0 ) Abc_ObjSetData( pObj, Abc_SopCreateOr(pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) ); else if ( strncmp( pObj->pData, "Nand", 4 ) == 0 ) diff --git a/src/base/io/ioWriteVerilog.c b/src/base/io/ioWriteVerilog.c new file mode 100644 index 00000000..f56da052 --- /dev/null +++ b/src/base/io/ioWriteVerilog.c @@ -0,0 +1,445 @@ +/**CFile**************************************************************** + + FileName [ioWriteVerilog.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedures to output a special subset of Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioWriteVerilog.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "io.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk ); +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_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ); +static void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ); +static void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros ); +static int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk ); +static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Write verilog.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName ) +{ + FILE * pFile; + + if ( !Abc_NtkIsSopNetlist(pNtk) || !Io_WriteVerilogCheckNtk(pNtk) ) + { + printf( "Io_WriteVerilog(): Can write Verilog for a very special subset of logic networks.\n" ); + printf( "The current network is not in the subset; writing Verilog is not performed.\n" ); + return; + } + + if ( Abc_NtkLatchNum(pNtk) > 0 ) + printf( "Io_WriteVerilog(): Warning: only combinational portion is being written.\n" ); + + // start the output stream + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + + // write the equations for the network + Io_WriteVerilogInt( pFile, pNtk ); + fprintf( pFile, "\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Writes verilog.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + // write inputs and outputs + fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); + fprintf( pFile, "module %s (\n ", Abc_NtkName(pNtk) ); + Io_WriteVerilogPis( pFile, pNtk, 3 ); + fprintf( pFile, ",\n " ); + Io_WriteVerilogPos( pFile, pNtk, 3 ); + fprintf( pFile, " );\n" ); + // write inputs, outputs and wires + fprintf( pFile, " input" ); + Io_WriteVerilogPis( pFile, pNtk, 5 ); + fprintf( pFile, ";\n" ); + fprintf( pFile, " output" ); + Io_WriteVerilogPos( pFile, pNtk, 5 ); + fprintf( pFile, ";\n" ); + fprintf( pFile, " wire" ); + Io_WriteVerilogWires( pFile, pNtk, 4 ); + fprintf( pFile, ";\n" ); + // write the nodes + Io_WriteVerilogNodes( pFile, pNtk ); + // finalize the file + fprintf( pFile, "endmodule\n\n" ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Writes the primary inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) +{ + Abc_Obj_t * pTerm, * pNet; + int LineLength; + int AddedLength; + int NameCounter; + int i; + + LineLength = Start; + NameCounter = 0; + Abc_NtkForEachCi( pNtk, pTerm, i ) + { + pNet = Abc_ObjFanout0(pTerm); + // get the line length after this name is written + AddedLength = strlen(Abc_ObjName(pNet)) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = 3; + NameCounter = 0; + } + fprintf( pFile, " %s%s", Abc_ObjName(pNet), (i==Abc_NtkCiNum(pNtk)-1)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } +} + +/**Function************************************************************* + + Synopsis [Writes the primary outputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) +{ + Abc_Obj_t * pTerm, * pNet; + int LineLength; + int AddedLength; + int NameCounter; + int i; + + LineLength = Start; + NameCounter = 0; + Abc_NtkForEachCo( pNtk, pTerm, i ) + { + pNet = Abc_ObjFanin0(pTerm); + // get the line length after this name is written + AddedLength = strlen(Abc_ObjName(pNet)) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = 3; + NameCounter = 0; + } + fprintf( pFile, " %s%s", Abc_ObjName(pNet), (i==Abc_NtkCoNum(pNtk)-1)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } +} + +/**Function************************************************************* + + Synopsis [Writes the wires.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start ) +{ + Abc_Obj_t * pTerm, * pNet; + int LineLength; + int AddedLength; + int NameCounter; + int i, Counter, nNodes; + + // count the number of wires + nNodes = 0; + Abc_NtkForEachNode( pNtk, pTerm, i ) + { + if ( i == 0 ) + continue; + pNet = Abc_ObjFanout0(pTerm); + if ( Abc_ObjIsCo(Abc_ObjFanout0(pNet)) ) + continue; + nNodes++; + } + + // write the wires + Counter = 0; + LineLength = Start; + NameCounter = 0; + Abc_NtkForEachNode( pNtk, pTerm, i ) + { + if ( i == 0 ) + continue; + pNet = Abc_ObjFanout0(pTerm); + if ( Abc_ObjIsCo(Abc_ObjFanout0(pNet)) ) + continue; + Counter++; + // get the line length after this name is written + AddedLength = strlen(Abc_ObjName(pNet)) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = 3; + NameCounter = 0; + } + fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } +} + +/**Function************************************************************* + + Synopsis [Writes the wires.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i, nCubes, nFanins, Counter, nDigits, fPadZeros; + char * pName; + extern int Abc_SopIsExorType( char * pSop ); + + nDigits = Extra_Base10Log( Abc_NtkNodeNum(pNtk) ); + Counter = 1; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + nFanins = Abc_ObjFaninNum(pObj); + nCubes = Abc_SopGetCubeNum(pObj->pData); + if ( Abc_SopIsAndType(pObj->pData) ) + pName = "ts_and", fPadZeros = 1; + else if ( Abc_SopIsExorType(pObj->pData) ) + pName = "ts_xor", fPadZeros = 1; + else // if ( Abc_SopIsOrType(pObj->pData) ) + pName = "ts_or", fPadZeros = 0; + + assert( nCubes < 2 ); + if ( nCubes == 0 ) + { + fprintf( pFile, " ts_gnd g%0*d ", nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 0, fPadZeros ); + } + else if ( nCubes == 1 && nFanins == 0 ) + { + fprintf( pFile, " ts_vdd g%0*d ", nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 0, fPadZeros ); + } + else if ( nFanins == 1 && Abc_SopIsInv(pObj->pData) ) + { + fprintf( pFile, " ts_inv g%0*d ", nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 1, fPadZeros ); + } + else if ( nFanins == 1 ) + { + fprintf( pFile, " ts_buf g%0*d ", nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 1, fPadZeros ); + } + else if ( nFanins <= 4 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 4, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 4, fPadZeros ); + } + else if ( nFanins <= 6 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 6, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 6, fPadZeros ); + } + else if ( nFanins == 7 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 7, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 7, fPadZeros ); + } + else if ( nFanins == 8 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 8, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 8, fPadZeros ); + } + else if ( nFanins <= 16 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 16, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 16, fPadZeros ); + } + else if ( nFanins <= 32 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 32, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 32, fPadZeros ); + } + else if ( nFanins <= 64 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 64, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 64, fPadZeros ); + } + else if ( nFanins <= 128 ) + { + fprintf( pFile, " %s%d g%0*d ", pName, 128, nDigits, Counter++ ); + Io_WriteVerilogArgs( pFile, pObj, 128, fPadZeros ); + } + } +} + +/**Function************************************************************* + + Synopsis [Writes the inputs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros ) +{ + Abc_Obj_t * pFanin; + int i, Counter = 2; + fprintf( pFile, "(.z (%s)", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) ); + Abc_ObjForEachFanin( pObj, pFanin, i ) + { + if ( Counter++ % 4 == 0 ) + fprintf( pFile, "\n " ); + fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogGetName(Abc_ObjFanin(pObj,i)) ); + } + for ( ; i < nInMax; i++ ) + { + if ( Counter++ % 4 == 0 ) + fprintf( pFile, "\n " ); + fprintf( pFile, " .i%d (%s)", i+1, fPadZeros? "1\'b0" : "1\'b1" ); + } + fprintf( pFile, ");\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + char * pSop; + int i, k, nFanins; + Abc_NtkForEachNode( pNtk, pObj, i ) + { + if ( Abc_SopGetCubeNum(pObj->pData) > 1 ) + { + printf( "Node %s contains a cover with more than one cube.\n", Abc_ObjName(pObj) ); + return 0; + } + nFanins = Abc_ObjFaninNum(pObj); + if ( nFanins < 2 ) + continue; + pSop = pObj->pData; + for ( k = 0; k < nFanins; k++ ) + if ( pSop[k] != '1' ) + { + printf( "Node %s contains a cover with non-positive literals.\n", Abc_ObjName(pObj) ); + return 0; + } + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Prepares the name for writing the Verilog file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Io_WriteVerilogGetName( Abc_Obj_t * pObj ) +{ + static char Buffer[20]; + char * pName; + pName = Abc_ObjName(pObj); + if ( pName[0] != '[' ) + return pName; + // replace opening bracket by the escape sign and closing bracket by space + // as a result of this transformation, the length of the name does not change + strcpy( Buffer, pName ); + Buffer[0] = '\\'; + Buffer[strlen(Buffer)-1] = ' '; + return Buffer; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |