whitespace cleanup
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 19 Jun 2020 23:08:45 +0000 (00:08 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 19 Jun 2020 23:08:45 +0000 (00:08 +0100)
nmigen_soc/csr/bus.py
nmigen_soc/csr/wishbone.py
nmigen_soc/memory.py
nmigen_soc/scheduler.py
nmigen_soc/test/test_csr_bus.py
nmigen_soc/test/test_csr_wishbone.py
nmigen_soc/test/test_memory.py
nmigen_soc/test/test_wishbone_bus.py
nmigen_soc/wishbone/bus.py
nmigen_soc/wishbone/sram.py

index 0786a9e4e4711ec5c12b30cc72db9b96bd2ce5d1..e760197dc9c764a7c6fcfdac3c1988b25846e690 100644 (file)
@@ -12,8 +12,9 @@ class Element(Record):
     class Access(enum.Enum):
         """Register access mode.
 
-        Coarse access mode for the entire register. Individual fields can have more restrictive
-        access mode, e.g. R/O fields can be a part of an R/W register.
+        Coarse access mode for the entire register. Individual fields
+        can have more restrictive access mode, e.g. R/O fields can be
+        a part of an R/W register.
         """
         R  = "r"
         W  = "w"
@@ -27,9 +28,10 @@ class Element(Record):
 
     """Peripheral-side CSR interface.
 
-    A low-level interface to a single atomically readable and writable register in a peripheral.
-    This interface supports any register width and semantics, provided that both reads and writes
-    always succeed and complete in one cycle.
+    A low-level interface to a single atomically readable and writable
+    register in a peripheral.  This interface supports any register
+    width and semantics, provided that both reads and writes always
+    succeed and complete in one cycle.
 
     Parameters
     ----------
@@ -43,15 +45,16 @@ class Element(Record):
     Attributes
     ----------
     r_data : Signal(width)
-        Read data. Must be always valid, and is sampled when ``r_stb`` is asserted.
+        Read data. Must be always valid, and is sampled when ``r_stb``
+        is asserted.
     r_stb : Signal()
-        Read strobe. Registers with read side effects should perform the read side effect when this
-        strobe is asserted.
+        Read strobe. Registers with read side effects should perform
+        the read side effect when this strobe is asserted.
     w_data : Signal(width)
         Write data. Valid only when ``w_stb`` is asserted.
     w_stb : Signal()
-        Write strobe. Registers should update their value or perform the write side effect when
-        this strobe is asserted.
+        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:
@@ -83,25 +86,29 @@ class Element(Record):
 class Interface(Record):
     """CPU-side CSR interface.
 
-    A low-level interface to a set of atomically readable and writable peripheral CSR registers.
+    A low-level interface to a set of atomically readable and writable
+    peripheral CSR registers.
 
     Operation
     ---------
 
-    CSR registers mapped to the CSR bus are split into chunks according to the bus data width.
-    Each chunk is assigned a consecutive address on the bus. This allows accessing CSRs of any
-    size using any datapath width.
+    CSR registers mapped to the CSR bus are split into chunks according to
+    the bus data width.  Each chunk is assigned a consecutive address on
+    the bus. This allows accessing CSRs of any size using any datapath
+    width.
 
-    When the first chunk of a register is read, the value of a register is captured, and reads
-    from subsequent chunks of the same register return the captured values. When any chunk except
-    the last chunk of a register is written, the written value is captured; a write to the last
-    chunk writes the captured value to the register. This allows atomically accessing CSRs larger
-    than datapath width.
+    When the first chunk of a register is read, the value of a register
+    is captured, and reads from subsequent chunks of the same register
+    return the captured values. When any chunk except the last chunk
+    of a register is written, the written value is captured; a write
+    to the last chunk writes the captured value to the register. This
+    allows atomically accessing CSRs larger than datapath width.
 
     Parameters
     ----------
     addr_width : int
-        Address width. At most ``(2 ** addr_width) * data_width`` register bits will be available.
+        Address width. At most ``(2 ** addr_width) * data_width``
+        register bits will be available.
     data_width : int
         Data width. Registers are accessed in ``data_width`` sized chunks.
     alignment : int
@@ -116,20 +123,23 @@ class Interface(Record):
     addr : Signal(addr_width)
         Address for reads and writes.
     r_data : Signal(data_width)
-        Read data. Valid on the next cycle after ``r_stb`` is asserted. Otherwise, zero. (Keeping
-        read data of an unused interface at zero simplifies multiplexers.)
+        Read data. Valid on the next cycle after ``r_stb`` is
+        asserted. Otherwise, zero. (Keeping read data of an unused
+        interface at zero simplifies multiplexers.)
     r_stb : Signal()
-        Read strobe. If ``addr`` points to the first chunk of a register, captures register value
-        and causes read side effects to be performed (if any). If ``addr`` points to any chunk
-        of a register, latches the captured value to ``r_data``. Otherwise, latches zero
-        to ``r_data``.
+        Read strobe. If ``addr`` points to the first chunk of a
+        register, captures register value and causes read side effects
+        to be performed (if any). If ``addr`` points to any chunk of a
+        register, latches the captured value to ``r_data``. Otherwise,
+        latches zero to ``r_data``.
     w_data : Signal(data_width)
         Write data. Must be valid when ``w_stb`` is asserted.
     w_stb : Signal()
-        Write strobe. If ``addr`` points to the last chunk of a register, writes captured value
-        to the register and causes write side effects to be performed (if any). If ``addr`` points
-        to any chunk of a register, latches ``w_data`` to the captured value. Otherwise, does
-        nothing.
+        Write strobe. If ``addr`` points to the last chunk of a register,
+        writes captured value to the register and causes write side
+        effects to be performed (if any). If ``addr`` points to
+        any chunk of a register, latches ``w_data`` to the captured
+        value. Otherwise, does nothing.
     """
 
     def __init__(self, *, addr_width, data_width, alignment=0, name=None):
@@ -161,30 +171,38 @@ class Multiplexer(Elaboratable):
     Latency
     -------
 
-    Writes are registered, and are performed 1 cycle after ``w_stb`` is asserted.
+    Writes are registered, and are performed 1 cycle after ``w_stb``
+    is asserted.
 
     Alignment
     ---------
 
-    Because the CSR bus conserves logic and routing resources, it is common to e.g. access
-    a CSR bus with an *n*-bit data path from a CPU with a *k*-bit datapath (*k>n*) in cases
-    where CSR access latency is less important than resource usage. In this case, two strategies
+    Because the CSR bus conserves logic and routing resources, it is
+    common to e.g. access a CSR bus with an *n*-bit data path from a CPU
+    with a *k*-bit datapath (*k>n*) in cases where CSR access latency
+    is less important than resource usage. In this case, two strategies
     are possible for connecting the CSR bus to the CPU:
-        * The CPU could access the CSR bus directly (with no intervening logic other than simple
-          translation of control signals). In this case, the register alignment should be set
-          to 1, and each *w*-bit register would occupy *ceil(w/n)* addresses from the CPU
-          perspective, requiring the same amount of memory instructions to access.
-        * The CPU could also access the CSR bus through a width down-converter, which would issue
-          *k/n* CSR accesses for each CPU access. In this case, the register alignment should be
-          set to *k/n*, and each *w*-bit register would occupy *ceil(w/k)* addresses from the CPU
-          perspective, requiring the same amount of memory instructions to access.
-
-    If alignment is greater than 1, it affects which CSR bus write is considered a write to
-    the last register chunk. For example, if a 24-bit register is used with a 8-bit CSR bus and
-    a CPU with a 32-bit datapath, a write to this register requires 4 CSR bus writes to complete
-    and the 4th write is the one that actually writes the value to the register. This allows
-    determining write latency solely from the amount of addresses the register occupies in
-    the CPU address space, and the width of the CSR bus.
+        * The CPU could access the CSR bus directly (with no intervening
+          logic other than simple translation of control signals). In
+          this case, the register alignment should be set to 1, and each
+          *w*-bit register would occupy *ceil(w/n)* addresses from the CPU
+          perspective, requiring the same amount of memory instructions
+          to access.
+        * The CPU could also access the CSR bus through a width
+          down-converter, which would issue *k/n* CSR accesses for each
+          CPU access. In this case, the register alignment should be set
+          to *k/n*, and each *w*-bit register would occupy *ceil(w/k)*
+          addresses from the CPU perspective, requiring the same amount
+          of memory instructions to access.
+
+    If alignment is greater than 1, it affects which CSR bus write
+    is considered a write to the last register chunk. For example,
+    if a 24-bit register is used with a 8-bit CSR bus and a CPU with a
+    32-bit datapath, a write to this register requires 4 CSR bus writes
+    to complete and the 4th write is the one that actually writes the
+    value to the register. This allows determining write latency solely
+    from the amount of addresses the register occupies in the CPU address
+    space, and the width of the CSR bus.
 
     Parameters
     ----------
@@ -282,14 +300,16 @@ class Decoder(Elaboratable):
     Usage
     -----
 
-    Although there is no functional difference between adding a set of registers directly to
-    a :class:`Multiplexer` and adding a set of registers to multiple :class:`Multiplexer`s that are
-    aggregated with a :class:`Decoder`, hierarchical CSR buses are useful for organizing
-    a hierarchical design. If many peripherals are directly served by a single
-    :class:`Multiplexer`, a very large amount of ports will connect the peripheral registers with
-    the decoder, and the cost of decoding logic would not be attributed to specific peripherals.
-    With a decoder, only five signals per peripheral will be used, and the logic could be kept
-    together with the peripheral.
+    Although there is no functional difference between adding a set of
+    registers directly to a :class:`Multiplexer` and adding a set of
+    registers to multiple :class:`Multiplexer`s that are aggregated with
+    a :class:`Decoder`, hierarchical CSR buses are useful for organizing
+    a hierarchical design. If many peripherals are directly served by
+    a single :class:`Multiplexer`, a very large amount of ports will
+    connect the peripheral registers with the decoder, and the cost of
+    decoding logic would not be attributed to specific peripherals.
+    With a decoder, only five signals per peripheral will be used,
+    and the logic could be kept together with the peripheral.
 
     Parameters
     ----------
index e9150b582e5b54ce2b7484c3ff5f1740fecad753..e20c85d1c2606080f230feb40a1e53cb9cc2fd80 100644 (file)
@@ -11,21 +11,24 @@ __all__ = ["WishboneCSRBridge"]
 class WishboneCSRBridge(Elaboratable):
     """Wishbone to CSR bridge.
 
-    A bus bridge for accessing CSR registers from Wishbone. This bridge supports any Wishbone
-    data width greater or equal to CSR data width and performs appropriate address translation.
+    A bus bridge for accessing CSR registers from Wishbone. This bridge
+    supports any Wishbone data width greater or equal to CSR data width
+    and performs appropriate address translation.
 
     Latency
     -------
 
-    Reads and writes always take ``self.data_width // csr_bus.data_width + 1`` cycles to complete,
-    regardless of the select inputs. Write side effects occur simultaneously with acknowledgement.
+    Reads and writes always take ``self.data_width // csr_bus.data_width +
+    1`` cycles to complete, regardless of the select inputs. Write side
+    effects occur simultaneously with acknowledgement.
 
     Parameters
     ----------
     csr_bus : :class:`..csr.Interface`
         CSR bus driven by the bridge.
     data_width : int or None
-        Wishbone bus data width. If not specified, defaults to ``csr_bus.data_width``.
+        Wishbone bus data width. If not specified, defaults to
+        ``csr_bus.data_width``.
 
     Attributes
     ----------
index b3a338692ae45ce48229d6df7c8611e45fdffdbf..4f130c530a4d36bfd4ea48a39eefd7a7145d69a4 100644 (file)
@@ -48,19 +48,21 @@ class _RangeMap:
 class MemoryMap:
     """Memory map.
 
-    A memory map is a hierarchical description of an address space, describing the structure of
-    address decoders of peripherals as well as bus bridges. It is built by adding resources
-    (range allocations for registers, memory, etc) and windows (range allocations for bus bridges),
-    and can be queried later to determine the address of any given resource from a specific
-    vantage point in the design.
+    A memory map is a hierarchical description of an address space,
+    describing the structure of address decoders of peripherals as well
+    as bus bridges. It is built by adding resources (range allocations
+    for registers, memory, etc) and windows (range allocations for bus
+    bridges), and can be queried later to determine the address of any
+    given resource from a specific vantage point in the design.
 
     Address assignment
     ------------------
 
-    To simplify address assignment, each memory map has an implicit next address, starting at 0.
-    If a resource or a window is added without specifying an address explicitly, the implicit next
-    address is used. In any case, the implicit next address is set to the address immediately
-    following the newly added resource or window.
+    To simplify address assignment, each memory map has an implicit
+    next address, starting at 0.  If a resource or a window is added
+    without specifying an address explicitly, the implicit next address
+    is used. In any case, the implicit next address is set to the address
+    immediately following the newly added resource or window.
 
     Parameters
     ----------
@@ -69,9 +71,9 @@ class MemoryMap:
     data_width : int
         Data width.
     alignment : int
-        Range alignment. Each added resource and window will be placed at an address that is
-        a multiple of ``2 ** alignment``, and its size will be rounded up to be a multiple of
-        ``2 ** alignment``.
+        Range alignment. Each added resource and window will be placed
+        at an address that is a multiple of ``2 ** alignment``, and its
+        size will be rounded up to be a multiple of ``2 ** alignment``.
     """
     def __init__(self, *, addr_width, data_width, alignment=0):
         if not isinstance(addr_width, int) or addr_width <= 0:
@@ -106,8 +108,8 @@ class MemoryMap:
         Arguments
         ---------
         alignment : int
-            Address alignment. The start of the implicit next address will be a multiple of
-            ``2 ** max(alignment, self.alignment)``.
+            Address alignment. The start of the implicit next address
+            will be a multiple of ``2 ** max(alignment, self.alignment)``.
 
         Return value
         ------------
@@ -162,31 +164,35 @@ class MemoryMap:
     def add_resource(self, resource, *, size, addr=None, alignment=None):
         """Add a resource.
 
-        A resource is any device on the bus that is a destination for bus transactions, e.g.
-        a register or a memory block.
+        A resource is any device on the bus that is a destination for
+        bus transactions, e.g.  a register or a memory block.
 
         Arguments
         ---------
         resource : object
             Arbitrary object representing a resource.
         addr : int or None
-            Address of the resource. If ``None``, the implicit next address will be used.
-            Otherwise, the exact specified address (which must be a multiple of
+            Address of the resource. If ``None``, the implicit next
+            address will be used.  Otherwise, the exact specified address
+            (which must be a multiple of
             ``2 ** max(alignment, self.alignment)``) will be used.
         size : int
-            Size of the resource, in minimal addressable units. Rounded up to a multiple of
-            ``2 ** max(alignment, self.alignment)``.
+            Size of the resource, in minimal addressable units. Rounded
+            up to a multiple of ``2 ** max(alignment, self.alignment)``.
         alignment : int or None
-            Alignment of the resource. If not specified, the memory map alignment is used.
+            Alignment of the resource. If not specified, the memory map
+            alignment is used.
 
         Return value
         ------------
-        A tuple ``(start, end)`` describing the address range assigned to the resource.
+        A tuple ``(start, end)`` describing the address range assigned
+        to the resource.
 
         Exceptions
         ----------
-        Raises :exn:`ValueError` if the requested address and size, after alignment, would overlap
-        with any resources or windows that have already been added, or would be out of bounds.
+        Raises :exn:`ValueError` if the requested address and size,
+        after alignment, would overlap with any resources or windows
+        that have already been added, or would be out of bounds.
         """
         if resource in self._resources:
             addr_range = self._resources[resource]
@@ -214,7 +220,8 @@ class MemoryMap:
 
         Yield values
         ------------
-        A tuple ``resource, (start, end)`` describing the address range assigned to the resource.
+        A tuple ``resource, (start, end)`` describing the address range
+        assigned to the resource.
         """
         for resource, resource_range in self._resources.items():
             yield resource, (resource_range.start, resource_range.stop)
@@ -222,47 +229,56 @@ class MemoryMap:
     def add_window(self, window, *, addr=None, sparse=None):
         """Add a window.
 
-        A window is a device on a bus that provides access to a different bus, i.e. a bus bridge.
-        It performs address translation, such that the devices on a subordinate bus have different
-        addresses; the memory map reflects this address translation when resources are looked up
-        through the window.
+        A window is a device on a bus that provides access to a different
+        bus, i.e. a bus bridge.  It performs address translation, such
+        that the devices on a subordinate bus have different addresses;
+        the memory map reflects this address translation when resources
+        are looked up through the window.
 
         Sparse addressing
         -----------------
 
-        If a narrow bus is bridged to a wide bus, the bridge can perform *sparse* or *dense*
-        address translation. In the sparse case, each transaction on the wide bus results in
-        one transaction on the narrow bus; high data bits on the wide bus are ignored, and any
-        contiguous resource on the narrow bus becomes discontiguous on the wide bus. In the dense
-        case, each transaction on the wide bus results in several transactions on the narrow bus,
-        and any contiguous resource on the narrow bus stays contiguous on the wide bus.
+        If a narrow bus is bridged to a wide bus, the bridge can perform
+        *sparse* or *dense* address translation. In the sparse case,
+        each transaction on the wide bus results in one transaction on
+        the narrow bus; high data bits on the wide bus are ignored, and
+        any contiguous resource on the narrow bus becomes discontiguous
+        on the wide bus. In the dense case, each transaction on the
+        wide bus results in several transactions on the narrow bus,
+        and any contiguous resource on the narrow bus stays contiguous
+        on the wide bus.
 
         Arguments
         ---------
         window : :class:`MemoryMap`
             A memory map describing the layout of the window.
         addr : int or None
-            Address of the window. If ``None``, the implicit next address will be used after
-            aligning it to ``2 ** window.addr_width``. Otherwise, the exact specified address
-            (which must be a multiple of ``2 ** window.addr_width``) will be used.
+            Address of the window. If ``None``, the implicit
+            next address will be used after aligning it to ``2 **
+            window.addr_width``. Otherwise, the exact specified address
+            (which must be a multiple of ``2 ** window.addr_width``)
+            will be used.
         sparse : bool or None
-            Address translation type. Ignored if the datapath widths of both memory maps are
-            equal; must be specified otherwise.
+            Address translation type. Ignored if the datapath widths of
+            both memory maps are equal; must be specified otherwise.
 
         Return value
         ------------
-        A tuple ``(start, end, ratio)`` describing the address range assigned to the window.
-        When bridging buses of unequal data width, ``ratio`` is the amount of contiguous addresses
-        on the narrower bus that are accessed for each transaction on the wider bus. Otherwise,
-        it is always 1.
+        A tuple ``(start, end, ratio)`` describing the address range
+        assigned to the window.  When bridging buses of unequal data
+        width, ``ratio`` is the amount of contiguous addresses on the
+        narrower bus that are accessed for each transaction on the wider
+        bus. Otherwise, it is always 1.
 
         Exceptions
         ----------
-        Raises :exn:`ValueError` if the requested address and size, after alignment, would overlap
-        with any resources or windows that have already been added, or would be out of bounds;
-        if the added memory map has wider datapath than this memory map; if dense address
-        translation is used and the datapath width of this memory map is not an integer multiple
-        of the datapath width of the added memory map.
+        Raises :exn:`ValueError` if the requested address and size,
+        after alignment, would overlap with any resources or windows
+        that have already been added, or would be out of bounds; if
+        the added memory map has wider datapath than this memory map;
+        if dense address translation is used and the datapath width of
+        this memory map is not an integer multiple of the datapath width
+        of the added memory map.
         """
         if not isinstance(window, MemoryMap):
             raise TypeError("Window must be a MemoryMap, not {!r}"
@@ -313,10 +329,11 @@ class MemoryMap:
 
         Yield values
         ------------
-        A tuple ``window, (start, end, ratio)`` describing the address range assigned to
-        the window. When bridging buses of unequal data width, ``ratio`` is the amount of
-        contiguous addresses on the narrower bus that are accessed for each transaction on
-        the wider bus. Otherwise, it is always 1.
+        A tuple ``window, (start, end, ratio)`` describing the address
+        range assigned to the window. When bridging buses of unequal
+        data width, ``ratio`` is the amount of contiguous addresses on
+        the narrower bus that are accessed for each transaction on the
+        wider bus. Otherwise, it is always 1.
         """
         for window, window_range in self._windows.items():
             yield window, (window_range.start, window_range.stop, window_range.step)
@@ -328,11 +345,13 @@ class MemoryMap:
 
         Yield values
         ------------
-        A tuple ``window, (pattern, ratio)`` describing the address range assigned to the window.
-        ``pattern`` is a ``self.addr_width`` wide pattern that may be used in ``Case`` or ``match``
-        to determine if an address signal is within the address range of ``window``. When bridging
-        buses of unequal data width, ``ratio`` is the amount of contiguous addresses on
-        the narrower bus that are accessed for each transaction on the wider bus. Otherwise,
+        A tuple ``window, (pattern, ratio)`` describing the address range
+        assigned to the window.  ``pattern`` is a ``self.addr_width``
+        wide pattern that may be used in ``Case`` or ``match`` to
+        determine if an address signal is within the address range of
+        ``window``. When bridging buses of unequal data width, ``ratio``
+        is the amount of contiguous addresses on the narrower bus that
+        are accessed for each transaction on the wider bus. Otherwise,
         it is always 1.
         """
         for window, window_range in self._windows.items():
@@ -355,15 +374,15 @@ class MemoryMap:
     def all_resources(self):
         """Iterate all resources and their address ranges.
 
-        Recursively iterate all resources in ascending order of their address, performing address
-        translation for resources that are located behind a window.
+        Recursively iterate all resources in ascending order of their
+        address, performing address translation for resources that are
+        located behind a window.
 
-        Yield values
-        ------------
-        A tuple ``resource, (start, end, width)`` describing the address range assigned to
-        the resource. ``width`` is the amount of data bits accessed at each address, which may be
-        equal to ``self.data_width``, or less if the resource is located behind a window that
-        uses sparse addressing.
+        Yield values ------------ A tuple ``resource, (start,
+        end, width)`` describing the address range assigned to the
+        resource. ``width`` is the amount of data bits accessed at each
+        address, which may be equal to ``self.data_width``, or less if the
+        resource is located behind a window that uses sparse addressing.
         """
         for addr_range, assignment in self._ranges.items():
             if assignment in self._resources:
@@ -377,8 +396,9 @@ class MemoryMap:
     def find_resource(self, resource):
         """Find address range corresponding to a resource.
 
-        Recursively find the address range of a resource, performing address translation for
-        resources that are located behind a window.
+        Recursively find the address range of a resource, performing
+        address translation for resources that are located behind
+        a window.
 
         Arguments
         ---------
@@ -387,10 +407,11 @@ class MemoryMap:
 
         Return value
         ------------
-        A tuple ``(start, end, width)`` describing the address range assigned to the resource.
-        ``width`` is the amount of data bits accessed at each address, which may be equal to
-        ``self.data_width``, or less if the resource is located behind a window that uses sparse
-        addressing.
+        A tuple ``(start, end, width)`` describing the address
+        range assigned to the resource.  ``width`` is the amount of
+        data bits accessed at each address, which may be equal to
+        ``self.data_width``, or less if the resource is located behind
+        a window that uses sparse addressing.
 
         Exceptions
         ----------
@@ -418,7 +439,8 @@ class MemoryMap:
 
         Return value
         ------------
-        A resource mapped to the provided address, or ``None`` if there is no such resource.
+        A resource mapped to the provided address, or ``None`` if there
+        is no such resource.
         """
         assignment = self._ranges.get(address)
         if assignment is None:
index 779e95c893ba0c4f53992ebc88005dff488f240c..588238abecd547c2b01982a31726b137749cda85 100644 (file)
@@ -15,11 +15,14 @@ class RoundRobin(Elaboratable):
     Attributes
     ----------
     request : Signal(n)
-        Signal where a '1' on the i-th bit represents an incoming request from the i-th device.
+        Signal where a '1' on the i-th bit represents an incoming request
+        from the i-th device.
     grant : Signal(range(n))
-        Signal that equals to the index of the device which is currently granted access.
+        Signal that equals to the index of the device which is currently
+        granted access.
     stb : Signal()
-        Strobe signal to enable granting access to the next device requesting. Externally driven.
+        Strobe signal to enable granting access to the next device
+        requesting. Externally driven.
     """
     def __init__(self, n):
         self.n = n
@@ -41,4 +44,4 @@ class RoundRobin(Elaboratable):
                             with m.If(self.request[t]):
                                 m.d.sync += self.grant.eq(t)
 
-        return m
\ No newline at end of file
+        return m
index bd3656e1844b1642fe8ddb887b4e1176aadc6744..12fb58098a87402589a9c24bb31a1ad24888afc5 100644 (file)
@@ -271,7 +271,7 @@ class DecoderTestCase(unittest.TestCase):
 
     def test_add_wrong_sub_bus(self):
         with self.assertRaisesRegex(TypeError,
-                r"Subordinate bus must be an instance of csr\.Interface, not 1"):
+               r"Subordinate bus must be an instance of csr\.Interface, not 1"):
             self.dut.add(1)
 
     def test_add_wrong_data_width(self):
