Remove uses of the RE signal on field registers
[litex.git] / milkymist / dfii / __init__.py
1 from migen.fhdl.structure import *
2 from migen.bus import dfi
3 from migen.bank.description import *
4 from migen.bank import csrgen
5
6 class PhaseInjector:
7 def __init__(self, phase):
8 self.phase = phase
9
10 self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
11 self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
12 self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
13 self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
14 self._wren = Field("wren", 1, WRITE_ONLY, READ_ONLY)
15 self._rden = Field("rden", 1, WRITE_ONLY, READ_ONLY)
16 self._command = RegisterFields("command",
17 [self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
18 self._command_issue = RegisterRaw("command_issue")
19
20 self._address = RegisterField("address", len(self.phase.address))
21 self._baddress = RegisterField("baddress", len(self.phase.bank))
22
23 self._wrdata = RegisterField("wrdata", len(self.phase.wrdata))
24 self._rddata = RegisterField("rddata", len(self.phase.rddata), READ_ONLY, WRITE_ONLY)
25
26 def get_registers(self):
27 return [self._command, self._command_issue,
28 self._address, self._baddress,
29 self._wrdata, self._rddata]
30
31 def get_fragment(self):
32 comb = [
33 If(self._command_issue.re,
34 self.phase.cs_n.eq(~self._cs.r),
35 self.phase.we_n.eq(~self._we.r),
36 self.phase.cas_n.eq(~self._cas.r),
37 self.phase.ras_n.eq(~self._ras.r)
38 ).Else(
39 self.phase.cs_n.eq(1),
40 self.phase.we_n.eq(1),
41 self.phase.cas_n.eq(1),
42 self.phase.ras_n.eq(1)
43 ),
44 self.phase.address.eq(self._address.field.r),
45 self.phase.bank.eq(self._baddress.field.r),
46 self.phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
47 self.phase.rddata_en.eq(self._command_issue.re & self._rden.r),
48 self.phase.wrdata.eq(self._wrdata.field.r),
49 self.phase.wrdata_mask.eq(0)
50 ]
51 sync = [
52 If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
53 ]
54 return Fragment(comb, sync)
55
56 class DFIInjector:
57 def __init__(self, csr_address, a, ba, d, nphases=1):
58 self._int = dfi.Interface(a, ba, d, nphases)
59 self.slave = dfi.Interface(a, ba, d, nphases)
60 self.master = dfi.Interface(a, ba, d, nphases)
61
62 self._sel = Field("sel")
63 self._cke = Field("cke")
64 self._control = RegisterFields("control", [self._sel, self._cke])
65
66 self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
67
68 registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
69 self.bank = csrgen.Bank(registers, address=csr_address)
70
71 def get_fragment(self):
72 connect_int = dfi.interconnect_stmts(self._int, self.master)
73 connect_slave = dfi.interconnect_stmts(self.slave, self.master)
74 comb = [
75 If(self._sel.r, *connect_slave).Else(*connect_int)
76 ]
77 comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
78
79 return Fragment(comb) \
80 + sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
81 + self.bank.get_fragment()