diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index feff41c75..480b67e31 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -479,9 +479,10 @@ class SoCCSRHandler(SoCLocHandler): 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...") @@ -524,18 +525,28 @@ class SoCCSRHandler(SoCLocHandler): 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 @@ -586,11 +597,12 @@ class SoCCSRHandler(SoCLocHandler): # 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] @@ -678,6 +690,7 @@ class SoC(Module): csr_data_width = 32, csr_address_width = 14, csr_paging = 0x800, + csr_ordering = "big", csr_reserved_csrs = {}, irq_n_irqs = 32, @@ -718,6 +731,7 @@ class SoC(Module): address_width = csr_address_width, alignment = 32, paging = csr_paging, + ordering = csr_ordering, reserved_csrs = csr_reserved_csrs, ) @@ -947,6 +961,7 @@ class SoC(Module): 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( diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 6fff77047..281f34e4e 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -84,6 +84,7 @@ class SoCCore(LiteXSoC): csr_data_width = 8, csr_address_width = 14, csr_paging = 0x800, + csr_ordering = "big", # Identifier parameters ident = "", ident_version = False, @@ -111,6 +112,7 @@ class SoCCore(LiteXSoC): 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, @@ -289,6 +291,9 @@ def soc_core_args(parser): 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=\"\"") diff --git a/litex/soc/interconnect/csr.py b/litex/soc/interconnect/csr.py index 9922117fd..fbc66d84a 100644 --- a/litex/soc/interconnect/csr.py +++ b/litex/soc/interconnect/csr.py @@ -295,9 +295,9 @@ class CSRStatus(_CompoundCSR): 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]) @@ -384,11 +384,11 @@ class CSRStorage(_CompoundCSR): 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) @@ -479,7 +479,8 @@ class AutoCSR: 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: @@ -487,7 +488,7 @@ class GenericBank(Module): 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) diff --git a/litex/soc/interconnect/csr_bus.py b/litex/soc/interconnect/csr_bus.py index cded5ae29..c09bfe5d3 100644 --- a/litex/soc/interconnect/csr_bus.py +++ b/litex/soc/interconnect/csr_bus.py @@ -163,7 +163,7 @@ class SRAM(Module): # 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 @@ -171,7 +171,11 @@ class CSRBank(csr.GenericBank): # # # - 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) @@ -201,10 +205,11 @@ class CSRBank(csr.GenericBank): # 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) @@ -246,6 +251,7 @@ class CSRBankArray(Module): 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))