Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 18 files changed
  • 0 comments
  • 1 contributor
62  milkymist/asmicon/__init__.py
... ...
@@ -1,62 +0,0 @@
1  
-from migen.fhdl.std import *
2  
-from migen.bus import dfi, asmibus
3  
-
4  
-from milkymist.asmicon.refresher import *
5  
-from milkymist.asmicon.bankmachine import *
6  
-from milkymist.asmicon.multiplexer import *
7  
-
8  
-class PhySettings:
9  
-	def __init__(self, dfi_d, nphases, rdphase, wrphase):
10  
-		self.dfi_d = dfi_d
11  
-		self.nphases = nphases
12  
-		self.rdphase = rdphase
13  
-		self.wrphase = wrphase
14  
-
15  
-class GeomSettings:
16  
-	def __init__(self, bank_a, row_a, col_a):
17  
-		self.bank_a = bank_a
18  
-		self.row_a = row_a
19  
-		self.col_a = col_a
20  
-		self.mux_a = max(row_a, col_a)
21  
-
22  
-class TimingSettings:
23  
-	def __init__(self, tRP, tRCD, tWR, tREFI, tRFC, CL, rd_delay, read_time, write_time, slot_time=0):
24  
-		self.tRP = tRP
25  
-		self.tRCD = tRCD
26  
-		self.tWR = tWR
27  
-		self.tREFI = tREFI
28  
-		self.tRFC = tRFC
29  
-		
30  
-		self.CL = CL
31  
-		self.rd_delay = rd_delay
32  
-		
33  
-		self.read_time = read_time
34  
-		self.write_time = write_time
35  
-		self.slot_time = slot_time
36  
-
37  
-class ASMIcon(Module):
38  
-	def __init__(self, phy_settings, geom_settings, timing_settings, full_selector=False):
39  
-		self.phy_settings = phy_settings
40  
-		self.geom_settings = geom_settings
41  
-		self.timing_settings = timing_settings
42  
-		self.full_selector = full_selector
43  
-		
44  
-		self.dfi = dfi.Interface(self.geom_settings.mux_a,
45  
-			self.geom_settings.bank_a,
46  
-			self.phy_settings.dfi_d,
47  
-			self.phy_settings.nphases)
48  
-		burst_length = self.phy_settings.nphases*2
49  
-		self.address_align = log2_int(burst_length)
50  
-		aw = self.geom_settings.bank_a + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align
51  
-		dw = self.phy_settings.dfi_d*self.phy_settings.nphases
52  
-		self.submodules.hub = asmibus.Hub(aw, dw, self.timing_settings.slot_time)
53  
-	
54  
-	def do_finalize(self):
55  
-		slots = self.hub.get_slots()
56  
-		self.submodules.refresher = Refresher(self.geom_settings.mux_a, self.geom_settings.bank_a,
57  
-			self.timing_settings.tRP, self.timing_settings.tREFI, self.timing_settings.tRFC)
58  
-		self.submodules.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots, self.full_selector)
59  
-			for i in range(2**self.geom_settings.bank_a)]
60  
-		self.submodules.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
61  
-			self.bank_machines, self.refresher,
62  
-			self.dfi, self.hub)
273  milkymist/asmicon/bankmachine.py
... ...
@@ -1,273 +0,0 @@
1  
-from migen.fhdl.std import *
2  
-from migen.bus.asmibus import *
3  
-from migen.genlib.roundrobin import *
4  
-from migen.genlib.fsm import FSM
5  
-from migen.genlib.misc import optree
6  
-
7  
-from milkymist.asmicon.multiplexer import *
8  
-
9  
-# Row:Bank:Col address mapping
10  
-class _AddressSlicer:
11  
-	def __init__(self, geom_settings, address_align):
12  
-		self.geom_settings = geom_settings
13  
-		self.address_align = address_align
14  
-		
15  
-		self._b1 = self.geom_settings.col_a - self.address_align
16  
-		self._b2 = self._b1 + self.geom_settings.bank_a
17  
-	
18  
-	def row(self, address):
19  
-		if isinstance(address, int):
20  
-			return address >> self._b2
21  
-		else:
22  
-			return address[self._b2:]
23  
-	
24  
-	def bank(self, address):
25  
-		if isinstance(address, int):
26  
-			return (address & (2**self._b2 - 1)) >> self._b1
27  
-		else:
28  
-			return address[self._b1:self._b2]
29  
-	
30  
-	def col(self, address):
31  
-		if isinstance(address, int):
32  
-			return (address & (2**self._b1 - 1)) << self.address_align
33  
-		else:
34  
-			return Cat(Replicate(0, self.address_align), address[:self._b1])
35  
-
36  
-class _Selector(Module):
37  
-	def __init__(self, slicer, bankn, slots):
38  
-		nslots = len(slots)
39  
-		self.stb = Signal()
40  
-		self.ack = Signal()
41  
-		self.tag = Signal(max=nslots)
42  
-		self.adr = Signal(slots[0].adr.nbits)
43  
-		self.we = Signal()
44  
-		
45  
-		# derived classes should drive rr.request
46  
-		self.submodules.rr = RoundRobin(nslots, SP_CE)
47  
-	
48  
-		###
49  
-
50  
-		# Multiplex
51  
-		rr = self.rr
52  
-		state = Signal(2)
53  
-		self.comb += [
54  
-			state.eq(Array(slot.state for slot in slots)[rr.grant]),
55  
-			self.adr.eq(Array(slot.adr for slot in slots)[rr.grant]),
56  
-			self.we.eq(Array(slot.we for slot in slots)[rr.grant]),
57  
-			self.stb.eq(
58  
-				(slicer.bank(self.adr) == bankn) \
59  
-				& (state == SLOT_PENDING)),
60  
-			rr.ce.eq(self.ack | ~self.stb),
61  
-			self.tag.eq(rr.grant)
62  
-		]
63  
-		self.comb += [If((rr.grant == i) & self.stb & self.ack, slot.process.eq(1))
64  
-			for i, slot in enumerate(slots)]
65  
-
66  
-		self.complete_selector(slicer, bankn, slots)
67  
-
68  
-class _SimpleSelector(_Selector):
69  
-	def complete_selector(self, slicer, bankn, slots):
70  
-		for i, slot in enumerate(slots):
71  
-			self.comb += self.rr.request[i].eq(
72  
-				(slicer.bank(slot.adr) == bankn) & \
73  
-				(slot.state == SLOT_PENDING))
74  
-
75  
-class _FullSelector(_Selector):
76  
-	def complete_selector(self, slicer, bankn, slots):
77  
-		rr = self.rr
78  
-
79  
-		# List outstanding requests for our bank
80  
-		outstandings = []
81  
-		for slot in slots:
82  
-			outstanding = Signal()
83  
-			self.comb += outstanding.eq(
84  
-				(slicer.bank(slot.adr) == bankn) & \
85  
-				(slot.state == SLOT_PENDING))
86  
-			outstandings.append(outstanding)
87  
-		
88  
-		# Row tracking
89  
-		openrow_r = Signal(slicer.geom_settings.row_a)
90  
-		openrow_n = Signal(slicer.geom_settings.row_a)
91  
-		openrow = Signal(slicer.geom_settings.row_a)
92  
-		self.comb += [
93  
-			openrow_n.eq(slicer.row(self.adr)),
94  
-			If(self.stb,
95  
-				openrow.eq(openrow_n)
96  
-			).Else(
97  
-				openrow.eq(openrow_r)
98  
-			)
99  
-		]
100  
-		self.sync += If(self.stb & self.ack, openrow_r.eq(openrow_n))
101  
-		hits = []
102  
-		for slot, os in zip(slots, outstandings):
103  
-			hit = Signal()
104  
-			self.comb += hit.eq((slicer.row(slot.adr) == openrow) & os)
105  
-			hits.append(hit)
106  
-		
107  
-		# Determine best request
108  
-		rr = RoundRobin(self.nslots, SP_CE)
109  
-		has_hit = Signal()
110  
-		self.comb += has_hit.eq(optree("|", hits))
111  
-		
112  
-		best_hit = [rr.request[i].eq(hit)
113  
-			for i, hit in enumerate(hits)]
114  
-		best_fallback = [rr.request[i].eq(os)
115  
-			for i, os in enumerate(outstandings)]
116  
-		select_stmt = If(has_hit,
117  
-				*best_hit
118  
-			).Else(
119  
-				*best_fallback
120  
-			)
121  
-		
122  
-		if slots[0].time:
123  
-			# Implement anti-starvation timer
124  
-			matures = []
125  
-			for slot, os in zip(slots, outstandings):
126  
-				mature = Signal()
127  
-				comb.append(mature.eq(slot.mature & os))
128  
-				matures.append(mature)
129  
-			has_mature = Signal()
130  
-			self.comb += has_mature.eq(optree("|", matures))
131  
-			best_mature = [rr.request[i].eq(mature)
132  
-				for i, mature in enumerate(matures)]
133  
-			select_stmt = If(has_mature, *best_mature).Else(select_stmt)
134  
-		self.comb += select_stmt
135  
-
136  
-class _Buffer(Module):
137  
-	def __init__(self, source):
138  
-		self.stb = Signal()
139  
-		self.ack = Signal()
140  
-		self.tag = Signal(source.tag.bv)
141  
-		self.adr = Signal(source.adr.bv)
142  
-		self.we = Signal()
143  
-	
144  
-		###
145  
-
146  
-		en = Signal()
147  
-		self.comb += [
148  
-			en.eq(self.ack | ~self.stb),
149  
-			source.ack.eq(en)
150  
-		]
151  
-		self.sync += [
152  
-			If(en,
153  
-				self.stb.eq(source.stb),
154  
-				self.tag.eq(source.tag),
155  
-				self.adr.eq(source.adr),
156  
-				self.we.eq(source.we)
157  
-			)
158  
-		]
159  
-	
160  
-class BankMachine(Module):
161  
-	def __init__(self, geom_settings, timing_settings, address_align, bankn, slots, full_selector):
162  
-		self.refresh_req = Signal()
163  
-		self.refresh_gnt = Signal()
164  
-		self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a,
165  
-			bits_for(len(slots)-1))
166  
-
167  
-		###
168  
-
169  
-		# Sub components
170  
-		slicer = _AddressSlicer(geom_settings, address_align)
171  
-		if full_selector:
172  
-			selector = _FullSelector(slicer, bankn, slots)
173  
-			self.submodules.buf = _Buffer(selector)
174  
-			cmdsource = self.buf
175  
-		else:
176  
-			selector = _SimpleSelector(slicer, bankn, slots)
177  
-			cmdsource = selector
178  
-		self.submodules += selector
179  
-		
180  
-		# Row tracking
181  
-		has_openrow = Signal()
182  
-		openrow = Signal(geom_settings.row_a)
183  
-		hit = Signal()
184  
-		self.comb += hit.eq(openrow == slicer.row(cmdsource.adr))
185  
-		track_open = Signal()
186  
-		track_close = Signal()
187  
-		self.sync += [
188  
-			If(track_open,
189  
-				has_openrow.eq(1),
190  
-				openrow.eq(slicer.row(cmdsource.adr))
191  
-			),
192  
-			If(track_close,
193  
-				has_openrow.eq(0)
194  
-			)
195  
-		]
196  
-		
197  
-		# Address generation
198  
-		s_row_adr = Signal()
199  
-		self.comb += [
200  
-			self.cmd.ba.eq(bankn),
201  
-			If(s_row_adr,
202  
-				self.cmd.a.eq(slicer.row(cmdsource.adr))
203  
-			).Else(
204  
-				self.cmd.a.eq(slicer.col(cmdsource.adr))
205  
-			)
206  
-		]
207  
-		
208  
-		self.comb += self.cmd.tag.eq(cmdsource.tag)
209  
-		
210  
-		# Respect write-to-precharge specification
211  
-		precharge_ok = Signal()
212  
-		t_unsafe_precharge = 2 + timing_settings.tWR - 1
213  
-		unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
214  
-		self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
215  
-		self.sync += [
216  
-			If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
217  
-				unsafe_precharge_count.eq(t_unsafe_precharge)
218  
-			).Elif(~precharge_ok,
219  
-				unsafe_precharge_count.eq(unsafe_precharge_count-1)
220  
-			)
221  
-		]
222  
-		
223  
-		# Control and command generation FSM
224  
-		fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[
225  
-			("TRP", "ACTIVATE", timing_settings.tRP-1),
226  
-			("TRCD", "REGULAR", timing_settings.tRCD-1)
227  
-		])
228  
-		self.submodules += fsm
229  
-		fsm.act(fsm.REGULAR,
230  
-			If(self.refresh_req,
231  
-				fsm.next_state(fsm.REFRESH)
232  
-			).Elif(cmdsource.stb,
233  
-				If(has_openrow,
234  
-					If(hit,
235  
-						# NB: write-to-read specification is enforced by multiplexer
236  
-						self.cmd.stb.eq(1),
237  
-						cmdsource.ack.eq(self.cmd.ack),
238  
-						self.cmd.is_read.eq(~cmdsource.we),
239  
-						self.cmd.is_write.eq(cmdsource.we),
240  
-						self.cmd.cas_n.eq(0),
241  
-						self.cmd.we_n.eq(~cmdsource.we)
242  
-					).Else(
243  
-						fsm.next_state(fsm.PRECHARGE)
244  
-					)
245  
-				).Else(
246  
-					fsm.next_state(fsm.ACTIVATE)
247  
-				)
248  
-			)
249  
-		)
250  
-		fsm.act(fsm.PRECHARGE,
251  
-			# Notes:
252  
-			# 1. we are presenting the column address, A10 is always low
253  
-			# 2. since we always go to the ACTIVATE state, we do not need
254  
-			# to assert track_close.
255  
-			If(precharge_ok,
256  
-				self.cmd.stb.eq(1),
257  
-				If(self.cmd.ack, fsm.next_state(fsm.TRP)),
258  
-				self.cmd.ras_n.eq(0),
259  
-				self.cmd.we_n.eq(0)
260  
-			)
261  
-		)
262  
-		fsm.act(fsm.ACTIVATE,
263  
-			s_row_adr.eq(1),
264  
-			track_open.eq(1),
265  
-			self.cmd.stb.eq(1),
266  
-			If(self.cmd.ack, fsm.next_state(fsm.TRCD)),
267  
-			self.cmd.ras_n.eq(0)
268  
-		)
269  
-		fsm.act(fsm.REFRESH,
270  
-			self.refresh_gnt.eq(precharge_ok),
271  
-			track_close.eq(1),
272  
-			If(~self.refresh_req, fsm.next_state(fsm.REGULAR))
273  
-		)
28  milkymist/asmiprobe/__init__.py
... ...
@@ -1,28 +0,0 @@
1  
-from migen.fhdl.std import *
2  
-from migen.bank.description import *
3  
-
4  
-class ASMIprobe(Module):
5  
-	def __init__(self, hub, trace_depth=16):
6  
-		slots = hub.get_slots()
7  
-		slot_count = len(slots)
8  
-		
9  
-		self._slot_count = CSRStatus(bits_for(slot_count))
10  
-		self._trace_depth = CSRStatus(bits_for(trace_depth))
11  
-		self._slot_status = [CSRStatus(2, name="slot_status" + str(i)) for i in range(slot_count)]
12  
-		self._trace = [CSRStatus(bits_for(slot_count-1), name="trace" + str(i)) for i in range(trace_depth)]
13  
-
14  
-		###
15  
-		
16  
-		self.comb += [
17  
-			self._slot_count.status.eq(slot_count),
18  
-			self._trace_depth.status.eq(trace_depth)
19  
-		]
20  
-		for slot, status in zip(slots, self._slot_status):
21  
-			self.sync += status.status.eq(slot.state)
22  
-		shift_tags = [self._trace[n].status.eq(self._trace[n+1].status)
23  
-			for n in range(len(self._trace) - 1)]
24  
-		shift_tags.append(self._trace[-1].status.eq(hub.tag_call))
25  
-		self.sync += If(hub.call, *shift_tags)
26  
-
27  
-	def get_csrs(self):
28  
-		return [self._slot_count, self._trace_depth] + self._slot_status + self._trace
8  milkymist/dfii/__init__.py
@@ -13,6 +13,7 @@ def __init__(self, phase):
13 13
 	
