75 lines
1.5 KiB
C
75 lines
1.5 KiB
C
#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;
|
|
}
|