bank: refactoring
This commit is contained in:
parent
1a86f26a66
commit
f3ddfffc47
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in New Issue