1 /**CFile****************************************************************
2
3 FileName [wlnNdr.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Word-level network.]
8
9 Synopsis [Constructing WLN network from NDR data structure.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - September 23, 2018.]
16
17 Revision [$Id: wlnNdr.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "wln.h"
22 #include "aig/miniaig/ndr.h"
23
24 ABC_NAMESPACE_IMPL_START
25
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29
30 ////////////////////////////////////////////////////////////////////////
31 /// FUNCTION DEFINITIONS ///
32 ////////////////////////////////////////////////////////////////////////
33
34 /**Function*************************************************************
35
36 Synopsis []
37
38 Description []
39
40 SideEffects []
41
42 SeeAlso []
43
44 ***********************************************************************/
Wln_NtkToNdr(Wln_Ntk_t * p)45 void * Wln_NtkToNdr( Wln_Ntk_t * p )
46 {
47 Vec_Int_t * vFanins;
48 int i, k, iObj, iFanin;
49 // create a new module
50 void * pDesign = Ndr_Create( 1 );
51 int ModId = Ndr_AddModule( pDesign, 1 );
52 // add primary inputs
53 Wln_NtkForEachPi( p, iObj, i )
54 {
55 Ndr_AddObject( pDesign, ModId, ABC_OPER_CI, 0,
56 Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
57 0, NULL, 1, &iObj, NULL ); // no fanins
58 }
59 // add internal nodes
60 vFanins = Vec_IntAlloc( 10 );
61 Wln_NtkForEachObjInternal( p, iObj )
62 {
63 Vec_IntClear( vFanins );
64 Wln_ObjForEachFanin( p, iObj, iFanin, k )
65 Vec_IntPush( vFanins, iFanin );
66 Ndr_AddObject( pDesign, ModId, Wln_ObjType(p, iObj), 0,
67 Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
68 Vec_IntSize(vFanins), Vec_IntArray(vFanins), 1, &iObj,
69 Wln_ObjIsConst(p, iObj) ? Wln_ObjConstString(p, iObj) : NULL );
70 }
71 Vec_IntFree( vFanins );
72 // add primary outputs
73 Wln_NtkForEachPo( p, iObj, i )
74 {
75 Ndr_AddObject( pDesign, ModId, ABC_OPER_CO, 0,
76 Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
77 1, &iObj, 0, NULL, NULL );
78 }
79 return pDesign;
80 }
Wln_WriteNdr(Wln_Ntk_t * p,char * pFileName)81 void Wln_WriteNdr( Wln_Ntk_t * p, char * pFileName )
82 {
83 void * pDesign = Wln_NtkToNdr( p );
84 Ndr_Write( pFileName, pDesign );
85 Ndr_Delete( pDesign );
86 printf( "Dumped the current design into file \"%s\".\n", pFileName );
87 }
Wln_NtkToNdrTest(Wln_Ntk_t * p)88 void Wln_NtkToNdrTest( Wln_Ntk_t * p )
89 {
90 // transform
91 void * pDesign = Wln_NtkToNdr( p );
92
93 // collect names
94 char ** ppNames = ABC_ALLOC( char *, Wln_NtkObjNum(p) + 1 ); int i;
95 Wln_NtkForEachObj( p, i )
96 ppNames[i] = Abc_UtilStrsav(Wln_ObjName(p, i));
97
98 // verify by writing Verilog
99 Ndr_WriteVerilog( NULL, pDesign, ppNames );
100 Ndr_Write( "test.ndr", pDesign );
101
102 // cleanup
103 Ndr_Delete( pDesign );
104 Wln_NtkForEachObj( p, i )
105 ABC_FREE( ppNames[i] );
106 ABC_FREE( ppNames );
107 }
108
109 /**Function*************************************************************
110
111 Synopsis []
112
113 Description []
114
115 SideEffects []
116
117 SeeAlso []
118
119 ***********************************************************************/
Ndr_ObjGetRange(Ndr_Data_t * p,int Obj,int * End,int * Beg)120 int Ndr_ObjGetRange( Ndr_Data_t * p, int Obj, int * End, int * Beg )
121 {
122 int * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_RANGE, &pArray );
123 int Signed = 0; *End = *Beg = 0;
124 if ( nArray == 0 )
125 return 0;
126 if ( nArray == 3 )
127 Signed = 1;
128 if ( nArray == 1 )
129 *End = *Beg = pArray[0];
130 else
131 *End = pArray[0], *Beg = pArray[1];
132 return Signed;
133 }
Ndr_NtkPrintObjects(Wln_Ntk_t * pNtk)134 void Ndr_NtkPrintObjects( Wln_Ntk_t * pNtk )
135 {
136 int k, iObj, iFanin;
137 printf( "Node IDs and their fanins:\n" );
138 Wln_NtkForEachObj( pNtk, iObj )
139 {
140 printf( "%5d = ", iObj );
141 Wln_ObjForEachFanin( pNtk, iObj, iFanin, k )
142 printf( "%5d ", iFanin );
143 for ( ; k < 4; k++ )
144 printf( " " );
145 printf( " Name Id %d ", Wln_ObjNameId(pNtk, iObj) );
146 if ( Wln_ObjIsPi(pNtk, iObj) )
147 printf( " pi " );
148 if ( Wln_ObjIsPo(pNtk, iObj) )
149 printf( " po " );
150 printf( "\n" );
151 }
152 }
Wln_NtkCheckIntegrity(void * pData)153 void Wln_NtkCheckIntegrity( void * pData )
154 {
155 Ndr_Data_t * p = (Ndr_Data_t *)pData;
156 Vec_Int_t * vMap = Vec_IntAlloc( 100 );
157 int Mod = 2, Obj;
158 Ndr_ModForEachObj( p, Mod, Obj )
159 {
160 int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
161 if ( NameId == -1 )
162 {
163 int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
164 if ( Type != ABC_OPER_CO )
165 printf( "Internal object %d of type %s has no output name.\n", Obj, Abc_OperName(Type) );
166 continue;
167 }
168 if ( Vec_IntGetEntry(vMap, NameId) > 0 )
169 printf( "Output name %d is used more than once (obj %d and obj %d).\n", NameId, Vec_IntGetEntry(vMap, NameId), Obj );
170 Vec_IntSetEntry( vMap, NameId, Obj );
171 }
172 Ndr_ModForEachObj( p, Mod, Obj )
173 {
174 int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
175 int i, * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
176 for ( i = 0; i < nArray; i++ )
177 if ( Vec_IntGetEntry(vMap, pArray[i]) == 0 && !(Type == ABC_OPER_DFFRSE && (i >= 5 && i <= 7)) )
178 printf( "Input name %d appearing as fanin %d of obj %d is not used as output name in any object.\n", pArray[i], i, Obj );
179 }
180 Vec_IntFree( vMap );
181 }
Wln_NtkFromNdr(void * pData)182 Wln_Ntk_t * Wln_NtkFromNdr( void * pData )
183 {
184 Ndr_Data_t * p = (Ndr_Data_t *)pData;
185 Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 );
186 Vec_Ptr_t * vConstStrings = Vec_PtrAlloc( 100 );
187 int Mod = 2, i, k, iFanin, iObj, Obj, * pArray, nDigits, fFound, NameId, NameIdMax;
188 Wln_Ntk_t * pTemp, * pNtk = Wln_NtkAlloc( "top", Ndr_DataObjNum(p, Mod) );
189 Wln_NtkCheckIntegrity( pData );
190 //pNtk->pSpec = Abc_UtilStrsav( pFileName );
191 // construct network and save name IDs
192 Wln_NtkCleanNameId( pNtk );
193 Wln_NtkCleanInstId( pNtk );
194 Ndr_ModForEachPi( p, Mod, Obj )
195 {
196 int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
197 int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CI, Signed, End, Beg );
198 int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
199 int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
200 Wln_ObjSetNameId( pNtk, iObj, NameId );
201 if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId );
202 }
203 Ndr_ModForEachNode( p, Mod, Obj )
204 {
205 int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
206 int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
207 int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
208 Vec_Int_t F = {nArray, nArray, pArray}, * vTemp = &F;
209 int iObj = Wln_ObjAlloc( pNtk, Type, Signed, End, Beg );
210 int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
211 int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
212 Vec_IntClear( vFanins );
213 Vec_IntAppend( vFanins, vTemp );
214 assert( Type != ABC_OPER_DFF );
215 if ( Wln_ObjIsSlice(pNtk, iObj) )
216 Wln_ObjSetSlice( pNtk, iObj, Hash_Int2ManInsert(pNtk->pRanges, End, Beg, 0) );
217 else if ( Wln_ObjIsConst(pNtk, iObj) )
218 Vec_PtrPush( vConstStrings, (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
219 // else if ( Type == ABC_OPER_BIT_MUX && Vec_IntSize(vFanins) == 3 )
220 // ABC_SWAP( int, Wln_ObjFanins(pNtk, iObj)[1], Wln_ObjFanins(pNtk, iObj)[2] );
221 Wln_ObjAddFanins( pNtk, iObj, vFanins );
222 Wln_ObjSetNameId( pNtk, iObj, NameId );
223 if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId );
224 if ( Type == ABC_OPER_ARI_SMUL )
225 {
226 assert( Wln_ObjFaninNum(pNtk, iObj) == 2 );
227 Wln_ObjSetSigned( pNtk, Wln_ObjFanin0(pNtk, iObj) );
228 Wln_ObjSetSigned( pNtk, Wln_ObjFanin1(pNtk, iObj) );
229 }
230 }
231 // mark primary outputs
232 Ndr_ModForEachPo( p, Mod, Obj )
233 {
234 int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
235 int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
236 int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CO, Signed, End, Beg );
237 int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
238 int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
239 assert( nArray == 1 && NameId == -1 && InstId == -1 );
240 Wln_ObjAddFanin( pNtk, iObj, pArray[0] );
241 }
242 Vec_IntFree( vFanins );
243 // remove instance names if they are not given
244 //Vec_IntPrint( &pNtk->vInstIds );
245 if ( Vec_IntCountPositive(&pNtk->vInstIds) == 0 )
246 Vec_IntErase( &pNtk->vInstIds );
247 // map name IDs into object IDs
248 vName2Obj = Vec_IntInvert( &pNtk->vNameIds, 0 );
249 Wln_NtkForEachObj( pNtk, i )
250 Wln_ObjForEachFanin( pNtk, i, iFanin, k )
251 Wln_ObjSetFanin( pNtk, i, k, Vec_IntEntry(vName2Obj, iFanin) );
252 Vec_IntFree(vName2Obj);
253 // create fake object names
254 NameIdMax = Vec_IntFindMax(&pNtk->vNameIds);
255 nDigits = Abc_Base10Log( NameIdMax+1 );
256 pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 );
257 for ( i = 1; i <= NameIdMax; i++ )
258 {
259 char pName[20]; sprintf( pName, "s%0*d", nDigits, i );
260 NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
261 assert( !fFound && i == NameId );
262 }
263 // add const strings
264 i = 0;
265 Wln_NtkForEachObj( pNtk, iObj )
266 if ( Wln_ObjIsConst(pNtk, iObj) )
267 Wln_ObjSetConst( pNtk, iObj, Abc_NamStrFindOrAdd(pNtk->pManName, (char *)Vec_PtrEntry(vConstStrings, i++), NULL) );
268 assert( i == Vec_PtrSize(vConstStrings) );
269 Vec_PtrFree( vConstStrings );
270 //Ndr_NtkPrintObjects( pNtk );
271 Wln_WriteVer( pNtk, "temp_ndr.v" );
272 printf( "Dumped design \"%s\" into file \"temp_ndr.v\".\n", pNtk->pName );
273 // derive topological order
274 pNtk = Wln_NtkDupDfs( pTemp = pNtk );
275 Wln_NtkFree( pTemp );
276 //Ndr_NtkPrintObjects( pNtk );
277 //pNtk->fMemPorts = 1; // the network contains memory ports
278 //pNtk->fEasyFfs = 1; // the network contains simple flops
279 return pNtk;
280 }
281
282 /**Function*************************************************************
283
284 Synopsis []
285
286 Description []
287
288 SideEffects []
289
290 SeeAlso []
291
292 ***********************************************************************/
Wln_ReadNdr(char * pFileName)293 Wln_Ntk_t * Wln_ReadNdr( char * pFileName )
294 {
295 void * pData = Ndr_Read( pFileName );
296 Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData ) : NULL;
297 if ( pNtk ) return NULL;
298 //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" };
299 //Ndr_WriteVerilog( NULL, pData, ppNames );
300 Ndr_Delete( pData );
301 return pNtk;
302 }
Wln_ReadNdrTest()303 void Wln_ReadNdrTest()
304 {
305 Wln_Ntk_t * pNtk = Wln_ReadNdr( "D:\\temp\\brijesh\\for_alan_dff_warning\\work_fir_filter_fir_filter_proc_out.ndr" );
306 //Wln_Ntk_t * pNtk = Wln_ReadNdr( "flop.ndr" );
307 Wln_WriteVer( pNtk, "test__test.v" );
308 Wln_NtkPrint( pNtk );
309 Wln_NtkStaticFanoutTest( pNtk );
310 Wln_NtkFree( pNtk );
311 }
Wln_NtkRetimeTest(char * pFileName,int fSkipSimple,int fVerbose)312 void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fVerbose )
313 {
314 Vec_Int_t * vMoves;
315 void * pData = Ndr_Read( pFileName );
316 Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData ) : NULL;
317 if ( pNtk == NULL )
318 {
319 printf( "Retiming network is not available.\n" );
320 return;
321 }
322 Ndr_Delete( pData );
323 Wln_NtkRetimeCreateDelayInfo( pNtk );
324 vMoves = Wln_NtkRetime( pNtk, fSkipSimple, fVerbose );
325 //Vec_IntPrint( vMoves );
326 Vec_IntFree( vMoves );
327 Wln_NtkFree( pNtk );
328 }
329
330 ////////////////////////////////////////////////////////////////////////
331 /// END OF FILE ///
332 ////////////////////////////////////////////////////////////////////////
333
334
335 ABC_NAMESPACE_IMPL_END
336
337