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>
8 from gram
.phy
import dfi
9 from gram
.compat
import CSRPrefixProxy
10 from lambdasoc
.periph
import Peripheral
12 # PhaseInjector ------------------------------------------------------------------------------------
15 class PhaseInjector(Elaboratable
):
16 def __init__(self
, csr_bank
, phase
):
17 self
._command
= csr_bank
.csr(6, "rw")
18 self
._command
_issue
= csr_bank
.csr(1, "rw")
19 self
._address
= csr_bank
.csr(len(phase
.address
), "rw")
20 self
._baddress
= csr_bank
.csr(len(phase
.bank
), "rw")
21 self
._wrdata
= csr_bank
.csr(len(phase
.wrdata
), "rw")
22 self
._rddata
= csr_bank
.csr(len(phase
.rddata
), "rw")
26 def elaborate(self
, platform
):
30 self
._phase
.address
.eq(self
._address
.r_data
),
31 self
._phase
.bank
.eq(self
._baddress
.r_data
),
32 self
._phase
.wrdata_en
.eq(
33 self
._command
_issue
.r_stb
& self
._command
.r_data
[4]),
34 self
._phase
.rddata_en
.eq(
35 self
._command
_issue
.r_stb
& self
._command
.r_data
[5]),
36 self
._phase
.wrdata
.eq(self
._wrdata
.r_data
),
37 self
._phase
.wrdata_mask
.eq(0)
40 with m
.If(self
._command
_issue
.r_stb
):
43 Repl(value
=~self
._command
.r_data
[0], count
=len(self
._phase
.cs_n
))),
44 self
._phase
.we_n
.eq(~self
._command
.r_data
[1]),
45 self
._phase
.cas_n
.eq(~self
._command
.r_data
[2]),
46 self
._phase
.ras_n
.eq(~self
._command
.r_data
[3]),
51 Repl(value
=1, count
=len(self
._phase
.cs_n
))),
52 self
._phase
.we_n
.eq(1),
53 self
._phase
.cas_n
.eq(1),
54 self
._phase
.ras_n
.eq(1),
57 with m
.If(self
._phase
.rddata_valid
):
58 m
.d
.sync
+= self
._rddata
.w_data
.eq(self
._phase
.rddata
)
62 # DFIInjector --------------------------------------------------------------------------------------
65 class DFIInjector(Elaboratable
):
66 def __init__(self
, csr_bank
, addressbits
, bankbits
, nranks
, databits
, nphases
=1):
69 self
._inti
= dfi
.Interface(
70 addressbits
, bankbits
, nranks
, databits
, nphases
)
71 self
.slave
= dfi
.Interface(
72 addressbits
, bankbits
, nranks
, databits
, nphases
)
73 self
.master
= dfi
.Interface(
74 addressbits
, bankbits
, nranks
, databits
, nphases
)
76 self
._control
= csr_bank
.csr(4, "rw") # sel, cke, odt, reset_n
79 for n
, phase
in enumerate(self
._inti
.phases
):
80 self
._phases
+= [PhaseInjector(CSRPrefixProxy(csr_bank
,
81 "p{}".format(n
)), phase
)]
83 def elaborate(self
, platform
):
86 m
.submodules
+= self
._phases
88 with m
.If(self
._control
.r_data
[0]):
89 m
.d
.comb
+= self
.slave
.connect(self
.master
)
91 m
.d
.comb
+= self
._inti
.connect(self
.master
)
93 for i
in range(self
._nranks
):
94 m
.d
.comb
+= [phase
.cke
[i
].eq(self
._control
.r_data
[1])
95 for phase
in self
._inti
.phases
]
96 m
.d
.comb
+= [phase
.odt
[i
].eq(self
._control
.r_data
[2])
97 for phase
in self
._inti
.phases
if hasattr(phase
, "odt")]
98 m
.d
.comb
+= [phase
.reset_n
.eq(self
._control
.r_data
[3])
99 for phase
in self
._inti
.phases
if hasattr(phase
, "reset_n")]