index 48dd43f2af6fb57986dead32e7f062b662f6956d..a754d18554f39e6e274efc9cdddc999cac16b80b 100644 (file)
@@ -38,7 +38,8 @@ class WishboneCSRBridgeTestCase(unittest.TestCase):
     def test_wrong_csr_bus_data_width(self):
         with self.assertRaisesRegex(ValueError,
                 r"CSR bus data width must be one of 8, 16, 32, 64, not 7"):
-            WishboneCSRBridge(csr_bus=csr.Interface(addr_width=10, data_width=7))
+            WishboneCSRBridge(csr_bus=csr.Interface(addr_width=10,
+                              data_width=7))
 
     def test_narrow(self):
         mux   = csr.Multiplexer(addr_width=10, data_width=8)
index 1e61511849197bdf1afdeef764b69b0f48f36c87..040f7774846cfcfcb6b625b1d754e7d4b63222a4 100644 (file)
@@ -86,7 +86,8 @@ class MemoryMapTestCase(unittest.TestCase):
     def test_add_resource_wrong_address_unaligned(self):
         memory_map = MemoryMap(addr_width=16, data_width=8, alignment=1)
         with self.assertRaisesRegex(ValueError,
-                r"Explicitly specified address 0x1 must be a multiple of 0x2 bytes"):
+                r"Explicitly specified address 0x1 must be "
+                r"a multiple of 0x2 bytes"):
             memory_map.add_resource("a", size=1, addr=1)
 
     def test_add_resource_wrong_size(self):
