Initial commit
[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 bank = self.csr_bank()
16 self._command = bank.csr(6, "rw")
17 self._command_issue = bank.csr(1, "rw")
18 self._address = bank.csr(len(phase.address), "rw", reset_less=True)
19 self._baddress = bank.csr(len(phase.bank), "rw", reset_less=True)
20 self._wrdata = bank.csr(len(phase.wrdata), "rw", reset_less=True)
21 self._rddata = bank.csr(len(phase.rddata))
22
23 def elaborate(self, platform):
24 m = Module()
25
26 m.d.comb += [
27 phase.address.eq(self._address.storage),
28 phase.bank.eq(self._baddress.storage),
29 phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
30 phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
31 phase.wrdata.eq(self._wrdata.storage),
32 phase.wrdata_mask.eq(0)
33 ]
34
35 with m.If(self._command_issue.re):
36 m.d.comb += [
37 phase.cs_n.eq(Replicate(~self._command.storage[0], len(phase.cs_n))),
38 phase.we_n.eq(~self._command.storage[1]),
39 phase.cas_n.eq(~self._command.storage[2]),
40 phase.ras_n.eq(~self._command.storage[3]),
41 ]
42 with m.Else():
43 m.d.comb += [
44 phase.cs_n.eq(Replicate(1, len(phase.cs_n))),
45 phase.we_n.eq(1),
46 phase.cas_n.eq(1),
47 phase.ras_n.eq(1),
48 ]
49
50 with m.If(phase.rddata_valid):
51 m.d.sync += self._rddata.status.eq(phase.rddata)
52
53 return m
54
55 # DFIInjector --------------------------------------------------------------------------------------
56
57 class DFIInjector(Peripheral, Elaboratable):
58 def __init__(self, addressbits, bankbits, nranks, databits, nphases=1):
59 self._inti = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
60 self.slave = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
61 self.master = dfi.Interface(addressbits, bankbits, nranks, databits, nphases)
62
63 bank = self.csr_bank()
64 self._control = bank.csr(4) # sel, cke, odt, reset_n
65
66 #for n, phase in enumerate(inti.phases):
67 # setattr(self.submodules, "pi" + str(n), PhaseInjector(phase)) TODO
68
69 # # #
70
71 def elaborate(self, platform):
72 m = Module()
73
74 with m.If(self._control.storage[0]):
75 m.d.comb += self.slave.connect(self.master)
76 with m.Else():
77 m.d.comb += self._inti.connect(self.master)
78
79 for i in range(nranks):
80 m.d.comb += [phase.cke[i].eq(self._control.storage[1]) for phase in self._inti.phases]
81 m.d.comb += [phase.odt[i].eq(self._control.storage[2]) for phase in self._inti.phases if hasattr(phase, "odt")]
82 m.d.comb += [phase.reset_n.eq(self._control.storage[3]) for phase in self._inti.phases if hasattr(phase, "reset_n")]
83
84 return m