1 /**CFile****************************************************************
2 
3   FileName    [abcFpga.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Interface with the FPGA mapping package.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "base/abc/abc.h"
22 #include "map/fpga/fpgaInt.h"
23 
24 #ifdef ABC_USE_CUDD
25 #include "bdd/extrab/extraBdd.h"
26 #endif
27 
28 ABC_NAMESPACE_IMPL_START
29 
30 
31 ////////////////////////////////////////////////////////////////////////
32 ///                        DECLARATIONS                              ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose );
36 static Abc_Ntk_t *  Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
37 static Abc_Obj_t *  Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
38 
39 ////////////////////////////////////////////////////////////////////////
40 ///                     FUNCTION DEFINITIONS                         ///
41 ////////////////////////////////////////////////////////////////////////
42 
43 /**Function*************************************************************
44 
45   Synopsis    [Interface with the FPGA mapping package.]
46 
47   Description []
48 
49   SideEffects []
50 
51   SeeAlso     []
52 
53 ***********************************************************************/
Abc_NtkFpga(Abc_Ntk_t * pNtk,float DelayTarget,int fRecovery,int fSwitching,int fLatchPaths,int fVerbose)54 Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose )
55 {
56     int fShowSwitching = 1;
57     Abc_Ntk_t * pNtkNew;
58     Fpga_Man_t * pMan;
59     Vec_Int_t * vSwitching = NULL;
60     float * pSwitching = NULL;
61     int Num;
62 
63     assert( Abc_NtkIsStrash(pNtk) );
64 
65     // print a warning about choice nodes
66     if ( (Num = Abc_NtkGetChoiceNum( pNtk )) )
67         Abc_Print( 0, "Performing LUT mapping with %d choices.\n", Num );
68 
69     // compute switching activity
70     fShowSwitching |= fSwitching;
71     if ( fShowSwitching )
72     {
73         extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
74         vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
75         pSwitching = (float *)vSwitching->pArray;
76     }
77 
78     // perform FPGA mapping
79     pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose );
80     if ( pSwitching ) { assert(vSwitching); Vec_IntFree( vSwitching ); }
81     if ( pMan == NULL )
82         return NULL;
83     Fpga_ManSetSwitching( pMan, fSwitching );
84     Fpga_ManSetLatchPaths( pMan, fLatchPaths );
85     Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) );
86     Fpga_ManSetDelayTarget( pMan, DelayTarget );
87     if ( !Fpga_Mapping( pMan ) )
88     {
89         Fpga_ManFree( pMan );
90         return NULL;
91     }
92 
93     // transform the result of mapping into a BDD network
94     pNtkNew = Abc_NtkFromFpga( pMan, pNtk );
95     if ( pNtkNew == NULL )
96         return NULL;
97     Fpga_ManFree( pMan );
98 
99     // make the network minimum base
100     Abc_NtkMinimumBase( pNtkNew );
101 
102     if ( pNtk->pExdc )
103         pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
104 
105     // make sure that everything is okay
106     if ( !Abc_NtkCheck( pNtkNew ) )
107     {
108         printf( "Abc_NtkFpga: The network check has failed.\n" );
109         Abc_NtkDelete( pNtkNew );
110         return NULL;
111     }
112     return pNtkNew;
113 }
114 
115 /**Function*************************************************************
116 
117   Synopsis    [Load the network into FPGA manager.]
118 
119   Description []
120 
121   SideEffects []
122 
123   SeeAlso     []
124 
125 ***********************************************************************/
Abc_NtkToFpga(Abc_Ntk_t * pNtk,int fRecovery,float * pSwitching,int fLatchPaths,int fVerbose)126 Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fLatchPaths, int fVerbose )
127 {
128     Fpga_Man_t * pMan;
129     ProgressBar * pProgress;
130     Fpga_Node_t * pNodeFpga;
131     Vec_Ptr_t * vNodes;
132     Abc_Obj_t * pNode, * pFanin, * pPrev;
133     float * pfArrivals;
134     int i;
135 
136     assert( Abc_NtkIsStrash(pNtk) );
137 
138     // start the mapping manager and set its parameters
139     pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose );
140     if ( pMan == NULL )
141         return NULL;
142     Fpga_ManSetAreaRecovery( pMan, fRecovery );
143     Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
144     pfArrivals = Abc_NtkGetCiArrivalFloats(pNtk);
145     if ( fLatchPaths )
146     {
147         for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
148             pfArrivals[i] = -FPGA_FLOAT_LARGE;
149     }
150     Fpga_ManSetInputArrivals( pMan, pfArrivals );
151 
152     // create PIs and remember them in the old nodes
153     Abc_NtkCleanCopy( pNtk );
154     Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
155     Abc_NtkForEachCi( pNtk, pNode, i )
156     {
157         pNodeFpga = Fpga_ManReadInputs(pMan)[i];
158         pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
159         if ( pSwitching )
160             Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
161     }
162 
163     // load the AIG into the mapper
164     vNodes = Abc_AigDfs( pNtk, 0, 0 );
165     pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
166     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
167     {
168         Extra_ProgressBarUpdate( pProgress, i, NULL );
169         // add the node to the mapper
170         pNodeFpga = Fpga_NodeAnd( pMan,
171             Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
172             Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
173         assert( pNode->pCopy == NULL );
174         // remember the node
175         pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
176         if ( pSwitching )
177             Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
178         // set up the choice node
179         if ( Abc_AigNodeIsChoice( pNode ) )
180             for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData )
181             {
182                 Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy );
183                 Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy );
184             }
185     }
186     Extra_ProgressBarStop( pProgress );
187     Vec_PtrFree( vNodes );
188 
189     // set the primary outputs without copying the phase
190     Abc_NtkForEachCo( pNtk, pNode, i )
191         Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy;
192     return pMan;
193 }
194 
195 /**Function*************************************************************
196 
197   Synopsis    [Creates the mapped network.]
198 
199   Description []
200 
201   SideEffects []
202 
203   SeeAlso     []
204 
205 ***********************************************************************/
Abc_NtkFromFpga(Fpga_Man_t * pMan,Abc_Ntk_t * pNtk)206 Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
207 {
208     ProgressBar * pProgress;
209     Abc_Ntk_t * pNtkNew;
210     Abc_Obj_t * pNode, * pNodeNew;
211     int i, nDupGates;
212     // create the new network
213     pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
214     // make the mapper point to the new network
215     Fpga_CutsCleanSign( pMan );
216     Fpga_ManCleanData0( pMan );
217     Abc_NtkForEachCi( pNtk, pNode, i )
218         Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
219     // set the constant node
220 //    if ( Fpga_NodeReadRefs(Fpga_ManReadConst1(pMan)) > 0 )
221         Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NtkCreateNodeConst1(pNtkNew) );
222     // process the nodes in topological order
223     pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
224     Abc_NtkForEachCo( pNtk, pNode, i )
225     {
226         Extra_ProgressBarUpdate( pProgress, i, NULL );
227         pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] );
228         assert( !Abc_ObjIsComplement(pNodeNew) );
229         Abc_ObjFanin0(pNode)->pCopy = pNodeNew;
230     }
231     Extra_ProgressBarStop( pProgress );
232     // finalize the new network
233     Abc_NtkFinalize( pNtk, pNtkNew );
234     // remove the constant node if not used
235     pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0(Fpga_ManReadConst1(pMan));
236     if ( Abc_ObjFanoutNum(pNodeNew) == 0 )
237         Abc_NtkDeleteObj( pNodeNew );
238     // decouple the PO driver nodes to reduce the number of levels
239     nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
240     if ( nDupGates && Fpga_ManReadVerbose(pMan) )
241         printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
242     return pNtkNew;
243 }
244 
245 /**Function*************************************************************
246 
247   Synopsis    [Derive one node after FPGA mapping.]
248 
249   Description []
250 
251   SideEffects []
252 
253   SeeAlso     []
254 
255 ***********************************************************************/
Abc_NodeFromFpga_rec(Abc_Ntk_t * pNtkNew,Fpga_Node_t * pNodeFpga)256 Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga )
257 {
258     Fpga_Cut_t * pCutBest;
259     Fpga_Node_t ** ppLeaves;
260     Abc_Obj_t * pNodeNew;
261     int i, nLeaves;
262     assert( !Fpga_IsComplement(pNodeFpga) );
263     // return if the result if known
264     pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga );
265     if ( pNodeNew )
266         return pNodeNew;
267     assert( Fpga_NodeIsAnd(pNodeFpga) );
268     // get the parameters of the best cut
269     pCutBest = Fpga_NodeReadCutBest( pNodeFpga );
270     ppLeaves = Fpga_CutReadLeaves( pCutBest );
271     nLeaves  = Fpga_CutReadLeavesNum( pCutBest );
272     // create a new node
273     pNodeNew = Abc_NtkCreateNode( pNtkNew );
274     for ( i = 0; i < nLeaves; i++ )
275         Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) );
276     // derive the function of this node
277     pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest );   Cudd_Ref( (DdNode *)pNodeNew->pData );
278     Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew );
279     return pNodeNew;
280 }
281 
282 ////////////////////////////////////////////////////////////////////////
283 ///                       END OF FILE                                ///
284 ////////////////////////////////////////////////////////////////////////
285 
286 
287 ABC_NAMESPACE_IMPL_END
288 
289