ntlCheck.c 11.1 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**CFile****************************************************************

  FileName    [ntlCheck.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Netlist representation.]

  Synopsis    [Checks consistency of the netlist.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

Alan Mishchenko committed
17
  Revision    [$Id: ntlCheck.c,v 1.1 2008/10/10 14:09:29 mjarvin Exp $]
Alan Mishchenko committed
18 19 20 21 22 23

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

#include "ntl.h"
#include "aig.h"

24 25 26
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
27 28 29 30 31 32 33 34 35 36
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

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

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

Alan Mishchenko committed
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
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ntl_ModelCheckCombPoPaths_rec( Ntl_Mod_t * pModel, Ntl_Net_t * pNet )
{
    Ntl_Net_t * pFanin;
    int i;
    // skip visited nets
    if ( pNet->nVisits == 2 ) 
        return 1;
    pNet->nVisits = 2;
    // process PIs
    if ( Ntl_ObjIsPi(pNet->pDriver) )
        return 0;
    // process registers
    if ( Ntl_ObjIsLatch(pNet->pDriver) )
        return 1;
    assert( Ntl_ObjIsNode(pNet->pDriver) );
    // call recursively
    Ntl_ObjForEachFanin( pNet->pDriver, pFanin, i )
        if ( !Ntl_ModelCheckCombPoPaths_rec( pModel, pFanin ) )
            return 0;
    return 1;
}

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

  Synopsis    [Checks the existence of combinational paths from POs to PIs.]

  Description [Returns 0 if the path is found.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ntl_ModelCheckCombPoPaths( Ntl_Mod_t * pModel )
{
    Ntl_Obj_t * pObj;
    int i;
    Ntl_ModelClearNets( pModel );
    Ntl_ModelForEachPo( pModel, pObj, i )
        if ( !Ntl_ModelCheckCombPoPaths_rec( pModel, Ntl_ObjFanin0(pObj) ) )
            return 0;
    return 1;
}

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

Alan Mishchenko committed
92
  Synopsis    [Checks one model.]
Alan Mishchenko committed
93 94 95 96 97 98 99 100

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
101
int Ntl_ModelCheck( Ntl_Mod_t * pModel, int fMain )
Alan Mishchenko committed
102
{
Alan Mishchenko committed
103 104 105
    Ntl_Obj_t * pObj;
    Ntl_Net_t * pNet;
    int i, k, fStatus = 1;
Alan Mishchenko committed
106 107 108 109 110 111

    // check root level model
    if ( fMain )
    {
        if ( Ntl_ModelLatchNum(pModel) > 0 )
        {
Alan Mishchenko committed
112
            printf( "Root level model %s has %d registers.\n", pModel->pName, Ntl_ModelLatchNum(pModel) );
Alan Mishchenko committed
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
            fStatus = 0;
        }
        goto checkobjs;
    }

    // check delay information
    if ( pModel->attrBox && pModel->attrComb )
    {
        if ( pModel->vDelays == NULL )
        {
            printf( "Warning: Comb model %s does not have delay info. Default 1.0 delays are assumed.\n", pModel->pName );
            pModel->vDelays = Vec_IntAlloc( 3 );
            Vec_IntPush( pModel->vDelays, -1 );
            Vec_IntPush( pModel->vDelays, -1 );
            Vec_IntPush( pModel->vDelays, Aig_Float2Int(1.0) );        
        }
        if ( pModel->vTimeInputs != NULL )
        {
            printf( "Combinational model %s has input arrival/required time information.\n", pModel->pName );
            fStatus = 0;
        }
        if ( pModel->vTimeOutputs != NULL )
        {
            printf( "Combinational model %s has output arrival/required time information.\n", pModel->pName );
            fStatus = 0;
        }
    }
    if ( pModel->attrBox && !pModel->attrComb )
    {
        if ( pModel->vDelays != NULL )
        {
            printf( "Sequential model %s has delay info.\n", pModel->pName );
            fStatus = 0;
        }
        if ( pModel->vTimeInputs == NULL )
        {
            printf( "Warning: Seq model %s does not have input arrival/required time info. Default 0.0 is assumed.\n", pModel->pName );
            pModel->vTimeInputs = Vec_IntAlloc( 2 );
            Vec_IntPush( pModel->vTimeInputs, -1 );
Alan Mishchenko committed
152
            Vec_IntPush( pModel->vTimeInputs, Aig_Float2Int(0.0) );        
Alan Mishchenko committed
153 154 155
        }
        if ( pModel->vTimeOutputs == NULL )
        {
Alan Mishchenko committed
156
//            printf( "Warning: Seq model %s does not have output arrival/required time info. Default 0.0 is assumed.\n", pModel->pName );
Alan Mishchenko committed
157 158
            pModel->vTimeOutputs = Vec_IntAlloc( 2 );
            Vec_IntPush( pModel->vTimeOutputs, -1 );
Alan Mishchenko committed
159
            Vec_IntPush( pModel->vTimeOutputs, Aig_Float2Int(0.0) );        
Alan Mishchenko committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
        }
    }

    // check box attributes
    if ( pModel->attrBox )
    {
        if ( !pModel->attrWhite )
        {
            if ( Ntl_ModelNodeNum(pModel) + Ntl_ModelLut1Num(pModel) > 0 )
            {
                printf( "Model %s is a blackbox, yet it has %d nodes.\n", pModel->pName, Ntl_ModelNodeNum(pModel) + Ntl_ModelLut1Num(pModel) );
                fStatus = 0;
            }
            if ( Ntl_ModelLatchNum(pModel) > 0 )
            {
                printf( "Model %s is a blackbox, yet it has %d registers.\n", pModel->pName, Ntl_ModelLatchNum(pModel) );
                fStatus = 0;
            }
            return fStatus;
        }
        // this is a white box
        if ( pModel->attrComb && Ntl_ModelNodeNum(pModel) + Ntl_ModelLut1Num(pModel) == 0 )
        {
Alan Mishchenko committed
183 184 185 186 187 188
            printf( "Model %s is a comb white box, yet it has no nodes.\n", pModel->pName );
            fStatus = 0;
        }
        if ( pModel->attrComb && Ntl_ModelLatchNum(pModel) > 0 )
        {
            printf( "Model %s is a comb white box, yet it has registers.\n", pModel->pName );
Alan Mishchenko committed
189 190 191 192
            fStatus = 0;
        }
        if ( !pModel->attrComb && Ntl_ModelLatchNum(pModel) == 0 )
        {
Alan Mishchenko committed
193 194 195 196 197 198
            printf( "Model %s is a seq white box, yet it has no registers.\n", pModel->pName );
            fStatus = 0;
        }
        if ( !pModel->attrComb && !Ntl_ModelCheckCombPoPaths(pModel) )
        {
            printf( "Model %s is a seq white box with comb paths from PIs to POs.\n", pModel->pName );
Alan Mishchenko committed
199 200 201 202 203 204
            fStatus = 0;
        }
    }

checkobjs:
    // check nets
Alan Mishchenko committed
205 206 207 208
    Ntl_ModelForEachNet( pModel, pNet, i )
    {
        if ( pNet->pName == NULL )
        {
Alan Mishchenko committed
209
            printf( "Net in bin %d does not have a name\n", i );
Alan Mishchenko committed
210 211
            fStatus = 0;
        }
Alan Mishchenko committed
212
/*
Alan Mishchenko committed
213 214
        if ( pNet->pDriver == NULL )
        {
Alan Mishchenko committed
215
            printf( "Net %s does not have a driver\n", pNet->pName );
Alan Mishchenko committed
216 217
            fStatus = 0;
        }
Alan Mishchenko committed
218
*/
Alan Mishchenko committed
219
    }
Alan Mishchenko committed
220 221

    // check objects
Alan Mishchenko committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    Ntl_ModelForEachObj( pModel, pObj, i )
    {
        Ntl_ObjForEachFanin( pObj, pNet, k )
            if ( pNet == NULL )
            {
                printf( "Object %d does not have fanin net %d\n", i, k );
                fStatus = 0;
            }
        Ntl_ObjForEachFanout( pObj, pNet, k )
            if ( pNet == NULL )
            {
                printf( "Object %d does not have fanout net %d\n", i, k );
                fStatus = 0;
            }
    }
    return fStatus;
Alan Mishchenko committed
238 239 240 241
}

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

Alan Mishchenko committed
242
  Synopsis    [Checks the netlist.]
Alan Mishchenko committed
243 244 245 246 247 248 249 250

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
251
int Ntl_ManCheck( Ntl_Man_t * pMan )
Alan Mishchenko committed
252
{
Alan Mishchenko committed
253 254
    Ntl_Mod_t * pMod1;
    int i, fStatus = 1;
Alan Mishchenko committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
    // check that the models have unique names
    Ntl_ManForEachModel( pMan, pMod1, i )
    {
        if ( pMod1->pName == NULL )
        {
            printf( "Model %d does not have a name\n", i );
            fStatus = 0;
        }
    }
    // check that the models (except the first one) do not have boxes
    Ntl_ManForEachModel( pMan, pMod1, i )
    {
        if ( i == 0 )
            continue;
        if ( Ntl_ModelBoxNum(pMod1) > 0 )
        {
            printf( "Non-root model %d (%s) has %d boxes.\n", i, pMod1->pName, Ntl_ModelBoxNum(pMod1) );
            fStatus = 0;
        }
    }
    // check models
    Ntl_ManForEachModel( pMan, pMod1, i )
Alan Mishchenko committed
277
    {
Alan Mishchenko committed
278
        if ( !Ntl_ModelCheck( pMod1, i==0 ) )
Alan Mishchenko committed
279
            fStatus = 0;
Alan Mishchenko committed
280
    }
Alan Mishchenko committed
281
    return fStatus;
Alan Mishchenko committed
282 283 284 285 286
}


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

Alan Mishchenko committed
287
  Synopsis    [Fixed problems with non-driven nets in the model.]
Alan Mishchenko committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel )
{ 
    Vec_Ptr_t * vNets;
    Ntl_Net_t * pNet;
    Ntl_Obj_t * pNode;
    int i;

Alan Mishchenko committed
303
    if ( !pModel->attrWhite )
Alan Mishchenko committed
304 305 306 307 308 309 310 311 312 313
        return;

    // check for non-driven nets
    vNets = Vec_PtrAlloc( 100 );
    Ntl_ModelForEachNet( pModel, pNet, i )
    {
        if ( pNet->pDriver != NULL )
            continue;
        // add the constant 0 driver
        pNode = Ntl_ModelCreateNode( pModel, 0 );
Alan Mishchenko committed
314
        pNode->pSop = Ntl_ManStoreSop( pModel->pMan->pMemSops, " 0\n" );
Alan Mishchenko committed
315 316 317 318 319
        Ntl_ModelSetNetDriver( pNode, pNet );
        // add the net to those for which the warning will be printed
        Vec_PtrPush( vNets, pNet );
    }

Alan Mishchenko committed
320
#if 0  // sjang
Alan Mishchenko committed
321 322 323
    // print the warning
    if ( Vec_PtrSize(vNets) > 0 )
    {
Alan Mishchenko committed
324
        printf( "Warning: Constant-0 drivers added to %d non-driven nets in network \"%s\": ", Vec_PtrSize(vNets), pModel->pName );
325
        Vec_PtrForEachEntry( Ntl_Net_t *, vNets, pNet, i )
Alan Mishchenko committed
326 327 328 329 330 331 332 333 334 335 336
        {
            printf( "%s%s", (i? ", ": ""), pNet->pName );
            if ( i == 3 )
            {
                if ( Vec_PtrSize(vNets) > 3 )
                    printf( " ..." );
                break;
            }
        }
        printf( "\n" );
    }
Alan Mishchenko committed
337
#endif
Alan Mishchenko committed
338 339 340
    Vec_PtrFree( vNets );
}

Alan Mishchenko committed
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
/**Function*************************************************************

  Synopsis    [Fixed problems with non-driven nets in the model.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ntl_ModelTransformLatches( Ntl_Mod_t * pModel )
{ 
    Ntl_Mod_t * pMod[3] = { NULL };
    Ntl_Obj_t * pLatch;
    int i, Init;
    if ( Ntl_ModelLatchNum(pModel) == 0 )
        return;
    Ntl_ModelForEachLatch( pModel, pLatch, i )
    {
        Init = pLatch->LatchId.regInit;
        if ( pMod[Init] == NULL )
            pMod[Init] = Ntl_ManCreateLatchModel( pModel->pMan, Init );
        pLatch->pImplem = pMod[Init];
        pLatch->Type = NTL_OBJ_BOX;
    }
Alan Mishchenko committed
367
    printf( "In the main model \"%s\", %d latches are transformed into white seq boxes.\n", pModel->pName, Ntl_ModelLatchNum(pModel) );
Alan Mishchenko committed
368 369 370 371
    pModel->nObjs[NTL_OBJ_BOX] += Ntl_ModelLatchNum(pModel);
    pModel->nObjs[NTL_OBJ_LATCH] = 0;
}

Alan Mishchenko committed
372 373 374 375 376 377

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


378 379
ABC_NAMESPACE_IMPL_END