Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 2 files changed
  • 0 comments
  • 1 contributor
62  milkymist/dvisampler/chansync.py
... ...
@@ -1,13 +1,42 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
2 3
 from migen.fhdl.module import Module
3 4
 from migen.genlib.cdc import MultiReg
4  
-from migen.genlib.fifo import SyncFIFO
  5
+from migen.genlib.fifo import _inc
5 6
 from migen.genlib.record import Record, layout_len
6 7
 from migen.genlib.misc import optree
7 8
 from migen.bank.description import *
8 9
 
9 10
 from milkymist.dvisampler.common import channel_layout
10 11
 
  12
+class _SyncBuffer(Module):
  13
+	def __init__(self, width, depth):
  14
+		self.din = Signal(width)
  15
+		self.dout = Signal(width)
  16
+		self.re = Signal()
  17
+
  18
+		###
  19
+
  20
+		produce = Signal(max=depth)
  21
+		consume = Signal(max=depth)
  22
+		storage = Memory(width, depth)
  23
+		self.specials += storage
  24
+
  25
+		wrport = storage.get_port(write_capable=True)
  26
+		self.comb += [
  27
+			wrport.adr.eq(produce),
  28
+			wrport.dat_w.eq(self.din),
  29
+			wrport.we.eq(1)
  30
+		]
  31
+		self.sync += _inc(produce, depth)
  32
+
  33
+		rdport = storage.get_port(async_read=True)
  34
+		self.comb += [
  35
+			rdport.adr.eq(consume),
  36
+			self.dout.eq(rdport.dat_r)
  37
+		]
  38
+		self.sync += If(self.re, _inc(consume, depth))
  39
+
11 40
 class ChanSync(Module, AutoCSR):
12 41
 	def __init__(self, nchan=3, depth=8):
13 42
 		self.valid_i = Signal()
@@ -15,8 +44,8 @@ def __init__(self, nchan=3, depth=8):
15 44
 
16 45
 		self._r_channels_synced = CSRStatus()
17 46
 
18  
-		lst_control_starts = []
19  
-		all_control_starts = Signal()
  47
+		lst_control = []
  48
+		all_control = Signal()
20 49
 		for i in range(nchan):
21 50
 			name = "data_in" + str(i)
22 51
 			data_in = Record(channel_layout, name=name)
@@ -27,34 +56,29 @@ def __init__(self, nchan=3, depth=8):
27 56
 
28 57
 			###
29 58
 		
30  
-			fifo = SyncFIFO(layout_len(channel_layout), depth)
31  
-			self.add_submodule(fifo, "pix")
  59
+			syncbuffer = _SyncBuffer(layout_len(channel_layout), depth)
  60
+			self.add_submodule(syncbuffer, "pix")
32 61
 			self.comb += [
33  
-				fifo.we.eq(self.valid_i),
34  
-				fifo.din.eq(data_in.raw_bits()),
35  
-				data_out.raw_bits().eq(fifo.dout)
  62
+				syncbuffer.din.eq(data_in.raw_bits()),
  63
+				data_out.raw_bits().eq(syncbuffer.dout)
36 64
 			]
37 65
 			is_control = Signal()
38  
-			is_control_r = Signal()
39  
-			self.sync.pix += If(fifo.readable & fifo.re, is_control_r.eq(is_control))
40  
-			control_starts = Signal()
41 66
 			self.comb += [
42 67
 				is_control.eq(~data_out.de),
43  
-				control_starts.eq(is_control & ~is_control_r),
44  
-				fifo.re.eq(~is_control | all_control_starts)
  68
+				syncbuffer.re.eq(~is_control | all_control)
45 69
 			]
46  
-			lst_control_starts.append(control_starts)
  70
+			lst_control.append(is_control)
47 71
 
48  
-		some_control_starts = Signal()
  72
+		some_control = Signal()
49 73
 		self.comb += [
50  
-			all_control_starts.eq(optree("&", lst_control_starts)),
51  
-			some_control_starts.eq(optree("|", lst_control_starts))
  74
+			all_control.eq(optree("&", lst_control)),
  75
+			some_control.eq(optree("|", lst_control))
52 76
 		]
53 77
 		self.sync.pix += If(~self.valid_i,
54 78
 				self.chan_synced.eq(0)
55 79
 			).Else(
56  
-				If(some_control_starts,
57  
-					If(all_control_starts,
  80
+				If(some_control,
  81
+					If(all_control,
58 82
 						self.chan_synced.eq(1)
59 83
 					).Else(
60 84
 						self.chan_synced.eq(0)
48  tb/dvisampler/chansync.py
... ...
@@ -0,0 +1,48 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.fhdl.module import Module
  3
+from migen.sim.generic import *
  4
+
  5
+from milkymist.dvisampler.chansync import ChanSync
  6
+
  7
+class TB(Module):
  8
+	def __init__(self, test_seq_it):
  9
+		self.test_seq_it = test_seq_it
  10
+
  11
+		self.chansync = ChanSync()
  12
+		self.add_submodule(self.chansync, {"pix": "sys"})
  13
+		self.comb += self.chansync.valid_i.eq(1)
  14
+
  15
+	def do_simulation(self, s):
  16
+		try:
  17
+			de0, de1, de2 = next(self.test_seq_it)
  18
+		except StopIteration:
  19
+			s.interrupt = True
  20
+			return
  21
+
  22
+		s.wr(self.chansync.data_in0.de, de0)
  23
+		s.wr(self.chansync.data_in1.de, de1)
  24
+		s.wr(self.chansync.data_in2.de, de2)
  25
+		s.wr(self.chansync.data_in0.d, s.cycle_counter)
  26
+		s.wr(self.chansync.data_in1.d, s.cycle_counter)
  27
+		s.wr(self.chansync.data_in2.d, s.cycle_counter)
  28
+
  29
+		out0 = s.rd(self.chansync.data_out0.d)
  30
+		out1 = s.rd(self.chansync.data_out1.d)
  31
+		out2 = s.rd(self.chansync.data_out2.d)
  32
+
  33
+		print("{0:5} {1:5} {2:5}".format(out0, out1, out2))
  34
+
  35
+def main():
  36
+	test_seq = [
  37
+		(1, 1, 1),
  38
+		(1, 1, 0),
  39
+		(0, 0, 0),
  40
+		(0, 0, 0),
  41
+		(0, 0, 1),
  42
+		(1, 1, 1),
  43
+		(1, 1, 1),
  44
+	]
  45
+	tb = TB(iter(test_seq*2))
  46
+	Simulator(tb).run()
  47
+
  48
+main()

No commit comments for this range

Something went wrong with that request. Please try again.