-
Notifications
You must be signed in to change notification settings - Fork 101
/
sdram_mux.py
66 lines (46 loc) · 1.62 KB
/
sdram_mux.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
from migen.genlib.roundrobin import RoundRobin, SP_CE
from migen.fhdl.std import *
from migen.genlib.record import Record
from ovhw.ov_types import sdramHostIf
class SDRAMMux(Module):
def __init__(self, sdctl_port):
self.ports = []
self.downstream = sdctl_port
def getPort(self):
r = Record(sdramHostIf(
flen(self.downstream.d_read),
flen(self.downstream.i_addr)))
self.ports.append(r)
return r
def do_finalize(self):
self.submodules.rr = RoundRobin(len(self.ports), SP_CE)
busy = Signal()
adj_last = Signal()
granted = self.rr.grant
terms = 0
for i, port in enumerate(self.ports):
_grant = Signal(name="grant_to_%d" % i)
self.comb += [
_grant.eq(granted == i),
If (_grant,
port.connect(self.downstream),
),
self.rr.request[i].eq(port.i_stb),
]
# Busy signal tracks status of downstream controller
busy_start = Signal()
busy_stop = Signal()
self.comb += [
busy_start.eq(self.downstream.i_stb),
busy_stop.eq(self.downstream.d_stb & self.downstream.d_term)
]
self.sync += If(busy_start,
busy.eq(1),
).Elif(busy_stop,
busy.eq(0)
)
# Rearbitrate whenever the current command terminates,
# or when the current master has nothing to offer
self.comb += self.rr.ce.eq(
busy_stop | ~(busy | busy_start))
Module.do_finalize(self)