-
Notifications
You must be signed in to change notification settings - Fork 110
/
wishbone.py
86 lines (76 loc) · 2.51 KB
/
wishbone.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
from migen import *
from litex.soc.interconnect import wishbone
from litepcie.common import *
class LitePCIeWishboneBridge(Module):
def __init__(self, endpoint, address_decoder, shadow_base=0x00000000, qword_aligned=False):
self.wishbone = wishbone.Interface()
# # #
port = endpoint.crossbar.get_slave_port(address_decoder)
self.submodules.fsm = fsm = FSM()
update_dat = Signal()
fsm.act("IDLE",
If(port.sink.valid & port.sink.first,
If(port.sink.we,
NextState("WRITE"),
).Else(
NextState("READ")
)
).Else(
port.sink.ready.eq(port.sink.valid)
)
)
self.sync += [
self.wishbone.sel.eq(0xf),
self.wishbone.adr.eq(port.sink.adr[2:] | (shadow_base >> 2)),
If(qword_aligned,
If(port.sink.adr[2],
self.wishbone.dat_w.eq(port.sink.dat[:32])
).Else(
self.wishbone.dat_w.eq(port.sink.dat[32:])
)
).Else(
self.wishbone.dat_w.eq(port.sink.dat[:32]),
)
]
fsm.act("WRITE",
self.wishbone.stb.eq(1),
self.wishbone.we.eq(1),
self.wishbone.cyc.eq(1),
If(self.wishbone.ack,
NextState("TERMINATE")
)
)
fsm.act("READ",
self.wishbone.stb.eq(1),
self.wishbone.we.eq(0),
self.wishbone.cyc.eq(1),
If(self.wishbone.ack,
update_dat.eq(1),
NextState("COMPLETION")
)
)
self.sync += [
port.source.first.eq(1),
port.source.last.eq(1),
port.source.len.eq(1),
port.source.err.eq(0),
port.source.tag.eq(port.sink.tag),
port.source.adr.eq(port.sink.adr),
port.source.cmp_id.eq(endpoint.phy.id),
port.source.req_id.eq(port.sink.req_id),
If(update_dat,
port.source.dat.eq(self.wishbone.dat_r)
)
]
fsm.act("COMPLETION",
port.source.valid.eq(1),
If(port.source.ready,
NextState("TERMINATE")
)
)
fsm.act("TERMINATE",
port.sink.ready.eq(1),
NextState("IDLE")
)