| # Copyright 2025 Google LLC |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import cocotb |
| from cocotb.clock import Clock |
| from cocotb.triggers import RisingEdge, ClockCycles |
| import random |
| |
| from kelvin_test_utils.secded_golden import get_data_intg, secded_inv_39_32_enc, secded_inv_64_57_enc |
| |
| |
| async def setup_dut(dut): |
| """Common setup for all tests.""" |
| clock = Clock(dut.clock, 10, unit="us") |
| cocotb.start_soon(clock.start()) |
| |
| dut.reset.value = 1 |
| await ClockCycles(dut.clock, 2) |
| dut.reset.value = 0 |
| await RisingEdge(dut.clock) |
| |
| |
| @cocotb.test() |
| async def test_secded_encoder(dut): |
| """Test that the SecdedEncoder module matches the golden model for random data.""" |
| await setup_dut(dut) |
| |
| # Determine the data width from the DUT. |
| data_width = len(dut.io_data_i) |
| num_iterations = 1000 |
| |
| for i in range(num_iterations): |
| # Generate a random integer of the correct width. |
| random_data = random.getrandbits(data_width) |
| |
| # Drive the random data into the DUT. |
| dut.io_data_i.value = random_data |
| await RisingEdge(dut.clock) |
| |
| # Get the ECC from the DUT. |
| dut_ecc = dut.io_ecc_o.value |
| |
| # Calculate the expected ECC using the golden model. |
| if data_width == 32: |
| golden_ecc = secded_inv_39_32_enc(random_data) |
| elif data_width == 57: |
| golden_ecc = secded_inv_64_57_enc(random_data) |
| elif data_width == 128: |
| golden_ecc = get_data_intg(random_data, width=data_width) |
| else: |
| raise ValueError(f"Unsupported data width: {data_width}") |
| |
| # Compare the DUT's output with the golden model. |
| assert dut_ecc == golden_ecc, f"Mismatch on iteration {i}: data={hex(random_data)}, dut_ecc={hex(dut_ecc)}, golden_ecc={hex(golden_ecc)}" |
| |
| dut._log.info( |
| f"Successfully compared {num_iterations} random data values for data width {data_width}." |
| ) |