This post is about poor man’s toggle coverage collector written purely in cocotb. You may ask why? and i will simply reply by with “why not?!”.

First thing is getting design signals through cocotb infrastructure. I know that signals would be of type ModifiableObject so i use dir to everything and register monitors on signal objects.

     for i in dir(tb.top):
         o = getattr(tb.top,i)
         if (isinstance(o, ModifiableObject)):
             S = SignalToggleCov(o)
             sigs.append(S)
             cocotb.start_soon(S.signal_mon())

So, what is SignalToggleCov? it’s just wrapper over cocotb handle with the signal_mon waits on signal change and compare old and new values. Not the most efficient but good enough for what i am doing.

 class SignalToggleCov:
     def __init__(self, s):
         self.sig = s
         self.toggled = [0] * len(self.sig)
 
     async def signal_mon(self):
         while True:
             old_value = f"{self.sig}"
             await Edge(self.sig)
             new_value =  f"{self.sig}"
             #print(f"signal change: {(self.sig._fullname)}:{old_value} -> {new_value}")
             for idx in range(len(self.sig)):
                 if (new_value[idx] != old_value[idx]):
                     self.toggled[idx] = 1