lfsr: Update testbenches to use cocotb.parametrize

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-08-15 13:50:34 -07:00
parent ca26a48a28
commit 3aea897d9e
6 changed files with 151 additions and 167 deletions

View File

@@ -12,14 +12,12 @@ Authors:
import itertools
import logging
import os
import zlib
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.triggers import Timer
from cocotb.regression import TestFactory
class TB:
@@ -84,6 +82,46 @@ def crc32c(data, crc=0xffffffff, poly=0x82f63b78):
return ~crc & 0xffffffff
def prbs9(state=0x1ff):
while True:
for i in range(8):
if bool(state & 0x10) ^ bool(state & 0x100):
state = ((state & 0xff) << 1) | 1
else:
state = (state & 0xff) << 1
yield ~state & 0xff
def prbs31(state=0x7fffffff):
while True:
for i in range(8):
if bool(state & 0x08000000) ^ bool(state & 0x40000000):
state = ((state & 0x3fffffff) << 1) | 1
else:
state = (state & 0x3fffffff) << 1
yield ~state & 0xff
ref_crc = None
ref_prbs = None
if getattr(cocotb, 'top', None) is not None:
if cocotb.top.LFSR_POLY.value == 0x4c11db7:
if cocotb.top.STATE_SHIFT_PRE.value == 0:
ref_crc = crc32
else:
pass
if cocotb.top.LFSR_POLY.value == 0x1edc6f41:
ref_crc = crc32c
if cocotb.top.LFSR_POLY.value == 0x021:
ref_prbs = prbs9
if cocotb.top.LFSR_POLY.value == 0x10000001:
ref_prbs = prbs31
@cocotb.test(skip=(ref_crc is None))
@cocotb.parametrize(
("ref_crc", [ref_crc]),
)
async def run_test_crc(dut, ref_crc):
data_width = len(dut.data_in)
@@ -129,26 +167,10 @@ async def run_test_crc(dut, ref_crc):
await Timer(10, 'ns')
def prbs9(state=0x1ff):
while True:
for i in range(8):
if bool(state & 0x10) ^ bool(state & 0x100):
state = ((state & 0xff) << 1) | 1
else:
state = (state & 0xff) << 1
yield ~state & 0xff
def prbs31(state=0x7fffffff):
while True:
for i in range(8):
if bool(state & 0x08000000) ^ bool(state & 0x40000000):
state = ((state & 0x3fffffff) << 1) | 1
else:
state = (state & 0x3fffffff) << 1
yield ~state & 0xff
@cocotb.test(skip=(ref_prbs is None))
@cocotb.parametrize(
("ref_prbs", [ref_prbs]),
)
async def run_test_prbs(dut, ref_prbs):
data_width = len(dut.data_in)
@@ -181,6 +203,7 @@ async def run_test_prbs(dut, ref_prbs):
await Timer(10, 'ns')
@cocotb.test(skip=(ref_crc is not None or ref_prbs is not None))
async def run_test_shift_crc(dut):
data_width = len(dut.data_in)
@@ -230,33 +253,6 @@ async def run_test_shift_crc(dut):
await Timer(10, 'ns')
if getattr(cocotb, 'top', None) is not None:
if cocotb.top.LFSR_POLY.value == 0x4c11db7:
if cocotb.top.STATE_SHIFT_PRE.value == 0:
factory = TestFactory(run_test_crc)
factory.add_option("ref_crc", [crc32])
factory.generate_tests()
else:
factory = TestFactory(run_test_shift_crc)
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x1edc6f41:
factory = TestFactory(run_test_crc)
factory.add_option("ref_crc", [crc32c])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x021:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs9])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x10000001:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs31])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))

View File

@@ -20,7 +20,6 @@ import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.regression import TestFactory
class TB:
@@ -66,6 +65,18 @@ def crc32c(data, crc=0xffffffff, poly=0x82f63b78):
return ~crc & 0xffffffff
ref_crc = None
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x4c11db7:
ref_crc = crc32
if int(cocotb.top.LFSR_POLY.value) == 0x1edc6f41:
ref_crc = crc32c
@cocotb.test()
@cocotb.parametrize(
("ref_crc", [ref_crc]),
)
async def run_test_crc(dut, ref_crc):
data_width = len(dut.data_in)
@@ -112,19 +123,6 @@ async def run_test_crc(dut, ref_crc):
await RisingEdge(dut.clk)
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x4c11db7:
factory = TestFactory(run_test_crc)
factory.add_option("ref_crc", [crc32])
factory.generate_tests()
if int(cocotb.top.LFSR_POLY.value) == 0x1edc6f41:
factory = TestFactory(run_test_crc)
factory.add_option("ref_crc", [crc32c])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))

View File

@@ -19,7 +19,6 @@ import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.regression import TestFactory
class TB:
@@ -72,7 +71,7 @@ def descramble_64b66b(data, state=0x3ffffffffffffff):
if bool(state & (1 << 38)) ^ bool(state & (1 << 57)) ^ bool(d & (1 << i)):
b = b | (1 << i)
state = (state & 0x1ffffffffffffff) << 1 | bool(d & (1 << i))
data_out += bytearray([b])
data_out.append(b)
return data_out
@@ -104,6 +103,26 @@ def scramble_pcie_gen3(data, state=0x1efedc, poly=0x524042):
return data_out
ref_scramble = None
ref_descramble = None
if getattr(cocotb, 'top', None) is not None:
# if cocotb.top.LFSR_POLY.value == 0x8000000001:
if int(cocotb.top.LFSR_W.value) == 58:
ref_scramble = scramble_64b66b
ref_descramble = descramble_64b66b
if cocotb.top.LFSR_POLY.value == 0x0039:
ref_scramble = scramble_pcie
ref_descramble = scramble_pcie
if cocotb.top.LFSR_POLY.value == 0x210125:
ref_scramble = scramble_pcie_gen3
ref_descramble = scramble_pcie_gen3
@cocotb.test()
@cocotb.parametrize(
("ref_scramble", [ref_scramble]),
("ref_descramble", [ref_descramble]),
)
async def run_test_descramble(dut, ref_scramble, ref_descramble):
data_width = len(dut.data_in)
@@ -145,25 +164,6 @@ async def run_test_descramble(dut, ref_scramble, ref_descramble):
await RisingEdge(dut.clk)
if getattr(cocotb, 'top', None) is not None:
# if cocotb.top.LFSR_POLY.value == 0x8000000001:
if int(cocotb.top.LFSR_W.value) == 58:
factory = TestFactory(run_test_descramble)
factory.add_option(("ref_scramble", "ref_descramble"), [(scramble_64b66b, descramble_64b66b)])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x0039:
factory = TestFactory(run_test_descramble)
factory.add_option(("ref_scramble", "ref_descramble"), [(scramble_pcie, scramble_pcie)])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x210125:
factory = TestFactory(run_test_descramble)
factory.add_option(("ref_scramble", "ref_descramble"), [(scramble_pcie_gen3, scramble_pcie_gen3)])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))

View File

@@ -19,7 +19,6 @@ import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.regression import TestFactory
class TB:
@@ -78,6 +77,18 @@ def count_set_bits(n):
return cnt
ref_prbs = None
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x021:
ref_prbs = prbs9
if int(cocotb.top.LFSR_POLY.value) == 0x10000001:
ref_prbs = prbs31
@cocotb.test()
@cocotb.parametrize(
("ref_prbs", [ref_prbs]),
)
async def run_test_prbs(dut, ref_prbs):
data_width = len(dut.data_out)
@@ -146,19 +157,6 @@ async def run_test_prbs(dut, ref_prbs):
assert err_cnt == 3
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x021:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs9])
factory.generate_tests()
if int(cocotb.top.LFSR_POLY.value) == 0x10000001:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs31])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))

View File

