Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 9 files changed
  • 0 comments
  • 2 contributors
1  .gitignore
@@ -11,6 +11,7 @@ tools/flterm
11 11
 tools/mkmmimg
12 12
 tools/byteswap
13 13
 software/include/hw/csr.h
  14
+software/include/hw/sdram_phy.h
14 15
 software/videomixer/dvisampler0.c
15 16
 software/videomixer/dvisampler0.h
16 17
 software/videomixer/dvisampler1.c
8  make.py
@@ -27,7 +27,7 @@ def build(platform_name, build_bitstream, build_header):
27 27
 TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
28 28
 """)
29 29
 
30  
-	for d in ["mxcrg", "s6ddrphy", "minimac3"]:
  30
+	for d in ["mxcrg", "minimac3"]:
31 31
 		platform.add_source_dir(os.path.join("verilog", d))
32 32
 	platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), 
33 33
 		"lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
@@ -47,12 +47,16 @@ def build(platform_name, build_bitstream, build_header):
47 47
 	if build_header:
48 48
 		csr_header = cif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
49 49
 		write_to_file("software/include/hw/csr.h", csr_header)
  50
+		
  51
+		sdram_phy_header = cif.get_sdram_phy_header(soc.ddrphy)
  52
+		write_to_file("software/include/hw/sdram_phy.h", sdram_phy_header)
  53
+
50 54
 
51 55
 def main():
52 56
 	parser = argparse.ArgumentParser(description="milkymist-ng - a high performance SoC built on Migen technology.")
53 57
 	parser.add_argument("-p", "--platform", default="mixxeo", help="platform to build for")
54 58
 	parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file")
55  
-	parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header file with CSR/IRQ defs")
  59
+	parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header file with CSR/IRQ/SDRAM_PHY defs")
56 60
 	parser.add_argument("-l", "--load", default=False, action="store_true", help="load bitstream to SRAM")
57 61
 	parser.add_argument("-f", "--flash", default=False, action="store_true", help="load bitstream to flash")
58 62
 	args = parser.parse_args()
134  milkymist/cif.py
... ...
@@ -1,6 +1,7 @@
1 1
 from operator import itemgetter
2 2
 import re
3 3
 
  4
+from migen.fhdl.std import *
4 5
 from migen.bank.description import CSRStatus
5 6
 
6 7
 def get_macros(filename):
@@ -64,3 +65,136 @@ def get_csr_header(csr_base, bank_array, interrupt_map):
64 65
 			r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n"
65 66
 	r += "\n#endif\n"
66 67
 	return r
  68
+
  69
+def get_sdram_phy_header(sdram_phy):
  70
+		if sdram_phy.phy_settings.type not in ["SDR", "DDR", "LPDDR", "DDR2"]:
  71
+			raise NotImplementedError("The SDRAM PHY header generator only supports SDR, DDR, LPDDR and DDR2")
  72
+
  73
+		r = "#ifndef __HW_SDRAM_PHY_H\n#define __HW_SDRAM_PHY_H\n"
  74
+		r += "#include <hw/common.h>\n#include <hw/csr.h>\n#include <hw/flags.h>\n\n"
  75
+
  76
+		r += "static void cdelay(int i);\n"
  77
+
  78
+		#
  79
+		# commands_px functions
  80
+		# 
  81
+		for n in range(sdram_phy.phy_settings.nphases):
  82
+			r += """
  83
+static void command_p{n}(int cmd)
  84
+{{
  85
+	dfii_pi{n}_command_write(cmd);
  86
+	dfii_pi{n}_command_issue_write(1);
  87
+}}""".format(n=str(n))
  88
+		r += "\n\n"
  89
+
  90
+		#
  91
+		# rd/wr access macros
  92
+		#
  93
+		r += """
  94
+#define dfii_pird_address_write(X) dfii_pi{rdphase}_address_write(X)
  95
+#define dfii_piwr_address_write(X) dfii_pi{wrphase}_address_write(X)
  96
+
  97
+#define dfii_pird_baddress_write(X) dfii_pi{rdphase}_baddress_write(X)
  98
+#define dfii_piwr_baddress_write(X) dfii_pi{wrphase}_baddress_write(X)
  99
+
  100
+#define command_prd(X) command_p{rdphase}(X)
  101
+#define command_pwr(X) command_p{wrphase}(X)
  102
