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): return (self.inactive + self.nack + self.ack)/self.ack # 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