mirror of https://github.com/YosysHQ/abc.git
Enable blasting LUTs in NDR.
This commit is contained in:
parent
548fa9d45b
commit
dd5a1f5d30
|
|
@ -207,17 +207,25 @@ static inline void Ndr_DataPushArray( Ndr_Data_t * p, int Type, int nArray, int
|
||||||
memcpy( p->pBody + p->nSize, pArray, (size_t)4*nArray );
|
memcpy( p->pBody + p->nSize, pArray, (size_t)4*nArray );
|
||||||
p->nSize += nArray;
|
p->nSize += nArray;
|
||||||
}
|
}
|
||||||
static inline void Ndr_DataPushString( Ndr_Data_t * p, int Type, char * pFunc )
|
static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, char * pFunc )
|
||||||
{
|
{
|
||||||
int nBuffInts;
|
int nBuffInts;
|
||||||
int * pBuff;
|
int * pBuff;
|
||||||
if ( !pFunc )
|
if ( !pFunc )
|
||||||
return;
|
return;
|
||||||
nBuffInts = ((int)strlen(pFunc) + 4) / 4;
|
if ( ObjType == ABC_OPER_LUT )
|
||||||
pBuff = (int *)calloc( 1, 4*nBuffInts );
|
{
|
||||||
memcpy( pBuff, pFunc, strlen(pFunc) );
|
word Truth = (word)pFunc;
|
||||||
Ndr_DataPushArray( p, Type, nBuffInts, pBuff );
|
Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
|
||||||
free( pBuff );
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nBuffInts = ((int)strlen(pFunc) + 4) / 4;
|
||||||
|
pBuff = (int *)calloc( 1, 4*nBuffInts );
|
||||||
|
memcpy( pBuff, pFunc, strlen(pFunc) );
|
||||||
|
Ndr_DataPushArray( p, Type, nBuffInts, pBuff );
|
||||||
|
free( pBuff );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -554,7 +562,7 @@ static inline void Ndr_AddObject( void * pDesign, int ModuleId,
|
||||||
Ndr_DataPush( p, NDR_NAME, InstName );
|
Ndr_DataPush( p, NDR_NAME, InstName );
|
||||||
Ndr_DataPushArray( p, NDR_INPUT, nInputs, pInputs );
|
Ndr_DataPushArray( p, NDR_INPUT, nInputs, pInputs );
|
||||||
Ndr_DataPushArray( p, NDR_OUTPUT, nOutputs, pOutputs );
|
Ndr_DataPushArray( p, NDR_OUTPUT, nOutputs, pOutputs );
|
||||||
Ndr_DataPushString( p, NDR_FUNCTION, pFunction );
|
Ndr_DataPushString( p, ObjType, NDR_FUNCTION, pFunction );
|
||||||
Ndr_DataAddTo( p, Obj, p->nSize - Obj );
|
Ndr_DataAddTo( p, Obj, p->nSize - Obj );
|
||||||
Ndr_DataAddTo( p, Mod, p->nSize - Obj );
|
Ndr_DataAddTo( p, Mod, p->nSize - Obj );
|
||||||
Ndr_DataAddTo( p, 0, p->nSize - Obj );
|
Ndr_DataAddTo( p, 0, p->nSize - Obj );
|
||||||
|
|
@ -1088,6 +1096,35 @@ static inline void Ndr_ModuleTestAddSub()
|
||||||
Ndr_Delete( pDesign );
|
Ndr_Delete( pDesign );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This testing procedure creates and writes into a Verilog file
|
||||||
|
// the following design composed of one lookup table with function of AND2
|
||||||
|
|
||||||
|
// module lut_test ( input [1:0] in, output out );
|
||||||
|
// assign out = LUT #(TT=4'h8) lut_inst { in[0], in[1], out } ;
|
||||||
|
// endmodule
|
||||||
|
|
||||||
|
static inline void Ndr_ModuleTestLut()
|
||||||
|
{
|
||||||
|
// map name IDs into char strings
|
||||||
|
//char * ppNames[12] = { NULL, "lut_test", "in", "out" };
|
||||||
|
// name IDs
|
||||||
|
int NameIdIn = 2;
|
||||||
|
int NameIdOut = 3;
|
||||||
|
|
||||||
|
// create a new module
|
||||||
|
void * pDesign = Ndr_Create( 1 );
|
||||||
|
|
||||||
|
int ModuleID = Ndr_AddModule( pDesign, 1 );
|
||||||
|
|
||||||
|
// add objects to the modele
|
||||||
|
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
|
||||||
|
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_LUT, 0, 0, 0, 0, 1, &NameIdIn, 1, &NameIdOut, (char *)(ABC_CONST(0x8)) );
|
||||||
|
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
|
||||||
|
|
||||||
|
Ndr_Write( "lut_test.ndr", pDesign );
|
||||||
|
Ndr_Delete( pDesign );
|
||||||
|
}
|
||||||
|
|
||||||
ABC_NAMESPACE_HEADER_END
|
ABC_NAMESPACE_HEADER_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ struct Wlc_Ntk_t_
|
||||||
Mem_Flex_t * pMemFanin;
|
Mem_Flex_t * pMemFanin;
|
||||||
Mem_Flex_t * pMemTable;
|
Mem_Flex_t * pMemTable;
|
||||||
Vec_Ptr_t * vTables;
|
Vec_Ptr_t * vTables;
|
||||||
|
Vec_Wrd_t * vLutTruths;
|
||||||
// object names
|
// object names
|
||||||
Abc_Nam_t * pManName; // object names
|
Abc_Nam_t * pManName; // object names
|
||||||
Vec_Int_t vNameIds; // object name IDs
|
Vec_Int_t vNameIds; // object name IDs
|
||||||
|
|
|
||||||
|
|
@ -718,6 +718,20 @@ void Wlc_BlastTable( Gia_Man_t * pNew, word * pTable, int * pFans, int nFans, in
|
||||||
Vec_IntFree( vMemory );
|
Vec_IntFree( vMemory );
|
||||||
ABC_FREE( pTruth );
|
ABC_FREE( pTruth );
|
||||||
}
|
}
|
||||||
|
void Wlc_BlastLut( Gia_Man_t * pNew, word Truth, int * pFans, int nFans, int nOuts, Vec_Int_t * vRes )
|
||||||
|
{
|
||||||
|
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||||
|
Vec_Int_t * vMemory = Vec_IntAlloc( 0 );
|
||||||
|
Vec_Int_t vLeaves = { nFans, nFans, pFans };
|
||||||
|
int iLit;
|
||||||
|
Vec_IntClear( vRes );
|
||||||
|
assert( nOuts == 1 );
|
||||||
|
if ( nFans < 6 )
|
||||||
|
Truth = Abc_Tt6Stretch( Truth, nFans );
|
||||||
|
iLit = Kit_TruthToGia( pNew, (unsigned *)&Truth, nFans, vMemory, &vLeaves, 1 );
|
||||||
|
Vec_IntPush( vRes, iLit );
|
||||||
|
Vec_IntFree( vMemory );
|
||||||
|
}
|
||||||
void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes )
|
void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes )
|
||||||
{
|
{
|
||||||
Vec_Int_t * vDegrees = Vec_IntAlloc( 2*nNum );
|
Vec_Int_t * vDegrees = Vec_IntAlloc( 2*nNum );
|
||||||
|
|
@ -1852,6 +1866,8 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
|
||||||
}
|
}
|
||||||
else if ( pObj->Type == WLC_OBJ_TABLE )
|
else if ( pObj->Type == WLC_OBJ_TABLE )
|
||||||
Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes );
|
Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes );
|
||||||
|
else if ( pObj->Type == WLC_OBJ_LUT && p->vLutTruths )
|
||||||
|
Wlc_BlastLut( pNew, Vec_WrdEntry(p->vLutTruths, Wlc_ObjId(p, pObj)), pFans0, nRange0, nRange, vRes );
|
||||||
else assert( 0 );
|
else assert( 0 );
|
||||||
assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) );
|
assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) );
|
||||||
Vec_IntAppend( vBits, vRes );
|
Vec_IntAppend( vBits, vRes );
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
|
||||||
Ndr_Data_t * p = (Ndr_Data_t *)pData;
|
Ndr_Data_t * p = (Ndr_Data_t *)pData;
|
||||||
Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 );
|
Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 );
|
||||||
int Mod = 2, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax;
|
int Mod = 2, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax;
|
||||||
|
Vec_Wrd_t * vTruths = NULL;
|
||||||
Wlc_Ntk_t * pTemp, * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, Mod)+1 );
|
Wlc_Ntk_t * pTemp, * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, Mod)+1 );
|
||||||
Wlc_NtkCheckIntegrity( pData );
|
Wlc_NtkCheckIntegrity( pData );
|
||||||
Vec_IntClear( &pNtk->vFfs );
|
Vec_IntClear( &pNtk->vFfs );
|
||||||
|
|
@ -412,6 +413,14 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
|
||||||
}
|
}
|
||||||
if ( Type == ABC_OPER_DFFRSE )
|
if ( Type == ABC_OPER_DFFRSE )
|
||||||
Vec_IntPush( &pNtk->vFfs2, iObj );
|
Vec_IntPush( &pNtk->vFfs2, iObj );
|
||||||
|
if ( Type == ABC_OPER_LUT )
|
||||||
|
{
|
||||||
|
if ( vTruths == NULL )
|
||||||
|
vTruths = Vec_WrdStart( 1000 );
|
||||||
|
if ( NameId >= Vec_WrdSize(vTruths) )
|
||||||
|
Vec_WrdFillExtra( vTruths, 2*NameId, 0 );
|
||||||
|
Vec_WrdWriteEntry( vTruths, NameId, *((word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION)) );
|
||||||
|
}
|
||||||
if ( Type == ABC_OPER_SLICE )
|
if ( Type == ABC_OPER_SLICE )
|
||||||
Vec_IntPushTwo( vFanins, End, Beg );
|
Vec_IntPushTwo( vFanins, End, Beg );
|
||||||
else if ( Type == ABC_OPER_CONST )
|
else if ( Type == ABC_OPER_CONST )
|
||||||
|
|
@ -487,6 +496,22 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
|
||||||
// derive topological order
|
// derive topological order
|
||||||
pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 );
|
pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 );
|
||||||
Wlc_NtkFree( pTemp );
|
Wlc_NtkFree( pTemp );
|
||||||
|
// copy truth tables
|
||||||
|
if ( vTruths )
|
||||||
|
{
|
||||||
|
pNtk->vLutTruths = Vec_WrdStart( Wlc_NtkObjNumMax(pNtk) );
|
||||||
|
Wlc_NtkForEachObj( pNtk, pObj, i )
|
||||||
|
{
|
||||||
|
int iObj = Wlc_ObjId(pNtk, pObj);
|
||||||
|
int NameId = Wlc_ObjNameId(pNtk, iObj);
|
||||||
|
word Truth = Vec_WrdEntry(vTruths, NameId);
|
||||||
|
if ( pObj->Type != WLC_OBJ_LUT || NameId == 0 )
|
||||||
|
continue;
|
||||||
|
assert( sizeof(void *) == 8 || Wlc_ObjFaninNum(pObj) < 6 );
|
||||||
|
Vec_WrdWriteEntry( pNtk->vLutTruths, iObj, Truth );
|
||||||
|
}
|
||||||
|
Vec_WrdFreeP( &vTruths );
|
||||||
|
}
|
||||||
//Ndr_NtkPrintNodes( pNtk );
|
//Ndr_NtkPrintNodes( pNtk );
|
||||||
pNtk->fMemPorts = 1; // the network contains memory ports
|
pNtk->fMemPorts = 1; // the network contains memory ports
|
||||||
pNtk->fEasyFfs = 1; // the network contains simple flops
|
pNtk->fEasyFfs = 1; // the network contains simple flops
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
|
||||||
Mem_FlexStop( p->pMemTable, 0 );
|
Mem_FlexStop( p->pMemTable, 0 );
|
||||||
ABC_FREE( p->vPoPairs.pArray );
|
ABC_FREE( p->vPoPairs.pArray );
|
||||||
Vec_PtrFreeP( &p->vTables );
|
Vec_PtrFreeP( &p->vTables );
|
||||||
|
Vec_WrdFreeP( &p->vLutTruths );
|
||||||
ABC_FREE( p->vPis.pArray );
|
ABC_FREE( p->vPis.pArray );
|
||||||
ABC_FREE( p->vPos.pArray );
|
ABC_FREE( p->vPos.pArray );
|
||||||
ABC_FREE( p->vCis.pArray );
|
ABC_FREE( p->vCis.pArray );
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,12 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
|
||||||
for ( k = 1; k < Wlc_ObjFaninNum(pObj); k++ )
|
for ( k = 1; k < Wlc_ObjFaninNum(pObj); k++ )
|
||||||
fprintf( pFile, "%s, ", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) );
|
fprintf( pFile, "%s, ", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) );
|
||||||
fprintf( pFile, "%s)", Wlc_ObjName(p, i) );
|
fprintf( pFile, "%s)", Wlc_ObjName(p, i) );
|
||||||
|
if ( p->vLutTruths )
|
||||||
|
{
|
||||||
|
word Truth = Vec_WrdEntry( p->vLutTruths, Wlc_ObjId(p, pObj) );
|
||||||
|
fprintf( pFile, " ; // TT = " );
|
||||||
|
Extra_PrintHex( pFile, (unsigned *)&Truth, Wlc_ObjFaninNum(pObj) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( pObj->Type == WLC_OBJ_CONST )
|
else if ( pObj->Type == WLC_OBJ_CONST )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue