from migen.fhdl.structure import *
from migen.bus import dfi
+from migen.bank.description import *
+from migen.bank import csrgen
class S6DDRPHY:
- def __init__(self, a, ba, d):
+ def __init__(self, csr_address, a, ba, d):
ins = []
outs = []
inouts = []
"clk4x_rd_left",
"clk4x_rd_strb_left",
"clk4x_rd_right",
- "clk4x_rd_strb_right",
- "reset_n"
+ "clk4x_rd_strb_right"
]:
s = Signal(name=name)
setattr(self, name, s)
outs += self.dfi.get_standard_names(False, True)
ins += [
+ ("reset_n", BV(1)),
+
("cfg_al", BV(3)),
("cfg_cl", BV(3)),
("cfg_bl", BV(2)),
("DM_IO_LOC", Constant(2**4-1, BV(4)))
],
clkport="clk")
+
+ self._reset_n = Field("reset_n")
+ self._init_done = Field("init_done")
+ self._phy_cal_done = Field("phy_cal_done", 1, READ_ONLY, WRITE_ONLY)
+ self._status = RegisterFields("status",
+ [self._reset_n, self._init_done, self._phy_cal_done])
+ self._req = RegisterRaw("req", 2)
+ self._req_addr = RegisterField("req_addr", 8, READ_ONLY, WRITE_ONLY)
+
+ self.bank = csrgen.Bank([self._status, self._req, self._req_addr],
+ address=csr_address)
def get_fragment(self):
+ pending_r = Signal()
+ pending_w = Signal()
+ cpg_busy = Signal()
+
comb = [
self._inst.ins["cfg_al"].eq(0),
self._inst.ins["cfg_cl"].eq(3),
self._inst.ins["diag_io_sel"].eq(0),
self._inst.ins["diag_disable_cal_on_startup"].eq(0),
self._inst.ins["diag_cal_bits"].eq(0),
- self._inst.ins["diag_short_cal"].eq(0)
+ self._inst.ins["diag_short_cal"].eq(0),
+
+ self._inst.ins["reset_n"].eq(self._reset_n.r),
+ self._inst.ins["init_done"].eq(self._init_done.r),
+ self._phy_cal_done.w.eq(self._inst.outs["phy_cal_done"]),
+ self._req_addr.field.w.eq(self._inst.outs["cpg_addr"][2:10]),
+
+ self._req.w.eq(Cat(pending_r, pending_w)),
+ cpg_busy.eq(pending_r | pending_w),
+ self._inst.ins["cpg_busy"].eq(cpg_busy)
+ ]
+ sync = [
+ If(self._inst.outs["cpg_r_req"], pending_r.eq(1)),
+ If(self._inst.outs["cpg_w_req"], pending_w.eq(1)),
+ If(self._req.re & self._req.r[0], pending_r.eq(0)),
+ If(self._req.re & self._req.r[1], pending_w.eq(0))
]
- return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))
+ return Fragment(comb, sync, instances=[self._inst], pads=set(self._sd_pins)) \
+ + 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_S6DDRPHY_H
+#define __HW_S6DDRPHY_H
+
+#include <hw/common.h>
+
+#define CSR_DDRPHY_STATUS MMPTR(0xe0000800)
+
+#define DDRPHY_STATUS_RESETN (0x1)
+#define DDRPHY_STATUS_INIT_DONE (0x2)
+#define DDRPHY_STATUS_PHY_CAL_DONE (0x4)
+
+#define CSR_DDRPHY_REQUESTS MMPTR(0xe0000804)
+
+#define DDRPHY_REQUEST_READ (0x1)
+#define DDRPHY_REQUEST_WRITE (0x2)
+
+#define CSR_DDRPHY_REQADDR MMPTR(0xe0000808)
+
+#endif /* __HW_S6DDRPHY_H */
#
# ASMI
#
- ddrphy0 = s6ddrphy.S6DDRPHY(13, 2, 128)
+ 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()
# CSR
#
uart0 = uart.UART(0, clk_freq, baud=115200)
- csrcon0 = csr.Interconnect(wishbone2csr0.csr, [uart0.bank.interface])
+ csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
+ uart0.bank.interface,
+ ddrphy0.bank.interface
+ ])
#
# Interrupts