bank: refactoring
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 6 Feb 2012 12:55:50 +0000 (13:55 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 6 Feb 2012 12:55:50 +0000 (13:55 +0100)
examples/simple_gpio.py
migen/bank/csrgen.py
migen/bank/description.py

index e0d1c6b8d8e99cb8f4716a3bd4db33d075162c27..426df02ccc966dbac2bcec43827e15e1e92bd13c 100644 (file)
@@ -5,21 +5,18 @@ from migen.bank import description, csrgen
 ninputs = 4
 noutputs = 4
 
-oreg = description.Register("o")
-ofield = description.Field(oreg, "val", noutputs)
-ireg = description.Register("i")
-ifield = description.Field(ireg, "val", ninputs, description.READ_ONLY, description.WRITE_ONLY)
+oreg = description.RegisterField("o", noutputs)
+ireg = description.RegisterRaw("i", ninputs)
 
 # input path
 gpio_in = Signal(BV(ninputs))
 gpio_in_s = Signal(BV(ninputs)) # synchronizer
-incomb = [ifield.dev_we.eq(1)]
-insync = [gpio_in_s.eq(gpio_in), ifield.dev_w.eq(gpio_in_s)]
-inf = Fragment(incomb, insync)
+insync = [gpio_in_s.eq(gpio_in), ireg.w.eq(gpio_in_s)]
+inf = Fragment(sync=insync)
 
 bank = csrgen.Bank([oreg, ireg])
 f = bank.get_fragment() + inf
+oreg.field.r.name_override = "gpio_out"
 i = bank.interface
-ofield.dev_r.name_override = "gpio_out"
-v = verilog.convert(f, {i.d_o, ofield.dev_r, i.a_i, i.we_i, i.d_i, gpio_in})
+v = verilog.convert(f, {i.d_o, oreg.field.r, i.a_i, i.we_i, i.d_i, gpio_in})
 print(v)
index b732e162a45ceb082b428d4ccc6065845d3762a1..894579350de5459bbaba57ffc39c93cbfdf7972e 100644 (file)
@@ -20,7 +20,12 @@ class Bank:
                # Bus writes
                bwcases = []
                for i, reg in enumerate(self.description):
-                       if reg.raw is None:
+                       if isinstance(reg, RegisterRaw):
+                               comb.append(reg.r.eq(self.interface.d_i[:reg.size]))
+                               comb.append(reg.re.eq(sel & \
+                                       self.interface.we_i & \
+                                       (self.interface.a_i[:nbits] == Constant(i, BV(nbits)))))
+                       elif isinstance(reg, RegisterFields):
                                bwra = [Constant(i, BV(nbits))]
                                for j, field in enumerate(reg.fields):
                                        if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
@@ -28,17 +33,16 @@ class Bank:
                                if len(bwra) > 1:
                                        bwcases.append(bwra)
                        else:
-                               comb.append(reg.dev_r.eq(self.interface.d_i[:reg.raw.width]))
-                               comb.append(reg.dev_re.eq(sel & \
-                                       self.interface.we_i & \
-                                       (self.interface.a_i[:nbits] == Constant(i, BV(nbits)))))
+                               raise TypeError
                if bwcases:
                        sync.append(If(sel & self.interface.we_i, Case(self.interface.a_i[:nbits], *bwcases)))
                
                # Bus reads
                brcases = []
                for i, reg in enumerate(self.description):
-                       if reg.raw is None:
+                       if isinstance(reg, RegisterRaw):
+                               brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(reg.w)])
+                       elif isinstance(reg, RegisterFields):
                                brs = []
                                reg_readable = False
                                for j, field in enumerate(reg.fields):
@@ -53,7 +57,7 @@ class Bank:
                                        else:
                                                brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(brs[0])])
                        else:
-                               brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(reg.dev_w)])
+                               raise TypeError
                if brcases:
                        sync.append(self.interface.d_o.eq(Constant(0, BV(8))))
                        sync.append(If(sel, Case(self.interface.a_i[:nbits], *brcases)))
@@ -62,11 +66,11 @@ class Bank:
                
                # Device access
                for reg in self.description:
-                       if reg.raw is None:
+                       if isinstance(reg, RegisterFields):
                                for field in reg.fields:
                                        if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE:
-                                               comb.append(field.dev_r.eq(field.storage))
+                                               comb.append(field.r.eq(field.storage))
                                        if field.access_dev == WRITE_ONLY or field.access_dev == READ_WRITE:
-                                               sync.append(If(field.dev_we, field.storage.eq(field.dev_w)))
+                                               sync.append(If(field.we, field.storage.eq(field.w)))
                
                return Fragment(comb, sync)
index 102deff01801ced218bac9844f134ac75ec64d6d..14d2d136d050fefa51fe6db22096e3979100e9cf 100644 (file)
@@ -1,34 +1,34 @@
 from migen.fhdl.structure import *
 
-class Register:
-       def __init__(self, name, raw=None):
+class RegisterRaw:
+       def __init__(self, name, size=1):
                self.name = name
-               self.raw = raw
-               if raw is not None:
-                       self.dev_re = Signal(name=name + "_re")
-                       self.dev_r = Signal(raw, name + "_r")
-                       self.dev_w = Signal(raw, name + "_w")
-               else:
-                       self.fields = []
-       
-       def add_field(self, f):
-               self.fields.append(f)
+               self.size = size
+               self.re = Signal()
+               self.r = Signal(BV(self.size))
+               self.w = Signal(BV(self.size))
 
 (READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
 
 class Field:
-       def __init__(self, parent, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
-               self.parent = parent
+       def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
                self.name = name
                self.size = size
                self.access_bus = access_bus
                self.access_dev = access_dev
-               self.reset = reset
-               fullname = parent.name + "_" + name
-               self.storage = Signal(BV(self.size), fullname)
+               self.storage = Signal(BV(self.size), reset=reset)
                if self.access_dev == READ_ONLY or self.access_dev == READ_WRITE:
-                       self.dev_r = Signal(BV(self.size), fullname + "_r")
+                       self.r = Signal(BV(self.size))
                if self.access_dev == WRITE_ONLY or self.access_dev == READ_WRITE:
-                       self.dev_w = Signal(BV(self.size), fullname + "_w")
-                       self.dev_we = Signal(name=fullname + "_we")
-               self.parent.add_field(self)
+                       self.w = Signal(BV(self.size))
+                       self.we = Signal()
+
+class RegisterFields:
+       def __init__(self, name, fields):
+               self.name = name
+               self.fields = fields
+
+class RegisterField(RegisterFields):
+       def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
+               self.field = Field(name, size, access_bus, access_dev, reset)
+               RegisterFields.__init__(self, name, [self.field])