diff --git a/test/test_axi.py b/test/test_axi.py index fbaf185..306d670 100755 --- a/test/test_axi.py +++ b/test/test_axi.py @@ -12,6 +12,89 @@ from litex.gen.sim import * class TestAXI(unittest.TestCase): + def test_burst2beat(self): + class Beat: + def __init__(self, addr): + self.addr = addr + + class Burst: + def __init__(self, type, addr, len, size): + self.type = type + self.addr = addr + self.len = len + self.size = size + + def to_beats(self): + r = [] + for i in range(self.len + 1): + if self.type == burst_types["incr"]: + offset = i*2**(self.size) + r += [Beat(self.addr + offset)] + elif self.type == burst_types["wrap"]: + offset = (i*2**(self.size))%((2**self.size)*(self.len)) + r += [Beat(self.addr + offset)] + else: + r += [Beat(self.addr)] + return r + + def bursts_generator(ax, bursts, valid_rand=50): + prng = random.Random(42) + for burst in bursts: + yield ax.valid.eq(1) + yield ax.addr.eq(burst.addr) + yield ax.burst.eq(burst.type) + yield ax.len.eq(burst.len) + yield ax.size.eq(burst.size) + while (yield ax.ready) == 0: + yield + yield ax.valid.eq(0) + while prng.randrange(100) < valid_rand: + yield + yield + + @passive + def beats_checker(ax, beats, ready_rand=50): + self.errors = 0 + yield ax.ready.eq(0) + prng = random.Random(42) + for beat in beats: + while ((yield ax.valid) and (yield ax.ready)) == 0: + if prng.randrange(100) > ready_rand: + yield ax.ready.eq(1) + else: + yield ax.ready.eq(0) + yield + ax_addr = (yield ax.addr) + if ax_addr != beat.addr: + self.errors += 1 + yield + + # dut + ax_burst = stream.Endpoint(ax_description(32, 32)) + ax_beat = stream.Endpoint(ax_description(32, 32)) + dut = LiteDRAMAXIBurst2Beat(ax_burst, ax_beat) + + # generate dut input (bursts) + prng = random.Random(42) + bursts = [] + for i in range(32): + bursts.append(Burst(burst_types["fixed"], prng.randrange(2**32), prng.randrange(255), log2_int(32//8))) + bursts.append(Burst(burst_types["incr"], prng.randrange(2**32), prng.randrange(255), log2_int(32//8))) + bursts.append(Burst(burst_types["wrap"], 4, 4-1, log2_int(2))) + + # generate expexted dut output (beats for reference) + beats = [] + for burst in bursts: + beats += burst.to_beats() + + # simulation + generators = [ + bursts_generator(ax_burst, bursts), + beats_checker(ax_beat, beats) + ] + run_simulation(dut, generators, vcd_name="burst2beat.vcd") + self.assertEqual(self.errors, 0) + def test_axi2native(self): class Access: def __init__(self, addr, data, id): @@ -128,86 +211,3 @@ class TestAXI(unittest.TestCase): self.assertEqual(self.reads_data_errors, 0) self.assertEqual(self.reads_id_errors, 0) self.assertEqual(self.reads_last_errors, 0) - - def test_burst2beat(self): - class Beat: - def __init__(self, addr): - self.addr = addr - - class Burst: - def __init__(self, type, addr, len, size): - self.type = type - self.addr = addr - self.len = len - self.size = size - - def to_beats(self): - r = [] - for i in range(self.len + 1): - if self.type == burst_types["incr"]: - offset = i*2**(self.size) - r += [Beat(self.addr + offset)] - elif self.type == burst_types["wrap"]: - offset = (i*2**(self.size))%((2**self.size)*(self.len)) - r += [Beat(self.addr + offset)] - else: - r += [Beat(self.addr)] - return r - - def bursts_generator(ax, bursts, valid_rand=50): - prng = random.Random(42) - for burst in bursts: - yield ax.valid.eq(1) - yield ax.addr.eq(burst.addr) - yield ax.burst.eq(burst.type) - yield ax.len.eq(burst.len) - yield ax.size.eq(burst.size) - while (yield ax.ready) == 0: - yield - yield ax.valid.eq(0) - while prng.randrange(100) < valid_rand: - yield - yield - - @passive - def beats_checker(ax, beats, ready_rand=50): - self.errors = 0 - yield ax.ready.eq(0) - prng = random.Random(42) - for beat in beats: - while ((yield ax.valid) and (yield ax.ready)) == 0: - if prng.randrange(100) > ready_rand: - yield ax.ready.eq(1) - else: - yield ax.ready.eq(0) - yield - ax_addr = (yield ax.addr) - if ax_addr != beat.addr: - self.errors += 1 - yield - - # dut - ax_burst = stream.Endpoint(ax_description(32, 32)) - ax_beat = stream.Endpoint(ax_description(32, 32)) - dut = LiteDRAMAXIBurst2Beat(ax_burst, ax_beat) - - # generate dut input (bursts) - prng = random.Random(42) - bursts = [] - for i in range(32): - bursts.append(Burst(burst_types["fixed"], prng.randrange(2**32), prng.randrange(255), log2_int(32//8))) - bursts.append(Burst(burst_types["incr"], prng.randrange(2**32), prng.randrange(255), log2_int(32//8))) - bursts.append(Burst(burst_types["wrap"], 4, 4-1, log2_int(2))) - - # generate expexted dut output (beats for reference) - beats = [] - for burst in bursts: - beats += burst.to_beats() - - # simulation - generators = [ - bursts_generator(ax_burst, bursts), - beats_checker(ax_beat, beats) - ] - run_simulation(dut, generators, vcd_name="burst2beat.vcd") - self.assertEqual(self.errors, 0)