ethernet/tb/scramble.py

56 lines
1.4 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-Only
# Copyright (C) 2022 Sean Anderson <seanga2@gmail.com>
import itertools
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import FallingEdge, RisingEdge, Timer
from .util import alist, ReverseList, print_list_at, compare_lists
threshold = 32
async def descramble(scrambled):
consecutive = 0
locked = False
lfsr = ReverseList([0] * 11)
async for s in scrambled:
ldd = lfsr[8] ^ lfsr[10]
if s ^ ldd:
consecutive += 1
else:
consecutive = 0
if consecutive >= threshold:
locked = True
if locked:
yield s ^ ldd
lfsr.append(ldd)
else:
lfsr.append(0 if s else 1)
@cocotb.test(timeout_time=10, timeout_unit='us')
async def test_scramble(scrambler):
scrambler.unscrambled.value = 1
await Timer(1)
await cocotb.start(Clock(scrambler.clk, 8, units='ns').start())
idles = threshold + 10
ins = [1] * idles + [0] + [random.randrange(2) for _ in range(1000)]
async def send():
for bit in ins:
await FallingEdge(scrambler.clk)
scrambler.unscrambled.value = bit
await cocotb.start(send())
async def recv():
for _ in ins:
await RisingEdge(scrambler.clk)
yield scrambler.scrambled.value
compare_lists(ins[idles-1:], await alist(descramble(recv())))