bank: refactoring

This commit is contained in:
Sebastien Bourdeauducq 2012-02-06 13:55:50 +01:00
parent 1a86f26a66
commit f3ddfffc47
3 changed files with 41 additions and 40 deletions

View 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)

View 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)

View 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])