14 14
 		###
15 15
 
  16
+		wrdata_en_adv = Signal()
16 17
 		self.comb += [
17 18
 			If(self._command_issue.re,
18 19
 				phase.cs_n.eq(~self._command.storage[0]),
@@ -27,12 +28,15 @@ def __init__(self, phase):
27 28
 			),
28 29
 			phase.address.eq(self._address.storage),
29 30
 			phase.bank.eq(self._baddress.storage),
30  
-			phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
  31
+			wrdata_en_adv.eq(self._command_issue.re & self._command.storage[4]),
31 32
 			phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
32 33
 			phase.wrdata.eq(self._wrdata.storage),
33 34
 			phase.wrdata_mask.eq(0)
34 35
 		]
35  
-		self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
  36
+		self.sync += [
  37
+			phase.wrdata_en.eq(wrdata_en_adv),
  38
+			If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
  39
+		]
36 40
 
37 41
 class DFIInjector(Module, AutoCSR):
38 42
 	def __init__(self, a, ba, d, nphases=1):
4  milkymist/dvisampler/debug.py
@@ -2,7 +2,7 @@
2 2
 from migen.genlib.fifo import AsyncFIFO
3 3
 from migen.genlib.record import layout_len
4 4
 from migen.bank.description import AutoCSR
