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