saigRetStep.c 7.22 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/**CFile****************************************************************

  FileName    [saigRetStep.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Sequential AIG package.]

  Synopsis    [Implementation of retiming steps.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

  Revision    [$Id: saigRetStep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

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

#include "saig.h"

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

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

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

  Synopsis    [Performs one retiming step forward.]

  Description [Returns the pointer to the register output after retiming.]
               
40
  SideEffects [Remember to run Aig_ManSetCioIds() in advance.]
Alan Mishchenko committed
41 42 43 44

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
45
Aig_Obj_t * Saig_ManRetimeNodeFwd( Aig_Man_t * p, Aig_Obj_t * pObj, int fMakeBug )
Alan Mishchenko committed
46 47 48 49
{
    Aig_Obj_t * pFanin0, * pFanin1;
    Aig_Obj_t * pInput0, * pInput1;
    Aig_Obj_t * pObjNew, * pObjLi, * pObjLo;
Alan Mishchenko committed
50
    int fCompl;
Alan Mishchenko committed
51 52 53 54 55 56 57 58

    assert( Saig_ManRegNum(p) > 0 );
    assert( Aig_ObjIsNode(pObj) );

    // get the fanins
    pFanin0 = Aig_ObjFanin0(pObj);
    pFanin1 = Aig_ObjFanin1(pObj);
    // skip of they are not primary inputs
59
    if ( !Aig_ObjIsCi(pFanin0) || !Aig_ObjIsCi(pFanin1) )
Alan Mishchenko committed
60 61 62 63 64
        return NULL;

    // skip of they are not register outputs
    if ( !Saig_ObjIsLo(p, pFanin0) || !Saig_ObjIsLo(p, pFanin1) )
        return NULL;
65 66
    assert( Aig_ObjCioId(pFanin0) > 0 );
    assert( Aig_ObjCioId(pFanin1) > 0 );
Alan Mishchenko committed
67

Alan Mishchenko committed
68 69 70 71
    // skip latch guns
    if ( !Aig_ObjIsTravIdCurrent(p, pFanin0) && !Aig_ObjIsTravIdCurrent(p, pFanin1) )
        return NULL;

Alan Mishchenko committed
72
    // get the inputs of these registers
73 74
    pInput0 = Saig_ManLi( p, Aig_ObjCioId(pFanin0) - Saig_ManPiNum(p) );
    pInput1 = Saig_ManLi( p, Aig_ObjCioId(pFanin1) - Saig_ManPiNum(p) );
Alan Mishchenko committed
75 76 77 78
    pInput0 = Aig_ObjChild0( pInput0 );
    pInput1 = Aig_ObjChild0( pInput1 );
    pInput0 = Aig_NotCond( pInput0, Aig_ObjFaninC0(pObj) );
    pInput1 = Aig_NotCond( pInput1, Aig_ObjFaninC1(pObj) );
Alan Mishchenko committed
79 80
    // get the condition when the register should be complemetned
    fCompl = Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj);
Alan Mishchenko committed
81

Alan Mishchenko committed
82 83 84 85 86 87
    if ( fMakeBug )
    {
        printf( "Introducing bug during retiming.\n" );
        pInput1 = Aig_Not( pInput1 );
    }

Alan Mishchenko committed
88 89 90 91
    // create new node
    pObjNew = Aig_And( p, pInput0, pInput1 );

    // create new register input
92
    pObjLi = Aig_ObjCreateCo( p, Aig_NotCond(pObjNew, fCompl) );
93
    pObjLi->CioId = Aig_ManCoNum(p) - 1;
Alan Mishchenko committed
94 95

    // create new register output
96
    pObjLo = Aig_ObjCreateCi( p );
97
    pObjLo->CioId = Aig_ManCiNum(p) - 1;
Alan Mishchenko committed
98 99
    p->nRegs++;

Alan Mishchenko committed
100 101 102
    // make sure the register is retimable.
    Aig_ObjSetTravIdCurrent(p, pObjLo);

Alan Mishchenko committed
103 104 105
//printf( "Reg = %4d. Reg = %4d. Compl = %d. Phase = %d.\n", 
//       pFanin0->PioNum, pFanin1->PioNum, Aig_IsComplement(pObjNew), fCompl );

Alan Mishchenko committed
106
    // return register output
Alan Mishchenko committed
107
    return Aig_NotCond( pObjLo, fCompl );
Alan Mishchenko committed
108 109 110 111 112 113 114 115
}

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

  Synopsis    [Performs one retiming step backward.]

  Description [Returns the pointer to node after retiming.]
               
116
  SideEffects [Remember to run Aig_ManSetCioIds() in advance.]
Alan Mishchenko committed
117 118 119 120 121 122 123 124 125 126 127 128 129

  SeeAlso     []

***********************************************************************/
Aig_Obj_t * Saig_ManRetimeNodeBwd( Aig_Man_t * p, Aig_Obj_t * pObjLo )
{
    Aig_Obj_t * pFanin0, * pFanin1;
    Aig_Obj_t * pLo0New, * pLo1New;
    Aig_Obj_t * pLi0New, * pLi1New;
    Aig_Obj_t * pObj, * pObjNew, * pObjLi;
    int fCompl0, fCompl1;

    assert( Saig_ManRegNum(p) > 0 );
130
    assert( Aig_ObjCioId(pObjLo) > 0 );
Alan Mishchenko committed
131 132 133
    assert( Saig_ObjIsLo(p, pObjLo) );

    // get the corresponding latch input
134
    pObjLi = Saig_ManLi( p, Aig_ObjCioId(pObjLo) - Saig_ManPiNum(p) );
Alan Mishchenko committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

    // get the node
    pObj = Aig_ObjFanin0(pObjLi);
    if ( !Aig_ObjIsNode(pObj) )
        return NULL;

    // get the fanins
    pFanin0 = Aig_ObjFanin0(pObj);
    pFanin1 = Aig_ObjFanin1(pObj);

    // get the complemented attributes of the fanins
    fCompl0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFaninC0(pObjLi);
    fCompl1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFaninC0(pObjLi);

    // create latch inputs
150
    pLi0New = Aig_ObjCreateCo( p, Aig_NotCond(pFanin0, fCompl0) );
151
    pLi0New->CioId = Aig_ManCoNum(p) - 1;
152
    pLi1New = Aig_ObjCreateCo( p, Aig_NotCond(pFanin1, fCompl1) );
153
    pLi1New->CioId = Aig_ManCoNum(p) - 1;
Alan Mishchenko committed
154 155

    // create latch outputs
156
    pLo0New = Aig_ObjCreateCi(p);
157
    pLo0New->CioId = Aig_ManCiNum(p) - 1;
158
    pLo1New = Aig_ObjCreateCi(p);
159
    pLo1New->CioId = Aig_ManCiNum(p) - 1;
Alan Mishchenko committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
    pLo0New = Aig_NotCond( pLo0New, fCompl0 );
    pLo1New = Aig_NotCond( pLo1New, fCompl1 );
    p->nRegs += 2;

    // create node
    pObjNew = Aig_And( p, pLo0New, pLo1New );
//    assert( pObjNew->fPhase == 0 );
    return pObjNew;
}

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

  Synopsis    [Performs the given number of retiming steps.]

  Description [Returns the pointer to node after retiming.]
               
