Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

dfii: new design

  • Loading branch information...
commit 92ac69bae34d543fc842309b414a58a1594174b1 1 parent b3ca952
Sébastien Bourdeauducq authored February 23, 2012
150  milkymist/dfii/__init__.py
@@ -3,26 +3,53 @@
3 3
 from migen.bank.description import *
4 4
 from migen.bank import csrgen
5 5
 
6  
-def _data_en(trigger, output, delay, duration):
7  
-	dcounter = Signal(BV(4))
8  
-	dce = Signal()
9  
-	return [
10  
-		If(trigger,
11  
-			dcounter.eq(delay),
12  
-			dce.eq(1)
13  
-		).Elif(dce,
14  
-			dcounter.eq(dcounter - 1),
15  
-			If(dcounter == 0,
16  
-				If(~output,
17  
-					output.eq(1),
18  
-					dcounter.eq(duration)
19  
-				).Else(
20  
-					output.eq(0),
21  
-					dce.eq(0)
22  
-				)
23  
-			)
24  
-		)
25  
-	]
  6
+class PhaseInjector:
  7
+	def __init__(self, phase):
  8
+		self.phase = phase
  9
+		
  10
+		self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
  11
+		self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
  12
+		self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
  13
+		self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
  14
+		self._wren = Field("wren", 1, WRITE_ONLY, READ_ONLY)
  15
+		self._rden = Field("rden", 1, WRITE_ONLY, READ_ONLY)
  16
