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_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 -------------------------------------------------------------------------------------
# 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...")
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
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
# 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.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.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
colorer(self.n_locs)))
# Adding reserved CSRs
# Str ------------------------------------------------------------------------------------------
def __str__(self):
# 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.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]
colorer(self.n_locs))
r += SoCLocHandler.__str__(self)
r = r[:-1]
csr_data_width = 32,
csr_address_width = 14,
csr_paging = 0x800,
csr_data_width = 32,
csr_address_width = 14,
csr_paging = 0x800,
csr_reserved_csrs = {},
irq_n_irqs = 32,
csr_reserved_csrs = {},
irq_n_irqs = 32,
address_width = csr_address_width,
alignment = 32,
paging = csr_paging,
address_width = csr_address_width,
alignment = 32,
paging = csr_paging,
+ ordering = csr_ordering,
reserved_csrs = csr_reserved_csrs,
)
reserved_csrs = csr_reserved_csrs,
)
address_width = self.csr.address_width,
alignment = self.csr.alignment,
paging = self.csr.paging,
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(
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_data_width = 8,
csr_address_width = 14,
csr_paging = 0x800,
# Identifier parameters
ident = "",
ident_version = False,
# Identifier parameters
ident = "",
ident_version = False,
csr_data_width = csr_data_width,
csr_address_width = csr_address_width,
csr_paging = csr_paging,
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,
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")
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=\"\"")
# 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))
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
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])
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
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")
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)
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):
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:
# 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:
assert c.size <= busword
self.simple_csrs.append(c)
else:
+ c.finalize(busword, ordering)
self.simple_csrs += c.get_simple_csrs()
self.submodules += c
self.decode_bits = bits_for(len(self.simple_csrs)-1)
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):
# 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
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)
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):
# 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.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)
self.soc_bus_data_width = soc_bus_data_width
self.scan(ifargs, ifkwargs)
rmap = CSRBank(csrs, mapaddr,
bus = bank_bus,
paging = self.paging,
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))
soc_bus_data_width = self.soc_bus_data_width)
self.submodules += rmap
self.banks.append((name, csrs, mapaddr, rmap))