2012-02-17 17:50:10 -05:00
|
|
|
from migen.fhdl.structure import *
|
2013-03-10 14:32:38 -04:00
|
|
|
from migen.fhdl.module import Module
|
2012-02-17 17:50:10 -05:00
|
|
|
from migen.bus import dfi
|
|
|
|
from migen.bank.description import *
|
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
class PhaseInjector(Module, AutoReg):
|
2012-02-23 15:21:07 -05:00
|
|
|
def __init__(self, phase):
|
2013-03-12 10:47:54 -04:00
|
|
|
self._cs = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._we = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._cas = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._ras = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._wren = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._rden = Field(1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._command = RegisterFields(self._cs, self._we, self._cas, self._ras, self._wren, self._rden)
|
|
|
|
self._command_issue = RegisterRaw()
|
2012-02-23 15:21:07 -05:00
|
|
|
|
2013-03-12 10:47:54 -04:00
|
|
|
self._address = RegisterField(len(phase.address))
|
|
|
|
self._baddress = RegisterField(len(phase.bank))
|
2012-02-23 15:21:07 -05:00
|
|
|
|
2013-03-12 10:47:54 -04:00
|
|
|
self._wrdata = RegisterField(len(phase.wrdata))
|
|
|
|
self._rddata = RegisterField(len(phase.rddata), READ_ONLY, WRITE_ONLY)
|
2012-02-23 15:21:07 -05:00
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
###
|
|
|
|
|
|
|
|
self.comb += [
|
2012-10-09 13:08:37 -04:00
|
|
|
If(self._command_issue.re,
|
2013-03-10 14:32:38 -04:00
|
|
|
phase.cs_n.eq(~self._cs.r),
|
|
|
|
phase.we_n.eq(~self._we.r),
|
|
|
|
phase.cas_n.eq(~self._cas.r),
|
|
|
|
phase.ras_n.eq(~self._ras.r)
|
2012-02-23 15:21:07 -05:00
|
|
|
).Else(
|
2013-03-10 14:32:38 -04:00
|
|
|
phase.cs_n.eq(1),
|
|
|
|
phase.we_n.eq(1),
|
|
|
|
phase.cas_n.eq(1),
|
|
|
|
phase.ras_n.eq(1)
|
2012-02-23 15:21:07 -05:00
|
|
|
),
|
2013-03-10 14:32:38 -04:00
|
|
|
phase.address.eq(self._address.field.r),
|
|
|
|
phase.bank.eq(self._baddress.field.r),
|
|
|
|
phase.wrdata_en.eq(self._command_issue.re & self._wren.r),
|
|
|
|
phase.rddata_en.eq(self._command_issue.re & self._rden.r),
|
|
|
|
phase.wrdata.eq(self._wrdata.field.r),
|
|
|
|
phase.wrdata_mask.eq(0)
|
2012-02-23 15:21:07 -05:00
|
|
|
]
|
2013-03-10 14:32:38 -04:00
|
|
|
self.sync += If(phase.rddata_valid, self._rddata.field.w.eq(phase.rddata))
|
2012-02-17 17:50:10 -05:00
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
class DFIInjector(Module, AutoReg):
|
|
|
|
def __init__(self, a, ba, d, nphases=1):
|
|
|
|
inti = dfi.Interface(a, ba, d, nphases)
|
2012-02-17 17:50:10 -05:00
|
|
|
self.slave = dfi.Interface(a, ba, d, nphases)
|
|
|
|
self.master = dfi.Interface(a, ba, d, nphases)
|
|
|
|
|
2013-03-12 10:47:54 -04:00
|
|
|
self._sel = Field()
|
|
|
|
self._cke = Field()
|
|
|
|
self._control = RegisterFields(self._sel, self._cke)
|
2012-02-17 17:50:10 -05:00
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
for n, phase in enumerate(inti.phases):
|
|
|
|
setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
|
|
|
|
|
|
|
|
###
|
2012-02-17 17:50:10 -05:00
|
|
|
|
2013-03-10 14:32:38 -04:00
|
|
|
connect_inti = dfi.interconnect_stmts(inti, self.master)
|
2012-02-17 17:50:10 -05:00
|
|
|
connect_slave = dfi.interconnect_stmts(self.slave, self.master)
|
2013-03-10 14:32:38 -04:00
|
|
|
self.comb += If(self._sel.r, *connect_slave).Else(*connect_inti)
|
|
|
|
self.comb += [phase.cke.eq(self._cke.r) for phase in inti.phases]
|