5  
-from migen.actorlib import structuring, dma_asmi, spi
  5
+from migen.actorlib import structuring, dma_lasmi, spi
6 6
 
7 7
 from milkymist.dvisampler.edid import EDID
8 8
 from milkymist.dvisampler.clocking import Clocking
@@ -35,7 +35,7 @@ def __init__(self, pads, asmiport):
35 35
 		pack_factor = asmiport.hub.dw//16
36 36
 		self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
37 37
 		self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
38  
-		self.submodules.dma = spi.DMAWriteController(dma_asmi.Writer(asmiport), spi.MODE_SINGLE_SHOT, free_flow=True)
  38
+		self.submodules.dma = spi.DMAWriteController(dma_lasmi.Writer(lasmim), spi.MODE_SINGLE_SHOT)
39 39
 		self.comb += [
40 40
 			self.packer.sink.stb.eq(fifo.readable),
41 41
 			fifo.re.eq(self.packer.sink.ack),
10  milkymist/dvisampler/dma.py
@@ -3,7 +3,7 @@
3 3
 from migen.bank.description import *
4 4
 from migen.bank.eventmanager import *
5 5
 from migen.flow.actor import *
6  
-from migen.actorlib import dma_asmi
  6
+from migen.actorlib import dma_lasmi
7 7
 
8 8
 from milkymist.dvisampler.common import frame_layout
9 9
 
@@ -55,9 +55,9 @@ def __init__(self, nslots, addr_bits, alignment_bits):
55 55
 		self.comb += [slot.address_done.eq(self.address_done & (current_slot == n)) for n, slot in enumerate(slots)]
56 56
 
57 57
 class DMA(Module):
58  
-	def __init__(self, asmiport, nslots):
59  
-		bus_aw = asmiport.hub.aw
60  
-		bus_dw = asmiport.hub.dw
  58
+	def __init__(self, lasmim, nslots):
  59
+		bus_aw = lasmim.aw
  60
+		bus_dw = lasmim.dw
61 61
 		alignment_bits = bits_for(bus_dw//8) - 1
62 62
 
63 63
 		self.frame = Sink(frame_layout)
@@ -112,7 +112,7 @@ def __init__(self, asmiport, nslots):
112 112
 			)
113 113
 
114 114
 		# bus accessor
115  
-		self.submodules._bus_accessor = dma_asmi.Writer(asmiport)
  115
+		self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
116 116
 		self.comb += [
117 117
 			self._bus_accessor.address_data.payload.a.eq(current_address),
118 118
 			self._bus_accessor.address_data.payload.d.eq(cur_memory_word)
22  milkymist/framebuffer/__init__.py
@@ -2,18 +2,18 @@
2 2
 from migen.flow.actor import *
3 3
 from migen.flow.network import *
4 4
 from migen.bank.description import CSRStorage, AutoCSR
5  
-from migen.actorlib import dma_asmi, structuring, sim, spi
  5
+from migen.actorlib import dma_lasmi, structuring, sim, spi
6 6
 
7 7
 from milkymist.framebuffer.lib import bpp, pixel_layout, dac_layout, FrameInitiator, VTG, FIFO
8 8
 
9 9
 class Framebuffer(Module):
10  
-	def __init__(self, pads, asmiport, simulation=False):
11  
-		pack_factor = asmiport.hub.dw//(2*bpp)
  10
+	def __init__(self, pads, lasmim, simulation=False):
  11
+		pack_factor = lasmim.dw//(2*bpp)
12 12
 		packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
13 13
 		
14 14
 		fi = FrameInitiator()
15  
-		dma = spi.DMAReadController(dma_asmi.Reader(asmiport), spi.MODE_EXTERNAL, length_reset=640*480*4)
16  
-		cast = structuring.Cast(asmiport.hub.dw, packed_pixels, reverse_to=True)
  15
+		dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
  16
+		cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
17 17
 		unpack = structuring.Unpack(pack_factor, pixel_layout)
18 18
 		vtg = VTG()
19 19
 		if simulation:
@@ -93,19 +93,19 @@ def __init__(self, nimages, latency):
93 93
 		self.comb += self.source.payload.eq(outval)
94 94
 
95 95
 class MixFramebuffer(Module, AutoCSR):
96  
-	def __init__(self, pads, *asmiports, blender_latency=5):
97  
-		pack_factor = asmiports[0].hub.dw//(2*bpp)
  96
+	def __init__(self, pads, *lasmims, blender_latency=5):
  97
+		pack_factor = lasmims[0].dw//(2*bpp)
98 98
 		packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
99 99
 		
100 100
 		self._enable = CSRStorage()
101 101
 		self.fi = FrameInitiator()
102  
-		self.blender = Blender(len(asmiports), blender_latency)
  102
+		self.blender = Blender(len(lasmims), blender_latency)
103 103
 		self.comb += self.fi.trigger.eq(self._enable.storage)
104 104
 
105 105
 		g = DataFlowGraph()
106  
-		for n, asmiport in enumerate(asmiports):
107  
-			dma = spi.DMAReadController(dma_asmi.Reader(asmiport), spi.MODE_EXTERNAL, length_reset=640*480*4)
108  
-			cast = structuring.Cast(asmiport.hub.dw, packed_pixels, reverse_to=True)
  106
+		for n, lasmim in enumerate(lasmims):
  107
+			dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
  108
+			cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
109 109
 			unpack = structuring.Unpack(pack_factor, pixel_layout)
110 110
 
111 111
 			g.add_connection(dma, cast)
64  milkymist/lasmicon/__init__.py
... ...
@@ -0,0 +1,64 @@
  1
+from migen.fhdl.std import *
  2
+from migen.bus import dfi, lasmibus
  3
+
  4
+from milkymist.lasmicon.refresher import *
  5
+from milkymist.lasmicon.bankmachine import *
  6
+from milkymist.lasmicon.multiplexer import *
  7
+
  8
+class PhySettings:
  9
+	def __init__(self, dfi_d, nphases, rdphase, wrphase):
  10
+		self.dfi_d = dfi_d
  11
+		self.nphases = nphases
  12
+		self.rdphase = rdphase
  13
+		self.wrphase = wrphase
  14
+
  15
+class GeomSettings:
  16
+	def __init__(self, bank_a, row_a, col_a):
  17
+		self.bank_a = bank_a
  18
+		self.row_a = row_a
  19
+		self.col_a = col_a
  20
+		self.mux_a = max(row_a, col_a)
  21
+
  22
+class TimingSettings:
  23
+	def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, CL, read_latency, write_latency, read_time, write_time):
  24
+		self.tRP = tRP
  25
+		self.tRCD = tRCD
  26
+		self.tWR = tWR
  27
+		self.tWTR = tWTR
  28
+		self.tREFI = tREFI
  29
+		self.tRFC = tRFC
  30
+		
  31
+		self.CL = CL
  32
+		self.read_latency = read_latency
  33
+		self.write_latency = write_latency
  34
+		
  35
+		self.read_time = read_time
  36
+		self.write_time = write_time
  37
+
  38
+class LASMIcon(Module):
  39
+	def __init__(self, phy_settings, geom_settings, timing_settings):
  40
+		burst_length = phy_settings.nphases*2 # command multiplication*DDR
  41
+		address_align = log2_int(burst_length)
  42
+
  43
+		self.dfi = dfi.Interface(geom_settings.mux_a,
  44
+			geom_settings.bank_a,
  45
+			phy_settings.dfi_d,
  46
+			phy_settings.nphases)
  47
+		self.lasmic = lasmibus.Interface(
  48
+			aw=geom_settings.row_a + geom_settings.col_a - address_align,
  49
+			dw=phy_settings.dfi_d*phy_settings.nphases,
  50
+			nbanks=2**geom_settings.bank_a,
  51
+			read_latency=timing_settings.read_latency,
  52
+			write_latency=timing_settings.write_latency)
  53
+		self.nrowbits = geom_settings.col_a - address_align
  54
+	
  55
+		###
  56
+
  57
+		self.submodules.refresher = Refresher(geom_settings.mux_a, geom_settings.bank_a,
  58
+			timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
  59
+		self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, address_align, i,
  60
+				getattr(self.lasmic, "bank"+str(i)))
  61
+			for i in range(2**geom_settings.bank_a)]
  62
