Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 3 commits
  • 5 files changed
  • 0 comments
  • 2 contributors
7  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", "memtype dfi_d nphases rdphase wrphase cl read_latency write_latency")
  10
+PhySettings = namedtuple("PhySettings", "memtype dfi_d nphases rdphase wrphase rdcmdphase wrcmdphase cl read_latency write_latency")
11 11
 
12 12
 class GeomSettings(namedtuple("_GeomSettings", "bank_a row_a col_a")):
13 13
 	def __init__(self, *args, **kwargs):
@@ -18,7 +18,10 @@ def __init__(self, *args, **kwargs):
18 18
 
19 19
 class LASMIcon(Module):
20 20
 	def __init__(self, phy_settings, geom_settings, timing_settings):
21  
-		burst_length = phy_settings.nphases*2 # command multiplication*DDR
  21
+		if phy_settings.memtype in ["SDR"]:
  22
+			burst_length = phy_settings.nphases*1 # command multiplication*SDR
  23
+		elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
  24
+			burst_length = phy_settings.nphases*2 # command multiplication*DDR
22 25
 		address_align = log2_int(burst_length)
23 26
 
24 27
 		self.dfi = dfi.Interface(geom_settings.mux_a,
5  milkymist/lasmicon/bankmachine.py
@@ -122,19 +122,22 @@ def __init__(self, geom_settings, timing_settings, address_align, bankn, req):
122 122
 				self.cmd.stb.eq(1),
123 123
 				If(self.cmd.ack, NextState("TRP")),
124 124
 				self.cmd.ras_n.eq(0),
125  
-				self.cmd.we_n.eq(0)
  125
+				self.cmd.we_n.eq(0),
  126
+				self.cmd.is_cmd.eq(1)
126 127
 			)
127 128
 		)
128 129
 		fsm.act("ACTIVATE",
129 130
 			s_row_adr.eq(1),
130 131
 			track_open.eq(1),
131 132
 			self.cmd.stb.eq(1),
  133
+			self.cmd.is_cmd.eq(1),
132 134
 			If(self.cmd.ack, NextState("TRCD")),
133 135
 			self.cmd.ras_n.eq(0)
134 136
 		)
135 137
 		fsm.act("REFRESH",
136 138
 			self.refresh_gnt.eq(precharge_ok),
137 139
 			track_close.eq(1),
  140
+			self.cmd.is_cmd.eq(1),
138 141
 			If(~self.refresh_req, NextState("REGULAR"))
139 142
 		)
140 143
 		fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
43  milkymist/lasmicon/multiplexer.py
@@ -19,6 +19,7 @@ def __init__(self, a, ba):
19 19
 		CommandRequest.__init__(self, a, ba)
20 20
 		self.stb = Signal()
21 21
 		self.ack = Signal()
  22
+		self.is_cmd = Signal()
22 23
 		self.is_read = Signal()
23 24
 		self.is_write = Signal()
24 25
 
@@ -26,6 +27,7 @@ class _CommandChooser(Module):
26 27
 	def __init__(self, requests):
27 28
 		self.want_reads = Signal()
28 29
 		self.want_writes = Signal()
  30
+		self.want_cmds = Signal()
29 31
 		# NB: cas_n/ras_n/we_n are 1 when stb is inactive
30 32
 		self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba))
31 33
 	
@@ -34,12 +36,12 @@ def __init__(self, requests):
34 36
 		rr = RoundRobin(len(requests), SP_CE)
35 37
 		self.submodules += rr
36 38
 		
37  
-		self.comb += [rr.request[i].eq(req.stb & ((req.is_read == self.want_reads) | (req.is_write == self.want_writes)))
  39
+		self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
38 40
 			for i, req in enumerate(requests)]
39 41
 		
40 42
 		stb = Signal()
41 43
 		self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
42  
-		for name in ["a", "ba", "is_read", "is_write"]:
  44
+		for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
43 45
 			choices = Array(getattr(req, name) for req in requests)
44 46
 			self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
45 47
 		for name in ["cas_n", "ras_n", "we_n"]:
@@ -47,8 +49,8 @@ def __init__(self, requests):
47 49
 			choices = Array(getattr(req, name) for req in requests)
48 50
 			self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
49 51
 		self.comb += self.cmd.stb.eq(stb \
50  
-			& (self.cmd.is_read == self.want_reads) \
51  
-			& (self.cmd.is_write == self.want_writes))
  52
+			& ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
  53
+			& (self.cmd.is_write == self.want_writes))))
52 54
 		
53 55
 		self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
54 56
 			for i, req in enumerate(requests)]
@@ -85,8 +87,6 @@ def stb_and(cmd, attr):
85 87
 class Multiplexer(Module, AutoCSR):
86 88
 	def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
87 89
 		assert(phy_settings.nphases == len(dfi.phases))
