The original CSR registers ordering (big: MSB on lower addresses) is not convenient
when the SoC is interfaced with a real OS (for example as a PCIe add-on board or
with a CPU running Linux).
With this, the original ordering is kept as default (big), but it can now be switched
to little to avoid software workarounds in drivers and should probably be in the future
the default for PCIe/Linux SoCs.
supported_address_width = [14+i for i in range(4)]
supported_alignment = [32]
supported_paging = [0x800*2**i for i in range(4)]
+ supported_ordering = ["big", "little"]
# Creation -------------------------------------------------------------------------------------
- def __init__(self, data_width=32, address_width=14, alignment=32, paging=0x800, reserved_csrs={}):
+ def __init__(self, data_width=32, address_width=14, alignment=32, paging=0x800, ordering="big", reserved_csrs={}):
SoCLocHandler.__init__(self, "CSR", n_locs=alignment//8*(2**address_width)//paging)
self.logger = logging.getLogger("SoCCSRHandler")
self.logger.info("Creating CSR Handler...")
colorer(", ".join("0x{:x}".format(x) for x in self.supported_paging))))
raise
+ # Check Ordering
+ if ordering not in self.supported_ordering:
+ self.logger.error("Unsupported {} {}, supporteds: {:s}".format(
+ colorer("Ordering", color="red"),
+ colorer("{}".format(paging)),
+ colorer(", ".join("{}".format(x) for x in self.supported_ordering))))
+ raise
+
# Create CSR Handler
self.data_width = data_width
self.address_width = address_width
self.alignment = alignment
self.paging = paging
+ self.ordering = ordering
self.masters = {}
self.regions = {}
- self.logger.info("{}-bit CSR Bus, {}-bit Aligned, {}KiB Address Space, {}B Paging (Up to {} Locations).".format(
+ self.logger.info("{}-bit CSR Bus, {}-bit Aligned, {}KiB Address Space, {}B Paging, {} Ordering (Up to {} Locations).".format(
colorer(self.data_width),
colorer(self.alignment),
colorer(2**self.address_width/2**10),
colorer(self.paging),
+ colorer(self.ordering),
colorer(self.n_locs)))
# Adding reserved CSRs
# Str ------------------------------------------------------------------------------------------
def __str__(self):
- r = "{}-bit CSR Bus, {}-bit Aligned, {}KiB Address Space, {}B Paging (Up to {} Locations).\n".format(
+ r = "{}-bit CSR Bus, {}-bit Aligned, {}KiB Address Space, {}B Paging, {} Ordering (Up to {} Locations).\n".format(
colorer(self.data_width),
colorer(self.alignment),
colorer(2**self.address_width/2**10),
colorer(self.paging),
+ colorer(self.ordering),
colorer(self.n_locs))
r += SoCLocHandler.__str__(self)
r = r[:-1]
csr_data_width = 32,
csr_address_width = 14,
csr_paging = 0x800,
+ csr_ordering = "big",
csr_reserved_csrs = {},
irq_n_irqs = 32,
address_width = csr_address_width,
alignment = 32,
paging = csr_paging,
+ ordering = csr_ordering,
reserved_csrs = csr_reserved_csrs,
)
address_width = self.csr.address_width,
alignment = self.csr.alignment,
paging = self.csr.paging,
+ ordering = self.csr.ordering,
soc_bus_data_width = self.bus.data_width)
if len(self.csr.masters):
self.submodules.csr_interconnect = csr_bus.InterconnectShared(
csr_data_width = 8,
csr_address_width = 14,
csr_paging = 0x800,
+ csr_ordering = "big",
# Identifier parameters
ident = "",
ident_version = False,
csr_data_width = csr_data_width,
csr_address_width = csr_address_width,
csr_paging = csr_paging,
+ csr_ordering = csr_ordering,
csr_reserved_csrs = self.csr_map,
irq_n_irqs = 32,
help="CSR bus address-width")
parser.add_argument("--csr-paging", default=0x800, type=auto_int,
help="CSR bus paging")
+ parser.add_argument("--csr-ordering", default="big",
+ help="CSR registers ordering (default=big)")
+
# Identifier parameters
parser.add_argument("--ident", default=None, type=str,
help="SoC identifier (default=\"\"")
for field in fields:
self.comb += self.status[field.offset:field.offset + field.size].eq(getattr(self.fields, field.name))
- def do_finalize(self, busword):
+ def do_finalize(self, busword, ordering):
nwords = (self.size + busword - 1)//busword
- for i in reversed(range(nwords)):
+ for i in reversed(range(nwords)) if ordering == "big" else range(nwords):
nbits = min(self.size - i*busword, busword)
sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
else:
self.comb += field_assign
- def do_finalize(self, busword):
+ def do_finalize(self, busword, ordering):
nwords = (self.size + busword - 1)//busword
if nwords > 1 and self.atomic_write:
backstore = Signal(self.size - busword, name=self.name + "_backstore")
- for i in reversed(range(nwords)):
+ for i in reversed(range(nwords)) if ordering == "big" else range(nwords):
nbits = min(self.size - i*busword, busword)
sc = CSR(nbits, self.name + str(i) if nwords else self.name)
self.simple_csrs.append(sc)
class GenericBank(Module):
- def __init__(self, description, busword):
+ def __init__(self, description, busword, ordering="big"):
+ assert ordering in ["big", "little"]
# Turn description into simple CSRs and claim ownership of compound CSR modules
self.simple_csrs = []
for c in description:
assert c.size <= busword
self.simple_csrs.append(c)
else:
- c.finalize(busword)
+ c.finalize(busword, ordering)
self.simple_csrs += c.get_simple_csrs()
self.submodules += c
self.decode_bits = bits_for(len(self.simple_csrs)-1)
# CSR Bank -----------------------------------------------------------------------------------------
class CSRBank(csr.GenericBank):
- def __init__(self, description, address=0, bus=None, paging=0x800, soc_bus_data_width=32):
+ def __init__(self, description, address=0, bus=None, paging=0x800, ordering="big", soc_bus_data_width=32):
if bus is None:
bus = Interface()
self.bus = bus
# # #
- csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
+ csr.GenericBank.__init__(self,
+ description = description,
+ busword = len(self.bus.dat_w),
+ ordering = ordering,
+ )
sel = Signal()
self.comb += sel.eq(self.bus.adr[log2_int(aligned_paging):] == address)
# address_map is called exactly once for each object at each call to
# scan(), so it can have side effects.
class CSRBankArray(Module):
- def __init__(self, source, address_map, *ifargs, paging=0x800, soc_bus_data_width=32, **ifkwargs):
+ def __init__(self, source, address_map, *ifargs, paging=0x800, ordering="big", soc_bus_data_width=32, **ifkwargs):
self.source = source
self.address_map = address_map
self.paging = paging
+ self.ordering = ordering
self.soc_bus_data_width = soc_bus_data_width
self.scan(ifargs, ifkwargs)
rmap = CSRBank(csrs, mapaddr,
bus = bank_bus,
paging = self.paging,
+ ordering = self.ordering,
soc_bus_data_width = self.soc_bus_data_width)
self.submodules += rmap
self.banks.append((name, csrs, mapaddr, rmap))