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
11 # PhaseInjector ------------------------------------------------------------------------------------
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")
25 def elaborate(self
, platform
):
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)
37 with m
.If(self
._command
_issue
.w_stb
):
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]),
47 self
._phase
.cs_n
.eq(Repl(value
=1, count
=len(self
._phase
.cs_n
))),
49 self
._phase
.cas
.eq(0),
50 self
._phase
.ras
.eq(0),
53 with m
.If(self
._phase
.rddata_valid
):
54 m
.d
.sync
+= self
._rddata
.r_data
.eq(self
._phase
.rddata
)
58 # DFIInjector --------------------------------------------------------------------------------------
61 class DFIInjector(Elaboratable
):
62 def __init__(self
, csr_bank
, addressbits
, bankbits
, nranks
, databits
, nphases
=1):
63 print ("nranks", nranks
, "nphases", nphases
, "addressbits", addressbits
)
66 self
._inti
= dfi
.Interface(addressbits
, bankbits
,
67 nranks
, databits
, nphases
,
69 self
.slave
= dfi
.Interface(addressbits
, bankbits
,
70 nranks
, databits
, nphases
,
72 self
.master
= dfi
.Interface(addressbits
, bankbits
,
73 nranks
, databits
, nphases
,
76 self
._control
= csr_bank
.csr(4, "w") # sel, clk_en, odt, reset
77 self
._control
.w_data
.reset
= 0b1000 # reset HI
81 for n
, phase
in enumerate(self
._inti
.phases
):
82 self
._phases
+= [PhaseInjector(CSRPrefixProxy(csr_bank
,
85 if hasattr(phase
, "reset"):
88 def elaborate(self
, platform
):
91 for n
, phase
in enumerate(self
._phases
):
92 m
.submodules
['phase_%d' % n
] = phase
94 for phase
in self
._inti
.phases
:
95 print ("phase", phase
)
97 with m
.If(self
._control
.w_data
[0]):
98 m
.d
.comb
+= self
.slave
.connect(self
.master
)
100 m
.d
.comb
+= self
._inti
.connect(self
.master
)
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")]