+		self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
  63
+			self.bank_machines, self.refresher,
  64
+			self.dfi, self.lasmic)
129  milkymist/lasmicon/bankmachine.py
... ...
@@ -0,0 +1,129 @@
  1
+from migen.fhdl.std import *
  2
+from migen.bus.asmibus import *
  3
+from migen.genlib.roundrobin import *
  4
+from migen.genlib.fsm import FSM
  5
+from migen.genlib.misc import optree
  6
+
  7
+from milkymist.lasmicon.multiplexer import *
  8
+
  9
+class _AddressSlicer:
  10
+	def __init__(self, col_a, address_align):
  11
+		self.col_a = col_a
  12
+		self.address_align = address_align
  13
+	
  14
+	def row(self, address):
  15
+		split = self.col_a - self.address_align
  16
+		if isinstance(address, int):
  17
+			return address >> split
  18
+		else:
  19
+			return address[split:]
  20
+		
  21
+	def col(self, address):
  22
+		split = self.col_a - self.address_align
  23
+		if isinstance(address, int):
  24
+			return (address & (2**split - 1)) << self.address_align
  25
+		else:
  26
+			return Cat(Replicate(0, self.address_align), address[:split])
  27
+	
  28
+class BankMachine(Module):
  29
+	def __init__(self, geom_settings, timing_settings, address_align, bankn, req):
  30
