litex/migen/flow/perftools.py

71 lines
1.7 KiB
Python
Raw Normal View History

2012-06-20 15:59:17 -04:00
from migen.fhdl.structure import *
from migen.flow.actor import *
from migen.sim.generic import PureSimulable
class EndpointReporter(PureSimulable):
def __init__(self, endpoint):
self.endpoint = endpoint
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"
def do_simulation(self, s):
if s.rd(self.endpoint.stb):
if s.rd(self.endpoint.ack):
self.ack += 1
else:
self.nack += 1
else:
self.inactive += 1
class DFGReporter:
def __init__(self, dfg):
assert(not dfg.is_abstract())
self.nodepair_to_ep = dict()
for u, v, data in dfg.edges_iter(data=True):
if (u, v) in self.nodepair_to_ep:
ep_to_reporter = self.nodepair_to_ep[(u, v)]
else:
ep_to_reporter = dict()
self.nodepair_to_ep[(u, v)] = ep_to_reporter
ep = data["source"]
ep_to_reporter[ep] = EndpointReporter(u.actor.endpoints[ep])
def get_fragment(self):
frag = Fragment()
for v1 in self.nodepair_to_ep.values():
for v2 in v1.values():
frag += v2.get_fragment()
return frag
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