2012-02-17 17:50:10 -05:00
|
|
|
from migen.fhdl.structure import *
|
|
|
|
from migen.bus import dfi
|
|
|
|
from migen.bank.description import *
|
|
|
|
from migen.bank import csrgen
|
|
|
|
|
2012-02-23 15:21:07 -05:00
|
|
|
class PhaseInjector:
|
|
|
|
def __init__(self, phase):
|
|
|
|
self.phase = phase
|
|
|
|
|
|
|
|
self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._wren = Field("wren", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._rden = Field("rden", 1, WRITE_ONLY, READ_ONLY)
|
|
|
|
self._command = RegisterFields("command",
|
|
|
|
[self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
|
|
|
|
|
2012-07-13 12:33:03 -04:00
|
|
|
self._address = RegisterField("address", len(self.phase.address))
|
|
|
|
self._baddress = RegisterField("baddress", len(self.phase.bank))
|
2012-02-23 15:21:07 -05:00
|
|
|
|
2012-07-13 12:33:03 -04:00
|
|
|
self._wrdata = RegisterField("wrdata", len(self.phase.wrdata))
|
|
|
|
self._rddata = RegisterField("rddata", len(self.phase.rddata), READ_ONLY, WRITE_ONLY)
|
2012-02-23 15:21:07 -05:00
|
|
|
|
|
|
|
def get_registers(self):
|
|
|
|
return [self._command,
|
|
|
|
self._address, self._baddress,
|
|
|
|
self._wrdata, self._rddata]
|
|
|
|
|
|
|
|
def get_fragment(self):
|
|
|
|
comb = [
|
|
|
|
If(self._command.re,
|
|
|
|
self.phase.cs_n.eq(~self._cs.r),
|
|
|
|
self.phase.we_n.eq(~self._we.r),
|
|
|
|
self.phase.cas_n.eq(~self._cas.r),
|
|
|
|
self.phase.ras_n.eq(~self._ras.r)
|
|
|
|
).Else(
|
|
|
|
self.phase.cs_n.eq(1),
|
|
|
|
self.phase.we_n.eq(1),
|
|
|
|
self.phase.cas_n.eq(1),
|
|
|
|
self.phase.ras_n.eq(1)
|
|
|
|
),
|
|
|
|
self.phase.address.eq(self._address.field.r),
|
|
|
|
self.phase.bank.eq(self._baddress.field.r),
|
2012-02-24 09:14:58 -05:00
|
|
|
self.phase.wrdata_en.eq(self._command.re & self._wren.r),
|
|
|
|
self.phase.rddata_en.eq(self._command.re & self._rden.r),
|
2012-02-23 16:00:51 -05:00
|
|
|
self.phase.wrdata.eq(self._wrdata.field.r),
|
|
|
|
self.phase.wrdata_mask.eq(0)
|
2012-02-23 15:21:07 -05:00
|
|
|
]
|
|
|
|
sync = [
|
|
|
|
If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
|
|
|
|
]
|
|
|
|
return Fragment(comb, sync)
|
2012-02-17 17:50:10 -05:00
|
|
|
|
|
|
|
class DFIInjector:
|
|
|
|
def __init__(self, csr_address, a, ba, d, nphases=1):
|
|
|
|
self._int = dfi.Interface(a, ba, d, nphases)
|
|
|
|
self.slave = dfi.Interface(a, ba, d, nphases)
|
|
|
|
self.master = dfi.Interface(a, ba, d, nphases)
|
|
|
|
|
|
|
|
self._sel = Field("sel")
|
|
|
|
self._cke = Field("cke")
|
|
|
|
self._control = RegisterFields("control", [self._sel, self._cke])
|
|
|
|
|
2012-02-23 15:21:07 -05:00
|
|
|
self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
|
2012-02-17 17:50:10 -05:00
|
|
|
|
2012-02-23 15:21:07 -05:00
|
|
|
registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
|
|
|
|
self.bank = csrgen.Bank(registers, address=csr_address)
|
2012-02-17 17:50:10 -05:00
|
|
|
|
|
|
|
def get_fragment(self):
|
|
|
|
connect_int = dfi.interconnect_stmts(self._int, self.master)
|
|
|
|
connect_slave = dfi.interconnect_stmts(self.slave, self.master)
|
2012-02-23 15:21:07 -05:00
|
|
|
comb = [
|
|
|
|
If(self._sel.r, *connect_slave).Else(*connect_int)
|
2012-02-17 17:50:10 -05:00
|
|
|
]
|
2012-02-23 15:21:07 -05:00
|
|
|
comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
|
2012-02-17 17:50:10 -05:00
|
|
|
|
2012-02-23 15:21:07 -05:00
|
|
|
return Fragment(comb) \
|
|
|
|
+ sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
|
|
|
|
+ self.bank.get_fragment()
|