@@ -104,19 +105,20 @@ class MemoryMapTestCase(unittest.TestCase):
     def test_add_resource_wrong_out_of_bounds(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         with self.assertRaisesRegex(ValueError,
-                r"Address range 0x10000\.\.0x10001 out of bounds for memory map spanning "
-                r"range 0x0\.\.0x10000 \(16 address bits\)"):
+                r"Address range 0x10000\.\.0x10001 out of bounds for memory "
+                r"map spanning range 0x0\.\.0x10000 \(16 address bits\)"):
             memory_map.add_resource("a", addr=0x10000, size=1)
         with self.assertRaisesRegex(ValueError,
-                r"Address range 0x0\.\.0x10001 out of bounds for memory map spanning "
-                r"range 0x0\.\.0x10000 \(16 address bits\)"):
+                r"Address range 0x0\.\.0x10001 out of bounds for memory map "
+                r"spanning range 0x0\.\.0x10000 \(16 address bits\)"):
             memory_map.add_resource("a", size=0x10001)
 
     def test_add_resource_wrong_overlap(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         memory_map.add_resource("a", size=16)
         with self.assertRaisesRegex(ValueError,
-                r"Address range 0xa\.\.0xb overlaps with resource 'a' at 0x0\.\.0x10"):
+                r"Address range 0xa\.\.0xb overlaps with resource "
+                r"'a' at 0x0\.\.0x10"):
             memory_map.add_resource("b", size=1, addr=10)
 
     def test_add_resource_wrong_twice(self):
