1 from nmigen
import Array
, Elaboratable
, Module
, Record
, Signal
2 from nmigen
.hdl
.rec
import DIR_FANIN
, DIR_FANOUT
, DIR_NONE
3 from nmigen
.lib
.coding
import PriorityEncoder
6 __all__
= ["Cycle", "wishbone_layout", "WishboneArbiter"]
17 ("adr", 30, DIR_FANOUT
),
18 ("dat_w", 32, DIR_FANOUT
),
19 ("dat_r", 32, DIR_FANIN
),
20 ("sel", 4, DIR_FANOUT
),
21 ("cyc", 1, DIR_FANOUT
),
22 ("stb", 1, DIR_FANOUT
),
23 ("ack", 1, DIR_FANIN
),
24 ("we", 1, DIR_FANOUT
),
25 ("cti", 3, DIR_FANOUT
),
26 ("bte", 2, DIR_FANOUT
),
31 class WishboneArbiter(Elaboratable
):
33 self
.bus
= Record(wishbone_layout
)
34 self
._port
_map
= dict()
36 def port(self
, priority
):
37 if not isinstance(priority
, int) or priority
< 0:
38 raise TypeError("Priority must be a non-negative integer, not '{!r}'"
40 if priority
in self
._port
_map
:
41 raise ValueError("Conflicting priority: '{!r}'".format(priority
))
42 port
= self
._port
_map
[priority
] = Record
.like(self
.bus
)
45 def elaborate(self
, platform
):
48 ports
= [port
for priority
, port
in sorted(self
._port
_map
.items())]
51 m
.d
.comb
+= port
.dat_r
.eq(self
.bus
.dat_r
)
53 bus_pe
= m
.submodules
.bus_pe
= PriorityEncoder(len(ports
))
54 with m
.If(~self
.bus
.cyc
):
55 for j
, port
in enumerate(ports
):
56 m
.d
.sync
+= bus_pe
.i
[j
].eq(port
.cyc
)
58 source
= Array(ports
)[bus_pe
.o
]
60 self
.bus
.adr
.eq(source
.adr
),
61 self
.bus
.dat_w
.eq(source
.dat_w
),
62 self
.bus
.sel
.eq(source
.sel
),
63 self
.bus
.cyc
.eq(source
.cyc
),
64 self
.bus
.stb
.eq(source
.stb
),
65 self
.bus
.we
.eq(source
.we
),
66 self
.bus
.cti
.eq(source
.cti
),
67 self
.bus
.bte
.eq(source
.bte
),
68 source
.ack
.eq(self
.bus
.ack
),
69 source
.err
.eq(self
.bus
.err
)