@@ -19,7 +19,6 @@ import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.regression import TestFactory
class TB:
@@ -69,31 +68,6 @@ def prbs31(state=0x7fffffff):
yield ~state & 0xff
async def run_test_prbs(dut, ref_prbs):
data_width = len(dut.data_out)
byte_lanes = data_width // 8
tb = TB(dut)
await tb.reset()
gen = chunks(ref_prbs(), byte_lanes)
dut.enable.value = 1
await RisingEdge(dut.clk)
for i in range(512):
ref = int.from_bytes(bytes(next(gen)), 'big')
val = int(dut.data_out.value)
tb.log.info("PRBS: 0x%x (ref: 0x%x)", val, ref)
assert ref == val
await RisingEdge(dut.clk)
def scramble_pcie(data, state=0xffff, poly=0x9c00):
data_out = bytearray()
for d in data:
@@ -122,6 +96,52 @@ def scramble_pcie_gen3(data, state=0x1efedc, poly=0x524042):
return data_out
ref_prbs = None
ref_scramble = None
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x021:
ref_prbs = prbs9
if int(cocotb.top.LFSR_POLY.value) == 0x10000001:
ref_prbs = prbs31
if cocotb.top.LFSR_POLY.value == 0x0039:
ref_scramble = scramble_pcie
if cocotb.top.LFSR_POLY.value == 0x210125:
ref_scramble = scramble_pcie_gen3
@cocotb.test(skip=(ref_prbs is None))
@cocotb.parametrize(
("ref_prbs", [ref_prbs]),
)
async def run_test_prbs(dut, ref_prbs):
data_width = len(dut.data_out)
byte_lanes = data_width // 8
tb = TB(dut)
await tb.reset()
gen = chunks(ref_prbs(), byte_lanes)
dut.enable.value = 1
await RisingEdge(dut.clk)
for i in range(512):
ref = int.from_bytes(bytes(next(gen)), 'big')
val = int(dut.data_out.value)
tb.log.info("PRBS: 0x%x (ref: 0x%x)", val, ref)
assert ref == val
await RisingEdge(dut.clk)
@cocotb.test(skip=(ref_scramble is None))
@cocotb.parametrize(
("ref_scramble", [ref_scramble]),
)
async def run_test_scramble(dut, ref_scramble):
data_width = len(dut.data_out)
@@ -150,29 +170,6 @@ async def run_test_scramble(dut, ref_scramble):
await RisingEdge(dut.clk)
if getattr(cocotb, 'top', None) is not None:
if int(cocotb.top.LFSR_POLY.value) == 0x021:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs9])
factory.generate_tests()
if int(cocotb.top.LFSR_POLY.value) == 0x10000001:
factory = TestFactory(run_test_prbs)
factory.add_option("ref_prbs", [prbs31])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x0039:
factory = TestFactory(run_test_scramble)
factory.add_option("ref_scramble", [scramble_pcie])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x210125:
factory = TestFactory(run_test_scramble)
factory.add_option("ref_scramble", [scramble_pcie_gen3])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))

View File

@@ -19,7 +19,6 @@ import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
from cocotb.regression import TestFactory
class TB:
@@ -92,6 +91,21 @@ def scramble_pcie_gen3(data, state=0x1efedc, poly=0x524042):
return data_out
ref_scramble = None
if getattr(cocotb, 'top', None) is not None:
# if cocotb.top.LFSR_POLY.value == 0x8000000001:
if int(cocotb.top.LFSR_W.value) == 58:
ref_scramble = scramble_64b66b
if cocotb.top.LFSR_POLY.value == 0x0039:
ref_scramble = scramble_pcie
if cocotb.top.LFSR_POLY.value == 0x210125:
ref_scramble = scramble_pcie_gen3
@cocotb.test()
@cocotb.parametrize(
("ref_scramble", [ref_scramble]),
)
async def run_test_scramble(dut, ref_scramble):
data_width = len(dut.data_in)
@@ -128,25 +142,6 @@ async def run_test_scramble(dut, ref_scramble):
await RisingEdge(dut.clk)
if getattr(cocotb, 'top', None) is not None:
# if cocotb.top.LFSR_POLY.value == 0x8000000001:
if int(cocotb.top.LFSR_W.value) == 58:
factory = TestFactory(run_test_scramble)
factory.add_option("ref_scramble", [scramble_64b66b])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x0039:
factory = TestFactory(run_test_scramble)
factory.add_option("ref_scramble", [scramble_pcie])
factory.generate_tests()
if cocotb.top.LFSR_POLY.value == 0x210125:
factory = TestFactory(run_test_scramble)
factory.add_option("ref_scramble", [scramble_pcie_gen3])
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))