summaryrefslogtreecommitdiff
path: root/tb/gfx_shader_bind/testbench/checkers.py
blob: 0109249e88f80ad7ad66f406bd6902b0cf732aee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import cocotb
from cocotb.triggers import RisingEdge, ReadOnly

from cocotb_coverage.coverage import CoverCheck

class PipelineIntegrityChecker:
    def __init__(self, dut, name, clk):
        self._clk, self._dut = clk, dut
        self._queue = [None] * dut.front.bind_.BIND_STAGES.value
        self._ready_sticky = False

        @CoverCheck(
            f'{name}.runnable_tx_ready',
            f_pass = lambda ready: not self._ready_sticky and     ready,
            f_fail = lambda ready:     self._ready_sticky and not ready,
        )
        def sample_ready(ready):
            self._ready_sticky = self._ready_sticky or ready

        @CoverCheck(
            f'{name}.in_to_out_integrity',
            f_pass = lambda group: group == self._queue[0] and group is not None,
            f_fail = lambda group: group != self._queue[0],
        )
        def sample_wave_group(group):
            pass

        self._sample_ready = sample_ready
        self._sample_wave_group = sample_wave_group

        cocotb.start_soon(self._run())

    async def _run(self):
        while True:
            await RisingEdge(self._clk)
            await ReadOnly()

            self._sample_ready(self._dut.runnable_in_ready.value)

            if self._dut.wave_valid.value:
                self._sample_wave_group(self._dut.wave_group.value)
            else:
                self._sample_wave_group(None)

            new_group = None
            if self._dut.runnable_out_valid.value:
                new_group = self._dut.runnable_out_data.value

            self._queue[:-1] = self._queue[1:]
            self._queue[-1] = new_group

class PcChecker:
    def __init__(self, dut, name, clk, *, mem, pc_table):
        self._clk, self._dut = clk, dut
        self._mem, self._pc_table = mem, pc_table

        @CoverCheck(
            f'{name}.pc_ok',
            f_pass = lambda wave: wave.insn and self._pc_ok(wave),
            f_fail = lambda wave: wave.insn and not self._pc_ok(wave),
        )
        def sample_wave(wave):
            pass

        self.sample_wave = sample_wave

    def _pc_ok(self, wave):
        return wave.insn == self._mem.read(self._pc_table[wave.group] * 4)