more whitespace cleanup
[nmigen-soc.git] / nmigen_soc / csr / bus.py
index e760197dc9c764a7c6fcfdac3c1988b25846e690..b865a01835669242c17be1dba094621cc69718fb 100644 (file)
@@ -16,8 +16,8 @@ class Element(Record):
         can have more restrictive access mode, e.g. R/O fields can be
         a part of an R/W register.
         """
-        R  = "r"
-        W  = "w"
+        R = "r"
+        W = "w"
         RW = "rw"
 
         def readable(self):
@@ -56,26 +56,29 @@ class Element(Record):
         Write strobe. Registers should update their value or perform
         the write side effect when this strobe is asserted.
     """
+
     def __init__(self, width, access, *, name=None, src_loc_at=0):
         if not isinstance(width, int) or width < 0:
             raise ValueError("Width must be a non-negative integer, not {!r}"
                              .format(width))
-        if not isinstance(access, Element.Access) and access not in ("r", "w", "rw"):
-            raise ValueError("Access mode must be one of \"r\", \"w\", or \"rw\", not {!r}"
+        if not isinstance(access, Element.Access) and access not in (
+                "r", "w", "rw"):
+            raise ValueError("Access mode must be one of \"r\", "
+                             "\"w\", or \"rw\", not {!r}"
                              .format(access))
-        self.width  = width
+        self.width = width
         self.access = Element.Access(access)
 
         layout = []
         if self.access.readable():
             layout += [
                 ("r_data", width),
-                ("r_stb",  1),
+                ("r_stb", 1),
             ]
         if self.access.writable():
             layout += [
                 ("w_data", width),
-                ("w_stb",  1),
+                ("w_stb", 1),
             ]
         super().__init__(layout, name=name, src_loc_at=1)
 
@@ -144,22 +147,23 @@ class Interface(Record):
 
     def __init__(self, *, addr_width, data_width, alignment=0, name=None):
         if not isinstance(addr_width, int) or addr_width <= 0:
-            raise ValueError("Address width must be a positive integer, not {!r}"
-                             .format(addr_width))
+            raise ValueError("Address width must be a positive integer, "
+                            "not {!r}" .format(addr_width))
         if not isinstance(data_width, int) or data_width <= 0:
             raise ValueError("Data width must be a positive integer, not {!r}"
                              .format(data_width))
         self.addr_width = addr_width
         self.data_width = data_width
-        self.memory_map = MemoryMap(addr_width=addr_width, data_width=data_width,
+        self.memory_map = MemoryMap(addr_width=addr_width,
+                                    data_width=data_width,
                                     alignment=alignment)
 
         super().__init__([
-            ("addr",    addr_width),
-            ("r_data",  data_width),
-            ("r_stb",   1),
-            ("w_data",  data_width),
-            ("w_stb",   1),
+            ("addr", addr_width),
+            ("r_data", data_width),
+            ("r_stb", 1),
+            ("w_data", data_width),
+            ("w_stb", 1),
         ], name=name, src_loc_at=1)
 
 
@@ -218,9 +222,12 @@ class Multiplexer(Elaboratable):
     bus : :class:`Interface`
         CSR bus providing access to registers.
     """
+
     def __init__(self, *, addr_width, data_width, alignment=0):
-        self.bus  = Interface(addr_width=addr_width, data_width=data_width, alignment=alignment,
-                              name="csr")
+        self.bus = Interface(addr_width=addr_width,
+                            data_width=data_width,
+                            alignment=alignment,
+                             name="csr")
         self._map = self.bus.memory_map
 
     def align_to(self, alignment):
@@ -236,53 +243,64 @@ class Multiplexer(Elaboratable):
         See :meth:`MemoryMap.add_resource` for details.
         """
         if not isinstance(element, Element):
-            raise TypeError("Element must be an instance of csr.Element, not {!r}"
-                            .format(element))
+            raise TypeError("Element must be an instance of csr.Element, "
+                            "not {!r}" .format(element))
 
         size = (element.width + self.bus.data_width - 1) // self.bus.data_width
-        return self._map.add_resource(element, size=size, addr=addr, alignment=alignment)
+        return self._map.add_resource(
+            element, size=size, addr=addr, alignment=alignment)
 
     def elaborate(self, platform):
         m = Module()
 
-        # Instead of a straightforward multiplexer for reads, use a per-element address comparator,
-        # AND the shadow register chunk with the comparator output, and OR all of those together.
-        # If the toolchain doesn't already synthesize multiplexer trees this way, this trick can
-        # save a significant amount of logic, since e.g. one 4-LUT can pack one 2-MUX, but two
-        # 2-AND or 2-OR gates.
+        # Instead of a straightforward multiplexer for reads, use a
+        # per-element address comparator, AND the shadow register chunk
+        # with the comparator output, and OR all of those together.  If
+        # the toolchain doesn't already synthesize multiplexer trees this
+        # way, this trick can save a significant amount of logic, since
+        # e.g. one 4-LUT can pack one 2-MUX, but two 2-AND or 2-OR gates.
         r_data_fanin = 0
 
         for elem, (elem_start, elem_end) in self._map.resources():
             shadow = Signal(elem.width, name="{}__shadow".format(elem.name))
             if elem.access.readable():
-                shadow_en = Signal(elem_end - elem_start, name="{}__shadow_en".format(elem.name))
+                shadow_en = Signal(
+                    elem_end - elem_start,
+                    name="{}__shadow_en".format(
+                        elem.name))
                 m.d.sync += shadow_en.eq(0)
             if elem.access.writable():
                 m.d.comb += elem.w_data.eq(shadow)
                 m.d.sync += elem.w_stb.eq(0)
 
-            # Enumerate every address used by the register explicitly, rather than using
-            # arithmetic comparisons, since some toolchains (e.g. Yosys) are too eager to infer
-            # carry chains for comparisons, even with a constant. (Register sizes don't have
-            # to be powers of 2.)
+            # Enumerate every address used by the register explicitly,
+            # rather than using arithmetic comparisons, since some
+            # toolchains (e.g. Yosys) are too eager to infer carry chains
+            # for comparisons, even with a constant. (Register sizes don't
+            # have to be powers of 2.)
             with m.Switch(self.bus.addr):
-                for chunk_offset, chunk_addr in enumerate(range(elem_start, elem_end)):
-                    shadow_slice = shadow.word_select(chunk_offset, self.bus.data_width)
+                for chunk_offset, chunk_addr in enumerate(
+                        range(elem_start, elem_end)):
+                    shadow_slice = shadow.word_select(
+                        chunk_offset, self.bus.data_width)
 
                     with m.Case(chunk_addr):
                         if elem.access.readable():
-                            r_data_fanin |= Mux(shadow_en[chunk_offset], shadow_slice, 0)
+                            r_data_fanin |= Mux(
+                                shadow_en[chunk_offset], shadow_slice, 0)
                             if chunk_addr == elem_start:
                                 m.d.comb += elem.r_stb.eq(self.bus.r_stb)
                                 with m.If(self.bus.r_stb):
                                     m.d.sync += shadow.eq(elem.r_data)
                             # Delay by 1 cycle, allowing reads to be pipelined.
-                            m.d.sync += shadow_en.eq(self.bus.r_stb << chunk_offset)
+                            m.d.sync += shadow_en.eq(self.bus.r_stb <<
+                                                     chunk_offset)
 
                         if elem.access.writable():
                             if chunk_addr == elem_end - 1:
-                                # Delay by 1 cycle, avoiding combinatorial paths through
-                                # the CSR bus and into CSR registers.
+                                # Delay by 1 cycle, avoiding combinatorial
+                                # paths through the CSR bus and into
+                                # CSR registers.
                                 m.d.sync += elem.w_stb.eq(self.bus.w_stb)
                             with m.If(self.bus.w_stb):
                                 m.d.sync += shadow_slice.eq(self.bus.w_data)
@@ -325,10 +343,13 @@ class Decoder(Elaboratable):
     bus : :class:`Interface`
         CSR bus providing access to subordinate buses.
     """
+
     def __init__(self, *, addr_width, data_width, alignment=0):
-        self.bus   = Interface(addr_width=addr_width, data_width=data_width, alignment=alignment,
-                               name="csr")
-        self._map  = self.bus.memory_map
+        self.bus = Interface(addr_width=addr_width,
+                             data_width=data_width,
+                             alignment=alignment,
+                             name="csr")
+        self._map = self.bus.memory_map
         self._subs = dict()
 
     def align_to(self, alignment):
@@ -344,10 +365,11 @@ class Decoder(Elaboratable):
         See :meth:`MemoryMap.add_resource` for details.
         """
         if not isinstance(sub_bus, Interface):
-            raise TypeError("Subordinate bus must be an instance of csr.Interface, not {!r}"
-                            .format(sub_bus))
+            raise TypeError("Subordinate bus must be an instance of "
+                            "csr.Interface, not {!r}" .format(sub_bus))
         if sub_bus.data_width != self.bus.data_width:
-            raise ValueError("Subordinate bus has data width {}, which is not the same as "
+            raise ValueError("Subordinate bus has data width {}, "
+                             "which is not the same as "
                              "decoder data width {}"
                              .format(sub_bus.data_width, self.bus.data_width))
         self._subs[sub_bus.memory_map] = sub_bus
@@ -366,8 +388,8 @@ class Decoder(Elaboratable):
                 sub_bus = self._subs[sub_map]
                 m.d.comb += sub_bus.addr.eq(self.bus.addr[:sub_bus.addr_width])
 
-                # The CSR bus interface is defined to output zero when idle, allowing us to avoid
-                # adding a multiplexer here.
+                # The CSR bus interface is defined to output zero when
+                # idle, allowing us to avoid adding a multiplexer here.
                 r_data_fanin |= sub_bus.r_data
                 m.d.comb += sub_bus.w_data.eq(self.bus.w_data)