From: Sebastien Bourdeauducq Date: Sat, 2 Nov 2013 15:03:47 +0000 (+0100) Subject: replace use of __dict__ with dir()/xdir() X-Git-Tag: 24jan2021_ls180~2099^2~454 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f658802ff830f2638850e11bcb566cf6f79e447d;p=litex.git replace use of __dict__ with dir()/xdir() --- diff --git a/migen/bank/csrgen.py b/migen/bank/csrgen.py index 320b3ec0..9be01cb0 100644 --- a/migen/bank/csrgen.py +++ b/migen/bank/csrgen.py @@ -1,5 +1,4 @@ -from operator import itemgetter - +from migen.util.misc import xdir from migen.fhdl.std import * from migen.bus import csr from migen.bank.description import * @@ -69,7 +68,7 @@ class BankArray(Module): def scan(self, ifargs, ifkwargs): self.banks = [] self.srams = [] - for name, obj in sorted(self.source.__dict__.items(), key=itemgetter(0)): + for name, obj in xdir(self.source, True): if hasattr(obj, "get_csrs"): csrs = obj.get_csrs() else: diff --git a/migen/bank/description.py b/migen/bank/description.py index 5afbfdf1..8632dd2c 100644 --- a/migen/bank/description.py +++ b/migen/bank/description.py @@ -1,3 +1,4 @@ +from migen.util.misc import xdir from migen.fhdl.std import * from migen.fhdl.tracer import get_obj_var_name @@ -107,7 +108,7 @@ class AutoCSR: except AttributeError: prefixed = self.__prefixed = set() r = [] - for k, v in self.__dict__.items(): + for k, v in xdir(self, True): if k not in exclude: if isinstance(v, Memory): r.append(v) @@ -127,7 +128,7 @@ class AutoCSR: except AttributeError: prefixed = self.__prefixed = set() r = [] - for k, v in self.__dict__.items(): + for k, v in xdir(self, True): if k not in exclude: if isinstance(v, _CSRBase): r.append(v) diff --git a/migen/bank/eventmanager.py b/migen/bank/eventmanager.py index 9c9aa423..8cd47a7e 100644 --- a/migen/bank/eventmanager.py +++ b/migen/bank/eventmanager.py @@ -1,3 +1,4 @@ +from migen.util.misc import xdir from migen.fhdl.std import * from migen.bank.description import * from migen.genlib.misc import optree @@ -46,7 +47,7 @@ class EventManager(Module, AutoCSR): self.irq = Signal() def do_finalize(self): - sources_u = [v for v in self.__dict__.values() if isinstance(v, _EventSource)] + sources_u = [v for k, v in xdir(self, True) if isinstance(v, _EventSource)] sources = sorted(sources_u, key=lambda x: x.huid) n = len(sources) self.status = CSR(n) diff --git a/migen/fhdl/decorators.py b/migen/fhdl/decorators.py index 7c7efe16..03318bc0 100644 --- a/migen/fhdl/decorators.py +++ b/migen/fhdl/decorators.py @@ -20,6 +20,9 @@ class ModuleDecorator: self.transform_fragment(f) return f + def __dir__(self): + return dir(self._md_decorated) + class DecorateModule: def __init__(self, decorator, *dec_args, **dec_kwargs): self.decorator = decorator diff --git a/migen/fhdl/namer.py b/migen/fhdl/namer.py index ba24cf3b..1cfcf2ea 100644 --- a/migen/fhdl/namer.py +++ b/migen/fhdl/namer.py @@ -12,7 +12,7 @@ class _Node: self.children = OrderedDict() def _display_tree(filename, tree): - from migen.graph.treeviz import RenderNode + from migen.util.treeviz import RenderNode def _to_render_node(name, node): children = [_to_render_node(k, v) for k, v in node.children.items()] diff --git a/migen/flow/actor.py b/migen/flow/actor.py index a834046a..279182e7 100644 --- a/migen/flow/actor.py +++ b/migen/flow/actor.py @@ -1,3 +1,4 @@ +from migen.util.misc import xdir from migen.fhdl.std import * from migen.genlib.misc import optree from migen.genlib.record import * @@ -32,7 +33,7 @@ def get_endpoints(obj, filt=_Endpoint): if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints): return obj.get_endpoints(filt) r = dict() - for k, v in obj.__dict__.items(): + for k, v in xdir(obj, True): if isinstance(v, filt): r[k] = v return r diff --git a/migen/genlib/ioo.py b/migen/genlib/ioo.py index 66d411b0..0280b43d 100644 --- a/migen/genlib/ioo.py +++ b/migen/genlib/ioo.py @@ -1,3 +1,4 @@ +from migen.util.misc import xdir from migen.fhdl.std import * from migen.flow.actor import * from migen.flow.actor import _Endpoint @@ -10,13 +11,13 @@ class UnifiedIOObject(Module): def do_finalize(self): if self.get_dataflow(): self.busy = Signal() - self.specials += set(v for v in self.__dict__.values() if isinstance(v, Memory)) + self.specials += set(v for k, v in xdir(self, True) if isinstance(v, Memory)) def get_dataflow(self): - return dict((k, v) for k, v in self.__dict__.items() if isinstance(v, _Endpoint)) + return dict((k, v) for k, v in xdir(self, True) if isinstance(v, _Endpoint)) def get_buses(self): - return dict((k, v) for k, v in self.__dict__.items() if isinstance(v, (wishbone.Interface, Memory))) + return dict((k, v) for k, v in xdir(self, True) if isinstance(v, (wishbone.Interface, Memory))) (_WAIT_COMPLETE, _WAIT_POLL) = range(2) diff --git a/migen/graph/treeviz.py b/migen/graph/treeviz.py deleted file mode 100644 index 196871d1..00000000 --- a/migen/graph/treeviz.py +++ /dev/null @@ -1,108 +0,0 @@ -import cairo -import math - -def _cairo_draw_node(ctx, dx, radius, color, outer_color, s): - ctx.save() - - ctx.translate(dx, 0) - - ctx.set_line_width(0.0) - gradient_color = cairo.RadialGradient(0, 0, 0, 0, 0, radius) - gradient_color.add_color_stop_rgb(0, *color) - gradient_color.add_color_stop_rgb(1, *outer_color) - ctx.set_source(gradient_color) - ctx.arc(0, 0, radius, 0, 2*math.pi) - ctx.fill() - - lines = s.split("\n") - textws = [] - texths = [] - for line in lines: - x_bearing, y_bearing, w, h, x_advance, y_advance = ctx.text_extents(line) - textws.append(w) - texths.append(h + 2) - ctx.translate(0, -sum(texths[1:])/2) - for line, w, h in zip(lines, textws, texths): - ctx.translate(-w/2, h/2) - ctx.move_to(0, 0) - ctx.set_source_rgb(0, 0, 0) - ctx.show_text(line) - ctx.translate(w/2, h/2) - - ctx.restore() - -def _cairo_draw_connection(ctx, x0, y0, color0, x1, y1, color1): - ctx.move_to(x0, y0) - ctx.curve_to(x0, y0+20, x1, y1-20, x1, y1) - ctx.set_line_width(1.2) - gradient_color = cairo.LinearGradient(x0, y0, x1, y1) - gradient_color.add_color_stop_rgb(0, *color0) - gradient_color.add_color_stop_rgb(1, *color1) - ctx.set_source(gradient_color) - ctx.stroke() - -class RenderNode: - def __init__(self, label, children=None, color=(0.8, 0.8, 0.8), radius=40): - self.label = label - if children is None: - children = [] - self.children = children - self.color = color - self.outer_color = (color[0]*3/5, color[1]*3/5, color[2]*3/5) - self.radius = radius - self.pitch = self.radius*3 - - def get_dimensions(self): - if self.children: - cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children]) - w = sum(cws) - h = self.pitch + max(chs) - dx = cws[0]/4 - cws[-1]/4 - else: - w = h = self.pitch - dx = 0 - return w, h, dx - - def render(self, ctx): - if self.children: - cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children]) - first_child_x = -sum(cws)/2 - - ctx.save() - ctx.translate(first_child_x, self.pitch) - for c, w in zip(self.children, cws): - ctx.translate(w/2, 0) - c.render(ctx) - ctx.translate(w/2, 0) - ctx.restore() - - dx = cws[0]/4 - cws[-1]/4 - - current_x = first_child_x - for c, w, cdx in zip(self.children, cws, cdxs): - current_y = self.pitch - c.radius - current_x += w/2 - _cairo_draw_connection(ctx, dx, self.radius, self.outer_color, current_x+cdx, current_y, c.outer_color) - current_x += w/2 - else: - dx = 0 - _cairo_draw_node(ctx, dx, self.radius, self.color, self.outer_color, self.label) - - def to_svg(self, name): - w, h, dx = self.get_dimensions() - surface = cairo.SVGSurface(name, w, h) - ctx = cairo.Context(surface) - ctx.translate(w/2, self.pitch/2) - self.render(ctx) - surface.finish() - -def _test(): - xns = [RenderNode("X"+str(n)) for n in range(5)] - yns = [RenderNode("Y"+str(n), [RenderNode("foo", color=(0.1*n, 0.5+0.2*n, 1.0-0.3*n))]) for n in range(3)] - n1 = RenderNode("n1", yns) - n2 = RenderNode("n2", xns, color=(0.8, 0.5, 0.9)) - top = RenderNode("top", [n1, n2]) - top.to_svg("test.svg") - -if __name__ == "__main__": - _test() diff --git a/migen/pytholite/compiler.py b/migen/pytholite/compiler.py index bfe1f827..20d7db02 100644 --- a/migen/pytholite/compiler.py +++ b/migen/pytholite/compiler.py @@ -2,6 +2,7 @@ import inspect import ast from collections import OrderedDict +from migen.util.misc import xdir from migen.fhdl.structure import * from migen.fhdl.visit import TransformModule from migen.fhdl.specials import Memory @@ -293,7 +294,8 @@ class Pytholite(UnifiedIOObject): if self.get_dataflow(): self.busy.reset = 1 self.memory_ports = dict() - for mem in self.__dict__.values(): + for key in xdir(self): + mem = getattr(self, key) if isinstance(mem, Memory): port = mem.get_port(write_capable=True, we_granularity=8) self.specials += port diff --git a/migen/util/misc.py b/migen/util/misc.py new file mode 100644 index 00000000..0a35ea68 --- /dev/null +++ b/migen/util/misc.py @@ -0,0 +1,7 @@ +def xdir(obj, return_values=False): + for attr in dir(obj): + if attr[:2] != "__" and attr[-2:] != "__": + if return_values: + yield attr, getattr(obj, attr) + else: + yield attr diff --git a/migen/util/treeviz.py b/migen/util/treeviz.py new file mode 100644 index 00000000..196871d1 --- /dev/null +++ b/migen/util/treeviz.py @@ -0,0 +1,108 @@ +import cairo +import math + +def _cairo_draw_node(ctx, dx, radius, color, outer_color, s): + ctx.save() + + ctx.translate(dx, 0) + + ctx.set_line_width(0.0) + gradient_color = cairo.RadialGradient(0, 0, 0, 0, 0, radius) + gradient_color.add_color_stop_rgb(0, *color) + gradient_color.add_color_stop_rgb(1, *outer_color) + ctx.set_source(gradient_color) + ctx.arc(0, 0, radius, 0, 2*math.pi) + ctx.fill() + + lines = s.split("\n") + textws = [] + texths = [] + for line in lines: + x_bearing, y_bearing, w, h, x_advance, y_advance = ctx.text_extents(line) + textws.append(w) + texths.append(h + 2) + ctx.translate(0, -sum(texths[1:])/2) + for line, w, h in zip(lines, textws, texths): + ctx.translate(-w/2, h/2) + ctx.move_to(0, 0) + ctx.set_source_rgb(0, 0, 0) + ctx.show_text(line) + ctx.translate(w/2, h/2) + + ctx.restore() + +def _cairo_draw_connection(ctx, x0, y0, color0, x1, y1, color1): + ctx.move_to(x0, y0) + ctx.curve_to(x0, y0+20, x1, y1-20, x1, y1) + ctx.set_line_width(1.2) + gradient_color = cairo.LinearGradient(x0, y0, x1, y1) + gradient_color.add_color_stop_rgb(0, *color0) + gradient_color.add_color_stop_rgb(1, *color1) + ctx.set_source(gradient_color) + ctx.stroke() + +class RenderNode: + def __init__(self, label, children=None, color=(0.8, 0.8, 0.8), radius=40): + self.label = label + if children is None: + children = [] + self.children = children + self.color = color + self.outer_color = (color[0]*3/5, color[1]*3/5, color[2]*3/5) + self.radius = radius + self.pitch = self.radius*3 + + def get_dimensions(self): + if self.children: + cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children]) + w = sum(cws) + h = self.pitch + max(chs) + dx = cws[0]/4 - cws[-1]/4 + else: + w = h = self.pitch + dx = 0 + return w, h, dx + + def render(self, ctx): + if self.children: + cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children]) + first_child_x = -sum(cws)/2 + + ctx.save() + ctx.translate(first_child_x, self.pitch) + for c, w in zip(self.children, cws): + ctx.translate(w/2, 0) + c.render(ctx) + ctx.translate(w/2, 0) + ctx.restore() + + dx = cws[0]/4 - cws[-1]/4 + + current_x = first_child_x + for c, w, cdx in zip(self.children, cws, cdxs): + current_y = self.pitch - c.radius + current_x += w/2 + _cairo_draw_connection(ctx, dx, self.radius, self.outer_color, current_x+cdx, current_y, c.outer_color) + current_x += w/2 + else: + dx = 0 + _cairo_draw_node(ctx, dx, self.radius, self.color, self.outer_color, self.label) + + def to_svg(self, name): + w, h, dx = self.get_dimensions() + surface = cairo.SVGSurface(name, w, h) + ctx = cairo.Context(surface) + ctx.translate(w/2, self.pitch/2) + self.render(ctx) + surface.finish() + +def _test(): + xns = [RenderNode("X"+str(n)) for n in range(5)] + yns = [RenderNode("Y"+str(n), [RenderNode("foo", color=(0.1*n, 0.5+0.2*n, 1.0-0.3*n))]) for n in range(3)] + n1 = RenderNode("n1", yns) + n2 = RenderNode("n2", xns, color=(0.8, 0.5, 0.9)) + top = RenderNode("top", [n1, n2]) + top.to_svg("test.svg") + +if __name__ == "__main__": + _test()