+		self.refresh_req = Signal()
  31
+		self.refresh_gnt = Signal()
  32
+		self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a)
  33
+
  34
+		###
  35
+
  36
+		slicer = _AddressSlicer(geom_settings.col_a, address_align)
  37
+		
  38
+		# Row tracking
  39
+		has_openrow = Signal()
  40
+		openrow = Signal(geom_settings.row_a)
  41
+		hit = Signal()
  42
+		self.comb += hit.eq(openrow == slicer.row(req.adr))
  43
+		track_open = Signal()
  44
+		track_close = Signal()
  45
+		self.sync += [
  46
+			If(track_open,
  47
+				has_openrow.eq(1),
  48
+				openrow.eq(slicer.row(req.adr))
  49
+			),
  50
+			If(track_close,
  51
+				has_openrow.eq(0)
  52
+			)
  53
+		]
  54
+		
  55
+		# Address generation
  56
+		s_row_adr = Signal()
  57
+		self.comb += [
  58
+			self.cmd.ba.eq(bankn),
  59
+			If(s_row_adr,
  60
+				self.cmd.a.eq(slicer.row(req.adr))
  61
+			).Else(
  62
+				self.cmd.a.eq(slicer.col(req.adr))
  63
+			)
  64
+		]
  65
+		
  66
+		# Respect write-to-precharge specification
  67
+		precharge_ok = Signal()
  68
+		t_unsafe_precharge = 2 + timing_settings.tWR - 1
  69
+		unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
  70
+		self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
  71
+		self.sync += [
  72
+			If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
  73
+				unsafe_precharge_count.eq(t_unsafe_precharge)
  74
+			).Elif(~precharge_ok,
  75
+				unsafe_precharge_count.eq(unsafe_precharge_count-1)
  76
+			)
  77
+		]
  78
+		
  79
+		# Control and command generation FSM
  80
+		fsm = FSM("REGULAR", "PRECHARGE", "ACTIVATE", "REFRESH", delayed_enters=[
  81
+			("TRP", "ACTIVATE", timing_settings.tRP-1),
  82
+			("TRCD", "REGULAR", timing_settings.tRCD-1)
  83
+		])
  84
+		self.submodules += fsm
  85
+		fsm.act(fsm.REGULAR,
  86
+			If(self.refresh_req,
  87
+				fsm.next_state(fsm.REFRESH)
  88
+			).Elif(req.stb,
  89
+				If(has_openrow,
  90
+					If(hit,
  91
+						# NB: write-to-read specification is enforced by multiplexer
  92
+						self.cmd.stb.eq(1),
  93
+						req.ack.eq(self.cmd.ack),
  94
+						self.cmd.is_read.eq(~req.we),
  95
+						self.cmd.is_write.eq(req.we),
  96
+						self.cmd.cas_n.eq(0),
  97
+						self.cmd.we_n.eq(~req.we)
  98
+					).Else(
  99
+						fsm.next_state(fsm.PRECHARGE)
  100
+					)
  101
+				).Else(
  102
+					fsm.next_state(fsm.ACTIVATE)
  103
+				)
  104
+			)
  105
+		)
  106
+		fsm.act(fsm.PRECHARGE,
  107
+			# Notes:
  108
+			# 1. we are presenting the column address, A10 is always low
  109
+			# 2. since we always go to the ACTIVATE state, we do not need
  110
+			# to assert track_close.
  111
+			If(precharge_ok,
  112
+				self.cmd.stb.eq(1),
  113
+				If(self.cmd.ack, fsm.next_state(fsm.TRP)),
  114
+				self.cmd.ras_n.eq(0),
  115
+				self.cmd.we_n.eq(0)
  116
+			)
  117
+		)
  118
+		fsm.act(fsm.ACTIVATE,
  119
+			s_row_adr.eq(1),
  120
+			track_open.eq(1),
  121
+			self.cmd.stb.eq(1),
  122
+			If(self.cmd.ack, fsm.next_state(fsm.TRCD)),
  123
+			self.cmd.ras_n.eq(0)
  124
+		)
  125
+		fsm.act(fsm.REFRESH,
  126
+			self.refresh_gnt.eq(precharge_ok),
  127
+			track_close.eq(1),
  128
+			If(~self.refresh_req, fsm.next_state(fsm.REGULAR))
  129
+		)
81  milkymist/asmicon/multiplexer.py → milkymist/lasmicon/multiplexer.py
@@ -12,20 +12,19 @@ def __init__(self, a, ba):
12 12
 		self.we_n = Signal(reset=1)
13 13
 
14 14
 class CommandRequestRW(CommandRequest):
15  
-	def __init__(self, a, ba, tagbits):
  15
+	def __init__(self, a, ba):
16 16
 		CommandRequest.__init__(self, a, ba)
17 17
 		self.stb = Signal()
18 18
 		self.ack = Signal()
19 19
 		self.is_read = Signal()
20 20
 		self.is_write = Signal()
21  
-		self.tag = Signal(tagbits)
22 21
 
23 22
 class _CommandChooser(Module):
24  
-	def __init__(self, requests, tagbits):
  23
+	def __init__(self, requests):
25 24
 		self.want_reads = Signal()
26 25
 		self.want_writes = Signal()
27 26
 		# NB: cas_n/ras_n/we_n are 1 when stb is inactive
28  
-		self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba), tagbits)
  27
+		self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba))
29 28
 	
30 29
 		###
31 30
 
@@ -37,7 +36,7 @@ def __init__(self, requests, tagbits):
37 36
 		
38 37
 		stb = Signal()
39 38
 		self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
40  
-		for name in ["a", "ba", "is_read", "is_write", "tag"]:
  39
+		for name in ["a", "ba", "is_read", "is_write"]:
41 40
 			choices = Array(getattr(req, name) for req in requests)
42 41
 			self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
43 42
 		for name in ["cas_n", "ras_n", "we_n"]:
@@ -66,6 +65,7 @@ def stb_and(cmd, attr):
66 65
 			else:
67 66
 				return cmd.stb & getattr(cmd, attr)
68 67
 		for phase, sel in zip(dfi.phases, self.sel):
  68
+			wrdata_en_adv = Signal()
69 69
 			self.comb += [
70 70
 				phase.cke.eq(1),
71 71
 				phase.cs_n.eq(0)
@@ -77,67 +77,20 @@ def stb_and(cmd, attr):
77 77
 				phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
78 78
 				phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
79 79
 				phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
80  
-				phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
  80
+				wrdata_en_adv.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel]),
  81
+				phase.wrdata_en.eq(wrdata_en_adv)
81 82
 			]
82 83
 
