summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcFpga.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2007-10-01 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2007-10-01 08:01:00 -0700
commit4812c90424dfc40d26725244723887a2d16ddfd9 (patch)
treeb32ace96e7e2d84d586e09ba605463b6f49c3271 /src/base/abci/abcFpga.c
parente54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (diff)
downloadabc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.gz
abc-4812c90424dfc40d26725244723887a2d16ddfd9.tar.bz2
abc-4812c90424dfc40d26725244723887a2d16ddfd9.zip
Version abc71001
Diffstat (limited to 'src/base/abci/abcFpga.c')
-rw-r--r--src/base/abci/abcFpga.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c
new file mode 100644
index 00000000..3bc9fbed
--- /dev/null
+++ b/src/base/abci/abcFpga.c
@@ -0,0 +1,278 @@
+/**CFile****************************************************************
+
+ FileName [abcFpga.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fpgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose );
+static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose )
+{
+ int fShowSwitching = 1;
+ Abc_Ntk_t * pNtkNew;
+ Fpga_Man_t * pMan;
+ Vec_Int_t * vSwitching;
+ float * pSwitching = NULL;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // print a warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Performing FPGA mapping with choices.\n" );
+
+ // compute switching activity
+ fShowSwitching |= fSwitching;
+ if ( fShowSwitching )
+ {
+ extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
+ vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
+ pSwitching = (float *)vSwitching->pArray;
+ }
+
+ // perform FPGA mapping
+ pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose );
+ if ( pSwitching ) Vec_IntFree( vSwitching );
+ if ( pMan == NULL )
+ return NULL;
+ Fpga_ManSetSwitching( pMan, fSwitching );
+ Fpga_ManSetLatchPaths( pMan, fLatchPaths );
+ Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) );
+ Fpga_ManSetDelayTarget( pMan, DelayTarget );
+ if ( !Fpga_Mapping( pMan ) )
+ {
+ Fpga_ManFree( pMan );
+ return NULL;
+ }
+
+ // transform the result of mapping into a BDD network
+ pNtkNew = Abc_NtkFromFpga( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Fpga_ManFree( pMan );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ if ( pNtk->pExdc )
+ pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
+
+ // make sure that everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFpga: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into FPGA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose )
+{
+ Fpga_Man_t * pMan;
+ ProgressBar * pProgress;
+ Fpga_Node_t * pNodeFpga;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanin, * pPrev;
+ float * pfArrivals;
+ int i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // start the mapping manager and set its parameters
+ pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ Fpga_ManSetAreaRecovery( pMan, fRecovery );
+ Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
+ pfArrivals = Abc_NtkGetCiArrivalFloats(pNtk);
+ if ( fLatchPaths )
+ {
+ for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
+ pfArrivals[i] = -FPGA_FLOAT_LARGE;
+ }
+ Fpga_ManSetInputArrivals( pMan, pfArrivals );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ pNodeFpga = Fpga_ManReadInputs(pMan)[i];
+ pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
+ if ( pSwitching )
+ Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
+ }
+
+ // load the AIG into the mapper
+ vNodes = Abc_AigDfs( pNtk, 0, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // add the node to the mapper
+ pNodeFpga = Fpga_NodeAnd( pMan,
+ Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ // remember the node
+ pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
+ if ( pSwitching )
+ Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
+ // set up the choice node
+ if ( Abc_AigNodeIsChoice( pNode ) )
+ for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
+ {
+ Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy );
+ Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs without copying the phase
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy;
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i, nDupGates;
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
+ // make the mapper point to the new network
+ Fpga_CutsCleanSign( pMan );
+ Fpga_ManCleanData0( pMan );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
+ // set the constant node
+// if ( Fpga_NodeReadRefs(Fpga_ManReadConst1(pMan)) > 0 )
+ Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkCreateNodeConst1(pNtkNew) );
+ // process the nodes in topological order
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ Abc_ObjFanin0(pNode)->pCopy = pNodeNew;
+ }
+ Extra_ProgressBarStop( pProgress );
+ // finalize the new network
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ // remove the constant node if not used
+ pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0(Fpga_ManReadConst1(pMan));
+ if ( Abc_ObjFanoutNum(pNodeNew) == 0 )
+ Abc_NtkDeleteObj( pNodeNew );
+ // decouple the PO driver nodes to reduce the number of levels
+ nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
+// if ( nDupGates && Fpga_ManReadVerbose(pMan) )
+// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive one node after FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga )
+{
+ Fpga_Cut_t * pCutBest;
+ Fpga_Node_t ** ppLeaves;
+ Abc_Obj_t * pNodeNew;
+ int i, nLeaves;
+ assert( !Fpga_IsComplement(pNodeFpga) );
+ // return if the result if known
+ pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga );
+ if ( pNodeNew )
+ return pNodeNew;
+ assert( Fpga_NodeIsAnd(pNodeFpga) );
+ // get the parameters of the best cut
+ pCutBest = Fpga_NodeReadCutBest( pNodeFpga );
+ ppLeaves = Fpga_CutReadLeaves( pCutBest );
+ nLeaves = Fpga_CutReadLeavesNum( pCutBest );
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nLeaves; i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) );
+ // derive the function of this node
+ pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest ); Cudd_Ref( pNodeNew->pData );
+ Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+