Map DDR PHY controls in CSR
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 17 Feb 2012 16:34:59 +0000 (17:34 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 17 Feb 2012 16:34:59 +0000 (17:34 +0100)
milkymist/s6ddrphy/__init__.py
software/include/hw/s6ddrphy.h [new file with mode: 0644]
software/include/hw/uart.h
top.py

index 3e3b94db741a09b8857b3850c0755f7f46f4e865..6b2697031e766bf4ce8689a3d542dc50389a46a6 100644 (file)
@@ -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)
+               ]
+               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()
diff --git a/software/include/hw/s6ddrphy.h b/software/include/hw/s6ddrphy.h
new file mode 100644 (file)
index 0000000..a139c4c
--- /dev/null
@@ -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 <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 */
index c9e1e194b7643c2a9b307f8c35c8b8d5f70fa2ff..d472e5d727afd44027f63d8e0ee028c16f2ead8e 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <hw/common.h>
 
-#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 dbf67dfc58141226d777248f9b2cdeda15d95cdd..9452f7a46e09562b7da6da20d503870599098128 100644 (file)
--- 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