async def test_expect_error_bool_deprecated(_): async def t(): pass with assert_deprecated(): cocotb.test(expect_error=True)(t) with assert_deprecated(): cocotb.test(expect_error=False)(t)
async def test_expect_error_bool_deprecated(_): async def t(): pass with pytest.warns(DeprecationWarning): cocotb.test(expect_error=True)(t) with pytest.warns(DeprecationWarning): cocotb.test(expect_error=False)(t)
def _create_test(function, name, documentation, mod, *args, **kwargs): """Factory function to create tests, avoids late binding Creates a test dynamically. The test will call the supplied function with the supplied arguments. Args: function: (function) the test function to run name: (string) the name of the test documentation: (string) the docstring for the test mod: (module) the module this function belongs to *args: remaining args to pass to test function Kwaygs: **kwargs: passed to the test function Returns: decorated test function """ def _my_test(dut): yield function(dut, *args, **kwargs) _my_test.__name__ = name _my_test.__doc__ = documentation _my_test.__module__ = mod.__name__ return cocotb.test()(_my_test)
def _create_test(function, name, documentation, mod, *args, **kwargs): """Factory function to create tests, avoids late binding. Creates a test dynamically. The test will call the supplied function with the supplied arguments. Args: function (function): The test function to run. name (str): The name of the test. documentation (str): The docstring for the test. mod (module): The module this function belongs to. *args: Remaining args to pass to test function. **kwargs: Passed to the test function. Returns: Decorated test function """ async def _my_test(dut): await function(dut, *args, **kwargs) _my_test.__name__ = name _my_test.__qualname__ = name _my_test.__doc__ = documentation _my_test.__module__ = mod.__name__ return cocotb.test()(_my_test)
def test_edge(dut): ''' Simply writes data sequentially into the flip flop and checks for the correct output. ''' # Prepare test environments. tes = yield perform_setup(dut) # Implement the test coroutine. @coroutine def test(te): # Specify important data. itrs = 64 init = te.e.d.INIT width = te.e.d.W valen = te.e.d.EVLD hpen = int(te.dut.EHP.value) hnen = int(te.dut.EHN.value) getval = lambda w: randint(0, (1 << w) - 1) # Randomly generate the input transactions. in_trans = [ Transaction(d=getval(width), vld=getval(1)) for _ in range(itrs) ] # Generate the expected output. out_vals = getexp(in_trans, init, valen, hpen, hnen) #for val in out_vals: te.log.info("out val: {:x}".format(val)) # Write out the transactions. for trans in in_trans: te.e.d.append(trans) # Wait until all transactions have been written out. yield te.e.d.cycle(amount=itrs + 1) # Compare actual output values with expected. for idx, exp in enumerate(out_vals): act = te.e.m[idx] te.log.info("Actual: <{:x}>, Expected: <{:x}>...".format(act, exp)) if act != exp: te.log.error("Test failed!") raise ReturnValue(False) te.log.info("Test successful...") raise ReturnValue(True) # Run the test for the edge detectors. rcs = [fork(test(te)) for te in tes] for rc in rcs: yield rc.join() # Check if any of the coroutines failed. if any(rc.retval == False for rc in rcs): raise TestFailure() raise TestSuccess()
def test(): if using_cocotb(): wrapped = cocotb.test() return wrapped else: def wrapped(func): return func return wrapped
def internal_test(test): tester = cocotb.test(skip=skip) # To make the sorting better, CHANGE the "name" of the module that # the function we're calling is found in to exclude sub-modules. # This isn't necessarily something we always want to do, and it's # pretty serious black magic, but it works... if package_name is not None: test.__module__ = package_name tester_evaluated = tester(test) return tester_evaluated
def test_maker(*args, **kwargs): async def test_helper(dut): await coroutine(dut, *args, **kwargs) test_helper.__name__ = test_name #Cocotb uses the __qualname__ for it's results, but test_name to execute. #This makes them the same. test_helper.__qualname__ = test_name test_helper.__doc__ = "None" test_helper.__module__ = mod.__name__ return cocotb.test()(test_helper)
def test_eyeball(dut): ''' This tests various operations of the counter. This is incredibly lame, but this test was verified with the good ol' fashion "eye-ball" approach; I simply looked at the waveforms and made sure the output results made sense. ''' # Prepare the test envrionments. tes = yield perform_setup(dut) # Implement the test coroutine. @coroutine def test(te): # Gather important data. width = te.c.d.W aval = te.c.d.X init = te.c.d.INIT total = 1 << width itrs = [4, 3, 2, 3, 3, 6, 5] for _ in range(itrs[0]): te.c.d.append(Transaction(adv=1)) for _ in range(itrs[1]): te.c.d.append(Transaction(adv=1, clr=1)) for _ in range(itrs[2]): te.c.d.append(Transaction(adv=1, clr=0)) for _ in range(itrs[3]): te.c.d.append(Transaction(adv=0, clr=0)) for _ in range(itrs[4]): te.c.d.append(Transaction(ld=0, nval=randint(0, total - 1))) for _ in range(itrs[5]): te.c.d.append(Transaction(ld=1, nval=randint(0, total - 1))) for _ in range(itrs[6]): te.c.d.append(Transaction(adv=1)) yield te.c.d.cycle(amount=sum(itrs)) raise ReturnValue(True) # Run the test for both counters. rcs = [fork(test(te)) for te in tes] for rc in rcs: yield rc.join() # Check if any of the coroutines failed. if any(rc.retval == False for rc in rcs): raise TestFailure() raise TestSuccess()
def test_advance(dut): ''' This test simply tests the counting operation of the counters. ''' # Prepare the test envrionments. tes = yield perform_setup(dut) # Implement the test coroutine. @coroutine def test(te): # Gather important data. width = te.c.d.W aval = te.c.d.X init = te.c.d.INIT total = 1 << width itrs = 270 # Enable the counter for the specified amount of # clock cycles. yield te.c.d.write(adv=1, sync=False) for _ in range(itrs): yield te.c.d.cycle() yield te.c.d.write(adv=0, sync=False) # Generate the expected data. exps = [(val * aval + init) % total for val in range(itrs)] for idx, exp in enumerate(exps): act = te.c.m[idx] te.log.info("Actual: <{}>, Expected: <{}>...".format(act, exp)) if act != exp: te.log.error("Test failed!") raise ReturnValue(False) te.log.info("Test successful...") raise ReturnValue(True) # Run the test for both counters. rcs = [fork(test(te)) for te in tes if te.c.d.EDX == 0] for rc in rcs: yield rc.join() # Check if any of the coroutines failed. if any(rc.retval == False for rc in rcs): raise TestFailure() raise TestSuccess()
def test_access(dut): ''' This basic test simply involves writing data and reading random data into the ram. ''' # Prepare the test envrionments. tes = yield perform_setup(dut) # Implement the test coroutine. @coroutine def test(te): width = te.c.d.W depth = te.c.d.D biten = te.c.d.EWBE total = 1 << width rval = lambda: randint(0, total - 1) ens = {'wrvld': 1} if biten == 0 else {'wrbe': (1 << width) - 1} # Write in random values. exps = [] for idx in range(depth): exp = rval() exps.append(exp) yield te.c.d.write(wridx=idx, wrdata=exp, **ens) # Read random values. for idx, exp in enumerate(exps): act = yield te.c.d.read(rdidx=idx) te.log.info("Idx: {}. Expected: {}, Actual: {}...".format( idx, exp, act)) if exp != act: raise ReturnValue(False) raise ReturnValue(True) # Run the test for both counters. rcs = [fork(test(te)) for te in tes] for rc in rcs: yield rc.join() # Check if any of the coroutines failed. if any(rc.retval == False for rc in rcs): raise TestFailure() raise TestSuccess()
def _create_test(function, name, documentation, mod, *args, **kwargs): """Factory function to create tests, avoids late binding. Creates a test dynamically. The test will call the supplied function with the supplied arguments. Args: function (function): The test function to run. name (str): The name of the test. documentation (str): The docstring for the test. mod (module): The module this function belongs to. *args: Remaining args to pass to test function. **kwargs: Passed to the test function. Returns: Decorated test function """ def _my_test(dut): yield function(dut, *args, **kwargs) _my_test.__name__ = name _my_test.__doc__ = documentation _my_test.__module__ = mod.__name__ return cocotb.test()(_my_test)
def test_dynamic(dut): ''' This test only operates over the counters configured in dynamic increment / decrement mode of operation. This is basically the advcance test, however it randomly sets the dynamic x value. ''' # Prepare the test envrionments. tes = yield perform_setup(dut) # Implement the test coroutine. @coroutine def test(te): # Determine the parameters of the test. getval = lambda w: randint(0, (1 << w) - 1) width = te.c.d.W init = te.c.d.INIT total = 1 << width incx = getval(4) incitrs = randint(1, total) decx = -getval(4) decitrs = randint(1, total) itrs = incitrs + decitrs # Determine the expected results. incexp = [(val * incx + init) % total for val in range(incitrs)] decinit = incexp[-1] decexp = [((val + 1) * decx + decinit) % total for val in range(decitrs)] exp = list( ) # The initial value will be registered twice, so it's expected! exp.extend(incexp) exp.extend(decexp) #for val in exp: te.log.info("exp: {:x}".format(val)) # Determine the actual transactions. incact = [Transaction(dx=incx, adv=1) for _ in range(incitrs - 1)] decact = [Transaction(dx=decx, adv=1) for _ in range(decitrs + 1)] act = list() act.extend(incact) act.extend(decact) # Write out the transaction for trans in act: te.c.d.append(trans) # Wait until the appropriate amount of cycles have passed. yield te.c.d.cycle(itrs + 1) # Compare results for idx, ex in enumerate(exp): ac = te.c.m[idx] te.log.info("Actual: <{}>, Expected: <{}>...".format(ac, ex)) if ac != ex: te.log.error("Test failed!") raise ReturnValue(False) te.log.info("Test successful...") raise ReturnValue(True) # Run the test for each counter. rcs = [fork(test(te)) for te in tes if te.c.d.EDX != 0] for rc in rcs: yield rc.join() # Check if any of the coroutines failed. if any(rc.retval == False for rc in rcs): raise TestFailure() raise TestSuccess()