Extract clock enable
From Verific Design Automation FAQ
Here is a small example which will extract clock-enables for every DFF in the design.
It uses both CheckDriverFrom() (to check if there is any potential clock-enable) as well as ExtractCondition() to actually extract the clock-enables and reorganize the logic.
Please note that this (clock-enable and set/reset extraction) is pretty dependent on the STRUCTURE of the logic. We rely on MUX2's to be there, so that data and control flow is still clearly recognizable.
MapIter mi ;
Instance *inst ;
// Extract clock-enables. (this goes best without any optimization to the netlist)
FOREACH_INSTANCE_OF_NETLIST(this, mi, inst) {
if (inst->Type() != PRIM_DFFRS && inst->Type() != PRIM_DFF) continue ;
// Go to d-input :
Net *d = inst->GetInput() ;
Net *q = inst->GetOutput() ;
if (!d) continue ;
Set check_list(POINTER_HASH) ;
// Check clock-enable extraction :
if (d->CheckDriverFrom(q, check_list)) {
// Go an extract the condition :
Net *drive_cond = 0 ;
Map drive_conditions(POINTER_HASH) ;
Map return_values(POINTER_HASH) ;
// FIX ME : We might not need to replicate the cone. Only if fanout is encountered...
Net *new_d = d->ExtractCondition(q, &drive_cond, 0/*don't need z-condition */, 1 /*replicate*/, drive_conditions, return_values) ;
if (!drive_cond) continue ; // if no feedback condition was found after all, leave circuit as-is ?
// Create a MUX with feedback loop from q :
new_d = inst->Owner()->Mux(q, new_d, drive_cond, inst->Linefile()) ;
// Replace existing d input with this new one :
Port *d_port = inst->View()->GetInput() ;
inst->Disconnect(d_port) ;
inst->Connect(d_port, new_d) ;
}
}