+		self._command = RegisterFields("command",
  17
+			[self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
  18
+		
  19
+		self._address = RegisterField("address", self.phase.address.bv.width)
  20
+		self._baddress = RegisterField("baddress", self.phase.bank.bv.width)
  21
+		
  22
+		self._wrdata = RegisterField("wrdata", self.phase.wrdata.bv.width)
  23
+		self._rddata = RegisterField("rddata", self.phase.rddata.bv.width, READ_ONLY, WRITE_ONLY)
  24
+	
  25
+	def get_registers(self):
  26
+		return [self._command,
  27
+			self._address, self._baddress,
  28
+			self._wrdata, self._rddata]
  29
+		
  30
+	def get_fragment(self):
  31
+		comb = [
  32
+			If(self._command.re,
  33
+				self.phase.cs_n.eq(~self._cs.r),
  34
+				self.phase.we_n.eq(~self._we.r),
  35
+				self.phase.cas_n.eq(~self._cas.r),
  36
+				self.phase.ras_n.eq(~self._ras.r)
  37
+			).Else(
  38
+				self.phase.cs_n.eq(1),
  39
+				self.phase.we_n.eq(1),
  40
+				self.phase.cas_n.eq(1),
  41
+				self.phase.ras_n.eq(1)
  42
+			),
  43
+			self.phase.address.eq(self._address.field.r),
  44
+			self.phase.bank.eq(self._baddress.field.r),
  45
+			self.phase.wrdata.eq(self._wrdata.field.r)
  46
+		]
  47
+		sync = [
  48
+			self.phase.wrdata_en.eq(self._command.re & self._wren.r),
  49
+			self.phase.rddata_en.eq(self._command.re & self._rden.r),
  50
+			If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
  51
+		]
  52
+		return Fragment(comb, sync)
26 53
 
27 54
 class DFIInjector:
28 55
 	def __init__(self, csr_address, a, ba, d, nphases=1):
@@ -34,84 +61,19 @@ def __init__(self, csr_address, a, ba, d, nphases=1):
34 61
 		self._cke = Field("cke")
35 62
 		self._control = RegisterFields("control", [self._sel, self._cke])
36 63
 		
37  
-		self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
38  
-		self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
39  
-		self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
40  
-		self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
41  
-		self._rddata = Field("rddata", 1, WRITE_ONLY, READ_ONLY)
42  
-		self._wrdata = Field("wrdata", 1, WRITE_ONLY, READ_ONLY)
43  
-		self._command = RegisterFields("command",
44  
-			[self._cs, self._we, self._cas, self._ras, self._rddata, self._wrdata])
45  
-		
46  
-		self._address = RegisterField("address", a)
47  
-		self._baddress = RegisterField("baddress", ba)
  64
+		self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
48 65
 		
49  
-		self._rddelay = RegisterField("rddelay", 4, reset=5)
50  
-		self._rdduration = RegisterField("rdduration", 3, reset=0)
51  
-		self._wrdelay = RegisterField("wrdelay", 4, reset=3)
52  
-		self._wrduration = RegisterField("wrduration", 3, reset=0)
53  
-		
54  
-		self.bank = csrgen.Bank([
55  
-				self._control, self._command,
56  
-				self._address, self._baddress,
57  
-				self._rddelay, self._rdduration,
58  
-				self._wrdelay, self._wrduration
59  
-			], address=csr_address)
  66
+		registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
  67
+		self.bank = csrgen.Bank(registers, address=csr_address)
60 68
 	
61 69
 	def get_fragment(self):
62  
-		comb = []
63  
-		sync = []
64  
-		
65  
-		# mux
66 70
 		connect_int = dfi.interconnect_stmts(self._int, self.master)
67 71
 		connect_slave = dfi.interconnect_stmts(self.slave, self.master)
68  
-		comb.append(If(self._sel.r, *connect_slave).Else(*connect_int))
69  
-		
70  
-		# phases
71  
-		rddata_en = Signal()
72  
-		wrdata_en = Signal()
73  
-		for phase in self._int.phases:
74  
-			comb += [
75  
-				phase.cke.eq(self._cke.r),
76  
-				phase.rddata_en.eq(rddata_en),
77  
-				phase.wrdata_en.eq(wrdata_en)
78  
-			]
79  
-		cmdphase = self._int.phases[0]
80  
-		for phase in self._int.phases[1:]:
81  
-			comb += [
82  
-				phase.cs_n.eq(1),
83  
-				phase.we_n.eq(1),
84  
-				phase.cas_n.eq(1),
85  
-				phase.ras_n.eq(1)
86  
-			]
87  
-		
88  
-		# commands
89  
-		comb += [
90  
-			If(self._command.re,
91  
-				cmdphase.cs_n.eq(~self._cs.r),
92  
-				cmdphase.we_n.eq(~self._we.r),
93  
-				cmdphase.cas_n.eq(~self._cas.r),
94  
-				cmdphase.ras_n.eq(~self._ras.r)
95  
-			).Else(
96  
-				cmdphase.cs_n.eq(1),
97  
-				cmdphase.we_n.eq(1),
98  
-				cmdphase.cas_n.eq(1),
99  
-				cmdphase.ras_n.eq(1)
100  
-			)
  72
+		comb = [
  73
+			If(self._sel.r, *connect_slave).Else(*connect_int)
101 74
 		]
  75
+		comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
102 76
 		
103  
-		# addresses
104  
-		comb += [
105  
-			cmdphase.address.eq(self._address.field.r),
106  
-			cmdphase.bank.eq(self._baddress.field.r)
107  
-		]
108  
-		
109  
-		# data enables
110  
-		sync += _data_en(self._command.re & self._rddata.r,
111  
-			rddata_en,
112  
-			self._rddelay.field.r, self._rdduration.field.r)
113  
-		sync += _data_en(self._command.re & self._wrdata.r,
114  
-			wrdata_en,
115  
-			self._wrdelay.field.r, self._wrduration.field.r)
116  
-		
117  
-		return Fragment(comb, sync) + self.bank.get_fragment()
  77
+		return Fragment(comb) \
  78
+			+ sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
  79
+			+ self.bank.get_fragment()
84  software/bios/ddrinit.c
@@ -16,6 +16,7 @@
16 16
  */
17 17
 
18 18
 #include <stdio.h>
  19
+#include <stdlib.h>
19 20
 
20 21
 #include <hw/dfii.h>
21 22
 
@@ -31,8 +32,10 @@ static void cdelay(int i)
31 32
 
32 33
 static void setaddr(int a)
33 34
 {
34  
-	CSR_DFII_AH = (a & 0x1fe0) >> 5;
35  
-	CSR_DFII_AL = a & 0x001f;
  35
+	CSR_DFII_AH_P0 = (a & 0x1fe0) >> 5;
  36
+	CSR_DFII_AL_P0 = a & 0x001f;
  37
+	CSR_DFII_AH_P1 = (a & 0x1fe0) >> 5;
  38
+	CSR_DFII_AL_P1 = a & 0x001f;
36 39
 }
37 40
 
38 41
 static void init_sequence(void)
@@ -43,46 +46,105 @@ static void init_sequence(void)
43 46
 	
44 47
 	/* Bring CKE high */
45 48
 	setaddr(0x0000);
46  
-	CSR_DFII_BA = 0;
  49
+	CSR_DFII_BA_P0 = 0;
47 50
 	CSR_DFII_CONTROL = DFII_CONTROL_CKE;
48 51
 	
49 52
 	/* Precharge All */
50 53
 	setaddr(0x0400);
51  
-	CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
  54
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
52 55
 	
53 56
 	/* Load Extended Mode Register */
54  
-	CSR_DFII_BA = 1;
  57
+	CSR_DFII_BA_P0 = 1;
55 58
 	setaddr(0x0000);
56  
-	CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
57  
-	CSR_DFII_BA = 0;
  59
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
  60
+	CSR_DFII_BA_P0 = 0;
58 61
 	
59 62
 	/* Load Mode Register */
60 63
 	setaddr(0x0132); /* Reset DLL, CL=3, BL=4 */
61  
-	CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
  64
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
62 65
 	cdelay(200);
63 66
 	
64 67
 	/* Precharge All */
65 68
 	setaddr(0x0400);
66  
-	CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
  69
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
67 70
 	
68 71
 	/* 2x Auto Refresh */
69 72
 	for(i=0;i<2;i++) {
70 73
 		setaddr(0);
71  
-		CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS;
  74
+		CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS;
72 75
 		cdelay(4);
73 76
 	}
74 77
 	
75 78
 	/* Load Mode Register */
76 79
 	setaddr(0x0032); /* CL=3, BL=4 */
77  
-	CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
  80
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
78 81
 	cdelay(200);
79 82
 }
80 83
 
  84
+void ddrrd(char *startaddr)
  85
+{
  86
+	char *c;
  87
+	unsigned int addr;
  88
+	int i;
  89
+
  90
+	if(*startaddr == 0) {
  91
+		printf("ddrrd <address>\n");
  92
+		return;
  93
+	}
  94
+	addr = strtoul(startaddr, &c, 0);
  95
+	if(*c != 0) {
  96
+		printf("incorrect address\n");
  97
+		return;
  98
+	}
  99
+	
  100
+	setaddr(addr);
  101
+	CSR_DFII_BA_P0 = 0;
  102
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA;
  103
+	cdelay(15);
  104
+	
  105
+	for(i=0;i<8;i++)
  106
+		printf("%08x ", MMPTR(0xe0000834+4*i));
  107
+	for(i=0;i<8;i++)
  108
+		printf("%08x ", MMPTR(0xe0000884+4*i));
  109
+	printf("\n");
  110
+}
  111
+
  112
+void ddrwr(char *startaddr)
  113
+{
  114
+	char *c;
  115
+	unsigned int addr;
  116
+	int i;
  117
+
  118
+	if(*startaddr == 0) {
  119
+		printf("ddrrd <address>\n");
  120
+		return;
  121
+	}
  122
+	addr = strtoul(startaddr, &c, 0);
  123
+	if(*c != 0) {
  124
+		printf("incorrect address\n");
  125
+		return;
  126
+	}
  127
+	
  128
+	for(i=0;i<8;i++) {
  129
+		MMPTR(0xe0000814+4*i) = i;
  130
+		MMPTR(0xe0000864+4*i) = i;
  131
+	}
  132
+	
  133
+	setaddr(addr);
  134
+	CSR_DFII_BA_P1 = 0;
  135
+	CSR_DFII_COMMAND_P1 = DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA;
  136
+}
  137
+
81 138
 int ddrinit(void)
82 139
 {
83 140
 	printf("Initializing DDR SDRAM...\n");
84 141
 	
85 142
 	init_sequence();
86 143
 	
  144
+	setaddr(0x0000);
  145
+	CSR_DFII_BA_P0 = 0;
  146
+	CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CS;
  147
+	cdelay(15);
  148
+	
87 149
 	return 1;
88 150
 }
2  software/bios/ddrinit.h
@@ -19,5 +19,7 @@
19 19
 #define __DDRINIT_H
20 20
 
21 21
 int ddrinit(void);
  22
+void ddrrd(char *startaddr);
  23
+void ddrwr(char *startaddr);
22 24
 
23 25
 #endif /* __DDRINIT_H */
2  software/bios/main.c
@@ -353,6 +353,8 @@ static void do_command(char *c)
353 353
 	else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
354 354
 	
355 355
 	else if(strcmp(token, "ddrinit") == 0) ddrinit();
  356
+	else if(strcmp(token, "ddrrd") == 0) ddrrd(get_token(&c));
  357
+	else if(strcmp(token, "ddrwr") == 0) ddrwr(get_token(&c));
356 358
 
357 359
 	else if(strcmp(token, "") != 0)
358 360
 		printf("Command not found\n");
55  software/include/hw/dfii.h
@@ -25,22 +25,53 @@
25 25
 #define DFII_CONTROL_SEL		(0x01)
26 26
 #define DFII_CONTROL_CKE		(0x02)
27 27
 
28  
-#define CSR_DFII_COMMAND		MMPTR(0xe0001004)
  28
+#define CSR_DFII_COMMAND_P0		MMPTR(0xe0000804)
  29
+#define CSR_DFII_AH_P0			MMPTR(0xe0000808)
  30
+#define CSR_DFII_AL_P0			MMPTR(0xe000080C)
  31
+#define CSR_DFII_BA_P0			MMPTR(0xe0000810)
  32
+#define CSR_DFII_WD0_P0			MMPTR(0xe0000814)
  33
+#define CSR_DFII_WD1_P0			MMPTR(0xe0000818)
  34
+#define CSR_DFII_WD2_P0			MMPTR(0xe000081C)
  35
+#define CSR_DFII_WD3_P0			MMPTR(0xe0000820)
  36
+#define CSR_DFII_WD4_P0			MMPTR(0xe0000824)
  37
+#define CSR_DFII_WD5_P0			MMPTR(0xe0000828)
  38
+#define CSR_DFII_WD6_P0			MMPTR(0xe000082C)
  39
+#define CSR_DFII_WD7_P0			MMPTR(0xe0000830)
  40
+#define CSR_DFII_RD0_P0			MMPTR(0xe0000834)
  41
+#define CSR_DFII_RD1_P0			MMPTR(0xe0000838)
  42
+#define CSR_DFII_RD2_P0			MMPTR(0xe000083C)
  43
+#define CSR_DFII_RD3_P0			MMPTR(0xe0000840)
  44
+#define CSR_DFII_RD4_P0			MMPTR(0xe0000844)
  45
+#define CSR_DFII_RD5_P0			MMPTR(0xe0000848)
  46
+#define CSR_DFII_RD6_P0			MMPTR(0xe000084C)
  47
+#define CSR_DFII_RD7_P0			MMPTR(0xe0000850)
  48
+
  49
+#define CSR_DFII_COMMAND_P1		MMPTR(0xe0000854)
  50
+#define CSR_DFII_AH_P1			MMPTR(0xe0000858)
  51
+#define CSR_DFII_AL_P1			MMPTR(0xe000085C)
  52
+#define CSR_DFII_BA_P1			MMPTR(0xe0000860)
  53
+#define CSR_DFII_WD0_P1			MMPTR(0xe0000864)
  54
+#define CSR_DFII_WD1_P1			MMPTR(0xe0000868)
  55
+#define CSR_DFII_WD2_P1			MMPTR(0xe000086C)
  56
+#define CSR_DFII_WD3_P1			MMPTR(0xe0000870)
  57
+#define CSR_DFII_WD4_P1			MMPTR(0xe0000874)
  58
+#define CSR_DFII_WD5_P1			MMPTR(0xe0000878)
  59
+#define CSR_DFII_WD6_P1			MMPTR(0xe000087C)
  60
+#define CSR_DFII_WD7_P1			MMPTR(0xe0000880)
  61
+#define CSR_DFII_RD0_P1			MMPTR(0xe0000884)
  62
+#define CSR_DFII_RD1_P1			MMPTR(0xe0000888)
  63
+#define CSR_DFII_RD2_P1			MMPTR(0xe000088C)
  64
+#define CSR_DFII_RD3_P1			MMPTR(0xe0000890)
  65
+#define CSR_DFII_RD4_P1			MMPTR(0xe0000894)
  66
+#define CSR_DFII_RD5_P1			MMPTR(0xe0000898)
  67
+#define CSR_DFII_RD6_P1			MMPTR(0xe000089C)
  68
+#define CSR_DFII_RD7_P1			MMPTR(0xe00008a0)
29 69
 
30 70
 #define DFII_COMMAND_CS			(0x01)
31 71
 #define DFII_COMMAND_WE			(0x02)
32 72
 #define DFII_COMMAND_CAS		(0x04)
33 73
 #define DFII_COMMAND_RAS		(0x08)
34  
-#define DFII_COMMAND_RDDATA		(0x10)
35  
-#define DFII_COMMAND_WRDATA		(0x20)
36  
-
37  
-#define CSR_DFII_AH			MMPTR(0xe0000808)
38  
-#define CSR_DFII_AL			MMPTR(0xe000080C)
39  
-#define CSR_DFII_BA			MMPTR(0xe0000810)
40  
-
41  
-#define CSR_DFII_RDDELAY		MMPTR(0xe0000814)
42  
-#define CSR_DFII_RDDURATION		MMPTR(0xe0000818)
43  
-#define CSR_DFII_WRDELAY		MMPTR(0xe000081C)
44  
-#define CSR_DFII_WRDURATION		MMPTR(0xe0000820)
  74
+#define DFII_COMMAND_WRDATA		(0x10)
  75
+#define DFII_COMMAND_RDDATA		(0x20)
45 76
 
46 77
 #endif /* __HW_DFII_H */

0 notes on commit 92ac69b

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