Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Map DDR PHY controls in CSR

  • Loading branch information...
commit c387ce7ce5d25abaa982f76724ed04409669954b 1 parent 5d1dad5
Sébastien Bourdeauducq authored
44  milkymist/s6ddrphy/__init__.py
... ...
@@ -1,8 +1,10 @@
1 1
 from migen.fhdl.structure import *
2 2
 from migen.bus import dfi
  3
+from migen.bank.description import *
  4
+from migen.bank import csrgen
3 5
 
4 6
 class S6DDRPHY:
5  
-	def __init__(self, a, ba, d):
  7
+	def __init__(self, csr_address, a, ba, d):
6 8
 		ins = []
7 9
 		outs = []
8 10
 		inouts = []
@@ -16,8 +18,7 @@ def __init__(self, a, ba, d):
16 18
 			"clk4x_rd_left",
17 19
 			"clk4x_rd_strb_left",
18 20
 			"clk4x_rd_right",
19  
-			"clk4x_rd_strb_right",
20  
-			"reset_n"
  21
+			"clk4x_rd_strb_right"
21 22
 		]:
22 23
 			s = Signal(name=name)
23 24
 			setattr(self, name, s)
@@ -50,6 +51,8 @@ def __init__(self, a, ba, d):
50 51
 		outs += self.dfi.get_standard_names(False, True)
51 52
 		
52 53
 		ins += [
  54
+			("reset_n", BV(1)),
  55
+			
53 56
 			("cfg_al", BV(3)),
54 57
 			("cfg_cl", BV(3)),
55 58
 			("cfg_bl", BV(2)),
@@ -87,8 +90,23 @@ def __init__(self, a, ba, d):
87 90
 				("DM_IO_LOC", Constant(2**4-1, BV(4)))
88 91
 			],
89 92
 			clkport="clk")
  93
+		
  94
+		self._reset_n = Field("reset_n")
  95
+		self._init_done = Field("init_done")
  96
+		self._phy_cal_done = Field("phy_cal_done", 1, READ_ONLY, WRITE_ONLY)
  97
+		self._status = RegisterFields("status",
  98
+			[self._reset_n, self._init_done, self._phy_cal_done])
  99
+		self._req = RegisterRaw("req", 2)
  100
+		self._req_addr = RegisterField("req_addr", 8, READ_ONLY, WRITE_ONLY)
  101
+		
  102
+		self.bank = csrgen.Bank([self._status, self._req, self._req_addr],
  103
+			address=csr_address)
90 104
 
91 105
 	def get_fragment(self):
  106
+		pending_r = Signal()
  107
+		pending_w = Signal()
  108
+		cpg_busy = Signal()
  109
+		
92 110
 		comb = [
93 111
 			self._inst.ins["cfg_al"].eq(0),
94 112
 			self._inst.ins["cfg_cl"].eq(3),
@@ -99,6 +117,22 @@ def get_fragment(self):
99 117
 			self._inst.ins["diag_io_sel"].eq(0),
100 118
 			self._inst.ins["diag_disable_cal_on_startup"].eq(0),
101 119
 			self._inst.ins["diag_cal_bits"].eq(0),
102  
-			self._inst.ins["diag_short_cal"].eq(0)
  120
+			self._inst.ins["diag_short_cal"].eq(0),
  121
+			
  122
+			self._inst.ins["reset_n"].eq(self._reset_n.r),
  123
+			self._inst.ins["init_done"].eq(self._init_done.r),
  124
+			self._phy_cal_done.w.eq(self._inst.outs["phy_cal_done"]),
  125
+			self._req_addr.field.w.eq(self._inst.outs["cpg_addr"][2:10]),
  126
+			
  127
+			self._req.w.eq(Cat(pending_r, pending_w)),
  128
+			cpg_busy.eq(pending_r | pending_w),
  129
+			self._inst.ins["cpg_busy"].eq(cpg_busy)
  130
+		]
  131
+		sync = [
  132
+			If(self._inst.outs["cpg_r_req"], pending_r.eq(1)),
  133
+			If(self._inst.outs["cpg_w_req"], pending_w.eq(1)),
  134
+			If(self._req.re & self._req.r[0], pending_r.eq(0)),
  135
+			If(self._req.re & self._req.r[1], pending_w.eq(0))
103 136
 		]
104  
-		return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))
  137
+		return Fragment(comb, sync, instances=[self._inst], pads=set(self._sd_pins)) \
  138
+			+ self.bank.get_fragment()
36  software/include/hw/s6ddrphy.h
... ...
@@ -0,0 +1,36 @@
  1
+/*
  2
+ * Milkymist SoC (Software)
  3
+ * Copyright (C) 2012 Sebastien Bourdeauducq
  4
+ *
  5
+ * This program is free software: you can redistribute it and/or modify
  6
+ * it under the terms of the GNU General Public License as published by
  7
+ * the Free Software Foundation, version 3 of the License.
  8
+ *
  9
+ * This program is distributed in the hope that it will be useful,
  10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12
+ * GNU General Public License for more details.
  13
+ *
  14
+ * You should have received a copy of the GNU General Public License
  15
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16
+ */
  17
+
  18
+#ifndef __HW_S6DDRPHY_H
  19
+#define __HW_S6DDRPHY_H
  20
+
  21
+#include <hw/common.h>
  22
+
  23
+#define CSR_DDRPHY_STATUS		MMPTR(0xe0000800)
  24
+
  25
+#define DDRPHY_STATUS_RESETN		(0x1)
  26
+#define DDRPHY_STATUS_INIT_DONE		(0x2)
  27
+#define DDRPHY_STATUS_PHY_CAL_DONE	(0x4)
  28
+
  29
+#define CSR_DDRPHY_REQUESTS		MMPTR(0xe0000804)
  30
+
  31
+#define DDRPHY_REQUEST_READ		(0x1)
  32
+#define DDRPHY_REQUEST_WRITE		(0x2)
  33
+
  34
+#define CSR_DDRPHY_REQADDR		MMPTR(0xe0000808)
  35
+
  36
+#endif /* __HW_S6DDRPHY_H */
2  software/include/hw/uart.h
@@ -20,7 +20,7 @@
20 20
 
21 21
 #include <hw/common.h>
22 22
 
23  
-#define CSR_UART_RXTX 		MMPTR(0xe0000000)
  23
+#define CSR_UART_RXTX		MMPTR(0xe0000000)
24 24
 #define CSR_UART_DIVISORH	MMPTR(0xe0000004)
25 25
 #define CSR_UART_DIVISORL	MMPTR(0xe0000008)
26 26
 
7  top.py
@@ -31,7 +31,7 @@ def get():
31 31
 	#
32 32
 	# ASMI
33 33
 	#
34  
-	ddrphy0 = s6ddrphy.S6DDRPHY(13, 2, 128)
  34
+	ddrphy0 = s6ddrphy.S6DDRPHY(1, 13, 2, 128)
35 35
 	asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller
36 36
 	asmiport_wb = asmihub0.get_port()
37 37
 	asmihub0.finalize()
@@ -68,7 +68,10 @@ def get():
68 68
 	# CSR
69 69
 	#
70 70
 	uart0 = uart.UART(0, clk_freq, baud=115200)
71  
-	csrcon0 = csr.Interconnect(wishbone2csr0.csr, [uart0.bank.interface])
  71
+	csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
  72
+		uart0.bank.interface,
  73
+		ddrphy0.bank.interface
  74
+	])
72 75
 	
73 76
 	#
74 77
 	# Interrupts

0 notes on commit c387ce7

Please sign in to comment.
Something went wrong with that request. Please try again.