@@ -138,19 +140,22 @@ class MemoryMapTestCase(unittest.TestCase):
     def test_add_window(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         self.assertEqual(memory_map.add_resource("a", size=1), (0, 1))
-        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10, data_width=8)),
+        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10,
+                                                         data_width=8)),
                          (0x400, 0x800, 1))
         self.assertEqual(memory_map.add_resource("b", size=1), (0x800, 0x801))
 
     def test_add_window_sparse(self):
         memory_map = MemoryMap(addr_width=16, data_width=32)
-        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10, data_width=8),
+        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10,
+                                                         data_width=8),
                                                sparse=True),
                          (0, 0x400, 1))
 
     def test_add_window_dense(self):
         memory_map = MemoryMap(addr_width=16, data_width=32)
-        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10, data_width=8),
+        self.assertEqual(memory_map.add_window(MemoryMap(addr_width=10,
+                                                         data_width=8),
                                                sparse=False),
                          (0, 0x100, 4))
 
@@ -163,39 +168,44 @@ class MemoryMapTestCase(unittest.TestCase):
     def test_add_window_wrong_wider(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         with self.assertRaisesRegex(ValueError,
-                r"Window has data width 16, and cannot be added to a memory map "
-                r"with data width 8"):
+                r"Window has data width 16, and cannot be added to a memory "
+                r"map with data width 8"):
             memory_map.add_window(MemoryMap(addr_width=10, data_width=16))
 
     def test_add_window_wrong_no_mode(self):
         memory_map = MemoryMap(addr_width=16, data_width=16)
         with self.assertRaisesRegex(ValueError,
-                r"Address translation mode must be explicitly specified when adding "
-                r"a window with data width 8 to a memory map with data width 16"):
+                r"Address translation mode must be explicitly specified "
+                r"when adding a window with data width 8 to a memory map "
+                r"with data width 16"):
             memory_map.add_window(MemoryMap(addr_width=10, data_width=8))
 
     def test_add_window_wrong_ratio(self):
         memory_map = MemoryMap(addr_width=16, data_width=16)
         with self.assertRaisesRegex(ValueError,
-                r"Dense addressing cannot be used because the memory map data width "
-                r"16 is not an integer multiple of window data width 7"):
-            memory_map.add_window(MemoryMap(addr_width=10, data_width=7), sparse=False)
+                r"Dense addressing cannot be used because the memory map "
+                r"data width 16 is not an integer multiple of window data "
+                r"width 7"):
+            memory_map.add_window(MemoryMap(addr_width=10, data_width=7),
+                                            sparse=False)
 
     def test_add_window_wrong_overlap(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         memory_map.add_window(MemoryMap(addr_width=10, data_width=8))
         with self.assertRaisesRegex(ValueError,
                 r"Address range 0x200\.\.0x600 overlaps with window "
-                r"<nmigen_soc\.memory\.MemoryMap object at .+?> at 0x0\.\.0x400"):
-            memory_map.add_window(MemoryMap(addr_width=10, data_width=8), addr=0x200)
+                r"<nmigen_soc\.memory\.MemoryMap object at .+?> "
+                r"at 0x0\.\.0x400"):
+            memory_map.add_window(MemoryMap(addr_width=10, data_width=8),
+                                  addr=0x200)
 
     def test_add_window_wrong_twice(self):
         memory_map = MemoryMap(addr_width=16, data_width=8)
         window = MemoryMap(addr_width=10, data_width=8)
         memory_map.add_window(window)
         with self.assertRaisesRegex(ValueError,
-                r"Window <nmigen_soc\.memory\.MemoryMap object at .+?> is already added "
-                r"at address range 0x0\.\.0x400"):
+                r"Window <nmigen_soc\.memory\.MemoryMap object at .+?> is "
+                r"already added at address range 0x0\.\.0x400"):
             memory_map.add_window(window)
 
     def test_iter_windows(self):
