#include "cycle.h" | |
#include "ace.h" | |
bool in_cycle(Abc_Ntk_t * ntk, int obj_id_to_find, Abc_Obj_t * starting_obj_ptr, | |
int flag) { | |
Ace_Obj_Info_t * info; | |
Abc_Obj_t * fanin_ptr; | |
int i; | |
info = Ace_ObjInfo(starting_obj_ptr); | |
if (info->flag == flag) { | |
return FALSE; | |
} | |
info->flag = flag; | |
/* | |
if (Abc_ObjType(starting_obj_ptr) == ABC_OBJ_PI) | |
{ | |
return FALSE; | |
} | |
*/ | |
/* Don't think this is needed since ABC can traverse through a latch like any other node | |
else if (Abc_ObjType(starting_obj_ptr) == ABC_OBJ_BO) | |
{ | |
// Get BI of latch | |
fanin_ptr = Abc_ObjFanin0(Abc_ObjFanin0(starting_obj_ptr)); | |
assert(fanin_ptr); | |
return (in_cycle(ntk, obj_id_to_find, fanin_ptr, flag)); | |
} | |
*/ | |
Abc_ObjForEachFanin(starting_obj_ptr, fanin_ptr, i) | |
{ | |
if (Abc_ObjId(fanin_ptr) == obj_id_to_find) { | |
return TRUE; | |
} | |
if (in_cycle(ntk, obj_id_to_find, fanin_ptr, flag)) { | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} | |
Vec_Ptr_t * latches_in_cycles(Abc_Ntk_t * ntk) { | |
Vec_Ptr_t * latches_in_cycles_vec; | |
Abc_Obj_t * obj_ptr; | |
Abc_Obj_t * latch_ptr; | |
int i; | |
Ace_Obj_Info_t * info; | |
int pass_num; | |
// Initialize | |
latches_in_cycles_vec = Vec_PtrStart(0); | |
Abc_NtkForEachObj(ntk, obj_ptr, i) | |
{ | |
info = Ace_ObjInfo(obj_ptr); | |
info->flag = -1; | |
} | |
pass_num = 0; | |
Abc_NtkForEachLatch(ntk, latch_ptr, i) | |
{ | |
if (in_cycle(ntk, Abc_ObjId(latch_ptr), latch_ptr, pass_num)) { | |
Vec_PtrPush(latches_in_cycles_vec, latch_ptr); | |
} | |
pass_num++; | |
} | |
return latches_in_cycles_vec; | |
} |