From 04df076fba63205e1d8d6c00f7f78338d21a59d6 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 12 Mar 2013 15:45:24 +0100 Subject: [PATCH] bank: automatic register naming --- migen/actorlib/spi.py | 33 ++++++++++++++++----------------- migen/bank/description.py | 35 +++++++++++++++++++++-------------- migen/bank/eventmanager.py | 7 +++---- migen/bus/csr.py | 2 +- migen/fhdl/tracer.py | 18 ++++++++++++++++++ migen/flow/isd.py | 20 ++++++++++---------- 6 files changed, 69 insertions(+), 46 deletions(-) diff --git a/migen/actorlib/spi.py b/migen/actorlib/spi.py index 649d24bd..1981b72d 100644 --- a/migen/actorlib/spi.py +++ b/migen/actorlib/spi.py @@ -40,8 +40,7 @@ def _create_registers_assign(layout, target, atomic, prefix=""): alignment = element[3] else: alignment = 0 - reg = RegisterField(prefix + name, nbits + alignment, - reset=reset, atomic_write=atomic) + reg = RegisterField(nbits + alignment, reset=reset, atomic_write=atomic, name=prefix + name) registers.append(reg) assigns.append(getattr(target, name).eq(reg.field.r[alignment:])) return registers, assigns @@ -57,11 +56,11 @@ class SingleGenerator(Actor): if mode == MODE_EXTERNAL: self.trigger = Signal() elif mode == MODE_SINGLE_SHOT: - shoot = RegisterRaw("shoot") + shoot = RegisterRaw() self._registers.insert(0, shoot) self.trigger = shoot.re elif mode == MODE_CONTINUOUS: - enable = RegisterField("enable") + enable = RegisterField() self._registers.insert(0, enable) self.trigger = enable.field.r else: @@ -86,13 +85,13 @@ class Collector(Actor): self._depth = depth self._dw = sum(len(s) for s in self.token("sink").flatten()) - self._reg_wa = RegisterField("write_address", bits_for(self._depth-1), access_bus=READ_WRITE, access_dev=READ_WRITE) - self._reg_wc = RegisterField("write_count", bits_for(self._depth), access_bus=READ_WRITE, access_dev=READ_WRITE, atomic_write=True) - self._reg_ra = RegisterField("read_address", bits_for(self._depth-1), access_bus=READ_WRITE, access_dev=READ_ONLY) - self._reg_rd = RegisterField("read_data", self._dw, access_bus=READ_ONLY, access_dev=WRITE_ONLY) + self._r_wa = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_WRITE) + self._r_wc = RegisterField(bits_for(self._depth), READ_WRITE, READ_WRITE, atomic_write=True) + self._r_ra = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_ONLY) + self._r_rd = RegisterField(self._dw, READ_ONLY, WRITE_ONLY) def get_registers(self): - return [self._reg_wa, self._reg_wc, self._reg_ra, self._reg_rd] + return [self._r_wa, self._r_wc, self._r_ra, self._r_rd] def get_fragment(self): mem = Memory(self._dw, self._depth) @@ -100,22 +99,22 @@ class Collector(Actor): rp = mem.get_port() comb = [ - If(self._reg_wc.field.r != 0, + If(self._r_wc.field.r != 0, self.endpoints["sink"].ack.eq(1), If(self.endpoints["sink"].stb, - self._reg_wa.field.we.eq(1), - self._reg_wc.field.we.eq(1), + self._r_wa.field.we.eq(1), + self._r_wc.field.we.eq(1), wp.we.eq(1) ) ), - self._reg_wa.field.w.eq(self._reg_wa.field.r + 1), - self._reg_wc.field.w.eq(self._reg_wc.field.r - 1), + self._r_wa.field.w.eq(self._r_wa.field.r + 1), + self._r_wc.field.w.eq(self._r_wc.field.r - 1), - wp.adr.eq(self._reg_wa.field.r), + wp.adr.eq(self._r_wa.field.r), wp.dat_w.eq(Cat(*self.token("sink").flatten())), - rp.adr.eq(self._reg_ra.field.r), - self._reg_rd.field.w.eq(rp.dat_r) + rp.adr.eq(self._r_ra.field.r), + self._r_rd.field.w.eq(rp.dat_r) ] return Fragment(comb, specials={mem}) diff --git a/migen/bank/description.py b/migen/bank/description.py index 106c5dd5..2fc74044 100644 --- a/migen/bank/description.py +++ b/migen/bank/description.py @@ -2,14 +2,20 @@ from copy import copy from migen.fhdl.structure import * from migen.fhdl.specials import Memory +from migen.fhdl.tracer import get_obj_var_name class _Register(HUID): - pass + def __init__(self, name): + HUID.__init__(self) + self.name = get_obj_var_name(name) + if self.name is None: + raise ValueError("Cannot extract register name from code, need to specify.") + if len(self.name) > 2 and self.name[:2] == "r_": + self.name = self.name[2:] class RegisterRaw(_Register): - def __init__(self, name, size=1): - _Register.__init__(self) - self.name = name + def __init__(self, size=1, name=None): + _Register.__init__(self, name) self.size = size self.re = Signal() self.r = Signal(self.size) @@ -18,8 +24,10 @@ class RegisterRaw(_Register): (READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3) class Field: - def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False): - self.name = name + def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None): + self.name = get_obj_var_name(name) + if self.name is None: + raise ValueError("Cannot extract field name from code, need to specify.") self.size = size self.access_bus = access_bus self.access_dev = access_dev @@ -35,15 +43,14 @@ class Field: self.we = Signal() class RegisterFields(_Register): - def __init__(self, name, fields): - _Register.__init__(self) - self.name = name + def __init__(self, *fields, name=None): + _Register.__init__(self, name) self.fields = fields class RegisterField(RegisterFields): - def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False): - self.field = Field(name, size, access_bus, access_dev, reset, atomic_write) - RegisterFields.__init__(self, name, [self.field]) + def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None): + self.field = Field(size, access_bus, access_dev, reset, atomic_write, name="") + RegisterFields.__init__(self, self.field, name=name) def regprefix(prefix, registers): r = [] @@ -140,7 +147,7 @@ def expand_description(description, busword): if mode == ALIAS_ATOMIC_HOLD: commit_list.append(alias) top -= slice1 - d.append(RegisterFields(reg.name, f)) + d.append(RegisterFields(*f, name=reg.name)) alias = FieldAlias(mode, field, top - slice2, top, commit_list) f = [alias] if mode == ALIAS_ATOMIC_HOLD: @@ -150,7 +157,7 @@ def expand_description(description, busword): else: f.append(field) if f: - d.append(RegisterFields(reg.name, f)) + d.append(RegisterFields(*f, name=reg.name)) else: raise TypeError return d diff --git a/migen/bank/eventmanager.py b/migen/bank/eventmanager.py index c85ed6b2..d325d0de 100644 --- a/migen/bank/eventmanager.py +++ b/migen/bank/eventmanager.py @@ -23,10 +23,9 @@ class EventManager(Module, AutoReg): sources_u = [v for v in self.__dict__.values() if isinstance(v, _EventSource)] sources = sorted(sources_u, key=lambda x: x.huid) n = len(sources) - self.status = RegisterRaw("status", n) - self.pending = RegisterRaw("pending", n) - self.enable = RegisterFields("enable", - [Field("s" + str(i), access_bus=READ_WRITE, access_dev=READ_ONLY) for i in range(n)]) + self.status = RegisterRaw(n) + self.pending = RegisterRaw(n) + self.enable = RegisterFields(*(Field(1, READ_WRITE, READ_ONLY, name="e" + str(i)) for i in range(n))) # status for i, source in enumerate(sources): diff --git a/migen/bus/csr.py b/migen/bus/csr.py index 27999378..44076e7f 100644 --- a/migen/bus/csr.py +++ b/migen/bus/csr.py @@ -68,7 +68,7 @@ class SRAM: self.word_bits = 0 page_bits = _compute_page_bits(self.mem.depth + self.word_bits) if page_bits: - self._page = RegisterField(self.mem.name_override + "_page", page_bits) + self._page = RegisterField(page_bits, name=self.mem.name_override + "_page") else: self._page = None if read_only is None: diff --git a/migen/fhdl/tracer.py b/migen/fhdl/tracer.py index fa6d4064..3d4d7313 100644 --- a/migen/fhdl/tracer.py +++ b/migen/fhdl/tracer.py @@ -34,6 +34,24 @@ def remove_underscore(s): s = s[1:] return s +def get_obj_var_name(override=None, default=None): + if override: + return override + + frame = inspect.currentframe().f_back + # We can be called via derived classes. Go back the stack frames + # until we reach the first class that does not inherit from us. + ourclass = frame.f_locals["self"].__class__ + while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass): + frame = frame.f_back + + vn = get_var_name(frame) + if vn is None: + vn = default + else: + vn = remove_underscore(vn) + return vn + name_to_idx = defaultdict(int) classname_to_objs = dict() diff --git a/migen/flow/isd.py b/migen/flow/isd.py index a077fc7c..a112070c 100644 --- a/migen/flow/isd.py +++ b/migen/flow/isd.py @@ -11,11 +11,11 @@ class EndpointReporter: self.reset = Signal() self.freeze = Signal() - self._ack_count = RegisterField("ack_count", self.nbits, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._nack_count = RegisterField("nack_count", self.nbits, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._cur_stb = Field("cur_stb", 1, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._cur_ack = Field("cur_ack", 1, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._cur_status = RegisterFields("cur_status", [self._cur_stb, self._cur_ack]) + self._ack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY) + self._nack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY) + self._cur_stb = Field(1, READ_ONLY, WRITE_ONLY) + self._cur_ack = Field(1, READ_ONLY, WRITE_ONLY) + self._cur_status = RegisterFields(self._cur_stb, self._cur_ack) def get_registers(self): return [self._ack_count, self._nack_count, self._cur_status] @@ -57,11 +57,11 @@ class DFGReporter(DFGHook): def __init__(self, dfg, nbits): self._nbits = nbits - self._r_magic = RegisterField("magic", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._r_neps = RegisterField("neps", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._r_nbits = RegisterField("nbits", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY) - self._r_freeze = RegisterField("freeze", 1) - self._r_reset = RegisterRaw("reset", 1) + self._r_magic = RegisterField(16, access_bus=READ_ONLY, access_dev=WRITE_ONLY) + self._r_neps = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY) + self._r_nbits = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY) + self._r_freeze = RegisterField() + self._r_reset = RegisterRaw() self.order = [] DFGHook.__init__(self, dfg, self._create) -- 2.30.2