blob: 34c473874d071e107d4e132d57b92a87e99b3024 [file] [log] [blame]
import cocotb
from cocotb.triggers import Timer, RisingEdge, ClockCycles
from cocotb.clock import Clock
import cocotb_coverage
import random
import fractional_n_divider_model
from test_fractional_n_divider_coverage import *
# hardware constants
WIDTH_INTEGER = 10
WIDTH_MODULUS = 16
ORDER = 3
# test constants
NUMBER_TESTS = 64
NUMBER_SAMPLES = 2**16
@cocotb.test()
async def coverage(dut):
"""
Test the output against the model with random input values
"""
# create the model
model = fractional_n_divider_model.fractional_n_divider_model(integer_width=WIDTH_INTEGER, modulus_width=WIDTH_MODULUS, order=ORDER)
# create an object that views the DUT state
status = FractionalNStatus(dut)
# start clock
clock = Clock(dut.input_frequency, 2)
cocotb.fork(clock.start())
# loop through the tests
for test in range(NUMBER_TESTS):
# reset the DUT
dut.rst = 1
dut.divide_value = 0
await ClockCycles(dut.input_frequency, 8)
dut.rst = 0
model.reset()
# create some random data
divide_value = random.random() * (2**WIDTH_INTEGER - 0.5*2**ORDER - 1)
divide_value_fp = int(divide_value * 2**WIDTH_MODULUS)
dut._log.info("Test number %d, input value = %f" % (test+1, divide_value))
# change the divide value
model.set_divide_value(divide_value)
# update the divider value into the DUT
status.update()
output_data = await new_divider_value(dut, status, divide_value_fp)
await RisingEdge(dut.input_frequency)
# loop through some clock cycles calculating samples
for sample in range(NUMBER_SAMPLES):
# check the output matches the model
model_data = model.update()
output_data = int(dut.output_frequency)
assert(output_data == model_data), 'Model = %x, Simulation = %x' % (model_data, output_data)
await RisingEdge(dut.input_frequency)
# print and export coverage report
coverage_db.report_coverage(dut._log.info, bins=True)
coverage_db.export_to_xml(filename="coverage_fractional_n_divider.xml")
coverage_db.export_to_yaml(filename="coverage_fractional_n_divider.yml")