3 from nmigen
.hdl
.rec
import Direction
4 from nmigen
.utils
import log2_int
6 from ..memory
import MemoryMap
9 __all__
= ["CycleType", "BurstTypeExt", "Interface"]
12 class CycleType(Enum
):
13 """Wishbone Registered Feedback cycle type."""
20 class BurstTypeExt(Enum
):
21 """Wishbone Registered Feedback burst type extension."""
28 class Interface(Record
):
29 """Wishbone interface.
31 See the `Wishbone specification <https://opencores.org/howto/wishbone>`_ for description
32 of the Wishbone signals. The ``RST_I`` and ``CLK_I`` signals are provided as a part of
33 the clock domain that drives the interface.
35 Note that the data width of the underlying memory map of the interface is equal to port
36 granularity, not port size. If port granularity is less than port size, then the address width
37 of the underlying memory map is extended to reflect that.
42 Width of the address signal.
44 Width of the data signals ("port size" in Wishbone terminology).
47 Granularity of select signals ("port granularity" in Wishbone terminology).
50 Selects the optional signals that will be a part of this interface.
52 Resource and window alignment. See :class:`MemoryMap`.
54 Name of the underlying record.
58 The correspondence between the nMigen-SoC signals and the Wishbone signals changes depending
59 on whether the interface acts as an initiator or a target.
61 adr : Signal(addr_width)
62 Corresponds to Wishbone signal ``ADR_O`` (initiator) or ``ADR_I`` (target).
63 dat_w : Signal(data_width)
64 Corresponds to Wishbone signal ``DAT_O`` (initiator) or ``DAT_I`` (target).
65 dat_r : Signal(data_width)
66 Corresponds to Wishbone signal ``DAT_I`` (initiator) or ``DAT_O`` (target).
67 sel : Signal(data_width // granularity)
68 Corresponds to Wishbone signal ``SEL_O`` (initiator) or ``SEL_I`` (target).
70 Corresponds to Wishbone signal ``CYC_O`` (initiator) or ``CYC_I`` (target).
72 Corresponds to Wishbone signal ``STB_O`` (initiator) or ``STB_I`` (target).
74 Corresponds to Wishbone signal ``WE_O`` (initiator) or ``WE_I`` (target).
76 Corresponds to Wishbone signal ``ACK_I`` (initiator) or ``ACK_O`` (target).
78 Optional. Corresponds to Wishbone signal ``ERR_I`` (initiator) or ``ERR_O`` (target).
80 Optional. Corresponds to Wishbone signal ``RTY_I`` (initiator) or ``RTY_O`` (target).
82 Optional. Corresponds to Wishbone signal ``STALL_I`` (initiator) or ``STALL_O`` (target).
84 Optional. Corresponds to Wishbone signal ``CTI_O`` (initiator) or ``CTI_I`` (target).
86 Optional. Corresponds to Wishbone signal ``BTE_O`` (initiator) or ``BTE_I`` (target).
88 def __init__(self
, *, addr_width
, data_width
, granularity
=None, optional
=frozenset(),
89 alignment
=0, name
=None):
90 if not isinstance(addr_width
, int) or addr_width
< 0:
91 raise ValueError("Address width must be a non-negative integer, not {!r}"
93 if data_width
not in (8, 16, 32, 64):
94 raise ValueError("Data width must be one of 8, 16, 32, 64, not {!r}"
96 if granularity
is None:
97 granularity
= data_width
98 elif granularity
not in (8, 16, 32, 64):
99 raise ValueError("Granularity must be one of 8, 16, 32, 64, not {!r}"
100 .format(granularity
))
101 if granularity
> data_width
:
102 raise ValueError("Granularity {} may not be greater than data width {}"
103 .format(granularity
, data_width
))
104 self
.addr_width
= addr_width
105 self
.data_width
= data_width
106 self
.granularity
= granularity
107 granularity_bits
= log2_int(data_width
// granularity
)
108 self
.memory_map
= MemoryMap(addr_width
=max(1, addr_width
+ granularity_bits
),
109 data_width
=data_width
>> granularity_bits
,
112 optional
= set(optional
)
113 unknown
= optional
- {"rty", "err", "stall", "cti", "bte"}
115 raise ValueError("Optional signal(s) {} are not supported"
116 .format(", ".join(map(repr, unknown
))))
118 ("adr", addr_width
, Direction
.FANOUT
),
119 ("dat_w", data_width
, Direction
.FANOUT
),
120 ("dat_r", data_width
, Direction
.FANIN
),
121 ("sel", data_width
// granularity
, Direction
.FANOUT
),
122 ("cyc", 1, Direction
.FANOUT
),
123 ("stb", 1, Direction
.FANOUT
),
124 ("we", 1, Direction
.FANOUT
),
125 ("ack", 1, Direction
.FANIN
),
127 if "err" in optional
:
128 layout
+= [("err", 1, Direction
.FANIN
)]
129 if "rty" in optional
:
130 layout
+= [("rty", 1, Direction
.FANIN
)]
131 if "stall" in optional
:
132 layout
+= [("stall", 1, Direction
.FANIN
)]
133 if "cti" in optional
:
134 layout
+= [("cti", CycleType
, Direction
.FANOUT
)]
135 if "bte" in optional
:
136 layout
+= [("bte", BurstTypeExt
, Direction
.FANOUT
)]
137 super().__init
__(layout
, name
=name
, src_loc_at
=1)