index 63d410950403dbbbd9060067fa712dffacf70a04..7360edc8d1a0a5f6c6810bd1eada6e4acd8a26fc 100644 (file)
@@ -47,7 +47,8 @@ class InterfaceTestCase(unittest.TestCase):
 
     def test_features(self):
         iface = Interface(addr_width=32, data_width=32,
-                          features={"rty", "err", "stall", "lock", "cti", "bte"})
+                          features={"rty", "err", "stall", "lock",
+                                     "cti", "bte"})
         self.assertEqual(iface.layout, Layout.cast([
             ("adr",   32, DIR_FANOUT),
             ("dat_w", 32, DIR_FANOUT),
@@ -104,32 +105,40 @@ class DecoderTestCase(unittest.TestCase):
 
     def test_add_wrong(self):
         with self.assertRaisesRegex(TypeError,
-                r"Subordinate bus must be an instance of wishbone\.Interface, not 'foo'"):
+                r"Subordinate bus must be an instance of "
+                r"wishbone\.Interface, not 'foo'"):
             self.dut.add("foo")
 
     def test_add_wrong_granularity(self):
         with self.assertRaisesRegex(ValueError,
                 r"Subordinate bus has granularity 32, which is greater than "
                 r"the decoder granularity 16"):
-            self.dut.add(Interface(addr_width=15, data_width=32, granularity=32))
+            self.dut.add(Interface(addr_width=15, data_width=32,
+                                   granularity=32))
 
     def test_add_wrong_width_dense(self):
         with self.assertRaisesRegex(ValueError,
-                r"Subordinate bus has data width 16, which is not the same as decoder "
+                r"Subordinate bus has data width 16, which is not the "
+                r"same as decoder "
                 r"data width 32 \(required for dense address translation\)"):
-            self.dut.add(Interface(addr_width=15, data_width=16, granularity=16))
+            self.dut.add(Interface(addr_width=15, data_width=16,
+                                   granularity=16))
 
     def test_add_wrong_granularity_sparse(self):
         with self.assertRaisesRegex(ValueError,
-                r"Subordinate bus has data width 64, which is not the same as subordinate "
-                r"bus granularity 16 \(required for sparse address translation\)"):
-            self.dut.add(Interface(addr_width=15, data_width=64, granularity=16), sparse=True)
+                r"Subordinate bus has data width 64, which is not the same "
+                r"as subordinate bus granularity 16 \(required for "
+                r"sparse address translation\)"):
+            self.dut.add(Interface(addr_width=15, data_width=64,
+                                   granularity=16), sparse=True)
 
     def test_add_wrong_optional_output(self):
         with self.assertRaisesRegex(ValueError,
-                r"Subordinate bus has optional output 'err', but the decoder does "
+                r"Subordinate bus has optional output 'err', "
+                r"but the decoder does "
                 r"not have a corresponding input"):
-            self.dut.add(Interface(addr_width=15, data_width=32, granularity=16, features={"err"}))
+            self.dut.add(Interface(addr_width=15, data_width=32,
+                                    granularity=16, features={"err"}))
 
 
 class DecoderSimulationTestCase(unittest.TestCase):
@@ -140,7 +149,8 @@ class DecoderSimulationTestCase(unittest.TestCase):
         self.assertEqual(dut.add(sub_1, addr=0x10000),
                          (0x10000, 0x20000, 1))
         sub_2 = Interface(addr_width=14, data_width=32, granularity=8,
-                          features={"err", "rty", "stall", "lock", "cti", "bte"})
+                          features={"err", "rty", "stall", "lock",
+                                    "cti", "bte"})
         self.assertEqual(dut.add(sub_2),
                          (0x20000, 0x30000, 1))
 
