annoyingly reverting reset_n naming back to reset
[gram.git] / gram / dfii.py
1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2016-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
4 # License: BSD
5
6 from nmigen import *
7
8 from gram.phy import dfi
9 from gram.compat import CSRPrefixProxy
10
11 # PhaseInjector ------------------------------------------------------------------------------------
12
13
14 class PhaseInjector(Elaboratable):
15 def __init__(self, csr_bank, phase):
16 self._command = csr_bank.csr(6, "w")
17 self._command_issue = csr_bank.csr(1, "w")
18 self._address = csr_bank.csr(len(phase.address), "w")
19 self._baddress = csr_bank.csr(len(phase.bank), "w")
20 self._wrdata = csr_bank.csr(len(phase.wrdata), "w")
21 self._rddata = csr_bank.csr(len(phase.rddata), "r")
22
23 self._phase = phase
24
25 def elaborate(self, platform):
26 m = Module()
27
28 m.d.comb += [
29 self._phase.address.eq(self._address.w_data),
30 self._phase.bank.eq(self._baddress.w_data),
31 self._phase.wrdata_en.eq(self._command_issue.w_stb & self._command.w_data[4]),
32 self._phase.rddata_en.eq(self._command_issue.w_stb & self._command.w_data[5]),
33 self._phase.wrdata.eq(self._wrdata.w_data),
34 self._phase.wrdata_mask.eq(0)
35 ]
36
37 with m.If(self._command_issue.w_stb):
38 m.d.comb += [
39 self._phase.cs_n.eq(Repl(value=~self._command.w_data[0],
40 count=len(self._phase.cs_n))),
41 self._phase.we.eq(self._command.w_data[1]),
42 self._phase.cas.eq(self._command.w_data[2]),
43 self._phase.ras.eq(self._command.w_data[3]),
44 ]
45 with m.Else():
46 m.d.comb += [
47 self._phase.cs_n.eq(Repl(value=1, count=len(self._phase.cs_n))),
48 self._phase.we.eq(0),
49 self._phase.cas.eq(0),
50 self._phase.ras.eq(0),
51 ]
52
53 with m.If(self._phase.rddata_valid):
54 m.d.sync += self._rddata.r_data.eq(self._phase.rddata)
55
56 return m
57
58 # DFIInjector --------------------------------------------------------------------------------------
59
60
61 class DFIInjector(Elaboratable):
62 def __init__(self, csr_bank, addressbits, bankbits, nranks, databits, nphases=1):
63 print ("nranks", nranks, "nphases", nphases, "addressbits", addressbits)
64 self._nranks = nranks
65
66 self._inti = dfi.Interface(addressbits, bankbits,
67 nranks, databits, nphases,
68 name="inti")
69 self.slave = dfi.Interface(addressbits, bankbits,
70 nranks, databits, nphases,
71 name="slave")
72 self.master = dfi.Interface(addressbits, bankbits,
73 nranks, databits, nphases,
74 name="master")
75
76 self._control = csr_bank.csr(4, "w") # sel, clk_en, odt, reset
77 self._control.w_data.reset = 0b1000 # reset HI
78
79
80 self._phases = []
81 for n, phase in enumerate(self._inti.phases):
82 self._phases += [PhaseInjector(CSRPrefixProxy(csr_bank,
83 "p{}".format(n)),
84 phase)]
85 if hasattr(phase, "reset"):
86 phase.reset.reset = 1
87
88 def elaborate(self, platform):
89 m = Module()
90
91 for n, phase in enumerate(self._phases):
92 m.submodules['phase_%d' % n] = phase
93
94 for phase in self._inti.phases:
95 print ("phase", phase)
96
97 with m.If(self._control.w_data[0]):
98 m.d.comb += self.slave.connect(self.master)
99 with m.Else():
100 m.d.comb += self._inti.connect(self.master)
101
102 for i in range(self._nranks):
103 m.d.comb += [phase.clk_en[i].eq(self._control.w_data[1])
104 for phase in self._inti.phases]
105 m.d.comb += [phase.odt[i].eq(self._control.w_data[2])
106 for phase in self._inti.phases if hasattr(phase, "odt")]
107 m.d.comb += [phase.reset.eq(~self._control.w_data[3])
108 for phase in self._inti.phases if hasattr(phase, "reset")]
109
110 return m