1 from migen
.fhdl
.std
import *
2 from migen
.genlib
.cdc
import MultiReg
3 from migen
.genlib
.fifo
import _inc
4 from migen
.genlib
.record
import Record
, layout_len
5 from migen
.genlib
.misc
import optree
6 from migen
.bank
.description
import *
8 from milkymist
.dvisampler
.common
import channel_layout
10 class _SyncBuffer(Module
):
11 def __init__(self
, width
, depth
):
12 self
.din
= Signal(width
)
13 self
.dout
= Signal(width
)
18 produce
= Signal(max=depth
)
19 consume
= Signal(max=depth
)
20 storage
= Memory(width
, depth
)
21 self
.specials
+= storage
23 wrport
= storage
.get_port(write_capable
=True)
24 self
.specials
+= wrport
26 wrport
.adr
.eq(produce
),
27 wrport
.dat_w
.eq(self
.din
),
30 self
.sync
+= _inc(produce
, depth
)
32 rdport
= storage
.get_port(async_read
=True)
33 self
.specials
+= rdport
35 rdport
.adr
.eq(consume
),
36 self
.dout
.eq(rdport
.dat_r
)
38 self
.sync
+= If(self
.re
, _inc(consume
, depth
))
40 class ChanSync(Module
, AutoCSR
):
41 def __init__(self
, nchan
=3, depth
=8):
42 self
.valid_i
= Signal()
43 self
.chan_synced
= Signal()
45 self
._r
_channels
_synced
= CSRStatus()
48 all_control
= Signal()
49 for i
in range(nchan
):
50 name
= "data_in" + str(i
)
51 data_in
= Record(channel_layout
, name
=name
)
52 setattr(self
, name
, data_in
)
53 name
= "data_out" + str(i
)
54 data_out
= Record(channel_layout
, name
=name
)
55 setattr(self
, name
, data_out
)
59 syncbuffer
= _SyncBuffer(layout_len(channel_layout
), depth
)
60 self
.add_submodule(syncbuffer
, "pix")
62 syncbuffer
.din
.eq(data_in
.raw_bits()),
63 data_out
.raw_bits().eq(syncbuffer
.dout
)
67 is_control
.eq(~data_out
.de
),
68 syncbuffer
.re
.eq(~is_control | all_control
)
70 lst_control
.append(is_control
)
72 some_control
= Signal()
74 all_control
.eq(optree("&", lst_control
)),
75 some_control
.eq(optree("|", lst_control
))
77 self
.sync
.pix
+= If(~self
.valid_i
,
78 self
.chan_synced
.eq(0)
82 self
.chan_synced
.eq(1)
84 self
.chan_synced
.eq(0)
88 self
.specials
+= MultiReg(self
.chan_synced
, self
._r
_channels
_synced
.status
)