83  
-class _Datapath(Module):
84  
-	def __init__(self, timing_settings, command, dfi, hub):
85  
-		tagbits = flen(hub.tag_call)
86  
-		
87  
-		rd_valid = Signal()
88  
-		rd_tag = Signal(tagbits)
89  
-		wr_valid = Signal()
90  
-		wr_tag = Signal(tagbits)
91  
-		self.comb += [
92  
-			hub.call.eq(rd_valid | wr_valid),
93  
-			If(wr_valid,
94  
-				hub.tag_call.eq(wr_tag)
95  
-			).Else(
96  
-				hub.tag_call.eq(rd_tag)
97  
-			)
98  
-		]
99  
-		
100  
-		rd_delay = timing_settings.rd_delay + 1
101  
-		rd_valid_d = [Signal() for i in range(rd_delay)]
102  
-		rd_tag_d = [Signal(tagbits) for i in range(rd_delay)]
103  
-		for i in range(rd_delay):
104  
-			if i:
105  
-				self.sync += [
106  
-					rd_valid_d[i].eq(rd_valid_d[i-1]),
107  
-					rd_tag_d[i].eq(rd_tag_d[i-1])
108  
-				]
109  
-			else:
110  
-				self.sync += [
111  
-					rd_valid_d[i].eq(command.stb & command.ack & command.is_read),
112  
-					rd_tag_d[i].eq(command.tag)
113  
-				]		
114  
-		self.comb += [
115  
-			rd_valid.eq(rd_valid_d[-1]),
116  
-			rd_tag.eq(rd_tag_d[-1]),
117  
-			wr_valid.eq(command.stb & command.ack & command.is_write),
118  
-			wr_tag.eq(command.tag),
119  
-		]
120  
-		
121  
-		all_rddata = [p.rddata for p in dfi.phases]
122  
-		all_wrdata = [p.wrdata for p in dfi.phases]
123  
-		all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
124  
-		self.comb += [
125  
-			hub.dat_r.eq(Cat(*all_rddata)),
126  
-			Cat(*all_wrdata).eq(hub.dat_w),
127  
-			Cat(*all_wrdata_mask).eq(hub.dat_wm)
128  
-		]
129  
-
130 84
 class Multiplexer(Module):
131  
-	def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub):
  85
+	def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
132 86
 		assert(phy_settings.nphases == len(dfi.phases))
133 87
 		if phy_settings.nphases != 2:
134 88
 			raise NotImplementedError("TODO: multiplexer only supports 2 phases")
135 89
 	
136 90
 		# Command choosing
137 91
 		requests = [bm.cmd for bm in bank_machines]
138  
-		tagbits = flen(hub.tag_call)
139  
-		choose_cmd = _CommandChooser(requests, tagbits)
140  
-		choose_req = _CommandChooser(requests, tagbits)
  92
+		choose_cmd = _CommandChooser(requests)
  93
+		choose_req = _CommandChooser(requests)
141 94
 		self.comb += [
142 95
 			choose_cmd.want_reads.eq(0),
143 96
 			choose_cmd.want_writes.eq(0)
@@ -183,13 +136,19 @@ def anti_starvation(timeout):
183 136
 		self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
184 137
 		
185 138
 		# Datapath
186  
-		datapath = _Datapath(timing_settings, choose_req.cmd, dfi, hub)
187  
-		self.submodules += datapath
  139
+		all_rddata = [p.rddata for p in dfi.phases]
  140
+		all_wrdata = [p.wrdata for p in dfi.phases]
  141
+		all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
  142
+		self.comb += [
  143
+			lasmic.dat_r.eq(Cat(*all_rddata)),
  144
+			Cat(*all_wrdata).eq(lasmic.dat_w),
  145
+			Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
  146
+		]
188 147
 		
189 148
 		# Control FSM
190 149
 		fsm = FSM("READ", "WRITE", "REFRESH", delayed_enters=[
191  
-			("RTW", "WRITE", timing_settings.rd_delay),
192  
-			("WTR", "READ", timing_settings.tWR)
  150
+			("RTW", "WRITE", timing_settings.read_latency),
  151
+			("WTR", "READ", timing_settings.tWTR)
193 152
 		])
194 153
 		self.submodules += fsm
195 154
 		fsm.act(fsm.READ,
2  milkymist/asmicon/refresher.py → milkymist/lasmicon/refresher.py
@@ -2,7 +2,7 @@
2 2
 from migen.genlib.misc import timeline
3 3
 from migen.genlib.fsm import FSM
4 4
 
5  
-from milkymist.asmicon.multiplexer import *
  5
+from milkymist.lasmicon.multiplexer import *
6 6
 
7 7
 class Refresher(Module):
8 8
 	def __init__(self, a, ba, tRP, tREFI, tRFC):
1  software/bios/main.c
@@ -367,7 +367,6 @@ static void do_command(char *c)
367 367
 	else if(strcmp(token, "ddrwr") == 0) ddrwr(get_token(&c));
368 368
 	else if(strcmp(token, "memtest") == 0) memtest();
369 369
 	else if(strcmp(token, "ddrinit") == 0) ddrinit();
370  
-	else if(strcmp(token, "asmiprobe") == 0) asmiprobe();
371 370
 	
372 371
 	else if(strcmp(token, "dfs") == 0) dfs(get_token(&c));
373 372
 
37  software/bios/sdram.c
@@ -127,9 +127,9 @@ void ddrrd(char *startaddr)
127 127
 	cdelay(15);
128 128
 	
129 129
 	for(i=0;i<8;i++)
130  
-		printf("%02x", MMPTR(0xe0000834+4*i));
  130
+		printf("%02x", MMPTR(0xe0001038+4*i));
131 131
 	for(i=0;i<8;i++)
132  
-		printf("%02x", MMPTR(0xe0000884+4*i));
  132
+		printf("%02x", MMPTR(0xe000108c+4*i));
133 133
 	printf("\n");
134 134
 }
135 135
 
@@ -150,8 +150,8 @@ void ddrwr(char *startaddr)
150 150
 	}
151 151
 	
152 152
 	for(i=0;i<8;i++) {
153  
-		MMPTR(0xe0000814+4*i) = i;
154  
-		MMPTR(0xe0000864+4*i) = 0xf0 + i;
  153
+		MMPTR(0xe0001018+4*i) = i;
  154
+		MMPTR(0xe000106c+4*i) = 0xf0 + i;
155 155
 	}
156 156
 	
157 157
 	dfii_pi1_address_write(addr);
@@ -209,32 +209,3 @@ int ddrinit(void)
209 209
 	
210 210
 	return 1;
211 211
 }
