2012-07-06 17:36:23 -04:00
|
|
|
from migen.flow.hooks import *
|
2012-06-20 15:59:17 -04:00
|
|
|
|
2012-08-03 06:58:41 -04:00
|
|
|
class EndpointReporter(EndpointSimHook):
|
2012-06-20 15:59:17 -04:00
|
|
|
def __init__(self, endpoint):
|
2012-07-06 17:36:23 -04:00
|
|
|
super().__init__(endpoint)
|
2012-06-20 15:59:17 -04:00
|
|
|
self.reset()
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
self.inactive = 0
|
|
|
|
self.ack = 0
|
|
|
|
self.nack = 0
|
|
|
|
|
|
|
|
# Total number of cycles per token (inverse token rate)
|
|
|
|
def cpt(self):
|
2012-06-20 18:41:22 -04:00
|
|
|
return (self.inactive + self.nack + self.ack)/self.ack
|
2012-06-20 15:59:17 -04:00
|
|
|
|
|
|
|
# Inactivity cycles per token (slack)
|
|
|
|
def ipt(self):
|
|
|
|
return self.inactive/self.ack
|
|
|
|
|
|
|
|
# NAK cycles per token (backpressure)
|
|
|
|
def npt(self):
|
|
|
|
return self.nack/self.ack
|
|
|
|
|
|
|
|
def report_str(self):
|
|
|
|
if self.ack:
|
|
|
|
return "C/T={:.2f}\nI/T={:.2f}\nN/T={:.2f}".format(self.cpt(), self.ipt(), self.npt())
|
|
|
|
else:
|
|
|
|
return "N/A"
|
|
|
|
|
2012-07-06 17:36:23 -04:00
|
|
|
def on_ack(self):
|
|
|
|
self.ack += 1
|
|
|
|
|
|
|
|
def on_nack(self):
|
|
|
|
self.nack += 1
|
|
|
|
|
|
|
|
def on_inactive(self):
|
|
|
|
self.inactive += 1
|
2012-06-20 15:59:17 -04:00
|
|
|
|
2012-07-06 17:36:23 -04:00
|
|
|
class DFGReporter(DFGHook):
|
2012-06-20 15:59:17 -04:00
|
|
|
def __init__(self, dfg):
|
2012-07-06 17:36:23 -04:00
|
|
|
super().__init__(dfg, lambda u, ep, v: EndpointReporter(u.actor.endpoints[ep]))
|
|
|
|
|
2012-06-20 15:59:17 -04:00
|
|
|
def get_edge_labels(self):
|
|
|
|
d = dict()
|
|
|
|
for (u, v), eps in self.nodepair_to_ep.items():
|
|
|
|
if len(eps) == 1:
|
|
|
|
d[(u, v)] = list(eps.values())[0].report_str()
|
|
|
|
else:
|
|
|
|
d[(u, v)] = "\n".join(ep + ":\n" + reporter.report_str()
|
|
|
|
for ep, reporter in eps)
|
|
|
|
return d
|