Test File: test_pe_diag.py
Back to Test: Systolic Gauss-Jordan.
Source file: test/systolic_gauss_jordan/test_pe_diag.py
RTL counterpart
What this test checks
This page corresponds to the direct cocotb truth-table test for the diagonal processing element. It is the shortest path from the RTL page to an executable behavior check.
The test:
resets the DUT
optionally preloads the internal diagonal state bit
enumerates
reduce_sig_i, previous state, anddata_icompares observed outputs and next state against the Python golden model
How to run it
make -C test/systolic_gauss_jordan TEST=pe_diag
What to inspect while reading it
reset_dut()for the reset convention used by the suitestep()for the cycle-by-cycle driver patternpe_diag_truth_table_exhaustive()for the actual behavioral contract
Python source
1import cocotb
2from cocotb.clock import Clock
3from cocotb.triggers import FallingEdge, ReadOnly, RisingEdge
4
5from trapeziod_test_utils import (
6 OP_ADD,
7 OP_LOCK,
8 OP_PASS,
9 OPCODE_NAMES,
10 pe_diag_golden,
11)
12
13
14async def reset_dut(dut):
15 await FallingEdge(dut.clk)
16 dut.rst.value = 1
17 dut.en_i.value = 1
18 dut.data_i.value = 0
19 dut.reduce_sig_i.value = 0
20
21 for _ in range(2):
22 await RisingEdge(dut.clk)
23
24 dut.rst.value = 0
25
26
27async def step(dut, data_i, reduce_sig_i):
28 await FallingEdge(dut.clk)
29 dut.data_i.value = data_i
30 dut.reduce_sig_i.value = reduce_sig_i
31 await RisingEdge(dut.clk)
32 await ReadOnly()
33
34 return {
35 "r": int(dut.r.value),
36 "data_o": int(dut.data_o.value),
37 "op_o": int(dut.op_o.value),
38 "reduce_o": int(dut.reduce_sig_o.value),
39 }
40
41
42@cocotb.test()
43async def pe_diag_truth_table_exhaustive(dut):
44 cocotb.start_soon(Clock(dut.clk, 10, unit="ns").start())
45 dut.en_i.value = 1
46
47 for reduce_sig_i in (0, 1):
48 for r_prev in (0, 1):
49 for data_i in (0, 1):
50 await reset_dut(dut)
51
52 if r_prev == 1:
53 preload = await step(dut, 1, 0)
54 assert preload["r"] == 1, "Failed to preload pe_diag.r to 1"
55 assert preload["op_o"] == OP_LOCK, (
56 "Expected preload cycle to lock the diagonal state"
57 )
58
59 observed = await step(dut, data_i, reduce_sig_i)
60 expected = pe_diag_golden(
61 r_prev=r_prev,
62 data_i=data_i,
63 reduce_i=reduce_sig_i,
64 )
65
66 mismatch_row = (
67 f"(reduce_sig_i={reduce_sig_i}, r_prev={r_prev}, data_i={data_i})"
68 )
69
70 assert observed["r"] == expected["r_next"], (
71 f"{mismatch_row}: expected r_next={expected['r_next']}, "
72 f"got {observed['r']}"
73 )
74 assert observed["data_o"] == expected["data_o"], (
75 f"{mismatch_row}: expected data_o={expected['data_o']}, "
76 f"got {observed['data_o']}"
77 )
78 assert observed["op_o"] == expected["op_o"], (
79 f"{mismatch_row}: expected op_o={OPCODE_NAMES[expected['op_o']]}, "
80 f"got {OPCODE_NAMES.get(observed['op_o'], observed['op_o'])}"
81 )
82 assert observed["reduce_o"] == expected["reduce_o"], (
83 f"{mismatch_row}: expected reduce_o={expected['reduce_o']}, "
84 f"got {observed['reduce_o']}"
85 )