Saving module interface.

This commit is contained in:
Alan Mishchenko 2024-01-11 19:45:42 -08:00
parent 7f0a319564
commit dc68fe27f9
4 changed files with 107 additions and 9 deletions

View File

@ -448,7 +448,7 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
/*=== wlcReadVer.c ========================================================*/
extern char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p );
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr, int fInter );
/*=== wlcUif.c ========================================================*/
extern Vec_Int_t * Wlc_NtkCollectAddMult( Wlc_Ntk_t * p, Wlc_BstPar_t * pPar, int * pCountA, int * CountM );
extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );

View File

@ -2667,6 +2667,71 @@ Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis )
return vPerm;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Wlc_TransferPioNames( Wlc_Ntk_t * p, Gia_Man_t * pNew )
{
int fSkipBitRange = 0;
Wlc_Obj_t * pObj; int i, k;
Vec_PtrFreeP( &pNew->vNamesIn );
Vec_PtrFreeP( &pNew->vNamesOut );
pNew->vNamesIn = Vec_PtrAlloc( Gia_ManPiNum(pNew) );
pNew->vNamesOut = Vec_PtrAlloc( Gia_ManPoNum(pNew) );
// create input names
Wlc_NtkForEachCi( p, pObj, i )
if ( Wlc_ObjIsPi(pObj) )
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
int nRange = Wlc_ObjRange( pObj );
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
{
char Buffer[1000];
sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
//printf( "Writing %s\n", Buffer );
}
}
// add real primary outputs
Wlc_NtkForEachCo( p, pObj, i )
if ( Wlc_ObjIsPo(pObj) )
{
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
int nRange = Wlc_ObjRange( pObj );
if ( fSkipBitRange && nRange == 1 )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
else
for ( k = 0; k < nRange; k++ )
{
char Buffer[1000];
sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
}
}
if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) )
printf( "The number of input bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesIn), Gia_ManPiNum(pNew) );
if ( Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
printf( "The number of output bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesOut), Gia_ManPoNum(pNew) );
if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) || Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
{
Vec_PtrFreeP( &pNew->vNamesIn );
Vec_PtrFreeP( &pNew->vNamesOut );
}
else
printf( "Successfully transferred the primary input/output names from the word-level design to the current AIG.\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -149,14 +149,16 @@ void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk )
******************************************************************************/
int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Wlc_TransferPioNames( Wlc_Ntk_t * p, Gia_Man_t * pNew );
FILE * pFile;
Wlc_Ntk_t * pNtk = NULL;
char * pFileName = NULL;
int fOldParser = 0;
int fPrintTree = 0;
int fInter = 0;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "opivh" ) ) != EOF )
{
switch ( c )
{
@ -166,6 +168,9 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'p':
fPrintTree ^= 1;
break;
case 'i':
fInter ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
@ -193,8 +198,12 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
fclose( pFile );
// perform reading
if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
pNtk = Wlc_ReadVer( pFileName, NULL );
if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
{
pNtk = Wlc_ReadVer( pFileName, NULL, fInter );
if ( fInter && pAbc->pGia )
Wlc_TransferPioNames( pNtk, pAbc->pGia );
}
else if ( !strcmp( Extra_FileNameExtension(pFileName), "smt" ) || !strcmp( Extra_FileNameExtension(pFileName), "smt2" ) )
pNtk = Wlc_ReadSmt( pFileName, fOldParser, fPrintTree );
else if ( !strcmp( Extra_FileNameExtension(pFileName), "ndr" ) )
@ -207,10 +216,11 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
Wlc_AbcUpdateNtk( pAbc, pNtk );
return 0;
usage:
Abc_Print( -2, "usage: %%read [-opvh] <file_name>\n" );
Abc_Print( -2, "usage: %%read [-opivh] <file_name>\n" );
Abc_Print( -2, "\t reads word-level design from Verilog file\n" );
Abc_Print( -2, "\t-o : toggle using old SMT-LIB parser [default = %s]\n", fOldParser? "yes": "no" );
Abc_Print( -2, "\t-p : toggle printing parse SMT-LIB tree [default = %s]\n", fPrintTree? "yes": "no" );
Abc_Print( -2, "\t-i : toggle reading interface only [default = %s]\n", fInter? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;

View File

@ -951,7 +951,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
}
return 1;
}
int Wlc_PrsDerive( Wlc_Prs_t * p )
int Wlc_PrsDerive( Wlc_Prs_t * p, int fInter )
{
Wlc_Obj_t * pObj;
char * pStart, * pName;
@ -1031,6 +1031,8 @@ startword:
while ( (pName = Wlc_PrsStrtok( NULL, "(,)" )) )
{
pName = Wlc_PrsSkipSpaces( pName );
if ( fInter && Wlc_PrsStrCmp( pName, "wire" ) )
return 0;
if ( Wlc_PrsStrCmp( pName, "input" ) || Wlc_PrsStrCmp( pName, "output" ) || Wlc_PrsStrCmp( pName, "wire" ) )
{
if ( !Wlc_PrsReadDeclaration( p, pName ) )
@ -1095,12 +1097,16 @@ startword:
// these are read as part of the interface
else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" ) )
{
if ( fInter && (Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" )) )
return 0;
if ( !Wlc_PrsReadDeclaration( p, pStart ) )
return 0;
}
else if ( Wlc_PrsStrCmp( pStart, "assign" ) )
{
int Type, NameId, fFound, XValue = 0;
if ( fInter )
return 0;
pStart += strlen("assign");
// read name
pStart = Wlc_PrsFindName( pStart, &pName );
@ -1159,6 +1165,8 @@ startword:
{
// THIS IS A HACK to detect always statement representing combinational MUX
int NameId, NameIdOut = -1, fFound, nValues, fDefaultFound = 0;
if ( fInter )
return 0;
// find control
pStart = Wlc_PrsFindWord( pStart, "case", &fFound );
if ( pStart == NULL )
@ -1682,7 +1690,7 @@ startword:
}
return 1;
}
Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr, int fInter )
{
Wlc_Prs_t * p;
Wlc_Ntk_t * pNtk = NULL;
@ -1696,8 +1704,23 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
if ( !Wlc_PrsPrepare( p ) )
goto finish;
// parse models
if ( !Wlc_PrsDerive( p ) )
if ( !Wlc_PrsDerive( p, fInter ) )
{
if ( fInter )
{
printf( "Finished deriving interface for module \"%s\".\n", p->pNtk->pName );
pNtk = p->pNtk; p->pNtk = NULL;
pNtk->pSpec = Abc_UtilStrsav( pFileName );
if ( Vec_IntSize(&pNtk->vNameIds) == 0 )
{
Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(pNtk) );
pNtk->vNameIds = *vTemp, Vec_IntZero(vTemp);
Vec_IntFree( vTemp );
}
return pNtk;
}
goto finish;
}
// derive topological order
if ( p->pNtk )
{
@ -1728,7 +1751,7 @@ finish:
void Io_ReadWordTest( char * pFileName )
{
Gia_Man_t * pNew;
Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName, NULL );
Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName, NULL, 0 );
if ( pNtk == NULL )
return;
Wlc_WriteVer( pNtk, "test.v", 0, 0 );