Remove setaddr for submodule instanciation
[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 lambdasoc.periph import Peripheral
10
11 # PhaseInjector ------------------------------------------------------------------------------------
12
13 class PhaseInjector(Peripheral, Elaboratable):
14 def __init__(self, phase):
15 super().__init__(name = "phaseinjector")
16
17 bank = self.csr_bank()
18 self._command = bank.csr(6, "rw")
19 self._command_issue = bank.csr(1, "rw")
20 self._address = bank.csr(len(phase.address), "rw")
21 self._baddress = bank.csr(len(phase.bank), "rw")
22 self._wrdata = bank.csr(len(phase.wrdata), "rw")
23 self._rddata = bank.csr(len(phase.rddata), "rw")
24
25 self._phase = phase
26
27 def elaborate(self, platform):
28 m = Module()
29
30 m.d.comb += [
31 self._phase.address.eq(self._address.r_data),
32 self._phase.bank.eq(self._baddress.r_data),
33 self._phase.wrdata_en.eq(self._command_issue.r_stb & self._command.r_data[4]),
34 self._phase.rddata_en.eq(self._command_issue.r_stb & self._command.r_data[5]),
35 self._phase.wrdata.eq(self._wrdata.r_data),
36 self._phase.wrdata_mask.eq(0)
37 ]
38
39 with m.If(self._command_issue.r_stb):
40 m.d.comb += [
41 self._phase.cs_n.eq(Repl(value=~self._command.r_data[0], count=len(self._phase.cs_n))),
42 self._phase.we_n.eq(~self._command.r_data[1]),
43 self._phase.cas_n.eq(~self._command.r_data[2]),
44 self._phase.ras_n.eq(~self._command.r_data[3]),
45 ]
46 with m.Else():
47 m.d.comb += [
48 self._phase.cs_n.eq(Repl(value=1, count=len(self._phase.cs_n))),
49 self._phase.we_n.eq(1),
50 self._phase.cas_n.eq(1),
51 self._phase.ras_n.eq(1),
52 ]
53
54 with m.If(self._phase.rddata_valid):
55 m.d.sync += self._rddata.w_data.eq(self._phase.rddata)
56
57 return m
58
59 # DFIInjector --------------------------------------------------------------------------------------
60
61 class DFIInjector(Peripheral, Elaboratable):
62 def __init__(self, addressbits, bankbits, nranks, databits, nphases=1):
63 super().__init__(name = "dfii")
64
65 self._nranks = nranks
66
67 self._inti = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
68 self.slave = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
69 self.master = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
70
71 bank = self.csr_bank()
72 self._control = bank.csr(4, "rw") # sel, cke, odt, reset_n
73
74 def elaborate(self, platform):
75 m = Module()
76
77 for n, phase in enumerate(self._inti.phases):
78 m.submodules += PhaseInjector(phase)
79
80 with m.If(self._control.r_data[0]):
81 m.d.comb += self.slave.connect(self.master)
82 with m.Else():
83 m.d.comb += self._inti.connect(self.master)
84
85 for i in range(self._nranks):
86 m.d.comb += [phase.cke[i].eq(self._control.r_data[1]) for phase in self._inti.phases]
87 m.d.comb += [phase.odt[i].eq(self._control.r_data[2]) for phase in self._inti.phases if hasattr(phase, "odt")]
88 m.d.comb += [phase.reset_n.eq(self._control.r_data[3]) for phase in self._inti.phases if hasattr(phase, "reset_n")]
89
90 return m