bacPrsBuild.c 13.4 KB
Newer Older
1 2
/**CFile****************************************************************

3
  FileName    [bacPrsBuild.c]
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Hierarchical word-level netlist.]

  Synopsis    [Parse tree to netlist transformation.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - November 29, 2014.]

17
  Revision    [$Id: bacPrsBuild.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
18 19 20

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

21 22
#include "bac.h"
#include "bacPrs.h"
23 24
#include "map/mio/mio.h"
#include "base/main/main.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

ABC_NAMESPACE_IMPL_START

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

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

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
47
int Psr_ManIsMapped( Psr_Ntk_t * pNtk )
48 49
{
    Vec_Int_t * vSigs; int iBox;
50
    Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
51 52
    if ( pLib == NULL )
        return 0;
53 54
    Psr_NtkForEachBox( pNtk, vSigs, iBox )
        if ( !Psr_BoxIsNode(pNtk, iBox) )
55
        {
56 57
            int NtkId = Psr_BoxNtk( pNtk, iBox );
            if ( Mio_LibraryReadGateByName(pLib, Psr_NtkStr(pNtk, NtkId), NULL) )
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
                return 1;
        }
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
74
int Psr_NtkCountObjects( Psr_Ntk_t * pNtk )
75 76
{
    Vec_Int_t * vFanins; 
77 78 79
    int i, Count = Psr_NtkObjNum(pNtk);
    Psr_NtkForEachBox( pNtk, vFanins, i )
        Count += Psr_BoxIONum(pNtk, i);
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    return Count;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
// replaces NameIds of formal names by their index in the box model
95
void Psr_ManRemapOne( Vec_Int_t * vSigs, Psr_Ntk_t * pNtkBox, Vec_Int_t * vMap )
96 97 98
{
    int i, NameId;
    // map formal names into I/O indexes
99
    Psr_NtkForEachPi( pNtkBox, NameId, i )
100 101 102 103
    {
        assert( Vec_IntEntry(vMap, NameId) == -1 );
        Vec_IntWriteEntry( vMap, NameId, i + 1 ); // +1 to keep 1st form input non-zero
    }
104
    Psr_NtkForEachPo( pNtkBox, NameId, i )
105 106
    {
        assert( Vec_IntEntry(vMap, NameId) == -1 );
107
        Vec_IntWriteEntry( vMap, NameId, Psr_NtkPiNum(pNtkBox) + i + 1 ); // +1 to keep 1st form input non-zero
108 109 110 111 112 113 114 115 116
    }
    // remap box
    assert( Vec_IntSize(vSigs) % 2 == 0 );
    Vec_IntForEachEntry( vSigs, NameId, i )
    {
        assert( Vec_IntEntry(vMap, NameId) != -1 );
        Vec_IntWriteEntry( vSigs, i++, Vec_IntEntry(vMap, NameId) );
    }
    // unmap formal inputs
117
    Psr_NtkForEachPi( pNtkBox, NameId, i )
118
        Vec_IntWriteEntry( vMap, NameId, -1 );
119
    Psr_NtkForEachPo( pNtkBox, NameId, i )
120 121
        Vec_IntWriteEntry( vMap, NameId, -1 );
}
122
void Psr_ManRemapGate( Vec_Int_t * vSigs )
123 124 125 126 127
{
    int i, FormId;
    Vec_IntForEachEntry( vSigs, FormId, i )
        Vec_IntWriteEntry( vSigs, i, i/2 + 1 ), i++;
}
128
void Psr_ManRemapBoxes( Bac_Man_t * pNew, Vec_Ptr_t * vDes, Psr_Ntk_t * pNtk, Vec_Int_t * vMap )
129 130
{
    Vec_Int_t * vSigs; int iBox;
131 132
    Psr_NtkForEachBox( pNtk, vSigs, iBox )
        if ( !Psr_BoxIsNode(pNtk, iBox) )
133
        {
134 135
            int NtkId = Psr_BoxNtk( pNtk, iBox );
            int NtkIdNew = Bac_ManNtkFindId( pNew, Psr_NtkStr(pNtk, NtkId) );
136
            assert( NtkIdNew > 0 );
137 138 139
            Psr_BoxSetNtk( pNtk, iBox, NtkIdNew );
            if ( NtkIdNew <= Bac_ManNtkNum(pNew) )
                Psr_ManRemapOne( vSigs, Psr_ManNtk(vDes, NtkIdNew-1), vMap );
140
            //else
141
            //    Psr_ManRemapGate( vSigs );
142 143
        }
}
144
void Psr_ManCleanMap( Psr_Ntk_t * pNtk, Vec_Int_t * vMap )
145 146 147
{
    Vec_Int_t * vSigs; 
    int i, k, NameId, Sig;
148
    Psr_NtkForEachPi( pNtk, NameId, i )
149
        Vec_IntWriteEntry( vMap, NameId, -1 );
150
    Psr_NtkForEachBox( pNtk, vSigs, i )
151
        Vec_IntForEachEntryDouble( vSigs, NameId, Sig, k )
152 153
            Vec_IntWriteEntry( vMap, Psr_NtkSigName(pNtk, Sig), -1 );
    Psr_NtkForEachPo( pNtk, NameId, i )
154 155 156
        Vec_IntWriteEntry( vMap, NameId, -1 );
}
// create maps of NameId and boxes
157
void Psr_ManBuildNtk( Bac_Ntk_t * pNew, Vec_Ptr_t * vDes, Psr_Ntk_t * pNtk, Vec_Int_t * vMap, Vec_Int_t * vBoxes )
158
{
159
    Psr_Ntk_t * pNtkBox; Vec_Int_t * vSigs; int iBox;
160 161
    int i, Index, NameId, iObj, iConst0, iTerm;
    int iNonDriven = -1, nNonDriven = 0;
162 163 164
    assert( Psr_NtkPioNum(pNtk) == 0 );
    Psr_ManRemapBoxes( pNew->pDesign, vDes, pNtk, vMap );
    Bac_NtkStartNames( pNew );
165
    // create primary inputs 
166
    Psr_NtkForEachPi( pNtk, NameId, i )
167 168 169
    {
        if ( Vec_IntEntry(vMap, NameId) != -1 )
            printf( "Primary inputs %d and %d have the same name.\n", Vec_IntEntry(vMap, NameId), i );
170 171
        iObj = Bac_ObjAlloc( pNew, BAC_OBJ_PI, -1 );
        Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(NameId, BAC_NAME_BIN) );
172 173 174 175
        Vec_IntWriteEntry( vMap, NameId, iObj );
    }
    // create box outputs
    Vec_IntClear( vBoxes );
176 177
    Psr_NtkForEachBox( pNtk, vSigs, iBox )
        if ( !Psr_BoxIsNode(pNtk, iBox) )
178
        {
179
            pNtkBox = Psr_ManNtk( vDes, Psr_BoxNtk(pNtk, iBox)-1 );
180
            if ( pNtkBox == NULL )
181
            {
182 183
                iObj = Bac_BoxAlloc( pNew, BAC_BOX_GATE, Vec_IntSize(vSigs)/2-1, 1, Psr_BoxNtk(pNtk, iBox) );
                Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(Psr_BoxName(pNtk, iBox), BAC_NAME_BIN) );
184
                // consider box output 
185
                NameId = Vec_IntEntryLast( vSigs );
186
                NameId = Psr_NtkSigName( pNtk, NameId );
187 188
                if ( Vec_IntEntry(vMap, NameId) != -1 )
                    printf( "Box output name %d is already driven.\n", NameId );
189 190
                iTerm = Bac_BoxBo( pNew, iObj, 0 );
                Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) );
191 192
                Vec_IntWriteEntry( vMap, NameId, iTerm );
            }
193 194
            else
            {
195 196 197
                iObj = Bac_BoxAlloc( pNew, BAC_OBJ_BOX, Psr_NtkPiNum(pNtkBox), Psr_NtkPoNum(pNtkBox), Psr_BoxNtk(pNtk, iBox) );
                Bac_ObjSetName( pNew, iObj, Abc_Var2Lit2(Psr_BoxName(pNtk, iBox), BAC_NAME_BIN) );
                Bac_NtkSetHost( Bac_ManNtk(pNew->pDesign, Psr_BoxNtk(pNtk, iBox)), Bac_NtkId(pNew), iObj );
198 199 200
                Vec_IntForEachEntry( vSigs, Index, i )
                {
                    i++;
201
                    if ( --Index < Psr_NtkPiNum(pNtkBox) )
202
                        continue;
203
                    assert( Index - Psr_NtkPiNum(pNtkBox) < Psr_NtkPoNum(pNtkBox) );
204 205
                    // consider box output 
                    NameId = Vec_IntEntry( vSigs, i );
206
                    NameId = Psr_NtkSigName( pNtk, NameId );
207 208
                    if ( Vec_IntEntry(vMap, NameId) != -1 )
                        printf( "Box output name %d is already driven.\n", NameId );
209 210
                    iTerm = Bac_BoxBo( pNew, iObj, Index - Psr_NtkPiNum(pNtkBox) );
                    Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) );
211 212 213
                    Vec_IntWriteEntry( vMap, NameId, iTerm );
                }
            }
214 215 216 217 218
            // remember box
            Vec_IntPush( vBoxes, iObj );
        }
        else
        {
219
            iObj = Bac_BoxAlloc( pNew, (Bac_ObjType_t)Psr_BoxNtk(pNtk, iBox), Psr_BoxIONum(pNtk, iBox)-1, 1, -1 );
220 221
            // consider box output 
            NameId = Vec_IntEntryLast( vSigs );
222
            NameId = Psr_NtkSigName( pNtk, NameId );
223 224
            if ( Vec_IntEntry(vMap, NameId) != -1 )
                printf( "Node output name %d is already driven.\n", NameId );
225 226
            iTerm = Bac_BoxBo( pNew, iObj, 0 );
            Bac_ObjSetName( pNew, iTerm, Abc_Var2Lit2(NameId, BAC_NAME_BIN) );
227 228 229 230 231
            Vec_IntWriteEntry( vMap, NameId, iTerm );
            // remember box
            Vec_IntPush( vBoxes, iObj );
        }
    // add fanins for box inputs
232 233
    Psr_NtkForEachBox( pNtk, vSigs, iBox )
        if ( !Psr_BoxIsNode(pNtk, iBox) )
234
        {
235
            pNtkBox = Psr_ManNtk( vDes, Psr_BoxNtk(pNtk, iBox)-1 );
236
            iObj = Vec_IntEntry( vBoxes, iBox );
237
            if ( pNtkBox == NULL )
238
            {
239
                Vec_IntForEachEntryStop( vSigs, Index, i, Vec_IntSize(vSigs)-2 )
240
                {
241 242
                    i++;
                    NameId = Vec_IntEntry( vSigs, i );
243 244
                    NameId = Psr_NtkSigName( pNtk, NameId );
                    iTerm = Bac_BoxBi( pNew, iObj, i/2 );
245 246
                    if ( Vec_IntEntry(vMap, NameId) == -1 )
                    {
247
                        iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 );
248 249 250 251 252
                        Vec_IntWriteEntry( vMap, NameId, iConst0+1 );
                        if ( iNonDriven == -1 )
                            iNonDriven = NameId;
                        nNonDriven++;
                    }
253
                    Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) );
254 255 256 257 258 259 260
                }
            }
            else
            {
                Vec_IntForEachEntry( vSigs, Index, i )
                {
                    i++;
261
                    if ( --Index >= Psr_NtkPiNum(pNtkBox) )
262 263
                        continue;
                    NameId = Vec_IntEntry( vSigs, i );
264 265
                    NameId = Psr_NtkSigName( pNtk, NameId );
                    iTerm = Bac_BoxBi( pNew, iObj, Index );
266 267
                    if ( Vec_IntEntry(vMap, NameId) == -1 )
                    {
268
                        iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 );
269 270 271 272 273
                        Vec_IntWriteEntry( vMap, NameId, iConst0+1 );
                        if ( iNonDriven == -1 )
                            iNonDriven = NameId;
                        nNonDriven++;
                    }
274
                    Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) );
275 276 277 278 279 280 281 282 283
                }
            }
        }
        else
        {
            iObj = Vec_IntEntry( vBoxes, iBox );
            Vec_IntForEachEntryStop( vSigs, Index, i, Vec_IntSize(vSigs)-2 )
            {
                NameId = Vec_IntEntry( vSigs, ++i );
284 285
                NameId = Psr_NtkSigName( pNtk, NameId );
                iTerm = Bac_BoxBi( pNew, iObj, i/2 );
286 287
                if ( Vec_IntEntry(vMap, NameId) == -1 )
                {
288
                    iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 );
289 290 291 292 293
                    Vec_IntWriteEntry( vMap, NameId, iConst0+1 );
                    if ( iNonDriven == -1 )
                        iNonDriven = NameId;
                    nNonDriven++;
                }
294
                Bac_ObjSetFanin( pNew, iTerm, Vec_IntEntry(vMap, NameId) );
295 296 297
            }
        }
    // add fanins for primary outputs
298
    Psr_NtkForEachPo( pNtk, NameId, i )
299 300
        if ( Vec_IntEntry(vMap, NameId) == -1 )
        {
301
            iConst0 = Bac_BoxAlloc( pNew, BAC_BOX_CF, 0, 1, -1 );
302 303 304 305 306
            Vec_IntWriteEntry( vMap, NameId, iConst0+1 );
            if ( iNonDriven == -1 )
                iNonDriven = NameId;
            nNonDriven++;
        }
307 308
    Psr_NtkForEachPo( pNtk, NameId, i )
        iObj = Bac_ObjAlloc( pNew, BAC_OBJ_PO, Vec_IntEntry(vMap, NameId) );
309
    if ( nNonDriven )
310 311
        printf( "Module %s has %d non-driven nets (for example, %s).\n", Psr_NtkName(pNtk), nNonDriven, Psr_NtkStr(pNtk, iNonDriven) );
    Psr_ManCleanMap( pNtk, vMap );
312 313
    // setup info
    Vec_IntForEachEntry( &pNtk->vOrder, NameId, i )
314
        Bac_NtkAddInfo( pNew, NameId, -1, -1 );
315 316 317 318 319 320 321 322 323 324 325 326 327
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
328
Bac_Man_t * Psr_ManBuildCba( char * pFileName, Vec_Ptr_t * vDes )
329
{
330 331
    Psr_Ntk_t * pNtk = Psr_ManRoot( vDes );  int i;
    Bac_Man_t * pNew = Bac_ManAlloc( pFileName, Vec_PtrSize(vDes) );
332
    Vec_Int_t * vMap = Vec_IntStartFull( Abc_NamObjNumMax(pNtk->pStrs) + 1 );
333
    Vec_Int_t * vTmp = Vec_IntAlloc( Psr_NtkBoxNum(pNtk) );
334 335
    Abc_NamDeref( pNew->pStrs );
    pNew->pStrs = Abc_NamRef( pNtk->pStrs );  
336 337 338 339
    Vec_PtrForEachEntry( Psr_Ntk_t *, vDes, pNtk, i )
        Bac_NtkAlloc( Bac_ManNtk(pNew, i+1), Psr_NtkId(pNtk), Psr_NtkPiNum(pNtk), Psr_NtkPoNum(pNtk), Psr_NtkCountObjects(pNtk) );
    if ( (pNtk->fMapped || (pNtk->fSlices && Psr_ManIsMapped(pNtk))) && !Bac_NtkBuildLibrary(pNew) )
        Bac_ManFree(pNew), pNew = NULL;
340
    else 
341 342
        Vec_PtrForEachEntry( Psr_Ntk_t *, vDes, pNtk, i )
            Psr_ManBuildNtk( Bac_ManNtk(pNew, i+1), vDes, pNtk, vMap, vTmp );
343 344 345
    assert( Vec_IntCountEntry(vMap, -1) == Vec_IntSize(vMap) );
    Vec_IntFree( vMap );
    Vec_IntFree( vTmp );
346
//    Vec_StrPrint( &Bac_ManNtk(pNew, 1)->vType, 1 );
347 348 349 350 351 352 353 354 355 356
    return pNew;
}

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


ABC_NAMESPACE_IMPL_END