Re: [myhdl-list] Pythonic Test frameworks
Brought to you by:
jandecaluwe
From: Uri N. <ur...@gm...> - 2011-11-07 21:51:03
|
On 7 November 2011 08:30, Christopher Felton <chr...@gm...> wrote: > Looking for some opinions on methods to make my testbenches more > Pythonic. I have been humbled more often than not with my Python > programming skills, or lack there of (http://bit.ly/uQeRGm). And my > testbenches seem to be old-school version of my Verilog/VHDL equivalent > testbences. Looking to move from a testbench to a test framework. > > Frequently I will create a single testbench and have a bunch of > testcases in the testbench. In some cases I will create multiple > (different) forms in test_ functions to use with py.test. > > But too often, majority of my test cases are in this single testbench. > What I would like to do is leverage the py.test framework but only > define connections, models, etc *once*. Using the USB interface project > (USBP, http://bit.ly/sPEMC1) as an example I used something like the > following. > > ~~~ [Example Code] ~~~ > class BaseSim() > > def __init__(self, ...): > # all top-level signal definitions, dut instance and interface > # model instances > ... > > def GetGens(): > # return all the generators for > > def test_case1(): > bs = BaseSim() > > @instance > def tb_stimulus(): > yield bs.WriteRegister(0x00, 42) > rval = [0] > yield bs.ReadRegister(0x00, val) > assert rval[0] == 42 > raise StopSimulation > > Simulation((tb_stimulus, bs.GetGens())).run() > > def test_case2(): > bs = BaseSim() > > @instance > def tb_stimulus > bs.someSignal.next = True > yield delay(3) > bs.someSignal.next = False > # check some condition > raise StopSimulation > > Simulation((tb_stimulus, bs.GetGens())).run() > > ~~~ [End Example Code]~~~ > > Other methods that are more flexible? Is it worth it to add the > instantiations and connection signals to a class or just in a module? > > Thanks in advance, > Chris > > > > ------------------------------------------------------------------------------ > RSA(R) Conference 2012 > Save $700 by Nov 18 > Register now > http://p.sf.net/sfu/rsa-sfdev2dev1 > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > Hi Chris, I find the standard lib unittest flexible enough, allowing something like the example below. Any special reason for using py.test? Cheers, Uri ~~~ [Example Code] ~~~ import itertools import unittest from myhdl import Signal, always, delay, Simulation def Clock(clk): @always(delay(1)) def logic(): clk.next ^= 1 return logic def DUT(clk, din, dout): @always(clk.posedge) def logic(): dout.next = din.val + 1 return logic class TestDUT(unittest.TestCase): # unittest methods def setUp(self): self.clk = Signal(0) self.din = Signal(0) self.dout = Signal(0) self.clk_inst = Clock(self.clk) self.dut_inst = DUT(self.clk, self.din, self.dout) def tearDown(self): pass # core test routines def exec_test(self, stimulus, ticks): sim = Simulation(self.dut_inst, self.clk_inst, stimulus) sim.run(ticks) def stim_gen(self, clk, gen_data, init_value): sig_gen = itertools.count(init_value) @always(clk.posedge) def logic(): gen_data.next = sig_gen.next() return logic # specific test methods (scenarios) def test_1(self): stim_inst = self.stim_gen(self.clk, self.din, 3) self.exec_test(stim_inst, 7) self.assertEqual(self.dout.val, 6) def test_2(self): stim_inst = self.stim_gen(self.clk, self.din, 3) self.exec_test(stim_inst, 8) self.assertEqual(self.dout.val, 6) if __name__ == '__main__': mytests = unittest.TestLoader().loadTestsFromTestCase(TestDUT) unittest.TextTestRunner(verbosity=2).run(mytests) ~~~ [End Example Code]~~~ |