from milkymist.dvisampler.clocking import Clocking
from milkymist.dvisampler.datacapture import DataCapture
from milkymist.dvisampler.charsync import CharSync
+from milkymist.dvisampler.wer import WER
from milkymist.dvisampler.decoding import Decoding
from milkymist.dvisampler.chansync import ChanSync
from milkymist.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
setattr(self.submodules, name + "_charsync", charsync)
self.comb += charsync.raw_data.eq(cap.d)
+ wer = WER()
+ setattr(self.submodules, name + "_wer", wer)
+ self.comb += wer.data.eq(charsync.data)
+
decoding = Decoding()
setattr(self.submodules, name + "_decod", decoding)
self.comb += [
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.bank.description import *
+from migen.genlib.misc import optree
+from migen.genlib.cdc import PulseSynchronizer
+
+from milkymist.dvisampler.common import control_tokens
+
+class WER(Module, AutoCSR):
+ def __init__(self, period_bits=24):
+ self.data = Signal(10)
+ self._r_update = CSR()
+ self._r_value = CSRStatus(period_bits)
+
+ ###
+
+ # pipeline stage 1
+ # we ignore the 10th (inversion) bit, as it is independent of the transition minimization
+ data_r = Signal(9)
+ self.sync.pix += data_r.eq(self.data[:9])
+
+ # pipeline stage 2
+ transitions = Signal(8)
+ self.comb += [transitions[i].eq(data_r[i] ^ data_r[i+1]) for i in range(8)]
+ transition_count = Signal(max=9)
+ self.sync.pix += transition_count.eq(optree("+", [transitions[i] for i in range(8)]))
+
+ is_control = Signal()
+ self.sync.pix += is_control.eq(optree("|", [data_r == ct for ct in control_tokens]))
+
+ # pipeline stage 3
+ is_error = Signal()
+ self.sync.pix += is_error.eq((transition_count > 4) & ~is_control)
+
+ # counter
+ period_counter = Signal(period_bits)
+ period_done = Signal()
+ self.sync.pix += Cat(period_counter, period_done).eq(period_counter + 1)
+
+ wer_counter = Signal(period_bits)
+ wer_counter_r = Signal(period_bits)
+ wer_counter_r_updated = Signal()
+ self.sync.pix += [
+ wer_counter_r_updated.eq(period_done),
+ If(period_done,
+ wer_counter_r.eq(wer_counter),
+ wer_counter.eq(0)
+ ).Elif(is_error,
+ wer_counter.eq(wer_counter + 1)
+ )
+ ]
+
+ # sync to system clock domain
+ wer_counter_sys = Signal(period_bits)
+ self.submodules.ps_counter = PulseSynchronizer("pix", "sys")
+ self.comb += self.ps_counter.i.eq(wer_counter_r_updated)
+ self.sync += If(self.ps_counter.o, wer_counter_sys.eq(wer_counter_r))
+
+ # register interface
+ self.sync += If(self._r_update.re, self._r_value.status.eq(wer_counter_sys))
void dvisamplerX_print_status(void)
{
- printf("dvisamplerX: ph:%4d %4d %4d // charsync:%d%d%d [%d %d %d] // chansync:%d // res:%dx%d\n",
+ dvisamplerX_data0_wer_update_write(1);
+ dvisamplerX_data1_wer_update_write(1);
+ dvisamplerX_data2_wer_update_write(1);
+ printf("dvisamplerX: ph:%4d %4d %4d // charsync:%d%d%d [%d %d %d] // WER:%3d %3d %3d // chansync:%d // res:%dx%d\n",
dvisamplerX_d0, dvisamplerX_d1, dvisamplerX_d2,
dvisamplerX_data0_charsync_char_synced_read(),
dvisamplerX_data1_charsync_char_synced_read(),
dvisamplerX_data0_charsync_ctl_pos_read(),
dvisamplerX_data1_charsync_ctl_pos_read(),
dvisamplerX_data2_charsync_ctl_pos_read(),
+ dvisamplerX_data0_wer_value_read(),
+ dvisamplerX_data1_wer_value_read(),
+ dvisamplerX_data2_wer_value_read(),
dvisamplerX_chansync_channels_synced_read(),
dvisamplerX_resdetection_hres_read(),
dvisamplerX_resdetection_vres_read());