mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream/master' into yosys-experimental
This commit is contained in:
commit
734f64d5b9
|
|
@ -982,6 +982,106 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pNew->pAigExtra = pAigExtra;
|
||||
}
|
||||
|
||||
// Apply init state transformation for register boxes with init=1
|
||||
if ( pNew->vRegInits && Vec_IntCountEntry(pNew->vRegInits, 1) > 0 )
|
||||
{
|
||||
extern void Gia_ManFlipInit1( Gia_Man_t * p, Vec_Int_t * vInit );
|
||||
Tim_Man_t * pTimMan = (Tim_Man_t *)pNew->pManTime;
|
||||
|
||||
if ( pTimMan && Gia_ManRegBoxNum(pNew) > 0 )
|
||||
{
|
||||
// Handle register boxes: apply transformation to box inputs/outputs
|
||||
Gia_Obj_t * pObj;
|
||||
int i, curCo, curCi, nBoxIns, nBoxOuts;
|
||||
int iRegBox = 0;
|
||||
|
||||
assert( Vec_IntSize(pNew->vRegInits) == Gia_ManRegBoxNum(pNew) );
|
||||
|
||||
// Step 1: Mark register box outputs with init state 1
|
||||
curCi = Tim_ManPiNum(pTimMan);
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
// Check if this is a register box (1-input, 1-output)
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCi(pNew, curCi);
|
||||
pObj->fMark0 = 1;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCi += nBoxOuts;
|
||||
}
|
||||
|
||||
// Step 2: Propagate complementation through AND gates
|
||||
Gia_ManForEachAnd( pNew, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
if ( Gia_ObjFanin1(pObj)->fMark0 )
|
||||
pObj->fCompl1 ^= 1;
|
||||
}
|
||||
|
||||
// Step 3: Complement CO fanins if needed
|
||||
Gia_ManForEachCo( pNew, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
}
|
||||
|
||||
// Step 4: Clear marks
|
||||
curCi = Tim_ManPiNum(pTimMan);
|
||||
iRegBox = 0;
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCi(pNew, curCi);
|
||||
pObj->fMark0 = 0;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCi += nBoxOuts;
|
||||
}
|
||||
|
||||
// Step 5: Complement register box inputs with init state 1
|
||||
curCo = Tim_ManPoNum(pTimMan);
|
||||
iRegBox = 0;
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCo(pNew, curCo);
|
||||
pObj->fCompl0 ^= 1;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCo += nBoxIns;
|
||||
}
|
||||
|
||||
// Clear all init states to 0 (transformation is now structural)
|
||||
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
|
||||
}
|
||||
else if ( Gia_ManRegNum(pNew) > 0 )
|
||||
{
|
||||
// Handle regular flops (no boxes)
|
||||
Gia_ManFlipInit1( pNew, pNew->vRegInits );
|
||||
// Clear all init states to 0 (transformation is now structural)
|
||||
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fHieOnly )
|
||||
{
|
||||
// Tim_ManPrint( (Tim_Man_t *)pNew->pManTime );
|
||||
|
|
|
|||
|
|
@ -656,6 +656,40 @@ Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Complements some flops without duplicating AIG.]
|
||||
|
||||
Description [The array of integers containing the initial state
|
||||
of each flop in the AIG.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFlipInit1( Gia_Man_t * p, Vec_Int_t * vInit )
|
||||
{
|
||||
Gia_Obj_t * pObj; int c;
|
||||
assert( Gia_ManRegNum(p) == Vec_IntSize(vInit) );
|
||||
Gia_ManForEachRo( p, pObj, c )
|
||||
pObj->fMark0 = (int)(Vec_IntEntry(vInit, c) == 1);
|
||||
Gia_ManForEachAnd( p, pObj, c ) {
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
if ( Gia_ObjFanin1(pObj)->fMark0 )
|
||||
pObj->fCompl1 ^= 1;
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, c )
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
Gia_ManForEachRo( p, pObj, c )
|
||||
pObj->fMark0 = 0;
|
||||
Gia_ManForEachRi( p, pObj, c )
|
||||
if ( Vec_IntEntry(vInit, c) == 1 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ int Gia_ManClockDomainNum( Gia_Man_t * p )
|
|||
if ( p->vRegClasses == NULL )
|
||||
return 0;
|
||||
nDoms = Vec_IntFindMax(p->vRegClasses);
|
||||
assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
|
||||
// Class 0 is now allowed - means unmergeable flops not in any clock domain
|
||||
// assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
|
||||
for ( i = 1; i <= nDoms; i++ )
|
||||
if ( Vec_IntCountEntry(p->vRegClasses, i) > 0 )
|
||||
Count++;
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ static int Abc_CommandAbc9Gen ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9Cfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9ProdAdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9AddFlop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Init1 ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9BMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9GenHie ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9PutOnTop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -1477,6 +1478,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&cfs", Abc_CommandAbc9Cfs, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&prodadd", Abc_CommandAbc9ProdAdd, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&addflop", Abc_CommandAbc9AddFlop, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&init1", Abc_CommandAbc9Init1, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&bmiter", Abc_CommandAbc9BMiter, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&gen_hie", Abc_CommandAbc9GenHie, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&putontop", Abc_CommandAbc9PutOnTop, 0 );
|
||||
|
|
@ -10938,15 +10940,35 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( 0, "If LUT mapping is not enabled (switch \"-r\"), permutation has not effect.\n" );
|
||||
if ( argc == globalUtilOptind + 1 )
|
||||
pPars->pTtStr = argv[globalUtilOptind];
|
||||
else if ( argc == globalUtilOptind && Abc_FrameReadNtk(pAbc) )
|
||||
else if ( argc == globalUtilOptind && Abc_FrameReadNtk(pAbc) )
|
||||
{
|
||||
pPars->pTtStr = Abc_NtkReadTruth( Abc_FrameReadNtk(pAbc) );
|
||||
if ( pPars->pTtStr )
|
||||
pPars->nVars = Abc_NtkCiNum(Abc_FrameReadNtk(pAbc));
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
if ( Abc_NtkCiNum(pNtk) > 30 )
|
||||
{
|
||||
Abc_Print( -1, "Cannot derive truth table from network: too many inputs (%d > 30).\n", Abc_NtkCiNum(pNtk) );
|
||||
Abc_Print( -1, "Please provide truth table on the command line or use a smaller network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkCoNum(pNtk) != 1 )
|
||||
{
|
||||
Abc_Print( -1, "Cannot derive truth table from network: network must have exactly one output (has %d).\n", Abc_NtkCoNum(pNtk) );
|
||||
return 1;
|
||||
}
|
||||
pPars->pTtStr = Abc_NtkReadTruth( pNtk );
|
||||
if ( pPars->pTtStr )
|
||||
{
|
||||
pPars->nVars = Abc_NtkCiNum(pNtk);
|
||||
Abc_Print( 0, "Derived %d-input truth table from current network.\n", pPars->nVars );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_Print( -1, "Failed to derive truth table from current network.\n" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ( pPars->pTtStr == NULL && pPars->pSymStr == NULL && pPars->nRandFuncs == 0 )
|
||||
{
|
||||
Abc_Print( -1, "Truth table should be given on the command line.\n" );
|
||||
Abc_Print( -1, "Truth table should be given on the command line, or derived from current single-output network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pPars->nVars == 0 && pPars->pTtStr )
|
||||
|
|
@ -34617,6 +34639,11 @@ int Abc_CommandAbc9Put( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_NtkDelete( pNtkNoCh );
|
||||
Aig_ManStop( pMan );
|
||||
}
|
||||
// transfer the spec name to the pNtk
|
||||
if( pAbc->pGia->pSpec )
|
||||
{
|
||||
pNtk->pSpec = Extra_UtilStrsav( pAbc->pGia->pSpec );
|
||||
}
|
||||
// transfer PI names to pNtk
|
||||
if ( pAbc->pGia->vNamesIn )
|
||||
{
|
||||
|
|
@ -57043,6 +57070,59 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9Init1( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Gia_ManFlipInit1( Gia_Man_t * p, Vec_Int_t * vInit );
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9Init1(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ManRegNum(pAbc->pGia) == 0 ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9Init1(): There is no flops.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( pAbc->pGia->vRegInits == NULL ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9Init1(): Flop init states are not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManFlipInit1( pAbc->pGia, pAbc->pGia->vRegInits );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &init1 [-vh]\n" );
|
||||
Abc_Print( -2, "\t complements the inputs/outputs of flops with const-1 initial state\n" );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -562,33 +562,56 @@ void Tim_ManCreate( Tim_Man_t * p, void * pLib, Vec_Flt_t * vInArrs, Vec_Flt_t *
|
|||
*/
|
||||
if ( vInArrs )
|
||||
{
|
||||
assert( Vec_FltSize(vInArrs) >= Tim_ManPiNum(p) );
|
||||
if ( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) ) {
|
||||
// Handle special case when timing is only for PIs (without boxes/flops)
|
||||
// This happens when old files provide timing for actual design PIs only
|
||||
if ( Vec_FltSize(vInArrs) < Tim_ManPiNum(p) )
|
||||
{
|
||||
// Special case: timing for actual PIs only (less than Tim_ManPiNum when boxes exist)
|
||||
for ( i = 0; i < Vec_FltSize(vInArrs); i++ )
|
||||
p->pCis[i].timeArr = Vec_FltEntry(vInArrs, i);
|
||||
}
|
||||
else if ( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) )
|
||||
{
|
||||
// Original case: timing for PIs (up to first box)
|
||||
Tim_ManForEachPi( p, pObj, i )
|
||||
pObj->timeArr = Vec_FltEntry(vInArrs, i);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// General case: timing for all or partial CIs
|
||||
float Num;
|
||||
Vec_FltForEachEntry( vInArrs, Num, i )
|
||||
p->pCis[i].timeArr = Num;
|
||||
if ( i < p->nCis )
|
||||
p->pCis[i].timeArr = Num;
|
||||
}
|
||||
}
|
||||
|
||||
// create required times
|
||||
// Handles: POs only, POs+Flops (partial COs), or all COs
|
||||
if ( vOutReqs )
|
||||
{
|
||||
assert( Vec_FltSize(vOutReqs) >= Tim_ManPoNum(p) );
|
||||
if ( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) ) {
|
||||
// Handle special case when timing is only for POs (without boxes/flops)
|
||||
// This happens when old files provide timing for actual design POs only
|
||||
if ( Vec_FltSize(vOutReqs) < Tim_ManPoNum(p) )
|
||||
{
|
||||
// Special case: timing for actual POs only (less than Tim_ManPoNum when boxes exist)
|
||||
for ( i = 0; i < Vec_FltSize(vOutReqs); i++ )
|
||||
p->pCos[i].timeReq = Vec_FltEntry(vOutReqs, i);
|
||||
}
|
||||
else if ( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) )
|
||||
{
|
||||
// Original case: timing for POs
|
||||
k = 0;
|
||||
Tim_ManForEachPo( p, pObj, i )
|
||||
pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
|
||||
assert( k == Tim_ManPoNum(p) );
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// General case: timing for all or partial COs
|
||||
float Num;
|
||||
Vec_FltForEachEntry( vOutReqs, Num, i )
|
||||
p->pCos[i].timeReq = Num;
|
||||
if ( i < p->nCos )
|
||||
p->pCos[i].timeReq = Num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue