summaryrefslogtreecommitdiffstats
path: root/src/base/wlc/wlcNdr.c
blob: 0d5c8a41c89b1980a7e318d0879cd0c3e35dd083 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/**CFile****************************************************************

  FileName    [wlcNdr.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Experimental procedures.]

  Synopsis    [Constructing WLC network from NDR data structure.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - August 22, 2014.]

  Revision    [$Id: wlcNdr.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]

***********************************************************************/

#include "wlc.h"
#include "aig/miniaig/ndr.h"

ABC_NAMESPACE_IMPL_START

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ndr_TypeNdr2Wlc( int Type )
{
    if ( Type == ABC_OPER_CONST )         return WLC_OBJ_CONST;         // 06: constant
    if ( Type == ABC_OPER_BIT_BUF )       return WLC_OBJ_BUF;           // 07: buffer
    if ( Type == ABC_OPER_BIT_MUX )       return WLC_OBJ_MUX;           // 08: multiplexer
    if ( Type == ABC_OPER_SHIFT_R )       return WLC_OBJ_SHIFT_R;       // 09: shift right
    if ( Type == ABC_OPER_SHIFT_RA )      return WLC_OBJ_SHIFT_RA;      // 10: shift right (arithmetic)
    if ( Type == ABC_OPER_SHIFT_L )       return WLC_OBJ_SHIFT_L;       // 11: shift left
    if ( Type == ABC_OPER_SHIFT_LA )      return WLC_OBJ_SHIFT_LA;      // 12: shift left (arithmetic)
    if ( Type == ABC_OPER_SHIFT_ROTR )    return WLC_OBJ_ROTATE_R;      // 13: rotate right
    if ( Type == ABC_OPER_SHIFT_ROTL )    return WLC_OBJ_ROTATE_L;      // 14: rotate left
    if ( Type == ABC_OPER_BIT_INV )       return WLC_OBJ_BIT_NOT;       // 15: bitwise NOT
    if ( Type == ABC_OPER_BIT_AND )       return WLC_OBJ_BIT_AND;       // 16: bitwise AND
    if ( Type == ABC_OPER_BIT_OR )        return WLC_OBJ_BIT_OR;        // 17: bitwise OR
    if ( Type == ABC_OPER_BIT_XOR )       return WLC_OBJ_BIT_XOR;       // 18: bitwise XOR
    if ( Type == ABC_OPER_BIT_NAND )      return WLC_OBJ_BIT_NAND;      // 19: bitwise AND
    if ( Type == ABC_OPER_BIT_NOR )       return WLC_OBJ_BIT_NOR;       // 20: bitwise OR
    if ( Type == ABC_OPER_BIT_NXOR )      return WLC_OBJ_BIT_NXOR;      // 21: bitwise NXOR
    if ( Type == ABC_OPER_SLICE )         return WLC_OBJ_BIT_SELECT;    // 22: bit selection
    if ( Type == ABC_OPER_CONCAT )        return WLC_OBJ_BIT_CONCAT;    // 23: bit concatenation
    if ( Type == ABC_OPER_ZEROPAD )       return WLC_OBJ_BIT_ZEROPAD;   // 24: zero padding
    if ( Type == ABC_OPER_SIGNEXT )       return WLC_OBJ_BIT_SIGNEXT;   // 25: sign extension
    if ( Type == ABC_OPER_LOGIC_NOT )     return WLC_OBJ_LOGIC_NOT;     // 26: logic NOT
    if ( Type == ABC_OPER_LOGIC_IMPL )    return WLC_OBJ_LOGIC_IMPL;    // 27: logic implication
    if ( Type == ABC_OPER_LOGIC_AND )     return WLC_OBJ_LOGIC_AND;     // 28: logic AND
    if ( Type == ABC_OPER_LOGIC_OR )      return WLC_OBJ_LOGIC_OR;      // 29: logic OR
    if ( Type == ABC_OPER_LOGIC_XOR )     return WLC_OBJ_LOGIC_XOR;     // 30: logic XOR
    if ( Type == ABC_OPER_COMP_EQU )      return WLC_OBJ_COMP_EQU;      // 31: compare equal
    if ( Type == ABC_OPER_COMP_NOTEQU )   return WLC_OBJ_COMP_NOTEQU;   // 32: compare not equal
    if ( Type == ABC_OPER_COMP_LESS )     return WLC_OBJ_COMP_LESS;     // 33: compare less
    if ( Type == ABC_OPER_COMP_MORE )     return WLC_OBJ_COMP_MORE;     // 34: compare more
    if ( Type == ABC_OPER_COMP_LESSEQU )  return WLC_OBJ_COMP_LESSEQU;  // 35: compare less or equal
    if ( Type == ABC_OPER_COMP_MOREEQU )  return WLC_OBJ_COMP_MOREEQU;  // 36: compare more or equal
    if ( Type == ABC_OPER_RED_AND )       return WLC_OBJ_REDUCT_AND;    // 37: reduction AND
    if ( Type == ABC_OPER_RED_OR )        return WLC_OBJ_REDUCT_OR;     // 38: reduction OR
    if ( Type == ABC_OPER_RED_XOR )       return WLC_OBJ_REDUCT_XOR;    // 39: reduction XOR
    if ( Type == ABC_OPER_RED_NAND )      return WLC_OBJ_REDUCT_NAND;   // 40: reduction NAND
    if ( Type == ABC_OPER_RED_NOR )       return WLC_OBJ_REDUCT_NOR;    // 41: reduction NOR
    if ( Type == ABC_OPER_RED_NXOR )      return WLC_OBJ_REDUCT_NXOR;   // 42: reduction NXOR
    if ( Type == ABC_OPER_ARI_ADD )       return WLC_OBJ_ARI_ADD;       // 43: arithmetic addition
    if ( Type == ABC_OPER_ARI_SUB )       return WLC_OBJ_ARI_SUB;       // 44: arithmetic subtraction
    if ( Type == ABC_OPER_ARI_MUL )       return WLC_OBJ_ARI_MULTI;     // 45: arithmetic multiplier
    if ( Type == ABC_OPER_ARI_DIV )       return WLC_OBJ_ARI_DIVIDE;    // 46: arithmetic division
    if ( Type == ABC_OPER_ARI_REM )       return WLC_OBJ_ARI_REM;       // 47: arithmetic remainder
    if ( Type == ABC_OPER_ARI_MOD )       return WLC_OBJ_ARI_MODULUS;   // 48: arithmetic modulus
    if ( Type == ABC_OPER_ARI_POW )       return WLC_OBJ_ARI_POWER;     // 49: arithmetic power
    if ( Type == ABC_OPER_ARI_MIN )       return WLC_OBJ_ARI_MINUS;     // 50: arithmetic minus
    if ( Type == ABC_OPER_ARI_SQRT )      return WLC_OBJ_ARI_SQRT;      // 51: integer square root
    if ( Type == ABC_OPER_ARI_SQUARE )    return WLC_OBJ_ARI_SQUARE;    // 52: integer square
    return -1;
}
int Ndr_TypeWlc2Ndr( int Type )
{
    if ( Type == WLC_OBJ_CONST )          return ABC_OPER_CONST;        // 06: constant
    if ( Type == WLC_OBJ_BUF )            return ABC_OPER_BIT_BUF;      // 07: buffer
    if ( Type == WLC_OBJ_MUX )            return ABC_OPER_BIT_MUX;      // 08: multiplexer
    if ( Type == WLC_OBJ_SHIFT_R )        return ABC_OPER_SHIFT_R;      // 09: shift right
    if ( Type == WLC_OBJ_SHIFT_RA )       return ABC_OPER_SHIFT_RA;     // 10: shift right (arithmetic)
    if ( Type == WLC_OBJ_SHIFT_L )        return ABC_OPER_SHIFT_L;      // 11: shift left
    if ( Type == WLC_OBJ_SHIFT_LA )       return ABC_OPER_SHIFT_LA;     // 12: shift left (arithmetic)
    if ( Type == WLC_OBJ_ROTATE_R )       return ABC_OPER_SHIFT_ROTR;   // 13: rotate right
    if ( Type == WLC_OBJ_ROTATE_L )       return ABC_OPER_SHIFT_ROTL;   // 14: rotate left
    if ( Type == WLC_OBJ_BIT_NOT )        return ABC_OPER_BIT_INV;      // 15: bitwise NOT
    if ( Type == WLC_OBJ_BIT_AND )        return ABC_OPER_BIT_AND;      // 16: bitwise AND
    if ( Type == WLC_OBJ_BIT_OR )         return ABC_OPER_BIT_OR;       // 17: bitwise OR
    if ( Type == WLC_OBJ_BIT_XOR )        return ABC_OPER_BIT_XOR;      // 18: bitwise XOR
    if ( Type == WLC_OBJ_BIT_NAND )       return ABC_OPER_BIT_NAND;     // 19: bitwise AND
    if ( Type == WLC_OBJ_BIT_NOR )        return ABC_OPER_BIT_NOR;      // 20: bitwise OR
    if ( Type == WLC_OBJ_BIT_NXOR )       return ABC_OPER_BIT_NXOR;     // 21: bitwise NXOR
    if ( Type == WLC_OBJ_BIT_SELECT )     return ABC_OPER_SLICE;        // 22: bit selection
    if ( Type == WLC_OBJ_BIT_CONCAT )     return ABC_OPER_CONCAT;       // 23: bit concatenation
    if ( Type == WLC_OBJ_BIT_ZEROPAD )    return ABC_OPER_ZEROPAD;      // 24: zero padding
    if ( Type == WLC_OBJ_BIT_SIGNEXT )    return ABC_OPER_SIGNEXT;      // 25: sign extension
    if ( Type == WLC_OBJ_LOGIC_NOT )      return ABC_OPER_LOGIC_NOT;    // 26: logic NOT
    if ( Type == WLC_OBJ_LOGIC_IMPL )     return ABC_OPER_LOGIC_IMPL;   // 27: logic implication
    if ( Type == WLC_OBJ_LOGIC_AND )      return ABC_OPER_LOGIC_AND;    // 28: logic AND
    if ( Type == WLC_OBJ_LOGIC_OR )       return ABC_OPER_LOGIC_OR;     // 29: logic OR
    if ( Type == WLC_OBJ_LOGIC_XOR )      return ABC_OPER_LOGIC_XOR;    // 30: logic XOR
    if ( Type == WLC_OBJ_COMP_EQU )       return ABC_OPER_COMP_EQU;     // 31: compare equal
    if ( Type == WLC_OBJ_COMP_NOTEQU )    return ABC_OPER_COMP_NOTEQU;  // 32: compare not equal
    if ( Type == WLC_OBJ_COMP_LESS )      return ABC_OPER_COMP_LESS;    // 33: compare less
    if ( Type == WLC_OBJ_COMP_MORE )      return ABC_OPER_COMP_MORE;    // 34: compare more
    if ( Type == WLC_OBJ_COMP_LESSEQU )   return ABC_OPER_COMP_LESSEQU; // 35: compare less or equal
    if ( Type == WLC_OBJ_COMP_MOREEQU )   return ABC_OPER_COMP_MOREEQU; // 36: compare more or equal
    if ( Type == WLC_OBJ_REDUCT_AND )     return ABC_OPER_RED_AND;      // 37: reduction AND
    if ( Type == WLC_OBJ_REDUCT_OR )      return ABC_OPER_RED_OR;       // 38: reduction OR
    if ( Type == WLC_OBJ_REDUCT_XOR )     return ABC_OPER_RED_XOR;      // 39: reduction XOR
    if ( Type == WLC_OBJ_REDUCT_NAND )    return ABC_OPER_RED_NAND;     // 40: reduction NAND
    if ( Type == WLC_OBJ_REDUCT_NOR )     return ABC_OPER_RED_NOR;      // 41: reduction NOR
    if ( Type == WLC_OBJ_REDUCT_NXOR )    return ABC_OPER_RED_NXOR;     // 42: reduction NXOR
    if ( Type == WLC_OBJ_ARI_ADD )        return ABC_OPER_ARI_ADD;      // 43: arithmetic addition
    if ( Type == WLC_OBJ_ARI_SUB )        return ABC_OPER_ARI_SUB;      // 44: arithmetic subtraction
    if ( Type == WLC_OBJ_ARI_MULTI )      return ABC_OPER_ARI_MUL;      // 45: arithmetic multiplier
    if ( Type == WLC_OBJ_ARI_DIVIDE )     return ABC_OPER_ARI_DIV;      // 46: arithmetic division
    if ( Type == WLC_OBJ_ARI_REM )        return ABC_OPER_ARI_REM;      // 47: arithmetic remainder
    if ( Type == WLC_OBJ_ARI_MODULUS )    return ABC_OPER_ARI_MOD;      // 48: arithmetic modulus
    if ( Type == WLC_OBJ_ARI_POWER )      return ABC_OPER_ARI_POW;      // 49: arithmetic power
    if ( Type == WLC_OBJ_ARI_MINUS )      return ABC_OPER_ARI_MIN;      // 50: arithmetic minus
    if ( Type == WLC_OBJ_ARI_SQRT )       return ABC_OPER_ARI_SQRT;     // 51: integer square root
    if ( Type == WLC_OBJ_ARI_SQUARE )     return ABC_OPER_ARI_SQUARE;   // 52: integer square
    return -1;
}


/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void * Wlc_NtkToNdr( Wlc_Ntk_t * pNtk )
{
    Wlc_Obj_t * pObj; 
    int i, k, iFanin, iOutId;
    // create a new module
    void * pModule = Ndr_ModuleCreate( 1 );
    // add primary inputs
    Vec_Int_t * vFanins = Vec_IntAlloc( 10 );
    Wlc_NtkForEachPi( pNtk, pObj, i ) 
    {
        iOutId = Wlc_ObjId(pNtk, pObj);
        Ndr_ModuleAddObject( pModule, ABC_OPER_CI, 0,   
            pObj->End, pObj->Beg, pObj->Signed,   
            0, NULL,      1, &iOutId,  NULL  ); // no fanins
    }
    // add internal nodes 
    Wlc_NtkForEachObj( pNtk, pObj, iOutId ) 
    {
        if ( Wlc_ObjIsPi(pObj) )
            continue;
        Vec_IntClear( vFanins );
        Wlc_ObjForEachFanin( pObj, iFanin, k )
            Vec_IntPush( vFanins, iFanin );
        Ndr_ModuleAddObject( pModule, Ndr_TypeWlc2Ndr(pObj->Type), 0,   
            pObj->End, pObj->Beg, pObj->Signed,   
            Vec_IntSize(vFanins), Vec_IntArray(vFanins), 1, &iOutId,  NULL  ); 
    }
    // add primary outputs
    Wlc_NtkForEachObj( pNtk, pObj, iOutId ) 
    {
        if ( !Wlc_ObjIsPo(pObj) )
            continue;
        Vec_IntFill( vFanins, 1, iOutId );
        Ndr_ModuleAddObject( pModule, ABC_OPER_CO, 0,                   
            pObj->End, pObj->Beg, pObj->Signed,   
            1, Vec_IntArray(vFanins),  0, NULL,  NULL ); 
    }
    Vec_IntFree( vFanins );
    return pModule;
}
void Wlc_WriteNdr( Wlc_Ntk_t * pNtk, char * pFileName )
{
    void * pModule = Wlc_NtkToNdr( pNtk );
    Ndr_ModuleWrite( pFileName, pModule );
    Ndr_ModuleDelete( pModule );
    printf( "Dumped the current design into file \"%s\".\n", pFileName );
}
void Wlc_NtkToNdrTest( Wlc_Ntk_t * pNtk )
{
    // transform
    void * pModule = Wlc_NtkToNdr( pNtk );

    // collect names     
    Wlc_Obj_t * pObj;  int i;
    char ** ppNames = ABC_ALLOC( char *, Wlc_NtkObjNum(pNtk) + 1 );
    Wlc_NtkForEachObj( pNtk, pObj, i ) 
        ppNames[i] = Wlc_ObjName(pNtk, i);

    // verify by writing Verilog
    Ndr_ModuleWriteVerilog( NULL, pModule, ppNames );
    Ndr_ModuleWrite( "test.ndr", pModule );

    // cleanup
    Ndr_ModuleDelete( pModule );
    ABC_FREE( ppNames );
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ndr_ObjReadRange( Ndr_Data_t * p, int Obj, int * End, int * Beg )
{
    int * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_RANGE, &pArray );
    int Signed = 0; *End = *Beg = 0;
    if ( nArray == 0 )
        return 0;
    if ( nArray == 3 )
        Signed = 1;
    if ( nArray == 1 )
        *End = *Beg = pArray[0];
    else
        *End = pArray[0], *Beg = pArray[1];
    return Signed;
}
Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
{
    Ndr_Data_t * p = (Ndr_Data_t *)pData;  
    Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj;
    Wlc_Ntk_t * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, 0)+1 );
    int Mod = 0, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax = 0;
    //pNtk->pSpec = Abc_UtilStrsav( pFileName );
    Wlc_NtkCleanNameId( pNtk );
    Ndr_ModForEachPi( p, Mod, Obj )
    {
        int End, Beg, Signed = Ndr_ObjReadRange(p, Obj, &End, &Beg);
        int iObj = Wlc_ObjAlloc( pNtk, WLC_OBJ_PI, Signed, End, Beg );
        int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
        Wlc_ObjSetNameId( pNtk, iObj, NameId );
        NameIdMax = Abc_MaxInt( NameIdMax, NameId );
    }
    Ndr_ModForEachNode( p, Mod, Obj )
    {
        int End, Beg, Signed = Ndr_ObjReadRange(p, Obj, &End, &Beg);
        int Type    = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
        int nArray  = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
        Vec_Int_t F = {nArray, nArray, pArray}, * vFanins = &F;
        int iObj    = Wlc_ObjAlloc( pNtk, Ndr_TypeNdr2Wlc(Type), Signed, End, Beg );
        int NameId  = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
        Wlc_ObjAddFanins( pNtk, Wlc_NtkObj(pNtk, iObj), vFanins );
        Wlc_ObjSetNameId( pNtk, iObj, NameId );
        NameIdMax = Abc_MaxInt( NameIdMax, NameId );
    }
    Ndr_ModForEachPo( p, Mod, Obj )
    {
        int End, Beg, Signed = Ndr_ObjReadRange(p, Obj, &End, &Beg);
        int nArray  = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
        Wlc_Obj_t * pObj = Wlc_NtkObj( pNtk, pArray[0] );
        Wlc_ObjSetCo( pNtk, pObj, 0 );
        assert( nArray == 1 && End == pObj->End && Beg == pObj->Beg && Signed == (int)pObj->Signed );
    }
    // remap fanins from name IDs into object IDs
    vName2Obj = Vec_IntInvert( &pNtk->vNameIds, 0 );
    Wlc_NtkForEachObj( pNtk, pObj, i )
    {
        int * pFanins = Wlc_ObjFanins(pObj);
//        printf( "%d = ", Wlc_ObjNameId(pNtk, i) );
//        for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
//            printf( "%d ", Wlc_ObjNameId(pNtk, pFanins[k]) );
//        printf( "\n" );
        for ( k = 0; k < Wlc_ObjFaninNum(pObj); k++ )
            pFanins[k] = Vec_IntEntry(vName2Obj, pFanins[k]);
    }
    Vec_IntFree(vName2Obj);
    // create object names
    pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 );
    nDigits = Abc_Base10Log( NameIdMax+1 );
    for ( i = 1; i <= NameIdMax; i++ )
    {
        char pName[20]; sprintf( pName, "n%0*d", nDigits, i );
        NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
        assert( !fFound && i == NameId );
    }
    // derive topological order
//    pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 );
//    Wlc_NtkFree( pTemp );
    return pNtk;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Wlc_Ntk_t * Wlc_ReadNdr( char * pFileName )
{
    void * pData = Ndr_ModuleRead( pFileName );
    Wlc_Ntk_t * pNtk = Wlc_NtkFromNdr( pData );
    //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" };
    //Ndr_ModuleWriteVerilog( NULL, pData, ppNames );
    Ndr_ModuleDelete( pData );
    return pNtk;
}
void Wlc_ReadNdrTest()
{
    Wlc_Ntk_t * pNtk = Wlc_ReadNdr( "top.ndr" );
    Wlc_WriteVer( pNtk, "top.v", 0, 0 );
    Wlc_NtkFree( pNtk );
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END