+""".format(rdphase=str(sdram_phy.phy_settings.rdphase), wrphase=str(sdram_phy.phy_settings.wrphase)) 
  103
+		r +="\n"
  104
+		
  105
+		#
  106
+		# init sequence
  107
+		# 
  108
+		cmds = {
  109
+			"PRECHARGE_ALL" : "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
  110
+			"MODE_REGISTER" : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
  111
+			"AUTO_REFRESH"  : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
  112
+			"CKE"           : "DFII_CONTROL_CKE"
  113
+		}
  114
+
  115
+		def gen_cmd(comment, a, ba, cmd, delay):	
  116
+			r = "\t/* %s */\n" %comment
  117
+			r += "\tdfii_pi0_address_write(0x%04X);\n" %a
  118
+			r += "\tdfii_pi0_baddress_write(%d);\n" %ba
  119
+			if "CKE" in cmd:
  120
+				r += "\tdfii_control_write(%s);\n" %cmd
  121
+			else:
  122
+				r += "\tcommand_p0(%s);\n" %cmd
  123
+			r += "\tcdelay(%d);\n" %delay
  124
+			r += "\n"
  125
+			return r
  126
+
  127
+
  128
+		r += "static void init_sequence(void)\n{\n"
  129
+
  130
+		cl = sdram_phy.phy_settings.cl
  131
+		
  132
+		if sdram_phy.phy_settings.type == "SDR":
  133
+			bl = 1*sdram_phy.phy_settings.nphases
  134
+			mr  = log2_int(bl) + (cl << 4)
  135
+			reset_dll = 1 << 8
  136
+
  137
+			init_sequence = [
  138
+				("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
  139
+				("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  140
+				("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
  141
+				("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  142
+				("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
  143
+				("Load Mode Register / CL=%d, BL=%d" %(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
  144
+			]
  145
+
  146
+		elif sdram_phy.phy_settings.type == "DDR":
  147
+			bl = 2*sdram_phy.phy_settings.nphases
  148
+			mr  = log2_int(bl) + (cl << 4)
  149
+			emr = 0
  150
+			reset_dll = 1 << 8
  151
+ 
  152
+			init_sequence = [
  153
+				("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
  154
+				("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  155
+				("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
  156
+				("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
  157
+				("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  158
+				("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
  159
+				("Load Mode Register / CL=%d, BL=%d" %(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
  160
+			]
  161
+
  162
+		elif sdram_phy.phy_settings.type == "LPDDR":
  163
+			bl = 2*sdram_phy.phy_settings.nphases
  164
+			mr  = log2_int(bl) + (cl << 4)
  165
+			emr = 0
  166
+			reset_dll = 1 << 8
  167
+
  168
+			init_sequence = [
  169
+				("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
  170
+				("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  171
+				("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
  172
+				("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
  173
+				("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  174
+				("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
  175
+				("Load Mode Register / CL=%d, BL=%d" %(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
  176
+			]
  177
+
  178
+		elif sdram_phy.phy_settings.type == "DDR2":
  179
+			bl = 2*sdram_phy.phy_settings.nphases
  180
+			mr  = log2_int(bl) + (cl << 4)
  181
+			emr = 0
  182
+			reset_dll = 1 << 8
  183
+
  184
+			init_sequence = [
  185
+				("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
  186
+				("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  187
+				("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
  188
+				("Load Mode Register / Reset DLL, CL=%d, BL=%d" %(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
  189
+				("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
  190
+				("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
  191
+				("Load Mode Register / CL=%d, BL=%d" %(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
  192
+			]
  193
+
  194
+		for comment, a, ba, cmd, delay in init_sequence:
  195
+			r += gen_cmd(comment, a, ba, cmd, delay)
  196
+
  197
+		r += "}\n"
  198
+		r += "#endif\n"
  199
+
  200
+		return r
2  milkymist/lasmicon/__init__.py
@@ -7,7 +7,7 @@
7 7
 from milkymist.lasmicon.bankmachine import *
8 8
 from milkymist.lasmicon.multiplexer import *
9 9
 
10  
-PhySettings = namedtuple("PhySettings", "dfi_d nphases rdphase wrphase")
  10
+PhySettings = namedtuple("PhySettings", "type dfi_d nphases rdphase wrphase cl")
11 11
 
12 12
 class GeomSettings(namedtuple("_GeomSettings", "bank_a row_a col_a")):
13 13
 	def __init__(self, *args, **kwargs):
12  milkymist/mxcrg/__init__.py
@@ -6,9 +6,9 @@
6 6
 class MXCRG(Module, AutoCSR):
7 7
 	def __init__(self, pads, outfreq1x):
8 8
 		self.clock_domains.cd_sys = ClockDomain()
9  
-		self.clock_domains.cd_sys2x_270 = ClockDomain()
10  
-		self.clock_domains.cd_sys4x_wr = ClockDomain()
11  
-		self.clock_domains.cd_sys4x_rd = ClockDomain()
  9
+		self.clock_domains.cd_sdram_half = ClockDomain()
  10
+		self.clock_domains.cd_sdram_full_wr = ClockDomain()
  11
+		self.clock_domains.cd_sdram_full_rd = ClockDomain()
12 12
 		self.clock_domains.cd_eth_rx = ClockDomain()
13 13
 		self.clock_domains.cd_eth_tx = ClockDomain()
14 14
 		self.clock_domains.cd_vga = ClockDomain(reset_less=True)
@@ -44,9 +44,9 @@ def __init__(self, pads, outfreq1x):
44 44
 			
45 45
 			Instance.Output("sys_clk", self.cd_sys.clk),
46 46
 			Instance.Output("sys_rst", self.cd_sys.rst),
47  
-			Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
48  
-			Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
49  
-			Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
  47
+			Instance.Output("clk2x_270", self.cd_sdram_half.clk),
  48
+			Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
  49
+			Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
50 50
 			Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
51 51
 			Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
52 52
 			Instance.Output("vga_clk", self.cd_vga.clk),
370  milkymist/s6ddrphy/__init__.py
... ...
@@ -1,40 +1,348 @@
  1
+#
  2
+# 1:2 frequency-ratio DDR / LPDDR / DDR2 PHY for 
  3
+# Spartan-6
  4
+# 
  5
+# Assert dfi_wrdata_en and present the data 
  6
+# on dfi_wrdata_mask/dfi_wrdata in the same
  7
+# cycle as the write command.
  8
+#
  9
+# Assert dfi_rddata_en in the same cycle as the read
  10
+# command. The data will come back on dfi_rddata
  11
+# CL + 2 cycles later, along with the assertion 
  12
+# of dfi_rddata_valid.
  13
+#
  14
+# This PHY supports configurable CAS Latency.
  15
+# Read commands must be sent on phase RDPHASE.
  16
+# Write commands must be sent on phase WRPHASE.
  17
+#/
  18
+
  19
+# Todo:
  20
+#	- use CSR for bitslip?
  21
+
1 22
 from migen.fhdl.std import *
2  
-from migen.bus import dfi
  23
+from migen.bus.dfi import *
  24
+from migen.genlib.record import *
3 25
 
4 26
 class S6DDRPHY(Module):
5  
-	def __init__(self, pads):
6  
-		self.dfi = dfi.Interface(flen(pads.a), flen(pads.ba), 2*flen(pads.dq), 2)
  27
+	def __init__(self, pads, phy_settings, bitslip):
  28
+		if phy_settings.type not in ["DDR", "LPDDR", "DDR2"]:
  29
+			raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
  30
+
  31
+		a = flen(pads.a)
  32
+		ba = flen(pads.ba)
  33
+		d = flen(pads.dq)
  34
+		nphases = phy_settings.nphases
  35
+		self.phy_settings = phy_settings
  36
+
  37
+		self.dfi = Interface(a, ba, nphases*d, nphases)
7 38
 		self.clk4x_wr_strb = Signal()
8 39
 		self.clk4x_rd_strb = Signal()
9 40
 
10 41
 		###
11 42
 
12  
-		inst_items = [
13  
-			Instance.Parameter("NUM_AD", flen(pads.a)),
14  
-			Instance.Parameter("NUM_BA", flen(pads.ba)),
15  
-			Instance.Parameter("NUM_D", 2*flen(pads.dq)),
16  
-
17  
-			Instance.Input("sys_clk", ClockSignal()),
18  
-			Instance.Input("clk2x_270", ClockSignal("sys2x_270")),
19  
-			Instance.Input("clk4x_wr", ClockSignal("sys4x_wr")),
20  
-			Instance.Input("clk4x_rd", ClockSignal("sys4x_rd")),
21  
-
22  
-			Instance.Input("clk4x_wr_strb", self.clk4x_wr_strb),
23  
-			Instance.Input("clk4x_rd_strb", self.clk4x_rd_strb),
24  
-
25  
-			Instance.Output("sd_a", pads.a),
26  
-			Instance.Output("sd_ba", pads.ba),
27  
-			Instance.Output("sd_cs_n", pads.cs_n),
28  
-			Instance.Output("sd_cke", pads.cke),
29  
-			Instance.Output("sd_ras_n", pads.ras_n),
30  
-			Instance.Output("sd_cas_n", pads.cas_n),
31  
-			Instance.Output("sd_we_n", pads.we_n),
32  
-			Instance.InOut("sd_dq", pads.dq),
33  
-			Instance.Output("sd_dm", pads.dm),
34  
-			Instance.InOut("sd_dqs", pads.dqs)
  43
+		# sys_clk           : system clk, used for dfi interface
  44
+		# sdram_half_clk    : half rate sdram clk 
  45
+		# sdram_full_wr_clk : full rate sdram write clk
  46
+		# sdram_full_rd_clk : full rate sdram write clk
  47
+		sd_sys = getattr(self.sync, "sys")
  48
+		sd_sdram_half = getattr(self.sync, "sdram_half")
  49
+
  50
+		sys_clk = ClockSignal("sys")
  51
+		sdram_half_clk = ClockSignal("sdram_half")
  52
+		sdram_full_wr_clk = ClockSignal("sdram_full_wr")
  53
+		sdram_full_rd_clk = ClockSignal("sdram_full_rd")
  54
+
  55
+		# 
  56
+		# Command/address
  57
+		#
  58
+
  59
+		# select active phase
  60
+		#             sys_clk   ____----____----
  61
+		#  phase_sel(nphases=1) 0       0
  62
+		#  phase_sel(nphases=2) 0   1   0   1
  63
+		#  phase_sel(nphases=4) 0 1 2 3 0 1 2 3
  64
+		phase_sel = Signal(log2_int(nphases))
  65
+		sys_clk_d = Signal()
  66
+
  67
+		sd_sdram_half += [
  68
+			If(sys_clk & ~sys_clk_d, phase_sel.eq(0)
  69
+			).Else(phase_sel.eq(phase_sel+1)),
  70
+			sys_clk_d.eq(sys_clk)
  71
+		]
  72
+
  73
+		# register dfi cmds on half_rate clk
  74
+		r_dfi = Array(Record(phase_cmd_description(a, ba)) for i in range(nphases))
  75
+		for n, phase in enumerate(self.dfi.phases):
  76
+			sd_sdram_half +=[
  77
+				r_dfi[n].address.eq(phase.address),
  78
+				r_dfi[n].bank.eq(phase.bank),
  79
+				r_dfi[n].cs_n.eq(phase.cs_n),
  80
+				r_dfi[n].cke.eq(phase.cke),
  81
+				r_dfi[n].cas_n.eq(phase.cas_n),
  82
+				r_dfi[n].ras_n.eq(phase.ras_n),
  83
+				r_dfi[n].we_n.eq(phase.we_n)
  84
+			]
  85
+
  86
+		# output cmds
  87
+		sd_sdram_half += [
  88
+			pads.a.eq(r_dfi[phase_sel].address),
  89
+			pads.ba.eq(r_dfi[phase_sel].bank),
  90
+			pads.cs_n.eq(r_dfi[phase_sel].cs_n),
  91
+			pads.cke.eq(r_dfi[phase_sel].cke),
  92
+			pads.ras_n.eq(r_dfi[phase_sel].ras_n),
  93
+			pads.cas_n.eq(r_dfi[phase_sel].cas_n),
  94
+			pads.we_n.eq(r_dfi[phase_sel].we_n)
  95
+		]
  96
+
  97
+
  98
+		# 
  99
+		# Bitslip
  100
+		#
  101
+		bitslip_cnt = Signal(4)
  102
+		bitslip_inc = Signal()
  103
+
  104
+		sd_sys += [
  105
+			If(bitslip_cnt==bitslip, 
  106
+				bitslip_inc.eq(0)
  107
+			).Else(
  108
+				bitslip_cnt.eq(bitslip_cnt+1),
  109
+				bitslip_inc.eq(1)
  110
+			)
35 111
 		]
36  
-		inst_items += [Instance.Input(name, signal) 
37  
-			for name, signal in self.dfi.get_standard_names(True, False)]
38  
-		inst_items += [Instance.Output(name, signal)
39  
-			for name, signal in self.dfi.get_standard_names(False, True)]
40  
-		self.specials += Instance("s6ddrphy", *inst_items)
  112
+
  113
+		# 
  114
+		# DQ/DQS/DM data
  115
+		#
  116
+		sdram_half_clk_n = Signal()
  117
+		self.comb += sdram_half_clk_n.eq(~sdram_half_clk)
  118
+
  119
+		postamble = Signal()
  120
+		drive_dqs = Signal()
  121
+		dqs_t_d0 = Signal()
  122
+		dqs_t_d1 = Signal()
  123
+
  124
+		dqs_o = Signal(d//8) 
  125
+		dqs_t = Signal(d//8)
  126
+
  127
+		self.comb += [
  128
+			dqs_t_d0.eq(~(drive_dqs | postamble)),
  129
+			dqs_t_d1.eq(~drive_dqs),
  130
+		]
  131
+
  132
+		for i in range(d//8):
  133
+			# DQS output
  134
+			self.specials += Instance("ODDR2",
  135
+				Instance.Parameter("DDR_ALIGNMENT", "C1"),
  136
+				Instance.Parameter("INIT", 0),
  137
+				Instance.Parameter("SRTYPE", "ASYNC"),
  138
+
  139
+				Instance.Input("C0", sdram_half_clk),
  140
+				Instance.Input("C1", sdram_half_clk_n),
  141
+
  142
+				Instance.Input("CE", 1),
  143
+				Instance.Input("D0", 0),
  144
+				Instance.Input("D1", 1),
  145
+				Instance.Input("R", 0),
  146
+				Instance.Input("S", 0),
  147
+
  148
+				Instance.Output("Q", dqs_o[i])
  149
+				)
  150
+
  151
+			# DQS tristate cmd
  152
+			self.specials += Instance("ODDR2",
  153
+				Instance.Parameter("DDR_ALIGNMENT", "C1"),
  154
+				Instance.Parameter("INIT", 0),
  155
+				Instance.Parameter("SRTYPE", "ASYNC"),
  156
+
  157
+				Instance.Input("C0", sdram_half_clk),
  158
+				Instance.Input("C1", sdram_half_clk_n),
  159
+
  160
+				Instance.Input("CE", 1),
  161
+				Instance.Input("D0", dqs_t_d0),
  162
+				Instance.Input("D1", dqs_t_d1),
  163
+				Instance.Input("R", 0),
  164
+				Instance.Input("S", 0),
  165
+
  166
+				Instance.Output("Q", dqs_t[i])
  167
+				)
  168
+
  169
+			# DQS tristate buffer
  170
+			self.specials += Instance("OBUFT",
  171
+				Instance.Input("I", dqs_o[i]),
  172
+				Instance.Input("T", dqs_t[i]),
  173
+
  174
+				Instance.Output("O", pads.dqs[i])
  175
+				)
  176
+
  177
+		sd_sdram_half += postamble.eq(drive_dqs)
  178
+
  179
+		d_dfi = [Record(phase_wrdata_description(nphases*d)+phase_rddata_description(nphases*d)) 
  180
+			for i in range(2*nphases)]
  181
+
  182
+		for n, phase in enumerate(self.dfi.phases):
  183
+			self.comb += [
  184
+				d_dfi[n].wrdata.eq(phase.wrdata),
  185
+				d_dfi[n].wrdata_mask.eq(phase.wrdata_mask),
  186
+				d_dfi[n].wrdata_en.eq(phase.wrdata_en),
  187
+				d_dfi[n].rddata_en.eq(phase.rddata_en),
  188
+			]
  189
+			sd_sys += [
  190
+				d_dfi[nphases+n].wrdata.eq(phase.wrdata),
  191
+				d_dfi[nphases+n].wrdata_mask.eq(phase.wrdata_mask)
  192
+			]
  193
+
  194
+
  195
+		drive_dq = Signal()
  196
+		drive_dq_n = Signal()
  197
+		d_drive_dq = Signal()
  198
+		d_drive_dq_n = Signal()
  199
+		self.comb += [
  200
+			drive_dq_n.eq(~drive_dq),
  201
+			d_drive_dq_n.eq(~d_drive_dq)
  202
+		]
  203
+
  204
+		dq_t = Signal(d)
  205
+		dq_o = Signal(d)
  206
+		dq_i = Signal(d)
  207
+
  208
+		for i in range(d):
  209
+			# Data serializer
  210
+			self.specials += Instance("OSERDES2",
  211
+				Instance.Parameter("DATA_WIDTH", 4),
  212
+				Instance.Parameter("DATA_RATE_OQ", "SDR"),
  213
+				Instance.Parameter("DATA_RATE_OT", "SDR"),
  214
+				Instance.Parameter("SERDES_MODE", "NONE"),
  215
+				Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
  216
+
  217
+				Instance.Output("OQ", dq_o[i]),
  218
+				Instance.Input("OCE", 1),
  219
+				Instance.Input("CLK0", sdram_full_wr_clk),
  220
+				Instance.Input("CLK1", 0),
  221
+				Instance.Input("IOCE", self.clk4x_wr_strb),
  222
+				Instance.Input("RST", 0),
  223
+				Instance.Input("CLKDIV", sys_clk),
  224
+
  225
+				Instance.Input("D1", d_dfi[1*nphases+0].wrdata[i]),
  226
+				Instance.Input("D2", d_dfi[1*nphases+1].wrdata[i+d]),
  227
+				Instance.Input("D3", d_dfi[1*nphases+1].wrdata[i]),
  228
+				Instance.Input("D4", d_dfi[0*nphases+0].wrdata[i+d]),
  229
+				Instance.Output("TQ", dq_t[i]),
  230
+				Instance.Input("T1", d_drive_dq_n),
  231
+				Instance.Input("T2", d_drive_dq_n),
  232
+				Instance.Input("T3", d_drive_dq_n),
  233
+				Instance.Input("T4", drive_dq_n),
  234
+				Instance.Input("TRAIN", 0),
  235
+				Instance.Input("TCE", 1),
  236
+				Instance.Input("SHIFTIN1", 0),
  237
+				Instance.Input("SHIFTIN2", 0),
  238
+				Instance.Input("SHIFTIN3", 0),
  239
+				Instance.Input("SHIFTIN4", 0),
  240
+
  241
+				Instance.Output("SHIFTOUT1"),
  242
+				Instance.Output("SHIFTOUT2"),
  243
+				Instance.Output("SHIFTOUT3"),
  244
+				Instance.Output("SHIFTOUT4"),
  245
+			)
  246
+
  247
+			# Data deserializer
  248
+			self.specials += Instance("ISERDES2",
  249
+				Instance.Parameter("DATA_WIDTH", 4),
  250
+				Instance.Parameter("DATA_RATE", "SDR"),
  251
+				Instance.Parameter("BITSLIP_ENABLE", "TRUE"),
  252
+				Instance.Parameter("SERDES_MODE", "NONE"),
  253
+				Instance.Parameter("INTERFACE_TYPE", "RETIMED"),
  254
+
  255
+				Instance.Input("D", dq_i[i]),
  256
+				Instance.Input("CE0", 1),
  257
+				Instance.Input("CLK0", sdram_full_rd_clk),
  258
+				Instance.Input("CLK1", 0),
  259
+				Instance.Input("IOCE", self.clk4x_rd_strb),
  260
+				Instance.Input("RST", ResetSignal()),
  261
+				Instance.Input("CLKDIV", sys_clk),
  262
+				Instance.Output("SHIFTIN"),
  263
+				Instance.Input("BITSLIP", bitslip_inc),
  264
+				Instance.Output("FABRICOUT"),
  265
+
  266
+				Instance.Output("Q1", d_dfi[0*nphases+0].rddata[i+d]),
  267
+				Instance.Output("Q2", d_dfi[0*nphases+0].rddata[i]),
  268
+				Instance.Output("Q3", d_dfi[0*nphases+1].rddata[i+d]),
  269
+				Instance.Output("Q4", d_dfi[0*nphases+1].rddata[i]),
  270
+
  271
+				Instance.Output("DFB"),
  272
+				Instance.Output("CFB0"),
  273
+				Instance.Output("CFB1"),
  274
+				Instance.Output("VALID"),
  275
+				Instance.Output("INCDEC"),
  276
+				Instance.Output("SHIFTOUT")
  277
+			)
  278
+
  279
+			# Data buffer
  280
+			self.specials += Instance("IOBUF",
  281
+				Instance.Input("I", dq_o[i]),
  282
+				Instance.Output("O", dq_i[i]),
  283
+				Instance.Input("T", dq_t[i]),
  284
+				Instance.InOut("IO", pads.dq[i])
  285
+			)
  286
+
  287
+		for i in range(d//8):
  288
+			# Mask serializer
  289
+			self.specials += Instance("OSERDES2",
  290
+				Instance.Parameter("DATA_WIDTH", 4),
  291
+				Instance.Parameter("DATA_RATE_OQ", "SDR"),
  292
+				Instance.Parameter("DATA_RATE_OT", "SDR"),
  293
+				Instance.Parameter("SERDES_MODE", "NONE"),
  294
+				Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
  295
+
  296
+				Instance.Output("OQ", pads.dm[i]),
  297
+				Instance.Input("OCE", 1),
  298
+				Instance.Input("CLK0", sdram_full_wr_clk),
  299
+				Instance.Input("CLK1", 0),
  300
+				Instance.Input("IOCE", self.clk4x_wr_strb),
  301
+				Instance.Input("RST", 0),
  302
+				Instance.Input("CLKDIV", sys_clk),
  303
+
  304
+				Instance.Input("D1", d_dfi[1*nphases+0].wrdata_mask[i]),
  305
+				Instance.Input("D2", d_dfi[1*nphases+1].wrdata_mask[i+d//8]),
  306
+				Instance.Input("D3", d_dfi[1*nphases+1].wrdata_mask[i]),
  307
+				Instance.Input("D4", d_dfi[0*nphases+0].wrdata_mask[i+d//8]),
  308
+				Instance.Output("TQ"),
  309
+				Instance.Input("T1"),
  310
+				Instance.Input("T2"),
  311
+				Instance.Input("T3"),
  312
+				Instance.Input("T4"),
  313
+				Instance.Input("TRAIN", 0),
  314
+				Instance.Input("TCE", 0),
  315
+				Instance.Input("SHIFTIN1", 0),
  316
+				Instance.Input("SHIFTIN2", 0),
  317
+				Instance.Input("SHIFTIN3", 0),
  318
+				Instance.Input("SHIFTIN4", 0),
  319
+
  320
+				Instance.Output("SHIFTOUT1"),
  321
+				Instance.Output("SHIFTOUT2"),
  322
+				Instance.Output("SHIFTOUT3"),
  323
+				Instance.Output("SHIFTOUT4"),
  324
+			)
  325
+
  326
+
  327
+		# 
  328
+		# DQ/DQS/DM control
  329
+		#
  330
+		self.comb += drive_dq.eq(d_dfi[phy_settings.wrphase].wrdata_en)
  331
+		sd_sys += d_drive_dq.eq(drive_dq)
  332
+
  333
+		d_dfi_wrdata_en = Signal()
  334
+		sd_sys += d_dfi_wrdata_en.eq(d_dfi[phy_settings.wrphase].wrdata_en)
  335
+		
  336
+		r_dfi_wrdata_en = Signal(2)
  337
+		sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0])) 
  338
+
  339
+		self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
  340
+
  341
+		rddata_sr = Signal(phy_settings.cl+2)
  342
+		sd_sys += rddata_sr.eq(Cat(rddata_sr[1:phy_settings.cl+2], d_dfi[phy_settings.rdphase].rddata_en))
  343
+		
  344
+		for n, phase in enumerate(self.dfi.phases):
  345
+			self.comb += [
  346
+				phase.rddata.eq(d_dfi[n].rddata),
  347
+				phase.rddata_valid.eq(rddata_sr[0]),
  348
+			]
66  software/bios/sdram.c
@@ -2,6 +2,7 @@
2 2
 #include <stdlib.h>
3 3
 
4 4
 #include <hw/csr.h>
  5
+#include <hw/sdram_phy.h>
5 6
 #include <hw/flags.h>
6 7
 #include <hw/mem.h>
7 8
 
@@ -15,59 +16,6 @@ static void cdelay(int i)
15 16
 	}
16 17
 }
17 18
 
18  
-static void command_p0(int cmd)
19  
-{
20  
-	dfii_pi0_command_write(cmd);
21  
-	dfii_pi0_command_issue_write(1);
22  
-}
23  
-
24  
-static void command_p1(int cmd)
25  
-{
26  
-	dfii_pi1_command_write(cmd);
27  
-	dfii_pi1_command_issue_write(1);
28  
-}
29  
-
30  
-static void init_sequence(void)
31  
-{
32  
-	int i;
33  
-	
34  
-	/* Bring CKE high */
35  
-	dfii_pi0_address_write(0x0000);
36  
-	dfii_pi0_baddress_write(0);
37  
-	dfii_control_write(DFII_CONTROL_CKE);
38  
-	
39  
-	/* Precharge All */
40  
-	dfii_pi0_address_write(0x0400);
41  
-	command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
42  
-	
43  
-	/* Load Extended Mode Register */
44  
-	dfii_pi0_baddress_write(1);
45  
-	dfii_pi0_address_write(0x0000);
46  
-	command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
47  
-	dfii_pi0_baddress_write(0);
48  
-	
49  
-	/* Load Mode Register */
50  
-	dfii_pi0_address_write(0x0132); /* Reset DLL, CL=3, BL=4 */
51  
-	command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
52  
-	cdelay(200);
53  
-	
54  
-	/* Precharge All */
55  
-	dfii_pi0_address_write(0x0400);
56  
-	command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
57  
-	
58  
-	/* 2x Auto Refresh */
59  
-	for(i=0;i<2;i++) {
60  
-		dfii_pi0_address_write(0);
61  
-		command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS);
62  
-		cdelay(4);
63  
-	}
64  
-	
65  
-	/* Load Mode Register */
66  
-	dfii_pi0_address_write(0x0032); /* CL=3, BL=4 */
67  
-	command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
68  
-	cdelay(200);
69  
-}
70  
-
71 19
 void ddrsw(void)
72 20
 {
73 21
 	dfii_control_write(DFII_CONTROL_CKE);
@@ -121,9 +69,9 @@ void ddrrd(char *startaddr)
121 69
 		return;
122 70
 	}
123 71
 	
124  
-	dfii_pi0_address_write(addr);
125  
-	dfii_pi0_baddress_write(0);
126  
-	command_p0(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
  72
+	dfii_pird_address_write(addr);
  73
+	dfii_pird_baddress_write(0);
  74
+	command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
127 75
 	cdelay(15);
128 76
 	
129 77
 	for(i=0;i<8;i++)
@@ -154,9 +102,9 @@ void ddrwr(char *startaddr)
154 102
 		MMPTR(0xe000106c+4*i) = 0xf0 + i;
155 103
 	}
156 104
 	
157  
-	dfii_pi1_address_write(addr);
158  
-	dfii_pi1_baddress_write(0);
159  
-	command_p1(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
  105
+	dfii_piwr_address_write(addr);
  106
+	dfii_piwr_baddress_write(0);
  107
+	command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
160 108
 }
161 109
 
162 110
 #define TEST_SIZE (4*1024*1024)
6  top.py
@@ -26,10 +26,12 @@ def ns(t, margin=True):
26 26
 	return ceil(t/clk_period_ns)
27 27
 
28 28
 sdram_phy = lasmicon.PhySettings(
  29
+	type="DDR",
29 30
 	dfi_d=64, 
30 31
 	nphases=2,
31 32
 	rdphase=0,
32  
-	wrphase=1
  33
+	wrphase=1,
  34
+	cl=3
33 35
 )
34 36
 sdram_geom = lasmicon.GeomSettings(
35 37
 	bank_a=2,
@@ -109,7 +111,7 @@ def __init__(self, platform, platform_name):
109 111
 		#
110 112
 		# DFI
111 113
 		#
112  
-		self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"))
  114
+		self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), sdram_phy, 0)
113 115
 		self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
114 116
 			sdram_phy.nphases)
115 117
 		self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
343  verilog/s6ddrphy/s6ddrphy.v
... ...
@@ -1,343 +0,0 @@
1  
-/*
2  
- * 1:2 frequency-ratio DDR PHY for Spartan-6
3  
- *
4  
- * Assert dfi_wrdata_en and present the data 
5  
- * on dfi_wrdata_mask/dfi_wrdata in the same
6  
- * cycle as the write command.
7  
- *
8  
- * Assert dfi_rddata_en in the same cycle as the read
9  
- * command. The data will come back on dfi_rddata
10  
- * 5 cycles later, along with the assertion of
11  
- * dfi_rddata_valid.
12  
- *
13  
- * This PHY only supports CAS Latency 3.
14  
- * Read commands must be sent on phase 0.
15  
- * Write commands must be sent on phase 1.
16  
- */
17  
-
18  
-module s6ddrphy #(
19  
-	parameter NUM_AD = 0,
20  
-	parameter NUM_BA = 0,
21  
-	parameter NUM_D = 0 /* < number of data lines per DFI phase */
22  
-) (
23  
-	/* Clocks */
24  
-	input sys_clk,
25  
-	input clk2x_270,
26  
-	input clk4x_wr,
27  
-	input clk4x_wr_strb,
28  
-	input clk4x_rd,
29  
-	input clk4x_rd_strb,
30  
-	
31  
-	/* DFI phase 0 */
32  
-	input [NUM_AD-1:0] dfi_address_p0,
33  
-	input [NUM_BA-1:0] dfi_bank_p0,
34  
-	input dfi_cs_n_p0,
35  
-	input dfi_cke_p0,
36  
-	input dfi_ras_n_p0,
37  
-	input dfi_cas_n_p0,
38  
-	input dfi_we_n_p0,
39  
-	input dfi_wrdata_en_p0,
40  
-	input [NUM_D/8-1:0] dfi_wrdata_mask_p0,
41  
-	input [NUM_D-1:0] dfi_wrdata_p0,
42  
-	input dfi_rddata_en_p0,
43  
-	output [NUM_D-1:0] dfi_rddata_w0,
44  
-	output dfi_rddata_valid_w0,
45  
-	
46  
-	/* DFI phase 1 */
47  
-	input [NUM_AD-1:0] dfi_address_p1,
48  
-	input [NUM_BA-1:0] dfi_bank_p1,
49  
-	input dfi_cs_n_p1,
50  
-	input dfi_cke_p1,
51  
-	input dfi_ras_n_p1,
52  
-	input dfi_cas_n_p1,
53  
-	input dfi_we_n_p1,
54  
-	input dfi_wrdata_en_p1,
55  
-	input [NUM_D/8-1:0] dfi_wrdata_mask_p1,
56  
-	input [NUM_D-1:0] dfi_wrdata_p1,
57  
-	input dfi_rddata_en_p1,
58  
-	output [NUM_D-1:0] dfi_rddata_w1,
59  
-	output dfi_rddata_valid_w1,
60  
-	
61  
-	/* DDR SDRAM pads */
62  
-	output reg [NUM_AD-1:0] sd_a,
63  
-	output reg [NUM_BA-1:0] sd_ba,
64  
-	output reg sd_cs_n,
65  
-	output reg sd_cke,
66  
-	output reg sd_ras_n,
67  
-	output reg sd_cas_n,
68  
-	output reg sd_we_n,
69  
-	inout [NUM_D/2-1:0] sd_dq,
70  
-	output [NUM_D/16-1:0] sd_dm,
71  
-	inout [NUM_D/16-1:0] sd_dqs
72  
-);
73  
-
74  
-/* 
75  
- * Command/address
76  
- */
77  
-
78  
-reg phase_sel;
79  
-always @(posedge clk2x_270)
80  
-	phase_sel <= sys_clk;
81  
-
82  
-reg [NUM_AD-1:0] r_dfi_address_p0;
83  
-reg [NUM_BA-1:0] r_dfi_bank_p0;
84  
-reg r_dfi_cs_n_p0;
85  
-reg r_dfi_cke_p0;
86  
-reg r_dfi_ras_n_p0;
87  
-reg r_dfi_cas_n_p0;
88  
-reg r_dfi_we_n_p0;
89  
-reg [NUM_AD-1:0] r_dfi_address_p1;
90  
-reg [NUM_BA-1:0] r_dfi_bank_p1;
91  
-reg r_dfi_cs_n_p1;
92  
-reg r_dfi_cke_p1;
93  
-reg r_dfi_ras_n_p1;
94  
-reg r_dfi_cas_n_p1;
95  
-reg r_dfi_we_n_p1;
96  
-	
97  
-always @(posedge clk2x_270) begin
98  
-	r_dfi_address_p0 <= dfi_address_p0;
99  
-	r_dfi_bank_p0 <= dfi_bank_p0;
100  
-	r_dfi_cs_n_p0 <= dfi_cs_n_p0;
101  
-	r_dfi_cke_p0 <= dfi_cke_p0;
102  
-	r_dfi_ras_n_p0 <= dfi_ras_n_p0;
103  
-	r_dfi_cas_n_p0 <= dfi_cas_n_p0;
104  
-	r_dfi_we_n_p0 <= dfi_we_n_p0;
105  
-	
106  
-	r_dfi_address_p1 <= dfi_address_p1;
107  
-	r_dfi_bank_p1 <= dfi_bank_p1;
108  
-	r_dfi_cs_n_p1 <= dfi_cs_n_p1;
109  
-	r_dfi_cke_p1 <= dfi_cke_p1;
110  
-	r_dfi_ras_n_p1 <= dfi_ras_n_p1;
111  
-	r_dfi_cas_n_p1 <= dfi_cas_n_p1;
112  
-	r_dfi_we_n_p1 <= dfi_we_n_p1;
113  
-end
114  
-
115  
-always @(posedge clk2x_270) begin
116  
-	if(phase_sel) begin
117  
-		sd_a <= r_dfi_address_p0;
118  
-		sd_ba <= r_dfi_bank_p0;
119  
-		sd_cs_n <= r_dfi_cs_n_p0;
120  
-		sd_cke <= r_dfi_cke_p0;
121  
-		sd_ras_n <= r_dfi_ras_n_p0;
122  
-		sd_cas_n <= r_dfi_cas_n_p0;
123  
-		sd_we_n <= r_dfi_we_n_p0;
124  
-	end else begin
125  
-		sd_a <= r_dfi_address_p1;
126  
-		sd_ba <= r_dfi_bank_p1;
127  
-		sd_cs_n <= r_dfi_cs_n_p1;
128  
-		sd_cke <= r_dfi_cke_p1;
129  
-		sd_ras_n <= r_dfi_ras_n_p1;
130  
-		sd_cas_n <= r_dfi_cas_n_p1;
131  
-		sd_we_n <= r_dfi_we_n_p1;
132  
-	end
133  
-end
134  
-
135  
-/* 
136  
- * DQ/DQS/DM data
137  
- */
138  
-
139  
-genvar i;
140  
-
141  
-wire drive_dqs;
142  
-wire [NUM_D/16-1:0] dqs_o;
143  
-wire [NUM_D/16-1:0] dqs_t;
144  
-reg postamble;
145  
-generate
146  
-	for(i=0;i<NUM_D/16;i=i+1)
147  
-	begin: gen_dqs
148  
-		ODDR2 #(
149  
-			.DDR_ALIGNMENT("C1"),
150  
-			.INIT(1'b0),
151  
-			.SRTYPE("ASYNC")
152  
-		) dqs_o_oddr (
153  
-			.Q(dqs_o[i]),
154  
-			.C0(clk2x_270),
155  
-			.C1(~clk2x_270),
156  
-			.CE(1'b1),
157  
-			.D0(1'b0),
158  
-			.D1(1'b1),
159  
-			.R(1'b0),
160  
-			.S(1'b0)
161  
-		);
162  
-		ODDR2 #(
163  
-			.DDR_ALIGNMENT("C1"),
164  
-			.INIT(1'b0),
165  
-			.SRTYPE("ASYNC")
166  
-		) dqs_t_oddr (
167  
-			.Q(dqs_t[i]),
168  
-			.C0(clk2x_270),
169  
-			.C1(~clk2x_270),
170  
-			.CE(1'b1),
171  
-			.D0(~(drive_dqs | postamble)),
172  
-			.D1(~drive_dqs),
173  
-			.R(1'b0),
174  
-			.S(1'b0)
175  
-		);
176  
-		OBUFT dqs_obuft(
177  
-			.I(dqs_o[i]),
178  
-			.T(dqs_t[i]),
179  
-			.O(sd_dqs[i])
180  
-		);
181  
-	end
182  
-endgenerate
183  
-always @(posedge clk2x_270)
184  
-	postamble <= drive_dqs;
185  
-
186  
-reg [NUM_D-1:0] d_dfi_wrdata_p0;
187  
-reg [NUM_D-1:0] d_dfi_wrdata_p1;
188  
-reg [NUM_D/8-1:0] d_dfi_wrdata_mask_p0;
189  
-reg [NUM_D/8-1:0] d_dfi_wrdata_mask_p1;
190  
-always @(posedge sys_clk) begin
191  
-	d_dfi_wrdata_p0 <= dfi_wrdata_p0;
192  
-	d_dfi_wrdata_p1 <= dfi_wrdata_p1;
193  
-	d_dfi_wrdata_mask_p0 <= dfi_wrdata_mask_p0;
194  
-	d_dfi_wrdata_mask_p1 <= dfi_wrdata_mask_p1;
195  
-end
196  
-
197  
-wire drive_dq;
198  
-wire d_drive_dq;
199  
-wire [NUM_D/2-1:0] dq_i;
200  
-wire [NUM_D/2-1:0] dq_o;
201  
-wire [NUM_D/2-1:0] dq_t;
202  
-generate
203  
-	for(i=0;i<NUM_D/2;i=i+1)
204  
-	begin: gen_dq
205  
-		OSERDES2 #(
206  
-			.DATA_WIDTH(4),
207  
-			.DATA_RATE_OQ("SDR"),
208  
-			.DATA_RATE_OT("SDR"),
209  
-			.SERDES_MODE("NONE"),
210  
-			.OUTPUT_MODE("SINGLE_ENDED")
211  
-		) dq_oserdes (
212  
-			.OQ(dq_o[i]),
213  
-			.OCE(1'b1),
214  
-			.CLK0(clk4x_wr),
215  
-			.CLK1(1'b0),
216  
-			.IOCE(clk4x_wr_strb),
217  
-			.RST(1'b0),
218  
-			.CLKDIV(sys_clk),
219  
-			.D1(d_dfi_wrdata_p0[i]),
220  
-			.D2(d_dfi_wrdata_p1[i+NUM_D/2]),
221  
-			.D3(d_dfi_wrdata_p1[i]),
222  
-			.D4(dfi_wrdata_p0[i+NUM_D/2]),
223  
-			.TQ(dq_t[i]),
224  
-			.T1(~d_drive_dq),
225  
-			.T2(~d_drive_dq),
226  
-			.T3(~d_drive_dq),
227  
-			.T4(~drive_dq),
228  
-			.TRAIN(1'b0),
229  
-			.TCE(1'b1),
230  
-			.SHIFTIN1(1'b0),
231  
-			.SHIFTIN2(1'b0),
232  
-			.SHIFTIN3(1'b0),
233  
-			.SHIFTIN4(1'b0),
234  
-			.SHIFTOUT1(),
235  
-			.SHIFTOUT2(),
236  
-			.SHIFTOUT3(),
237  
-			.SHIFTOUT4()
238  
-		);
239  
-		ISERDES2 #(
240  
-			.DATA_WIDTH(4),
241  
-			.DATA_RATE("SDR"),
242  
-			.BITSLIP_ENABLE("FALSE"),
243  
-			.SERDES_MODE("NONE"),
244  
-			.INTERFACE_TYPE("RETIMED")
245  
-		) dq_iserdes (
246  
-			.D(dq_i[i]),
247  
-			.CE0(1'b1),
248  
-			.CLK0(clk4x_rd),
249  
-			.CLK1(1'b0),
250  
-			.IOCE(clk4x_rd_strb),
251  
-			.RST(1'b0),
252  
-			.CLKDIV(sys_clk),
253  
-			.SHIFTIN(),
254  
-			.BITSLIP(1'b0),
255  
-			.FABRICOUT(),
256  
-			.Q1(dfi_rddata_w0[i+NUM_D/2]),
257  
-			.Q2(dfi_rddata_w0[i]),
258  
-			.Q3(dfi_rddata_w1[i+NUM_D/2]),
259  
-			.Q4(dfi_rddata_w1[i]),
260  
-			.DFB(),
261  
-			.CFB0(),
262  
-			.CFB1(),
263  
-			.VALID(),
264  
-			.INCDEC(),
265  
-			.SHIFTOUT()
266  
-		);
267  
-		IOBUF dq_iobuf(
268  
-			.I(dq_o[i]),
269  
-			.O(dq_i[i]),
270  
-			.T(dq_t[i]),
271  
-			.IO(sd_dq[i])
272  
-		);
273  
-	end
274  
-endgenerate
275  
-
276  
-generate
277  
-	for(i=0;i<NUM_D/16;i=i+1)
278  
-	begin: gen_dm_oserdes
279  
-		OSERDES2 #(
280  
-			.DATA_WIDTH(4),
281  
-			.DATA_RATE_OQ("SDR"),
282  
-			.DATA_RATE_OT("SDR"),
283  
-			.SERDES_MODE("NONE"),
284  
-			.OUTPUT_MODE("SINGLE_ENDED")
285  
-		) dm_oserdes (
286  
-			.OQ(sd_dm[i]),
287  
-			.OCE(1'b1),
288  
-			.CLK0(clk4x_wr),
289  
-			.CLK1(1'b0),
290  
-			.IOCE(clk4x_wr_strb),
291  
-			.RST(1'b0),
292  
-			.CLKDIV(sys_clk),
293  
-			.D1(d_dfi_wrdata_mask_p0[i]),
294  
-			.D2(d_dfi_wrdata_mask_p1[i+NUM_D/16]),
295  
-			.D3(d_dfi_wrdata_mask_p1[i]),
296  
-			.D4(dfi_wrdata_mask_p0[i+NUM_D/16]),
297  
-			.TQ(),
298  
-			.T1(),
299  
-			.T2(),
300  
-			.T3(),
301  
-			.T4(),
302  
-			.TRAIN(1'b0),
303  
-			.TCE(1'b0),
304  
-			.SHIFTIN1(1'b0),
305  
-			.SHIFTIN2(1'b0),
306  
-			.SHIFTIN3(1'b0),
307  
-			.SHIFTIN4(1'b0),
308  
-			.SHIFTOUT1(),
309  
-			.SHIFTOUT2(),
310  
-			.SHIFTOUT3(),
311  
-			.SHIFTOUT4()
312  
-		);
313  
-	end
314  
-endgenerate
315  
- 
316  
-/* 
317  
- * DQ/DQS/DM control
318  
- */
319  
-
320  
-reg d_dfi_wrdata_en_p1;
321  
-always @(posedge sys_clk)
322  
-	d_dfi_wrdata_en_p1 <= dfi_wrdata_en_p1;
323  
- 
324  
-assign drive_dq = dfi_wrdata_en_p1;
325  
-assign d_drive_dq = d_dfi_wrdata_en_p1;
326  
- 
327  
-reg r_dfi_wrdata_en;
328  
-reg r2_dfi_wrdata_en;
329  
-always @(posedge clk2x_270) begin
330  
-	r_dfi_wrdata_en <= d_dfi_wrdata_en_p1;
331  
-	r2_dfi_wrdata_en <= r_dfi_wrdata_en;
332  
-end
333  
-
334  
-assign drive_dqs = r2_dfi_wrdata_en;
335  
-
336  
-wire rddata_valid;
337  
-reg [4:0] rddata_sr;
338  
-assign dfi_rddata_valid_w0 = rddata_sr[0];
339  
-assign dfi_rddata_valid_w1 = rddata_sr[0];
340  
-always @(posedge sys_clk)
341  
-	rddata_sr <= {dfi_rddata_en_p0, rddata_sr[4:1]};
342  
-
343  
-endmodule

No commit comments for this range

Something went wrong with that request. Please try again.