88  
-		if phy_settings.nphases != 2:
89  
-			raise NotImplementedError("TODO: multiplexer only supports 2 phases")
90 90
 	
91 91
 		# Command choosing
92 92
 		requests = [bm.cmd for bm in bank_machines]
@@ -96,6 +96,11 @@ def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines,
96 96
 			choose_cmd.want_reads.eq(0),
97 97
 			choose_cmd.want_writes.eq(0)
98 98
 		]
  99
+		if phy_settings.nphases == 1:
  100
+			self.comb += [
  101
+				choose_cmd.want_cmds.eq(1),
  102
+				choose_req.want_cmds.eq(1)
  103
+			]	
99 104
 		self.submodules += choose_cmd, choose_req
100 105
 		
101 106
 		# Command steering
@@ -149,13 +154,32 @@ def anti_starvation(timeout):
149 154
 		# Control FSM
150 155
 		fsm = FSM()
151 156
 		self.submodules += fsm
  157
+		
  158
+		def steerer_sel(steerer, phy_settings, r_w_n):
  159
+			r = []
  160
+			for i in range(phy_settings.nphases):
  161
+				s = steerer.sel[i].eq(STEER_NOP)
  162
+				if r_w_n == "read":
  163
+					if i == phy_settings.rdphase:
  164
+						s = steerer.sel[i].eq(STEER_REQ)
  165
+					elif i == phy_settings.wrcmdphase:
  166
+						s = steerer.sel[i].eq(STEER_CMD)
  167
+				elif r_w_n == "write":
  168
+					if i == phy_settings.wrphase:
  169
+						s = steerer.sel[i].eq(STEER_REQ)
  170
+					elif i == phy_settings.rdcmdphase:
  171
+						s = steerer.sel[i].eq(STEER_CMD)
  172
+				else:
  173
+					raise ValueError
  174
+				r.append(s)
  175
+			return r
  176
+
152 177
 		fsm.act("READ",
153 178
 			read_time_en.eq(1),
154 179
 			choose_req.want_reads.eq(1),
155 180
 			choose_cmd.cmd.ack.eq(1),
156 181
 			choose_req.cmd.ack.eq(1),
157  
-			steerer.sel[1-phy_settings.rdphase].eq(STEER_CMD),
158  
-			steerer.sel[phy_settings.rdphase].eq(STEER_REQ),
  182
+			steerer_sel(steerer, phy_settings, "read"),
159 183
 			If(write_available,
160 184
 				# TODO: switch only after several cycles of ~read_available?
161 185
 				If(~read_available | max_read_time, NextState("RTW"))
@@ -167,8 +191,7 @@ def anti_starvation(timeout):
167 191
 			choose_req.want_writes.eq(1),
168 192
 			choose_cmd.cmd.ack.eq(1),
169 193
 			choose_req.cmd.ack.eq(1),
170  
-			steerer.sel[1-phy_settings.wrphase].eq(STEER_CMD),
171  
-			steerer.sel[phy_settings.wrphase].eq(STEER_REQ),
  194
+			steerer_sel(steerer, phy_settings, "write"),
172 195
 			If(read_available,
173 196
 				If(~write_available | max_write_time, NextState("WTR"))
174 197
 			),
2  milkymist/s6ddrphy/__init__.py
@@ -43,6 +43,8 @@ def __init__(self, pads, memtype, nphases, cl, bitslip):
43 43
 			nphases=nphases,
44 44
 			rdphase=0,
45 45
 			wrphase=1,
  46
+			rdcmdphase=1,
  47
+			wrcmdphase=0,
46 48
 			cl=cl,
47 49
 			read_latency=5,
48 50
 			write_latency=0
12  tb/lasmicon/common.py
@@ -16,13 +16,18 @@ def ns(t, margin=True):
16 16
 	return ceil(t/clk_period_ns)
17 17
 
18 18
 sdram_phy = lasmicon.PhySettings(
19  
-	type="DDR",
  19
+	memtype="DDR",
20 20
 	dfi_d=64, 
21 21
 	nphases=2,
22 22
 	rdphase=0,
23 23
 	wrphase=1,
24  
-	cl=3
  24
+	rdcmdphase=1,
  25
+	wrcmdphase=0,
  26
+	cl=3,
  27
+	read_latency=5,
  28
+	write_latency=0
25 29
 )
  30
+
26 31
 sdram_geom = lasmicon.GeomSettings(
27 32
 	bank_a=2,
28 33
 	row_a=13,
@@ -36,9 +41,6 @@ def ns(t, margin=True):
36 41
 	tREFI=ns(7800, False),
37 42
 	tRFC=ns(70),
38 43
 	
39  
-	read_latency=5,
40  
-	write_latency=0,
41  
-
42 44
 	req_queue_size=8,
43 45
 	read_time=32,
44 46
 	write_time=16

No commit comments for this range

Something went wrong with that request. Please try again.