212  
-
213  
-static const char *format_slot_state(int state)
214  
-{
215  
-	switch(state) {
216  
-		case 0: return "Empty";
217  
-		case 1: return "Pending";
218  
-		case 2: return "Processing";
219  
-		default: return "UNEXPECTED VALUE";
220  
-	}
221  
-}
222  
-
223  
-void asmiprobe(void)
224  
-{
225  
-	volatile unsigned int *regs = (unsigned int *)ASMIPROBE_BASE;
226  
-	int slot_count;
227  
-	int trace_depth;
228  
-	int i;
229  
-	int offset;
230  
-	
231  
-	offset = 0;
232  
-	slot_count = regs[offset++];
233  
-	trace_depth = regs[offset++];
234  
-	for(i=0;i<slot_count;i++)
235  
-		printf("Slot #%d: %s\n", i, format_slot_state(regs[offset++]));
236  
-	printf("Latest tags:\n");
237  
-	for(i=0;i<trace_depth;i++)
238  
-		printf("%d ", regs[offset++]);
239  
-	printf("\n");
240  
-}
2  software/bios/sdram.h
@@ -10,6 +10,4 @@ int memtest_silent(void);
10 10
 int memtest(void);
11 11
 int ddrinit(void);
12 12
 
13  
-void asmiprobe(void);
14  
-
15 13
 #endif /* __SDRAM_H */
2  software/include/net/microudp.h
@@ -7,7 +7,7 @@
7 7
 
8 8
 typedef void (*udp_callback)(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *data, unsigned int length);
9 9
 
10  
-void microudp_start(unsigned char *macaddr, unsigned int ip);
  10
+void microudp_start(const unsigned char *macaddr, unsigned int ip);
11 11
 int microudp_arp_resolve(unsigned int ip);
12 12
 void *microudp_get_tx_buffer(void);
13 13
 int microudp_send(unsigned short src_port, unsigned short dst_port, unsigned int length);
2  software/libnet/microudp.c
@@ -350,7 +350,7 @@ static void process_frame(void)
350 350
 	else if(rxbuffer->frame.eth_header.ethertype == ETHERTYPE_IP) process_ip();
351 351
 }
352 352
 
353  
-void microudp_start(unsigned char *macaddr, unsigned int ip)
  353
+void microudp_start(const unsigned char *macaddr, unsigned int ip)
354 354
 {
355 355
 	int i;
356 356
 
57  top.py
@@ -3,11 +3,12 @@
3 3
 from operator import itemgetter
4 4
 
5 5
 from migen.fhdl.std import *
6  
-from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi
  6
+from migen.bus import wishbone, csr, lasmibus, dfi
  7
+from migen.bus import wishbone2lasmi, wishbone2csr
7 8
 from migen.bank import csrgen
8 9
 
9  
-from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
10  
-	identifier, timer, minimac3, framebuffer, asmiprobe, dvisampler, \
  10
+from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
  11
+	identifier, timer, minimac3, framebuffer, dvisampler, \
11 12
 	counteradc, gpio
12 13
 from milkymist.cif import get_macros
13 14
 
@@ -23,26 +24,28 @@ def ns(t, margin=True):
23 24
 		t += clk_period_ns/2
24 25
 	return ceil(t/clk_period_ns)
25 26
 
26  
-sdram_phy = asmicon.PhySettings(
  27
+sdram_phy = lasmicon.PhySettings(
27 28
 	dfi_d=64, 
28 29
 	nphases=2,
29 30
 	rdphase=0,
30 31
 	wrphase=1
31 32
 )
32  
-sdram_geom = asmicon.GeomSettings(
  33
+sdram_geom = lasmicon.GeomSettings(
33 34
 	bank_a=2,
34 35
 	row_a=13,
35 36
 	col_a=10
36 37
 )
37  
-sdram_timing = asmicon.TimingSettings(
  38
+sdram_timing = lasmicon.TimingSettings(
38 39
 	tRP=ns(15),
39 40
 	tRCD=ns(15),
40 41
 	tWR=ns(15),
  42
+	tWTR=2,
41 43
 	tREFI=ns(7800, False),
42 44
 	tRFC=ns(70),
43 45
 	
44 46
 	CL=3,
45  
-	rd_delay=4,
  47
+	read_latency=5,
  48
+	write_latency=1,
46 49
 
47 50
 	read_time=32,
48 51
 	write_time=16
@@ -72,14 +75,13 @@ class SoC(Module):
72 75
 		"timer0":				4,
73 76
 		"minimac":				5,
74 77
 		"fb":					6,
75  
-		"asmiprobe":			7,
76  
-		"dvisampler0":			8,
77  
-		"dvisampler0_edid_mem":	9,
78  
-		"dvisampler1":			10,
79  
-		"dvisampler1_edid_mem":	11,
80  
-		"pots":					12,
81  
-		"buttons":				13,
82  
-		"leds":					14
  78
+		"dvisampler0":			7,
  79
+		"dvisampler0_edid_mem":	8,
  80
+		"dvisampler1":			9,
  81
+		"dvisampler1_edid_mem":	10,
  82
+		"pots":					11,
  83
+		"buttons":				12,
  84
+		"leds":					13
83 85
 	}
84 86
 
85 87
 	interrupt_map = {
@@ -92,15 +94,11 @@ class SoC(Module):
92 94
 
93 95
 	def __init__(self, platform):
94 96
 		#
95  
-		# ASMI
  97
+		# LASMI
96 98
 		#
97  
-		self.submodules.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
98  
-		asmiport_wb = self.asmicon.hub.get_port()
99  
-		asmiport_fb0 = self.asmicon.hub.get_port(4)
100  
-		asmiport_fb1 = self.asmicon.hub.get_port(4)
101  
-		asmiport_dvi0 = self.asmicon.hub.get_port(4)
102  
-		asmiport_dvi1 = self.asmicon.hub.get_port(4)
103  
-		self.asmicon.finalize()
  99
+		self.submodules.lasmicon = lasmicon.LASMIcon(sdram_phy, sdram_geom, sdram_timing)
  100
+		self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], 5, self.lasmicon.nrowbits)
  101
+		lasmim_wb, lasmim_fb0, lasmim_fb1, lasmim_dvi0, lasmim_dvi1 = self.lasmixbar.masters
104 102
 		
105 103
 		#
106 104
 		# DFI
@@ -109,7 +107,7 @@ def __init__(self, platform):
109 107
 		self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d,
110 108
 			sdram_phy.nphases)
111 109
 		self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
112  
-		self.submodules.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
  110
+		self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave)
113 111
 
114 112
 		#
115 113
 		# WISHBONE
@@ -118,7 +116,7 @@ def __init__(self, platform):
118 116
 		self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
119 117
 		self.submodules.sram = wishbone.SRAM(sram_size)
120 118
 		self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
121  
-		self.submodules.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
  119
+		self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(l2_size//4, lasmim_wb)
122 120
 		self.submodules.wishbone2csr = wishbone2csr.WB2CSR()
123 121
 		
124 122
 		# norflash     0x00000000 (shadow @0x80000000)
@@ -135,7 +133,7 @@ def __init__(self, platform):
135 133
 				(lambda a: a[26:29] == 0, self.norflash.bus),
136 134
 				(lambda a: a[26:29] == 1, self.sram.bus),
137 135
 				(lambda a: a[26:29] == 3, self.minimac.membus),
138  
-				(lambda a: a[27:29] == 2, self.wishbone2asmi.wishbone),
  136
+				(lambda a: a[27:29] == 2, self.wishbone2lasmi.wishbone),
139 137
 				(lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
140 138
 			],
141 139
 			register=True)
@@ -147,10 +145,9 @@ def __init__(self, platform):
147 145
 		self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
148 146
 		self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
149 147
 		self.submodules.timer0 = timer.Timer()
150  
-		self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga"), asmiport_fb0, asmiport_fb1)
151  
-		self.submodules.asmiprobe = asmiprobe.ASMIprobe(self.asmicon.hub)
152  
-		self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), asmiport_dvi0)
153  
-		self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), asmiport_dvi1)
  148
