from migen.bank.description import *
from migen.bank import csrgen
-def _data_en(trigger, output, delay, duration):
- dcounter = Signal(BV(4))
- dce = Signal()
- return [
- If(trigger,
- dcounter.eq(delay),
- dce.eq(1)
- ).Elif(dce,
- dcounter.eq(dcounter - 1),
- If(dcounter == 0,
- If(~output,
- output.eq(1),
- dcounter.eq(duration)
- ).Else(
- output.eq(0),
- dce.eq(0)
- )
- )
- )
- ]
+class PhaseInjector:
+ def __init__(self, phase):
+ self.phase = phase
+
+ self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
+ self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
+ self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
+ self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
+ self._wren = Field("wren", 1, WRITE_ONLY, READ_ONLY)
+ self._rden = Field("rden", 1, WRITE_ONLY, READ_ONLY)
+ self._command = RegisterFields("command",
+ [self._cs, self._we, self._cas, self._ras, self._wren, self._rden])
+
+ self._address = RegisterField("address", self.phase.address.bv.width)
+ self._baddress = RegisterField("baddress", self.phase.bank.bv.width)
+
+ self._wrdata = RegisterField("wrdata", self.phase.wrdata.bv.width)
+ self._rddata = RegisterField("rddata", self.phase.rddata.bv.width, READ_ONLY, WRITE_ONLY)
+
+ def get_registers(self):
+ return [self._command,
+ self._address, self._baddress,
+ self._wrdata, self._rddata]
+
+ def get_fragment(self):
+ comb = [
+ If(self._command.re,
+ self.phase.cs_n.eq(~self._cs.r),
+ self.phase.we_n.eq(~self._we.r),
+ self.phase.cas_n.eq(~self._cas.r),
+ self.phase.ras_n.eq(~self._ras.r)
+ ).Else(
+ self.phase.cs_n.eq(1),
+ self.phase.we_n.eq(1),
+ self.phase.cas_n.eq(1),
+ self.phase.ras_n.eq(1)
+ ),
+ self.phase.address.eq(self._address.field.r),
+ self.phase.bank.eq(self._baddress.field.r),
+ self.phase.wrdata.eq(self._wrdata.field.r)
+ ]
+ sync = [
+ self.phase.wrdata_en.eq(self._command.re & self._wren.r),
+ self.phase.rddata_en.eq(self._command.re & self._rden.r),
+ If(self.phase.rddata_valid, self._rddata.field.w.eq(self.phase.rddata))
+ ]
+ return Fragment(comb, sync)
class DFIInjector:
def __init__(self, csr_address, a, ba, d, nphases=1):
self._cke = Field("cke")
self._control = RegisterFields("control", [self._sel, self._cke])
- self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
- self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
- self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
- self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
- self._rddata = Field("rddata", 1, WRITE_ONLY, READ_ONLY)
- self._wrdata = Field("wrdata", 1, WRITE_ONLY, READ_ONLY)
- self._command = RegisterFields("command",
- [self._cs, self._we, self._cas, self._ras, self._rddata, self._wrdata])
-
- self._address = RegisterField("address", a)
- self._baddress = RegisterField("baddress", ba)
+ self._phase_injectors = [PhaseInjector(phase) for phase in self._int.phases]
- self._rddelay = RegisterField("rddelay", 4, reset=5)
- self._rdduration = RegisterField("rdduration", 3, reset=0)
- self._wrdelay = RegisterField("wrdelay", 4, reset=3)
- self._wrduration = RegisterField("wrduration", 3, reset=0)
-
- self.bank = csrgen.Bank([
- self._control, self._command,
- self._address, self._baddress,
- self._rddelay, self._rdduration,
- self._wrdelay, self._wrduration
- ], address=csr_address)
+ registers = sum([pi.get_registers() for pi in self._phase_injectors], [self._control])
+ self.bank = csrgen.Bank(registers, address=csr_address)
def get_fragment(self):
- comb = []
- sync = []
-
- # mux
connect_int = dfi.interconnect_stmts(self._int, self.master)
connect_slave = dfi.interconnect_stmts(self.slave, self.master)
- comb.append(If(self._sel.r, *connect_slave).Else(*connect_int))
-
- # phases
- rddata_en = Signal()
- wrdata_en = Signal()
- for phase in self._int.phases:
- comb += [
- phase.cke.eq(self._cke.r),
- phase.rddata_en.eq(rddata_en),
- phase.wrdata_en.eq(wrdata_en)
- ]
- cmdphase = self._int.phases[0]
- for phase in self._int.phases[1:]:
- comb += [
- phase.cs_n.eq(1),
- phase.we_n.eq(1),
- phase.cas_n.eq(1),
- phase.ras_n.eq(1)
- ]
-
- # commands
- comb += [
- If(self._command.re,
- cmdphase.cs_n.eq(~self._cs.r),
- cmdphase.we_n.eq(~self._we.r),
- cmdphase.cas_n.eq(~self._cas.r),
- cmdphase.ras_n.eq(~self._ras.r)
- ).Else(
- cmdphase.cs_n.eq(1),
- cmdphase.we_n.eq(1),
- cmdphase.cas_n.eq(1),
- cmdphase.ras_n.eq(1)
- )
+ comb = [
+ If(self._sel.r, *connect_slave).Else(*connect_int)
]
+ comb += [phase.cke.eq(self._cke.r) for phase in self._int.phases]
- # addresses
- comb += [
- cmdphase.address.eq(self._address.field.r),
- cmdphase.bank.eq(self._baddress.field.r)
- ]
-
- # data enables
- sync += _data_en(self._command.re & self._rddata.r,
- rddata_en,
- self._rddelay.field.r, self._rdduration.field.r)
- sync += _data_en(self._command.re & self._wrdata.r,
- wrdata_en,
- self._wrdelay.field.r, self._wrduration.field.r)
-
- return Fragment(comb, sync) + self.bank.get_fragment()
+ return Fragment(comb) \
+ + sum([pi.get_fragment() for pi in self._phase_injectors], Fragment()) \
+ + self.bank.get_fragment()
*/
#include <stdio.h>
+#include <stdlib.h>
#include <hw/dfii.h>
static void setaddr(int a)
{
- CSR_DFII_AH = (a & 0x1fe0) >> 5;
- CSR_DFII_AL = a & 0x001f;
+ CSR_DFII_AH_P0 = (a & 0x1fe0) >> 5;
+ CSR_DFII_AL_P0 = a & 0x001f;
+ CSR_DFII_AH_P1 = (a & 0x1fe0) >> 5;
+ CSR_DFII_AL_P1 = a & 0x001f;
}
static void init_sequence(void)
/* Bring CKE high */
setaddr(0x0000);
- CSR_DFII_BA = 0;
+ CSR_DFII_BA_P0 = 0;
CSR_DFII_CONTROL = DFII_CONTROL_CKE;
/* Precharge All */
setaddr(0x0400);
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
/* Load Extended Mode Register */
- CSR_DFII_BA = 1;
+ CSR_DFII_BA_P0 = 1;
setaddr(0x0000);
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
- CSR_DFII_BA = 0;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+ CSR_DFII_BA_P0 = 0;
/* Load Mode Register */
setaddr(0x0132); /* Reset DLL, CL=3, BL=4 */
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
cdelay(200);
/* Precharge All */
setaddr(0x0400);
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
/* 2x Auto Refresh */
for(i=0;i<2;i++) {
setaddr(0);
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS;
cdelay(4);
}
/* Load Mode Register */
setaddr(0x0032); /* CL=3, BL=4 */
- CSR_DFII_COMMAND = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS;
cdelay(200);
}
+void ddrrd(char *startaddr)
+{
+ char *c;
+ unsigned int addr;
+ int i;
+
+ if(*startaddr == 0) {
+ printf("ddrrd <address>\n");
+ return;
+ }
+ addr = strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+
+ setaddr(addr);
+ CSR_DFII_BA_P0 = 0;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA;
+ cdelay(15);
+
+ for(i=0;i<8;i++)
+ printf("%08x ", MMPTR(0xe0000834+4*i));
+ for(i=0;i<8;i++)
+ printf("%08x ", MMPTR(0xe0000884+4*i));
+ printf("\n");
+}
+
+void ddrwr(char *startaddr)
+{
+ char *c;
+ unsigned int addr;
+ int i;
+
+ if(*startaddr == 0) {
+ printf("ddrrd <address>\n");
+ return;
+ }
+ addr = strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+
+ for(i=0;i<8;i++) {
+ MMPTR(0xe0000814+4*i) = i;
+ MMPTR(0xe0000864+4*i) = i;
+ }
+
+ setaddr(addr);
+ CSR_DFII_BA_P1 = 0;
+ CSR_DFII_COMMAND_P1 = DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA;
+}
+
int ddrinit(void)
{
printf("Initializing DDR SDRAM...\n");
init_sequence();
+ setaddr(0x0000);
+ CSR_DFII_BA_P0 = 0;
+ CSR_DFII_COMMAND_P0 = DFII_COMMAND_RAS|DFII_COMMAND_CS;
+ cdelay(15);
+
return 1;
}
#define DFII_CONTROL_SEL (0x01)
#define DFII_CONTROL_CKE (0x02)
-#define CSR_DFII_COMMAND MMPTR(0xe0001004)
+#define CSR_DFII_COMMAND_P0 MMPTR(0xe0000804)
+#define CSR_DFII_AH_P0 MMPTR(0xe0000808)
+#define CSR_DFII_AL_P0 MMPTR(0xe000080C)
+#define CSR_DFII_BA_P0 MMPTR(0xe0000810)
+#define CSR_DFII_WD0_P0 MMPTR(0xe0000814)
+#define CSR_DFII_WD1_P0 MMPTR(0xe0000818)
+#define CSR_DFII_WD2_P0 MMPTR(0xe000081C)
+#define CSR_DFII_WD3_P0 MMPTR(0xe0000820)
+#define CSR_DFII_WD4_P0 MMPTR(0xe0000824)
+#define CSR_DFII_WD5_P0 MMPTR(0xe0000828)
+#define CSR_DFII_WD6_P0 MMPTR(0xe000082C)
+#define CSR_DFII_WD7_P0 MMPTR(0xe0000830)
+#define CSR_DFII_RD0_P0 MMPTR(0xe0000834)
+#define CSR_DFII_RD1_P0 MMPTR(0xe0000838)
+#define CSR_DFII_RD2_P0 MMPTR(0xe000083C)
+#define CSR_DFII_RD3_P0 MMPTR(0xe0000840)
+#define CSR_DFII_RD4_P0 MMPTR(0xe0000844)
+#define CSR_DFII_RD5_P0 MMPTR(0xe0000848)
+#define CSR_DFII_RD6_P0 MMPTR(0xe000084C)
+#define CSR_DFII_RD7_P0 MMPTR(0xe0000850)
+
+#define CSR_DFII_COMMAND_P1 MMPTR(0xe0000854)
+#define CSR_DFII_AH_P1 MMPTR(0xe0000858)
+#define CSR_DFII_AL_P1 MMPTR(0xe000085C)
+#define CSR_DFII_BA_P1 MMPTR(0xe0000860)
+#define CSR_DFII_WD0_P1 MMPTR(0xe0000864)
+#define CSR_DFII_WD1_P1 MMPTR(0xe0000868)
+#define CSR_DFII_WD2_P1 MMPTR(0xe000086C)
+#define CSR_DFII_WD3_P1 MMPTR(0xe0000870)
+#define CSR_DFII_WD4_P1 MMPTR(0xe0000874)
+#define CSR_DFII_WD5_P1 MMPTR(0xe0000878)
+#define CSR_DFII_WD6_P1 MMPTR(0xe000087C)
+#define CSR_DFII_WD7_P1 MMPTR(0xe0000880)
+#define CSR_DFII_RD0_P1 MMPTR(0xe0000884)
+#define CSR_DFII_RD1_P1 MMPTR(0xe0000888)
+#define CSR_DFII_RD2_P1 MMPTR(0xe000088C)
+#define CSR_DFII_RD3_P1 MMPTR(0xe0000890)
+#define CSR_DFII_RD4_P1 MMPTR(0xe0000894)
+#define CSR_DFII_RD5_P1 MMPTR(0xe0000898)
+#define CSR_DFII_RD6_P1 MMPTR(0xe000089C)
+#define CSR_DFII_RD7_P1 MMPTR(0xe00008a0)
#define DFII_COMMAND_CS (0x01)
#define DFII_COMMAND_WE (0x02)
#define DFII_COMMAND_CAS (0x04)
#define DFII_COMMAND_RAS (0x08)
-#define DFII_COMMAND_RDDATA (0x10)
-#define DFII_COMMAND_WRDATA (0x20)
-
-#define CSR_DFII_AH MMPTR(0xe0000808)
-#define CSR_DFII_AL MMPTR(0xe000080C)
-#define CSR_DFII_BA MMPTR(0xe0000810)
-
-#define CSR_DFII_RDDELAY MMPTR(0xe0000814)
-#define CSR_DFII_RDDURATION MMPTR(0xe0000818)
-#define CSR_DFII_WRDELAY MMPTR(0xe000081C)
-#define CSR_DFII_WRDURATION MMPTR(0xe0000820)
+#define DFII_COMMAND_WRDATA (0x10)
+#define DFII_COMMAND_RDDATA (0x20)
#endif /* __HW_DFII_H */