mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
bank: refactoring
This commit is contained in:
parent
1a86f26a66
commit
f3ddfffc47
3 changed files with 41 additions and 40 deletions
|
@ -5,21 +5,18 @@ from migen.bank import description, csrgen
|
||||||
ninputs = 4
|
ninputs = 4
|
||||||
noutputs = 4
|
noutputs = 4
|
||||||
|
|
||||||
oreg = description.Register("o")
|
oreg = description.RegisterField("o", noutputs)
|
||||||
ofield = description.Field(oreg, "val", noutputs)
|
ireg = description.RegisterRaw("i", ninputs)
|
||||||
ireg = description.Register("i")
|
|
||||||
ifield = description.Field(ireg, "val", ninputs, description.READ_ONLY, description.WRITE_ONLY)
|
|
||||||
|
|
||||||
# input path
|
# input path
|
||||||
gpio_in = Signal(BV(ninputs))
|
gpio_in = Signal(BV(ninputs))
|
||||||
gpio_in_s = Signal(BV(ninputs)) # synchronizer
|
gpio_in_s = Signal(BV(ninputs)) # synchronizer
|
||||||
incomb = [ifield.dev_we.eq(1)]
|
insync = [gpio_in_s.eq(gpio_in), ireg.w.eq(gpio_in_s)]
|
||||||
insync = [gpio_in_s.eq(gpio_in), ifield.dev_w.eq(gpio_in_s)]
|
inf = Fragment(sync=insync)
|
||||||
inf = Fragment(incomb, insync)
|
|
||||||
|
|
||||||
bank = csrgen.Bank([oreg, ireg])
|
bank = csrgen.Bank([oreg, ireg])
|
||||||
f = bank.get_fragment() + inf
|
f = bank.get_fragment() + inf
|
||||||
|
oreg.field.r.name_override = "gpio_out"
|
||||||
i = bank.interface
|
i = bank.interface
|
||||||
ofield.dev_r.name_override = "gpio_out"
|
v = verilog.convert(f, {i.d_o, oreg.field.r, i.a_i, i.we_i, i.d_i, gpio_in})
|
||||||
v = verilog.convert(f, {i.d_o, ofield.dev_r, i.a_i, i.we_i, i.d_i, gpio_in})
|
|
||||||
print(v)
|
print(v)
|
||||||
|
|
|
@ -20,7 +20,12 @@ class Bank:
|
||||||
# Bus writes
|
# Bus writes
|
||||||
bwcases = []
|
bwcases = []
|
||||||
for i, reg in enumerate(self.description):
|
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))]
|
bwra = [Constant(i, BV(nbits))]
|
||||||
for j, field in enumerate(reg.fields):
|
for j, field in enumerate(reg.fields):
|
||||||
if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
|
if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
|
||||||
|
@ -28,17 +33,16 @@ class Bank:
|
||||||
if len(bwra) > 1:
|
if len(bwra) > 1:
|
||||||
bwcases.append(bwra)
|
bwcases.append(bwra)
|
||||||
else:
|
else:
|
||||||
comb.append(reg.dev_r.eq(self.interface.d_i[:reg.raw.width]))
|
raise TypeError
|
||||||
comb.append(reg.dev_re.eq(sel & \
|
|
||||||
self.interface.we_i & \
|
|
||||||
(self.interface.a_i[:nbits] == Constant(i, BV(nbits)))))
|
|
||||||
if bwcases:
|
if bwcases:
|
||||||
sync.append(If(sel & self.interface.we_i, Case(self.interface.a_i[:nbits], *bwcases)))
|
sync.append(If(sel & self.interface.we_i, Case(self.interface.a_i[:nbits], *bwcases)))
|
||||||
|
|
||||||
# Bus reads
|
# Bus reads
|
||||||
brcases = []
|
brcases = []
|
||||||
for i, reg in enumerate(self.description):
|
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 = []
|
brs = []
|
||||||
reg_readable = False
|
reg_readable = False
|
||||||
for j, field in enumerate(reg.fields):
|
for j, field in enumerate(reg.fields):
|
||||||
|
@ -53,7 +57,7 @@ class Bank:
|
||||||
else:
|
else:
|
||||||
brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(brs[0])])
|
brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(brs[0])])
|
||||||
else:
|
else:
|
||||||
brcases.append([Constant(i, BV(nbits)), self.interface.d_o.eq(reg.dev_w)])
|
raise TypeError
|
||||||
if brcases:
|
if brcases:
|
||||||
sync.append(self.interface.d_o.eq(Constant(0, BV(8))))
|
sync.append(self.interface.d_o.eq(Constant(0, BV(8))))
|
||||||
sync.append(If(sel, Case(self.interface.a_i[:nbits], *brcases)))
|
sync.append(If(sel, Case(self.interface.a_i[:nbits], *brcases)))
|
||||||
|
@ -62,11 +66,11 @@ class Bank:
|
||||||
|
|
||||||
# Device access
|
# Device access
|
||||||
for reg in self.description:
|
for reg in self.description:
|
||||||
if reg.raw is None:
|
if isinstance(reg, RegisterFields):
|
||||||
for field in reg.fields:
|
for field in reg.fields:
|
||||||
if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE:
|
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:
|
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)
|
return Fragment(comb, sync)
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
class Register:
|
class RegisterRaw:
|
||||||
def __init__(self, name, raw=None):
|
def __init__(self, name, size=1):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.raw = raw
|
self.size = size
|
||||||
if raw is not None:
|
self.re = Signal()
|
||||||
self.dev_re = Signal(name=name + "_re")
|
self.r = Signal(BV(self.size))
|
||||||
self.dev_r = Signal(raw, name + "_r")
|
self.w = Signal(BV(self.size))
|
||||||
self.dev_w = Signal(raw, name + "_w")
|
|
||||||
else:
|
|
||||||
self.fields = []
|
|
||||||
|
|
||||||
def add_field(self, f):
|
|
||||||
self.fields.append(f)
|
|
||||||
|
|
||||||
(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
|
(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
|
||||||
|
|
||||||
class Field:
|
class Field:
|
||||||
def __init__(self, parent, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
|
def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0):
|
||||||
self.parent = parent
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.size = size
|
self.size = size
|
||||||
self.access_bus = access_bus
|
self.access_bus = access_bus
|
||||||
self.access_dev = access_dev
|
self.access_dev = access_dev
|
||||||
self.reset = reset
|
self.storage = Signal(BV(self.size), reset=reset)
|
||||||
fullname = parent.name + "_" + name
|
|
||||||
self.storage = Signal(BV(self.size), fullname)
|
|
||||||
if self.access_dev == READ_ONLY or self.access_dev == READ_WRITE:
|
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:
|
if self.access_dev == WRITE_ONLY or self.access_dev == READ_WRITE:
|
||||||
self.dev_w = Signal(BV(self.size), fullname + "_w")
|
self.w = Signal(BV(self.size))
|
||||||
self.dev_we = Signal(name=fullname + "_we")
|
self.we = Signal()
|
||||||
self.parent.add_field(self)
|
|
||||||
|
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 a new issue