diff --git a/milkymist/s6ddrphy/__init__.py b/milkymist/s6ddrphy/__init__.py
index 3e3b94db7..6b2697031 100644
--- a/milkymist/s6ddrphy/__init__.py
+++ b/milkymist/s6ddrphy/__init__.py
@@ -1,8 +1,10 @@
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 = []
@@ -16,8 +18,7 @@ class S6DDRPHY:
"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)
@@ -50,6 +51,8 @@ class S6DDRPHY:
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)),
@@ -87,8 +90,23 @@ class S6DDRPHY:
("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),
@@ -99,6 +117,22 @@ class S6DDRPHY:
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)
]
- return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))
+ 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, sync, instances=[self._inst], pads=set(self._sd_pins)) \
+ + self.bank.get_fragment()
diff --git a/software/include/hw/s6ddrphy.h b/software/include/hw/s6ddrphy.h
new file mode 100644
index 000000000..a139c4c84
--- /dev/null
+++ b/software/include/hw/s6ddrphy.h
@@ -0,0 +1,36 @@
+/*
+ * 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 .
+ */
+
+#ifndef __HW_S6DDRPHY_H
+#define __HW_S6DDRPHY_H
+
+#include
+
+#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 */
diff --git a/software/include/hw/uart.h b/software/include/hw/uart.h
index c9e1e194b..d472e5d72 100644
--- a/software/include/hw/uart.h
+++ b/software/include/hw/uart.h
@@ -20,7 +20,7 @@
#include
-#define CSR_UART_RXTX MMPTR(0xe0000000)
+#define CSR_UART_RXTX MMPTR(0xe0000000)
#define CSR_UART_DIVISORH MMPTR(0xe0000004)
#define CSR_UART_DIVISORL MMPTR(0xe0000008)
diff --git a/top.py b/top.py
index dbf67dfc5..9452f7a46 100644
--- a/top.py
+++ b/top.py
@@ -31,7 +31,7 @@ def get():
#
# 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()
@@ -68,7 +68,10 @@ def get():
# 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