@@ -228,7 +238,8 @@ class DecoderSimulationTestCase(unittest.TestCase):
 
                 for index, sel_bit in enumerate(self.bus.sel):
                     with m.If(sel_bit):
-                        segment = self.bus.dat_r.word_select(index, self.bus.granularity)
+                        segment = self.bus.dat_r.word_select(index,
+                                                    self.bus.granularity)
                         m.d.comb += segment.eq(self.bus.adr + index)
 
                 return m
@@ -338,30 +349,37 @@ class ArbiterTestCase(unittest.TestCase):
 
     def test_add_wrong(self):
         with self.assertRaisesRegex(TypeError,
-                r"Initiator bus must be an instance of wishbone\.Interface, not 'foo'"):
+                r"Initiator bus must be an instance of "
+                r"wishbone\.Interface, not 'foo'"):
             self.dut.add("foo")
 
     def test_add_wrong_addr_width(self):
         with self.assertRaisesRegex(ValueError,
-                r"Initiator bus has address width 15, which is not the same as arbiter "
+                r"Initiator bus has address width 15, which is "
+                r"not the same as arbiter "
                 r"address width 31"):
-            self.dut.add(Interface(addr_width=15, data_width=32, granularity=16))
+            self.dut.add(Interface(addr_width=15, data_width=32,
+                                   granularity=16))
 
     def test_add_wrong_granularity(self):
         with self.assertRaisesRegex(ValueError,
                 r"Initiator bus has granularity 8, which is lesser than "
                 r"the arbiter granularity 16"):
-            self.dut.add(Interface(addr_width=31, data_width=32, granularity=8))
+            self.dut.add(Interface(addr_width=31, data_width=32,
+                                   granularity=8))
 
     def test_add_wrong_data_width(self):
         with self.assertRaisesRegex(ValueError,
-                r"Initiator bus has data width 16, which is not the same as arbiter "
+                r"Initiator bus has data width 16, which is not "
+                r"the same as arbiter "
                 r"data width 32"):
-            self.dut.add(Interface(addr_width=31, data_width=16, granularity=16))
+            self.dut.add(Interface(addr_width=31, data_width=16,
+                                   granularity=16))
 
     def test_add_wrong_optional_output(self):
         with self.assertRaisesRegex(ValueError,
-                r"Initiator bus has optional output 'lock', but the arbiter does "
+                r"Initiator bus has optional output 'lock', but "
+                r"the arbiter does "
                 r"not have a corresponding input"):
             self.dut.add(Interface(addr_width=31, data_width=32, granularity=16,
                                    features={"lock"}))
