Skip to content

Commit 92ac69b

Browse files
author
Sebastien Bourdeauducq
committedFeb 23, 2012
dfii: new design
1 parent b3ca952 commit 92ac69b

File tree

5 files changed

+176
-117
lines changed

5 files changed

+176
-117
lines changed
 

‎milkymist/dfii/__init__.py

+56-94
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,53 @@
33
from migen.bank.description import *
44
from migen.bank import csrgen
55

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)
2653

2754
class DFIInjector:
2855
def __init__(self, csr_address, a, ba, d, nphases=1):
@@ -34,84 +61,19 @@ def __init__(self, csr_address, a, ba, d, nphases=1):
3461
self._cke = Field("cke")
3562
self._control = RegisterFields("control", [self._sel, self._cke])
3663

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]
4865

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)
6068

6169
def get_fragment(self):
62-
comb = []
63-
sync = []
64-
65-
# mux
6670
connect_int = dfi.interconnect_stmts(self._int, self.master)
6771
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)
10174
]
75+
comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
10276

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()

‎software/bios/ddrinit.c

+73-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include <stdio.h>
19+
#include <stdlib.h>
1920

2021
#include <hw/dfii.h>
2122

@@ -31,8 +32,10 @@ static void cdelay(int i)
3132

3233
static void setaddr(int a)
3334
{
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;
3639
}
3740

3841
static void init_sequence(void)
@@ -43,46 +46,105 @@ static void init_sequence(void)
4346

4447
/* Bring CKE high */
4548
setaddr(0x0000);
46-
CSR_DFII_BA = 0;
49+
CSR_DFII_BA_P0 = 0;
4750
CSR_DFII_CONTROL = DFII_CONTROL_CKE;
4851

4952
/* Precharge All */
5053
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;
5255

5356
/* Load Extended Mode Register */
54-
CSR_DFII_BA = 1;
57+
CSR_DFII_BA_P0 = 1;
5558
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;
5861

5962
/* Load Mode Register */
6063
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;
6265
cdelay(200);
6366

6467
/* Precharge All */
6568
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;
6770

6871
/* 2x Auto Refresh */
6972
for(i=0;i<2;i++) {
7073
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;
7275
cdelay(4);
7376
}
7477

7578
/* Load Mode Register */
7679
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;
7881
cdelay(200);
7982
}
8083

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+
81138
int ddrinit(void)
82139
{
83140
printf("Initializing DDR SDRAM...\n");
84141

85142
init_sequence();
86143

144+
setaddr(0x0000);
145+
CSR_DFII_BA_P0 = 0;
146+
CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CS;
147+
cdelay(15);
148+
87149
return 1;
88150
}

‎software/bios/ddrinit.h

+2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@
1919
#define __DDRINIT_H
2020

2121
int ddrinit(void);
22+
void ddrrd(char *startaddr);
23+
void ddrwr(char *startaddr);
2224

2325
#endif /* __DDRINIT_H */

‎software/bios/main.c

+2
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ static void do_command(char *c)
353353
else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
354354

355355
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));
356358

357359
else if(strcmp(token, "") != 0)
358360
printf("Command not found\n");

‎software/include/hw/dfii.h

+43-12
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,53 @@
2525
#define DFII_CONTROL_SEL (0x01)
2626
#define DFII_CONTROL_CKE (0x02)
2727

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)
2969

3070
#define DFII_COMMAND_CS (0x01)
3171
#define DFII_COMMAND_WE (0x02)
3272
#define DFII_COMMAND_CAS (0x04)
3373
#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)
4576

4677
#endif /* __HW_DFII_H */

0 commit comments

Comments
 (0)
Please sign in to comment.