mirror of https://github.com/YosysHQ/abc.git
247 lines
8.2 KiB
C
247 lines
8.2 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [fraigTrans.c]
|
|
|
|
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
|
|
|
Synopsis [Adds the additive and distributive choices to the AIG.]
|
|
|
|
Author [MVSIS Group]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - February 1, 2003.]
|
|
|
|
Revision [$Id: fraigTrans.c,v 1.1 2005/02/28 05:34:34 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "fraigInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Adds choice nodes based on associativity.]
|
|
|
|
Description [Make nLimit big AND gates and add all decompositions
|
|
to the Fraig.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fraig_ManAddChoices( Fraig_Man_t * pMan, int fVerbose, int nLimit )
|
|
{
|
|
// ProgressBar * pProgress;
|
|
char Buffer[100];
|
|
abctime clkTotal = Abc_Clock();
|
|
int i, nNodesBefore, nNodesAfter, nInputs, nMaxNodes;
|
|
int /*nMaxLevel,*/ nDistributive;
|
|
Fraig_Node_t *pNode, *pRepr;
|
|
Fraig_Node_t *pX, *pA, *pB, *pC, /* *pD,*/ *pN, /* *pQ, *pR,*/ *pT;
|
|
int fShortCut = 0;
|
|
|
|
nDistributive = 0;
|
|
|
|
// Fraig_ManSetApprox( pMan, 1 );
|
|
|
|
// NO functional reduction
|
|
if (fShortCut) Fraig_ManSetFuncRed( pMan, 0 );
|
|
|
|
// First we mark critical functions i.e. compute those
|
|
// nodes which lie on the critical path. Note that this
|
|
// doesn't update the required times on any choice nodes
|
|
// which are not the representatives
|
|
/*
|
|
nMaxLevel = Fraig_GetMaxLevel( pMan );
|
|
for ( i = 0; i < pMan->nOutputs; i++ )
|
|
{
|
|
Fraig_SetNodeRequired( pMan, pMan->pOutputs[i], nMaxLevel );
|
|
}
|
|
*/
|
|
nNodesBefore = Fraig_ManReadNodeNum( pMan );
|
|
nInputs = Fraig_ManReadInputNum( pMan );
|
|
nMaxNodes = nInputs + nLimit * ( nNodesBefore - nInputs );
|
|
|
|
printf ("Limit = %d, Before = %d\n", nMaxNodes, nNodesBefore );
|
|
|
|
if (0)
|
|
{
|
|
char buffer[128];
|
|
sprintf (buffer, "test" );
|
|
// Fraig_MappingShow( pMan, buffer );
|
|
}
|
|
|
|
// pProgress = Extra_ProgressBarStart( stdout, nMaxNodes );
|
|
Fraig_ManCheckConsistency( pMan );
|
|
|
|
for ( i = nInputs+1; (i < Fraig_ManReadNodeNum( pMan ))
|
|
&& (nMaxNodes > Fraig_ManReadNodeNum( pMan )); ++i )
|
|
{
|
|
// if ( i == nNodesBefore )
|
|
// break;
|
|
|
|
pNode = Fraig_ManReadIthNode( pMan, i );
|
|
assert ( pNode );
|
|
|
|
pRepr = pNode->pRepr ? pNode->pRepr : pNode;
|
|
//printf ("Slack: %d\n", Fraig_NodeReadSlack( pRepr ));
|
|
|
|
// All the new associative choices we add will have huge slack
|
|
// since we do not redo timing, and timing doesnt handle choices
|
|
// well anyway. However every newly added node is a choice of an
|
|
// existing critical node, so they are considered critical.
|
|
// if ( (Fraig_NodeReadSlack( pRepr ) > 3) && (i < nNodesBefore) )
|
|
// continue;
|
|
|
|
// if ( pNode->pRepr )
|
|
// continue;
|
|
|
|
// Try ((ab)c), x = ab -> (a(bc)) and (b(ac))
|
|
pX = Fraig_NodeReadOne(pNode);
|
|
pC = Fraig_NodeReadTwo(pNode);
|
|
if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX))
|
|
{
|
|
pA = Fraig_NodeReadOne(Fraig_Regular(pX));
|
|
pB = Fraig_NodeReadTwo(Fraig_Regular(pX));
|
|
|
|
// pA = Fraig_NodeGetRepr( pA );
|
|
// pB = Fraig_NodeGetRepr( pB );
|
|
// pC = Fraig_NodeGetRepr( pC );
|
|
|
|
if (fShortCut)
|
|
{
|
|
pT = Fraig_NodeAnd(pMan, pB, pC);
|
|
if ( !pT->pRepr )
|
|
{
|
|
pN = Fraig_NodeAnd(pMan, pA, pT);
|
|
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
|
}
|
|
}
|
|
else
|
|
pN = Fraig_NodeAnd(pMan, pA, Fraig_NodeAnd(pMan, pB, pC));
|
|
// assert ( Fraig_NodesEqual(pN, pNode) );
|
|
|
|
|
|
if (fShortCut)
|
|
{
|
|
pT = Fraig_NodeAnd(pMan, pA, pC);
|
|
if ( !pT->pRepr )
|
|
{
|
|
pN = Fraig_NodeAnd(pMan, pB, pT);
|
|
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
|
}
|
|
}
|
|
else
|
|
pN = Fraig_NodeAnd(pMan, pB, Fraig_NodeAnd(pMan, pA, pC));
|
|
// assert ( Fraig_NodesEqual(pN, pNode) );
|
|
}
|
|
|
|
|
|
// Try (a(bc)), x = bc -> ((ab)c) and ((ac)b)
|
|
pA = Fraig_NodeReadOne(pNode);
|
|
pX = Fraig_NodeReadTwo(pNode);
|
|
if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX))
|
|
{
|
|
pB = Fraig_NodeReadOne(Fraig_Regular(pX));
|
|
pC = Fraig_NodeReadTwo(Fraig_Regular(pX));
|
|
|
|
// pA = Fraig_NodeGetRepr( pA );
|
|
// pB = Fraig_NodeGetRepr( pB );
|
|
// pC = Fraig_NodeGetRepr( pC );
|
|
|
|
if (fShortCut)
|
|
{
|
|
pT = Fraig_NodeAnd(pMan, pA, pB);
|
|
if ( !pT->pRepr )
|
|
{
|
|
pN = Fraig_NodeAnd(pMan, pC, pT);
|
|
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
|
}
|
|
}
|
|
else
|
|
pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pB), pC);
|
|
// assert ( Fraig_NodesEqual(pN, pNode) );
|
|
|
|
if (fShortCut)
|
|
{
|
|
pT = Fraig_NodeAnd(pMan, pA, pC);
|
|
if ( !pT->pRepr )
|
|
{
|
|
pN = Fraig_NodeAnd(pMan, pB, pT);
|
|
// Fraig_NodeAddChoice( pMan, pNode, pN );
|
|
}
|
|
}
|
|
else
|
|
pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pC), pB);
|
|
// assert ( Fraig_NodesEqual(pN, pNode) );
|
|
}
|
|
|
|
|
|
/*
|
|
// Try distributive transform
|
|
pQ = Fraig_NodeReadOne(pNode);
|
|
pR = Fraig_NodeReadTwo(pNode);
|
|
if ( (Fraig_IsComplement(pQ) && Fraig_NodeIsAnd(pQ))
|
|
&& (Fraig_IsComplement(pR) && Fraig_NodeIsAnd(pR)) )
|
|
{
|
|
pA = Fraig_NodeReadOne(Fraig_Regular(pQ));
|
|
pB = Fraig_NodeReadTwo(Fraig_Regular(pQ));
|
|
pC = Fraig_NodeReadOne(Fraig_Regular(pR));
|
|
pD = Fraig_NodeReadTwo(Fraig_Regular(pR));
|
|
|
|
// Now detect the !(xy + xz) pattern, store
|
|
// x in pA, y in pB and z in pC and set pD = 0 to indicate
|
|
// pattern was found
|
|
assert (pD != 0);
|
|
if (pA == pC) { pC = pD; pD = 0; }
|
|
if (pA == pD) { pD = 0; }
|
|
if (pB == pC) { pB = pA; pA = pC; pC = pD; pD = 0; }
|
|
if (pB == pD) { pB = pA; pA = pD; pD = 0; }
|
|
if (pD == 0)
|
|
{
|
|
nDistributive++;
|
|
pN = Fraig_Not(Fraig_NodeAnd(pMan, pA,
|
|
Fraig_NodeOr(pMan, pB, pC)));
|
|
if (fShortCut) Fraig_NodeAddChoice( pMan, pNode, pN );
|
|
// assert ( Fraig_NodesEqual(pN, pNode) );
|
|
}
|
|
}
|
|
*/
|
|
if ( i % 1000 == 0 )
|
|
{
|
|
sprintf( Buffer, "Adding choice %6d...", i - nNodesBefore );
|
|
// Extra_ProgressBarUpdate( pProgress, i, Buffer );
|
|
}
|
|
}
|
|
|
|
// Extra_ProgressBarStop( pProgress );
|
|
|
|
Fraig_ManCheckConsistency( pMan );
|
|
|
|
nNodesAfter = Fraig_ManReadNodeNum( pMan );
|
|
printf ( "Nodes before = %6d. Nodes with associative choices = %6d. Increase = %4.2f %%.\n",
|
|
nNodesBefore, nNodesAfter, ((float)(nNodesAfter - nNodesBefore)) * 100.0/(nNodesBefore - nInputs) );
|
|
printf ( "Distributive = %d\n", nDistributive );
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|