@@ -374,7 +392,8 @@ class ArbiterSimulationTestCase(unittest.TestCase):
         itor_1 = Interface(addr_width=30, data_width=32, granularity=8)
         dut.add(itor_1)
         itor_2 = Interface(addr_width=30, data_width=32, granularity=16,
-                           features={"err", "rty", "stall", "lock", "cti", "bte"})
+                           features={"err", "rty", "stall", "lock",
+                                   "cti", "bte"})
         dut.add(itor_2)
 
         def sim_test():
index 039413dff018847be07524e1a02e6d559006602a..ba5bc86efab1ff37d0e0989cfb0237f35ec07924 100644 (file)
@@ -30,13 +30,15 @@ class BurstTypeExt(Enum):
 class Interface(Record):
     """Wishbone interface.
 
-    See the `Wishbone specification <https://opencores.org/howto/wishbone>`_ for description
-    of the Wishbone signals. The ``RST_I`` and ``CLK_I`` signals are provided as a part of
-    the clock domain that drives the interface.
+    See the `Wishbone specification
+    <https://opencores.org/howto/wishbone>`_ for description of the
+    Wishbone signals. The ``RST_I`` and ``CLK_I`` signals are provided
+    as a part of the clock domain that drives the interface.
 
-    Note that the data width of the underlying memory map of the interface is equal to port
-    granularity, not port size. If port granularity is less than port size, then the address width
-    of the underlying memory map is extended to reflect that.
+    Note that the data width of the underlying memory map of the interface
+    is equal to port granularity, not port size. If port granularity is
+    less than port size, then the address width of the underlying memory
+    map is extended to reflect that.
 
     Parameters
     ----------
@@ -46,9 +48,9 @@ class Interface(Record):
         Width of the data signals ("port size" in Wishbone terminology).
         One of 8, 16, 32, 64.
     granularity : int or None
-        Granularity of select signals ("port granularity" in Wishbone terminology).
-        One of 8, 16, 32, 64. Optional and defaults to None, meaning it is equal
-        to the address width.
+        Granularity of select signals ("port granularity" in Wishbone
+        terminology).  One of 8, 16, 32, 64. Optional and defaults to
+        None, meaning it is equal to the address width.
     features : iter(str)
         Selects the optional signals that will be a part of this interface.
     alignment : int
@@ -58,37 +60,52 @@ class Interface(Record):
 
     Attributes
     ----------
-    The correspondence between the nMigen-SoC signals and the Wishbone signals changes depending
-    on whether the interface acts as an initiator or a target.
+    The correspondence between the nMigen-SoC signals and the Wishbone
+    signals changes depending on whether the interface acts as an
+    initiator or a target.
 
     adr : Signal(addr_width)
-        Corresponds to Wishbone signal ``ADR_O`` (initiator) or ``ADR_I`` (target).
+        Corresponds to Wishbone signal ``ADR_O`` (initiator) or ``ADR_I``
+        (target).
     dat_w : Signal(data_width)
-        Corresponds to Wishbone signal ``DAT_O`` (initiator) or ``DAT_I`` (target).
+        Corresponds to Wishbone signal ``DAT_O`` (initiator) or ``DAT_I``
+        (target).
     dat_r : Signal(data_width)
-        Corresponds to Wishbone signal ``DAT_I`` (initiator) or ``DAT_O`` (target).
+        Corresponds to Wishbone signal ``DAT_I`` (initiator) or ``DAT_O``
+        (target).
     sel : Signal(data_width // granularity)
-        Corresponds to Wishbone signal ``SEL_O`` (initiator) or ``SEL_I`` (target).
+        Corresponds to Wishbone signal ``SEL_O`` (initiator) or ``SEL_I``
+        (target).
     cyc : Signal()
-        Corresponds to Wishbone signal ``CYC_O`` (initiator) or ``CYC_I`` (target).
+        Corresponds to Wishbone signal ``CYC_O`` (initiator) or ``CYC_I``
+        (target).
     stb : Signal()
-        Corresponds to Wishbone signal ``STB_O`` (initiator) or ``STB_I`` (target).
+        Corresponds to Wishbone signal ``STB_O`` (initiator) or ``STB_I``
+        (target).
     we : Signal()
-        Corresponds to Wishbone signal ``WE_O``  (initiator) or ``WE_I``  (target).
+        Corresponds to Wishbone signal ``WE_O``  (initiator) or ``WE_I``
+        (target).
     ack : Signal()
-        Corresponds to Wishbone signal ``ACK_I`` (initiator) or ``ACK_O`` (target).
+        Corresponds to Wishbone signal ``ACK_I`` (initiator) or ``ACK_O``
+        (target).
     err : Signal()
-        Optional. Corresponds to Wishbone signal ``ERR_I`` (initiator) or ``ERR_O`` (target).
+        Optional. Corresponds to Wishbone signal ``ERR_I`` (initiator)
+        or ``ERR_O`` (target).
     rty : Signal()
-        Optional. Corresponds to Wishbone signal ``RTY_I`` (initiator) or ``RTY_O`` (target).
+        Optional. Corresponds to Wishbone signal ``RTY_I`` (initiator)
+        or ``RTY_O`` (target).
     stall : Signal()
-        Optional. Corresponds to Wishbone signal ``STALL_I`` (initiator) or ``STALL_O`` (target).
+        Optional. Corresponds to Wishbone signal ``STALL_I`` (initiator)
+        or ``STALL_O`` (target).
     lock : Signal()
-        Optional. Corresponds to Wishbone signal ``LOCK_O`` (initiator) or ``LOCK_I`` (target).
+        Optional. Corresponds to Wishbone signal ``LOCK_O`` (initiator)
+        or ``LOCK_I`` (target).
     cti : Signal()
-        Optional. Corresponds to Wishbone signal ``CTI_O`` (initiator) or ``CTI_I`` (target).
+        Optional. Corresponds to Wishbone signal ``CTI_O`` (initiator)
+        or ``CTI_I`` (target).
     bte : Signal()
-        Optional. Corresponds to Wishbone signal ``BTE_O`` (initiator) or ``BTE_I`` (target).
+        Optional. Corresponds to Wishbone signal ``BTE_O`` (initiator)
+        or ``BTE_I`` (target).
     """
     def __init__(self, *, addr_width, data_width, granularity=None, features=frozenset(),
                  alignment=0, name=None):