+		self.submodules.fb = framebuffer.MixFramebuffer(platform.request("vga"), lasmim_fb0, lasmim_fb1)
  149
+		self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), lasmim_dvi0)
  150
+		self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), lasmim_dvi1)
154 151
 		pots_pads = platform.request("dvi_pots")
155 152
 		self.submodules.pots = counteradc.CounterADC(pots_pads.charge,
156 153
 			[pots_pads.blackout, pots_pads.crossfade])
71  verilog/s6ddrphy/s6ddrphy.v
@@ -2,12 +2,12 @@
2 2
  * 1:2 frequency-ratio DDR PHY for Spartan-6
3 3
  *
4 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.
  5
+ * on dfi_wrdata_mask/dfi_wrdata in the cycle
  6
+ * immediately following the write command.
7 7
  *
8 8
  * Assert dfi_rddata_en in the same cycle as the read
9 9
  * command. The data will come back on dfi_rddata
10  
- * 4 cycles later, along with the assertion of
  10
+ * 5 cycles later, along with the assertion of
11 11
  * dfi_rddata_valid.
12 12
  *
13 13
  * This PHY only supports CAS Latency 3.
@@ -75,6 +75,39 @@ module s6ddrphy #(
75 75
  * Command/address
76 76
  */
77 77
 
  78
+reg [NUM_AD-1:0] r0_dfi_address_p0;
  79
+reg [NUM_BA-1:0] r0_dfi_bank_p0;
  80
+reg r0_dfi_cs_n_p0;
  81
+reg r0_dfi_cke_p0;
  82
+reg r0_dfi_ras_n_p0;
  83
+reg r0_dfi_cas_n_p0;
  84
+reg r0_dfi_we_n_p0;
  85
+reg [NUM_AD-1:0] r0_dfi_address_p1;
  86
+reg [NUM_BA-1:0] r0_dfi_bank_p1;
  87
+reg r0_dfi_cs_n_p1;
  88
+reg r0_dfi_cke_p1;
  89
+reg r0_dfi_ras_n_p1;
  90
+reg r0_dfi_cas_n_p1;
  91
+reg r0_dfi_we_n_p1;
  92
+	
  93
+always @(posedge sys_clk) begin
  94
+	r0_dfi_address_p0 <= dfi_address_p0;
  95
+	r0_dfi_bank_p0 <= dfi_bank_p0;
  96
+	r0_dfi_cs_n_p0 <= dfi_cs_n_p0;
  97
+	r0_dfi_cke_p0 <= dfi_cke_p0;
  98
+	r0_dfi_ras_n_p0 <= dfi_ras_n_p0;
  99
+	r0_dfi_cas_n_p0 <= dfi_cas_n_p0;
  100
+	r0_dfi_we_n_p0 <= dfi_we_n_p0;
  101
+	
  102
+	r0_dfi_address_p1 <= dfi_address_p1;
  103
+	r0_dfi_bank_p1 <= dfi_bank_p1;
  104
+	r0_dfi_cs_n_p1 <= dfi_cs_n_p1;
  105
+	r0_dfi_cke_p1 <= dfi_cke_p1;
  106
+	r0_dfi_ras_n_p1 <= dfi_ras_n_p1;
  107
+	r0_dfi_cas_n_p1 <= dfi_cas_n_p1;
  108
+	r0_dfi_we_n_p1 <= dfi_we_n_p1;
  109
+end
  110
+
78 111
 reg phase_sel;
79 112
 always @(posedge clk2x_270)
80 113
 	phase_sel <= sys_clk;
@@ -95,21 +128,21 @@ reg r_dfi_cas_n_p1;
95 128
 reg r_dfi_we_n_p1;
96 129
 	
97 130
 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;
  131
+	r_dfi_address_p0 <= r0_dfi_address_p0;
  132
+	r_dfi_bank_p0 <= r0_dfi_bank_p0;
  133
+	r_dfi_cs_n_p0 <= r0_dfi_cs_n_p0;
  134
+	r_dfi_cke_p0 <= r0_dfi_cke_p0;
  135
+	r_dfi_ras_n_p0 <= r0_dfi_ras_n_p0;
  136
+	r_dfi_cas_n_p0 <= r0_dfi_cas_n_p0;
  137
+	r_dfi_we_n_p0 <= r0_dfi_we_n_p0;
105 138
 	
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;
  139
+	r_dfi_address_p1 <= r0_dfi_address_p1;
  140
+	r_dfi_bank_p1 <= r0_dfi_bank_p1;
  141
+	r_dfi_cs_n_p1 <= r0_dfi_cs_n_p1;
  142
+	r_dfi_cke_p1 <= r0_dfi_cke_p1;
  143
+	r_dfi_ras_n_p1 <= r0_dfi_ras_n_p1;
  144
+	r_dfi_cas_n_p1 <= r0_dfi_cas_n_p1;
  145
+	r_dfi_we_n_p1 <= r0_dfi_we_n_p1;
113 146
 end
114 147
 
115 148
 always @(posedge clk2x_270) begin
@@ -334,10 +367,10 @@ end
334 367
 assign drive_dqs = r2_dfi_wrdata_en;
335 368
 
336 369
 wire rddata_valid;
337  
-reg [4:0] rddata_sr;
  370
+reg [5:0] rddata_sr;
338 371
 assign dfi_rddata_valid_w0 = rddata_sr[0];
339 372
 assign dfi_rddata_valid_w1 = rddata_sr[0];
340 373
 always @(posedge sys_clk)
341  
-	rddata_sr <= {dfi_rddata_en_p0, rddata_sr[4:1]};
  374
+	rddata_sr <= {dfi_rddata_en_p0, rddata_sr[5:1]};
342 375
 
343 376
 endmodule

No commit comments for this range

Something went wrong with that request. Please try again.