--- /dev/null
+from migen.fhdl.structure import *
+from migen.bus import dfi
+from migen.bank.description import *
+from migen.bank import csrgen
+
+def _data_en(trigger, output, delay, duration):
+ dcounter = Signal(BV(4))
+ dce = Signal()
+ return [
+ If(trigger,
+ dcounter.eq(delay),
+ dce.eq(1)
+ ).Elif(dce,
+ dcounter.eq(dcounter - 1),
+ If(dcounter == 0,
+ If(~output,
+ output.eq(1),
+ dcounter.eq(duration)
+ ).Else(
+ output.eq(0),
+ dce.eq(0)
+ )
+ )
+ )
+ ]
+
+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])
+
+ 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._rddata = Field("rddata", 1, WRITE_ONLY, READ_ONLY)
+ self._wrdata = Field("wrdata", 1, WRITE_ONLY, READ_ONLY)
+ self._command = RegisterFields("command",
+ [self._cs, self._we, self._cas, self._ras, self._rddata, self._wrdata])
+
+ self._address = RegisterField("address", a)
+ self._baddress = RegisterField("baddress", ba)
+
+ self._rddelay = RegisterField("rddelay", 4, reset=5)
+ self._rdduration = RegisterField("rdduration", 3, reset=0)
+ self._wrdelay = RegisterField("wrdelay", 4, reset=3)
+ self._wrduration = RegisterField("wrduration", 3, reset=0)
+
+ self.bank = csrgen.Bank([
+ self._control, self._command,
+ self._address, self._baddress,
+ self._rddelay, self._rdduration,
+ self._wrdelay, self._wrduration
+ ], address=csr_address)
+
+ def get_fragment(self):
+ comb = []
+ sync = []
+
+ # mux
+ connect_int = dfi.interconnect_stmts(self._int, self.master)
+ connect_slave = dfi.interconnect_stmts(self.slave, self.master)
+ comb.append(If(self._sel.r, *connect_slave).Else(*connect_int))
+
+ # phases
+ rddata_en = Signal()
+ wrdata_en = Signal()
+ for phase in self._int.phases:
+ comb += [
+ phase.cke.eq(self._cke.r),
+ phase.rddata_en.eq(rddata_en),
+ phase.wrdata_en.eq(wrdata_en)
+ ]
+ cmdphase = self._int.phases[0]
+ for phase in self._int.phases[1:]:
+ comb += [
+ phase.cs_n.eq(1),
+ phase.we_n.eq(1),
+ phase.cas_n.eq(1),
+ phase.ras_n.eq(1)
+
+ ]
+
+ # commands
+ comb += [
+ If(self._command.re,
+ cmdphase.cs_n.eq(~self._cs.r),
+ cmdphase.we_n.eq(~self._we.r),
+ cmdphase.cas_n.eq(~self._cas.r),
+ cmdphase.ras_n.eq(~self._ras.r)
+ ).Else(
+ cmdphase.cs_n.eq(1),
+ cmdphase.we_n.eq(1),
+ cmdphase.cas_n.eq(1),
+ cmdphase.ras_n.eq(1)
+ )
+ ]
+
+ # data enables
+ sync += _data_en(self._command.re & self._rddata.r,
+ rddata_en,
+ self._rddelay.field.r, self._rdduration.field.r)
+ sync += _data_en(self._command.re & self._wrdata.r,
+ wrdata_en,
+ self._wrdelay.field.r, self._wrduration.field.r)
+
+ return Fragment(comb, sync) + self.bank.get_fragment()
--- /dev/null
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2012 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HW_DFII_H
+#define __HW_DFII_H
+
+#include <hw/common.h>
+
+#define CSR_DFII_CONTROL MMPTR(0xe0001000)
+
+#define DFII_CONTROL_SEL (0x01)
+#define DFII_CONTROL_CKE (0x02)
+
+#define CSR_DFII_COMMAND MMPTR(0xe0001004)
+
+#define DFII_COMMAND_CS (0x01)
+#define DFII_COMMAND_WE (0x02)
+#define DFII_COMMAND_CAS (0x04)
+#define DFII_COMMAND_RAS (0x08)
+#define DFII_COMMAND_RDDATA (0x10)
+#define DFII_COMMAND_WRDATA (0x20)
+
+#define CSR_DFII_AH MMPTR(0xe0001008)
+#define CSR_DFII_AL MMPTR(0xe000100C)
+#define CSR_DFII_BA MMPTR(0xe0001010)
+
+#define CSR_DFII_RDDELAY MMPTR(0xe0001014)
+#define CSR_DFII_RDDURATION MMPTR(0xe0001018)
+#define CSR_DFII_WRDELAY MMPTR(0xe000101C)
+#define CSR_DFII_WRDURATION MMPTR(0xe0001020)
+
+#endif /* __HW_DFII_H */
from migen.fhdl.structure import *
from migen.fhdl import verilog, autofragment
-from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr
+from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr, dfi
-from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy
+from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii
import constraints
MHz = 1000000
sram_size = 4096 # in bytes
l2_size = 8192 # in bytes
+dfi_a = 13
+dfi_ba = 2
+dfi_d = 128 # TODO -> 64
+
def ddrphy_clocking(crg, phy):
names = [
"clk2x_90",
#
# ASMI
#
- ddrphy0 = s6ddrphy.S6DDRPHY(1, 13, 2, 128)
asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller
asmiport_wb = asmihub0.get_port()
asmihub0.finalize()
+ #
+ # DFI
+ #
+ ddrphy0 = s6ddrphy.S6DDRPHY(1, dfi_a, dfi_ba, dfi_d)
+ dfii0 = dfii.DFIInjector(2, dfi_a, dfi_ba, dfi_d, 2)
+ dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
+
#
# WISHBONE
#
uart0 = uart.UART(0, clk_freq, baud=115200)
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
uart0.bank.interface,
- ddrphy0.bank.interface
+ ddrphy0.bank.interface,
+ dfii0.bank.interface
])
#