@@ -216,12 +233,14 @@ class Decoder(Elaboratable):
     def add(self, sub_bus, *, addr=None, sparse=False):
         """Add a window to a subordinate bus.
 
-        The decoder can perform either sparse or dense address translation. If dense address
-        translation is used (the default), the subordinate bus must have the same data width as
-        the decoder; the window will be contiguous. If sparse address translation is used,
-        the subordinate bus may have data width less than the data width of the decoder;
-        the window may be discontiguous. In either case, the granularity of the subordinate bus
-        must be equal to or less than the granularity of the decoder.
+        The decoder can perform either sparse or dense address
+        translation. If dense address translation is used (the default),
+        the subordinate bus must have the same data width as the decoder;
+        the window will be contiguous. If sparse address translation is
+        used, the subordinate bus may have data width less than the data
+        width of the decoder; the window may be discontiguous. In either
+        case, the granularity of the subordinate bus must be equal to
+        or less than the granularity of the decoder.
 
         See :meth:`MemoryMap.add_resource` for details.
         """
@@ -319,8 +338,8 @@ class Arbiter(Elaboratable):
     features : iter(str)
         Optional signal set for the shared bus. See :class:`Interface`.
     scheduler : str
-        Method for bus arbitration. Optional and defaults to "rr" (Round Robin, see
-        :class:`scheduler.RoundRobin`).
+        Method for bus arbitration. Optional and defaults to "rr"
+        (Round Robin, see :class:`scheduler.RoundRobin`).
 
     Attributes
     ----------
@@ -340,9 +359,9 @@ class Arbiter(Elaboratable):
     def add(self, itor_bus):
         """Add an initiator bus to the arbiter.
 
-        The initiator bus must have the same address width and data width as the arbiter. The
-        granularity of the initiator bus must be greater than or equal to the granularity of
-        the arbiter.
+        The initiator bus must have the same address width and data
+        width as the arbiter. The granularity of the initiator bus must
+        be greater than or equal to the granularity of the arbiter.
         """
         if not isinstance(itor_bus, Interface):
             raise TypeError("Initiator bus must be an instance of wishbone.Interface, not {!r}"
@@ -452,16 +471,17 @@ class InterconnectShared(Elaboratable):
         If the item is a :class:`Record`, its fields must be named using the
         convention of :class:`Interface`.
     targets : list of (:class:`Interface` OR tuple of (:class:`Interface`, int))
-        List of SLAVEs on the decoder whose accesses are to be targeted by the shared bus.
-        If the item is a tuple of (intf, addr), the :class:`Interface`-type intf is added
-        at the (address width + granularity bits)-wide address of the int-type addr.
+        List of SLAVEs on the decoder whose accesses are to be targeted
+        by the shared bus.  If the item is a tuple of (intf, addr), the
+        :class:`Interface`-type intf is added at the (address width +
+        granularity bits)-wide address of the int-type addr.
     granularity : int or None
         Granularity of the shared bus. Optional. See :class:`Interface`.
     features : iter(str)
         Optional signal set for the shared bus. See :class:`Interface`.
     scheduler : str
-        Method for bus arbitration for the arbiter. Optional and defaults to "rr" (Round Robin, see
-        :class:`scheduler.RoundRobin`).
+        Method for bus arbitration for the arbiter. Optional and defaults
+        to "rr" (Round Robin, see :class:`scheduler.RoundRobin`).
     alignment : int
         Window alignment for the decoder. Optional. See :class:`Interface`.
 
index de5c15d551c081a224590ee4ba8706ca3d2d7547..eeeada3cc99c97c4eb246f2d3c7612a7b1bba5e2 100644 (file)
@@ -8,12 +8,14 @@ __all__ = ["SRAM"]
 
 
 class SRAM(Elaboratable):
-    """SRAM module carrying a volatile memory block (implemented with :class:`Memory`)
-    that can be read and write (or only read if the SRAM is read-only) through a Wishbone bus.
+    """SRAM module carrying a volatile memory block (implemented with
+    :class:`Memory`) that can be read and write (or only read if the
+    SRAM is read-only) through a Wishbone bus.
 
-    If no Wishbone bus is specified during initialisation, this creates one whose address width
-    is just enough to fit the whole memory (i.e. equals to the log2(memory depth) rounded up), and
-    whose data width is equal to the memory width.
+    If no Wishbone bus is specified during initialisation, this creates
+    one whose address width is just enough to fit the whole memory
+    (i.e. equals to the log2(memory depth) rounded up), and whose data
+    width is equal to the memory width.
 
     Parameters
     ----------
@@ -22,23 +24,25 @@ class SRAM(Elaboratable):
     read_only : bool
         Whether or not the memory is read-only. Defaults to False.
     bus : :class:`Interface` or None
-        The Wishbone bus interface providing access to the read/write ports of the memory.
-        Optional and defaults to None, which lets this module to instantiate one as described
-        above, having the granularity, features and alignment as specified by their
+        The Wishbone bus interface providing access to the read/write
+        ports of the memory.  Optional and defaults to None, which
+        lets this module to instantiate one as described above, having
+        the granularity, features and alignment as specified by their
         corresponding parameters.
     granularity : int or None
-        If the Wishbone bus is not sepcified, this is the granularity of the Wishbone bus.
-        Optional. See :class:`Interface`.
+        If the Wishbone bus is not sepcified, this is the granularity
+        of the Wishbone bus.  Optional. See :class:`Interface`.
     features : iter(str)
-        If the Wishbone bus is not sepcified, this is the optional signal set for the Wishbone bus.
-        See :class:`Interface`.
+        If the Wishbone bus is not sepcified, this is the optional signal
+        set for the Wishbone bus.  See :class:`Interface`.
 
     Attributes
     ----------
     memory : :class:`Memory`
         The memory to be accessed via the Wishbone bus.
     bus : :class:`Interface`
-        The Wishbone bus interface providing access to the read/write ports of the memory.
+        The Wishbone bus interface providing access to the read/write
+        ports of the memory.
     """
     def __init__(self, memory, read_only=False, bus=None,
                  granularity=None, features=frozenset()):
@@ -86,4 +90,4 @@ class SRAM(Elaboratable):
         with m.If(self.bus.cyc & self.bus.stb & ~self.bus.ack):
             m.d.sync += self.bus.ack.eq(1)
 
-        return m
\ No newline at end of file
+        return m