b73598f8c8887ef2fd4fc4c936ddb18afa604d33
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 ``LOCK_O`` (initiator) or ``LOCK_I`` (target).
86 Optional. Corresponds to Wishbone signal ``CTI_O`` (initiator) or ``CTI_I`` (target).
88 Optional. Corresponds to Wishbone signal ``BTE_O`` (initiator) or ``BTE_I`` (target).
90 def __init__(self
, *, addr_width
, data_width
, granularity
=None, optional
=frozenset(),
91 alignment
=0, name
=None):
92 if not isinstance(addr_width
, int) or addr_width
< 0:
93 raise ValueError("Address width must be a non-negative integer, not {!r}"
95 if data_width
not in (8, 16, 32, 64):
96 raise ValueError("Data width must be one of 8, 16, 32, 64, not {!r}"
98 if granularity
is None:
99 granularity
= data_width
100 elif granularity
not in (8, 16, 32, 64):
101 raise ValueError("Granularity must be one of 8, 16, 32, 64, not {!r}"
102 .format(granularity
))
103 if granularity
> data_width
:
104 raise ValueError("Granularity {} may not be greater than data width {}"
105 .format(granularity
, data_width
))
106 self
.addr_width
= addr_width
107 self
.data_width
= data_width
108 self
.granularity
= granularity
109 granularity_bits
= log2_int(data_width
// granularity
)
110 self
.memory_map
= MemoryMap(addr_width
=max(1, addr_width
+ granularity_bits
),
111 data_width
=data_width
>> granularity_bits
,
114 optional
= set(optional
)
115 unknown
= optional
- {"rty", "err", "stall", "lock", "cti", "bte"}
117 raise ValueError("Optional signal(s) {} are not supported"
118 .format(", ".join(map(repr, unknown
))))
120 ("adr", addr_width
, Direction
.FANOUT
),
121 ("dat_w", data_width
, Direction
.FANOUT
),
122 ("dat_r", data_width
, Direction
.FANIN
),
123 ("sel", data_width
// granularity
, Direction
.FANOUT
),
124 ("cyc", 1, Direction
.FANOUT
),
125 ("stb", 1, Direction
.FANOUT
),
126 ("we", 1, Direction
.FANOUT
),
127 ("ack", 1, Direction
.FANIN
),
129 if "err" in optional
:
130 layout
+= [("err", 1, Direction
.FANIN
)]
131 if "rty" in optional
:
132 layout
+= [("rty", 1, Direction
.FANIN
)]
133 if "stall" in optional
:
134 layout
+= [("stall", 1, Direction
.FANIN
)]
135 if "lock" in optional
:
136 layout
+= [("lock", 1, Direction
.FANOUT
)]
137 if "cti" in optional
:
138 layout
+= [("cti", CycleType
, Direction
.FANOUT
)]
139 if "bte" in optional
:
140 layout
+= [("bte", BurstTypeExt
, Direction
.FANOUT
)]
141 super().__init
__(layout
, name
=name
, src_loc_at
=1)