drtio: use additive scrambler reset by link init

This commit is contained in:
Sebastien Bourdeauducq 2016-09-27 11:38:05 +08:00
parent 8a92c2c7e5
commit e59142e344
2 changed files with 35 additions and 35 deletions

View File

@ -5,24 +5,6 @@ from migen import *
class Scrambler(Module): class Scrambler(Module):
def __init__(self, n_io, n_state=23, taps=[17, 22]):
self.i = Signal(n_io)
self.o = Signal(n_io)
# # #
state = Signal(n_state, reset=1)
curval = [state[i] for i in range(n_state)]
for i in reversed(range(n_io)):
out = self.i[i] ^ reduce(xor, [curval[tap] for tap in taps])
self.sync += self.o[i].eq(out)
curval.insert(0, out)
curval.pop()
self.sync += state.eq(Cat(*curval[:n_state]))
class Descrambler(Module):
def __init__(self, n_io, n_state=23, taps=[17, 22]): def __init__(self, n_io, n_state=23, taps=[17, 22]):
self.i = Signal(n_io) self.i = Signal(n_io)
self.o = Signal(n_io) self.o = Signal(n_io)
@ -33,8 +15,8 @@ class Descrambler(Module):
curval = [state[i] for i in range(n_state)] curval = [state[i] for i in range(n_state)]
for i in reversed(range(n_io)): for i in reversed(range(n_io)):
flip = reduce(xor, [curval[tap] for tap in taps]) flip = reduce(xor, [curval[tap] for tap in taps])
self.sync += self.o[i].eq(self.i[i] ^ flip) self.sync += self.o[i].eq(flip ^ self.i[i])
curval.insert(0, self.i[i]) curval.insert(0, flip)
curval.pop() curval.pop()
self.sync += state.eq(Cat(*curval[:n_state])) self.sync += state.eq(Cat(*curval[:n_state]))
@ -70,7 +52,7 @@ class LinkLayerTX(Module):
# the following meanings: # the following meanings:
# 100 idle/auxiliary framing # 100 idle/auxiliary framing
# 0AB 2 bits of auxiliary data # 0AB 2 bits of auxiliary data
aux_scrambler = CEInserter()(Scrambler(3*nwords)) aux_scrambler = ResetInserter()(CEInserter()(Scrambler(3*nwords)))
self.submodules += aux_scrambler self.submodules += aux_scrambler
aux_data_ctl = [] aux_data_ctl = []
for i in range(nwords): for i in range(nwords):
@ -82,6 +64,7 @@ class LinkLayerTX(Module):
).Else( ).Else(
aux_scrambler.i.eq(Replicate(0b100, nwords)) aux_scrambler.i.eq(Replicate(0b100, nwords))
), ),
aux_scrambler.reset.eq(self.link_init),
aux_scrambler.ce.eq(~self.rt_frame), aux_scrambler.ce.eq(~self.rt_frame),
self.aux_ack.eq(~self.rt_frame) self.aux_ack.eq(~self.rt_frame)
] ]
@ -98,10 +81,11 @@ class LinkLayerTX(Module):
# Real-time traffic uses data characters and is framed by the special # Real-time traffic uses data characters and is framed by the special
# characters of auxiliary traffic. RT traffic is also scrambled. # characters of auxiliary traffic. RT traffic is also scrambled.
rt_scrambler = CEInserter()(Scrambler(8*nwords)) rt_scrambler = ResetInserter()(CEInserter()(Scrambler(8*nwords)))
self.submodules += rt_scrambler self.submodules += rt_scrambler
self.comb += [ self.comb += [
rt_scrambler.i.eq(self.rt_data), rt_scrambler.i.eq(self.rt_data),
rt_scrambler.reset.eq(self.link_init),
rt_scrambler.ce.eq(self.rt_frame) rt_scrambler.ce.eq(self.rt_frame)
] ]
rt_frame_r = Signal() rt_frame_r = Signal()
@ -153,8 +137,8 @@ class LinkLayerRX(Module):
# # # # # #
aux_descrambler = CEInserter()(Descrambler(2*nwords)) aux_descrambler = ResetInserter()(CEInserter()(Scrambler(2*nwords)))
rt_descrambler = CEInserter()(Descrambler(8*nwords)) rt_descrambler = ResetInserter()(CEInserter()(Scrambler(8*nwords)))
self.submodules += aux_descrambler, rt_descrambler self.submodules += aux_descrambler, rt_descrambler
self.comb += [ self.comb += [
self.aux_frame.eq(~aux_descrambler.o[2]), self.aux_frame.eq(~aux_descrambler.o[2]),
@ -173,7 +157,9 @@ class LinkLayerRX(Module):
self.comb += [ self.comb += [
If(decoders[0].k, If(decoders[0].k,
If((decoders[0].d == K(28, 7)) | (decoders[0].d == K(29, 7)), If((decoders[0].d == K(28, 7)) | (decoders[0].d == K(29, 7)),
link_init_d.eq(1) link_init_d.eq(1),
aux_descrambler.reset.eq(1),
rt_descrambler.reset.eq(1)
), ),
aux_descrambler.ce.eq(1) aux_descrambler.ce.eq(1)
).Else( ).Else(

View File

@ -6,7 +6,8 @@ from migen import *
from artiq.gateware.drtio.link_layer import * from artiq.gateware.drtio.link_layer import *
def process(dut, seq): def process(seq):
dut = Scrambler(8)
rseq = [] rseq = []
def pump(): def pump():
yield dut.i.eq(seq[0]) yield dut.i.eq(seq[0])
@ -24,17 +25,11 @@ def process(dut, seq):
class TestScrambler(unittest.TestCase): class TestScrambler(unittest.TestCase):
def test_roundtrip(self): def test_roundtrip(self):
seq = list(range(256))*3 seq = list(range(256))*3
scrambled_seq = process(Scrambler(8), seq) scrambled_seq = process(seq)
descrambled_seq = process(Descrambler(8), scrambled_seq) descrambled_seq = process(scrambled_seq)
self.assertNotEqual(seq, scrambled_seq) self.assertNotEqual(seq, scrambled_seq)
self.assertEqual(seq, descrambled_seq) self.assertEqual(seq, descrambled_seq)
def test_resync(self):
seq = list(range(256))
scrambled_seq = process(Scrambler(8), seq)
descrambled_seq = process(Descrambler(8), scrambled_seq[20:])
self.assertEqual(seq[100:], descrambled_seq[80:])
class Loopback(Module): class Loopback(Module):
def __init__(self, nwords): def __init__(self, nwords):
@ -50,12 +45,24 @@ class TestLinkLayer(unittest.TestCase):
def test_packets(self): def test_packets(self):
dut = Loopback(4) dut = Loopback(4)
def link_init():
yield dut.tx.link_init.eq(1)
yield
yield
yield dut.tx.link_init.eq(0)
yield
rt_packets = [ rt_packets = [
[0x12459970, 0x9938cdef, 0x12340000], [0x12459970, 0x9938cdef, 0x12340000],
[0xabcdef00, 0x12345678], [0xabcdef00, 0x12345678],
[0xeeeeeeee, 0xffffffff, 0x01020304, 0x11223344] [0xeeeeeeee, 0xffffffff, 0x01020304, 0x11223344]
] ]
def transmit_rt_packets(): def transmit_rt_packets():
while not (yield dut.tx.link_init):
yield
while (yield dut.tx.link_init):
yield
for packet in rt_packets: for packet in rt_packets:
yield dut.tx.rt_frame.eq(1) yield dut.tx.rt_frame.eq(1)
for data in packet: for data in packet:
@ -70,6 +77,11 @@ class TestLinkLayer(unittest.TestCase):
rx_rt_packets = [] rx_rt_packets = []
@passive @passive
def receive_rt_packets(): def receive_rt_packets():
while not (yield dut.tx.link_init):
yield
while (yield dut.tx.link_init):
yield
while True: while True:
packet = [] packet = []
rx_rt_packets.append(packet) rx_rt_packets.append(packet)
@ -78,7 +90,9 @@ class TestLinkLayer(unittest.TestCase):
while (yield dut.rx.rt_frame): while (yield dut.rx.rt_frame):
packet.append((yield dut.rx.rt_data)) packet.append((yield dut.rx.rt_data))
yield yield
run_simulation(dut, [transmit_rt_packets(), receive_rt_packets()])
run_simulation(dut, [link_init(),
transmit_rt_packets(), receive_rt_packets()])
for packet in rx_rt_packets: for packet in rx_rt_packets:
print(" ".join("{:08x}".format(x) for x in packet)) print(" ".join("{:08x}".format(x) for x in packet))