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