bank: automatic register naming
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 12 Mar 2013 14:45:24 +0000 (15:45 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 12 Mar 2013 14:45:24 +0000 (15:45 +0100)
migen/actorlib/spi.py
migen/bank/description.py
migen/bank/eventmanager.py
migen/bus/csr.py
migen/fhdl/tracer.py
migen/flow/isd.py

index 649d24bd049c938e7d0dfed93dd377de58f6dfa4..1981b72d17bed21893d75d4cf40c33aa48a763e0 100644 (file)
@@ -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})
index 106c5dd56b57a92a470daaf556637e72e2ca372b..2fc74044dd5da20486e7fe8046c4ade79c28b9d8 100644 (file)
@@ -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
index c85ed6b2f3e835edce3504e145950dead3a8391c..d325d0de703589adbfb409da9d6adc52a0b35d6b 100644 (file)
@@ -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):
index 2799937868e4ca3754a48f2a42e91abbf7e6a836..44076e7ffaba312c081879a03f9714f5b3a70454 100644 (file)
@@ -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:
index fa6d40644d71f0434c808d91197ecf427adecb62..3d4d7313a816c67522a765056eb27228928dec89 100644 (file)
@@ -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()
 
index a077fc7ca05b9d1a935f73277bc8eacf3335c2e6..a112070c5d60569fae83242d63cec717a5dfee8b 100644 (file)
@@ -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)