Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 91 additions and 19 deletions.
  1. +43 −19 milkymist/dvisampler/chansync.py
  2. +48 −0 tb/dvisampler/chansync.py
View
62 milkymist/dvisampler/chansync.py
@@ -1,13 +1,42 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.fhdl.module import Module
from migen.genlib.cdc import MultiReg
-from migen.genlib.fifo import SyncFIFO
+from migen.genlib.fifo import _inc
from migen.genlib.record import Record, layout_len
from migen.genlib.misc import optree
from migen.bank.description import *
from milkymist.dvisampler.common import channel_layout
+class _SyncBuffer(Module):
+ def __init__(self, width, depth):
+ self.din = Signal(width)
+ self.dout = Signal(width)
+ self.re = Signal()
+
+ ###
+
+ produce = Signal(max=depth)
+ consume = Signal(max=depth)
+ storage = Memory(width, depth)
+ self.specials += storage
+
+ wrport = storage.get_port(write_capable=True)
+ self.comb += [
+ wrport.adr.eq(produce),
+ wrport.dat_w.eq(self.din),
+ wrport.we.eq(1)
+ ]
+ self.sync += _inc(produce, depth)
+
+ rdport = storage.get_port(async_read=True)
+ self.comb += [
+ rdport.adr.eq(consume),
+ self.dout.eq(rdport.dat_r)
+ ]
+ self.sync += If(self.re, _inc(consume, depth))
+
class ChanSync(Module, AutoCSR):
def __init__(self, nchan=3, depth=8):
self.valid_i = Signal()
@@ -15,8 +44,8 @@ def __init__(self, nchan=3, depth=8):
self._r_channels_synced = CSRStatus()
- lst_control_starts = []
- all_control_starts = Signal()
+ lst_control = []
+ all_control = Signal()
for i in range(nchan):
name = "data_in" + str(i)
data_in = Record(channel_layout, name=name)
@@ -27,34 +56,29 @@ def __init__(self, nchan=3, depth=8):
###
- fifo = SyncFIFO(layout_len(channel_layout), depth)
- self.add_submodule(fifo, "pix")
+ syncbuffer = _SyncBuffer(layout_len(channel_layout), depth)
+ self.add_submodule(syncbuffer, "pix")
self.comb += [
- fifo.we.eq(self.valid_i),
- fifo.din.eq(data_in.raw_bits()),
- data_out.raw_bits().eq(fifo.dout)
+ syncbuffer.din.eq(data_in.raw_bits()),
+ data_out.raw_bits().eq(syncbuffer.dout)
]
is_control = Signal()
- is_control_r = Signal()
- self.sync.pix += If(fifo.readable & fifo.re, is_control_r.eq(is_control))
- control_starts = Signal()
self.comb += [
is_control.eq(~data_out.de),
- control_starts.eq(is_control & ~is_control_r),
- fifo.re.eq(~is_control | all_control_starts)
+ syncbuffer.re.eq(~is_control | all_control)
]
- lst_control_starts.append(control_starts)
+ lst_control.append(is_control)
- some_control_starts = Signal()
+ some_control = Signal()
self.comb += [
- all_control_starts.eq(optree("&", lst_control_starts)),
- some_control_starts.eq(optree("|", lst_control_starts))
+ all_control.eq(optree("&", lst_control)),
+ some_control.eq(optree("|", lst_control))
]
self.sync.pix += If(~self.valid_i,
self.chan_synced.eq(0)
).Else(
- If(some_control_starts,
- If(all_control_starts,
+ If(some_control,
+ If(all_control,
self.chan_synced.eq(1)
).Else(
self.chan_synced.eq(0)
View
48 tb/dvisampler/chansync.py
@@ -0,0 +1,48 @@
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.sim.generic import *
+
+from milkymist.dvisampler.chansync import ChanSync
+
+class TB(Module):
+ def __init__(self, test_seq_it):
+ self.test_seq_it = test_seq_it
+
+ self.chansync = ChanSync()
+ self.add_submodule(self.chansync, {"pix": "sys"})
+ self.comb += self.chansync.valid_i.eq(1)
+
+ def do_simulation(self, s):
+ try:
+ de0, de1, de2 = next(self.test_seq_it)
+ except StopIteration:
+ s.interrupt = True
+ return
+
+ s.wr(self.chansync.data_in0.de, de0)
+ s.wr(self.chansync.data_in1.de, de1)
+ s.wr(self.chansync.data_in2.de, de2)
+ s.wr(self.chansync.data_in0.d, s.cycle_counter)
+ s.wr(self.chansync.data_in1.d, s.cycle_counter)
+ s.wr(self.chansync.data_in2.d, s.cycle_counter)
+
+ out0 = s.rd(self.chansync.data_out0.d)
+ out1 = s.rd(self.chansync.data_out1.d)
+ out2 = s.rd(self.chansync.data_out2.d)
+
+ print("{0:5} {1:5} {2:5}".format(out0, out1, out2))
+
+def main():
+ test_seq = [
+ (1, 1, 1),
+ (1, 1, 0),
+ (0, 0, 0),
+ (0, 0, 0),
+ (0, 0, 1),
+ (1, 1, 1),
+ (1, 1, 1),
+ ]
+ tb = TB(iter(test_seq*2))
+ Simulator(tb).run()
+
+main()

No commit comments for this range

Something went wrong with that request. Please try again.