176
  SideEffects [Remember to run Aig_ManSetCioIds() in advance.]
Alan Mishchenko committed
177 178 179 180

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
181
int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs )
Alan Mishchenko committed
182 183 184
{
    Aig_Obj_t * pObj, * pObjNew;
    int RetValue, s, i;
185
    Aig_ManSetCioIds( p );
Alan Mishchenko committed
186
    Aig_ManFanoutStart( p );
Alan Mishchenko committed
187
    p->fCreatePios = 1;
Alan Mishchenko committed
188 189
    if ( fForward )
    {
Alan Mishchenko committed
190
        Saig_ManMarkAutonomous( p );
Alan Mishchenko committed
191 192 193 194
        for ( s = 0; s < nSteps; s++ )
        {
            Aig_ManForEachNode( p, pObj, i )
            {
Alan Mishchenko committed
195 196
                pObjNew = Saig_ManRetimeNodeFwd( p, pObj, fAddBugs && (s == 10) );
//                pObjNew = Saig_ManRetimeNodeFwd( p, pObj, 0 );
Alan Mishchenko committed
197 198
                if ( pObjNew == NULL )
                    continue;
Alan Mishchenko committed
199
                Aig_ObjReplace( p, pObj, pObjNew, 0 );
Alan Mishchenko committed
200 201
                break;
            }
Alan Mishchenko committed
202 203
            if ( i == Vec_PtrSize(p->vObjs) )
                break;
Alan Mishchenko committed
204 205 206 207 208 209 210 211 212 213 214
        }
    }
    else
    {
        for ( s = 0; s < nSteps; s++ )
        {
            Saig_ManForEachLo( p, pObj, i )
            {
                pObjNew = Saig_ManRetimeNodeBwd( p, pObj );
                if ( pObjNew == NULL )
                    continue;
Alan Mishchenko committed
215
                Aig_ObjReplace( p, pObj, pObjNew, 0 );
Alan Mishchenko committed
216 217
                break;
            }
Alan Mishchenko committed
218 219
            if ( i == Vec_PtrSize(p->vObjs) )
                break;
Alan Mishchenko committed
220 221
        }
    }
Alan Mishchenko committed
222 223
    p->fCreatePios = 0;
    Aig_ManFanoutStop( p );
Alan Mishchenko committed
224 225
    RetValue = Aig_ManCleanup( p );
    assert( RetValue == 0 );
Alan Mishchenko committed
226
    Aig_ManSetRegNum( p, p->nRegs ); 
Alan Mishchenko committed
227
    return s;
Alan Mishchenko committed
228 229 230 231 232 233 234
}

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


235 236
ABC_NAMESPACE_IMPL_END