Re: [myhdl-list] yield before the end of a simulation
Brought to you by:
jandecaluwe
From: Uri N. <ur...@gm...> - 2011-12-26 19:32:35
|
On 23 December 2011 16:48, Christopher Felton <chr...@gm...>wrote: > > > On Tuesday, December 20, 2011, Oscar Diaz <osc...@gm...> wrote: > > 2011/12/20 Christopher Felton <chr...@gm...>: > >> On 12/20/2011 5:35 AM, Oscar Diaz wrote: > >>> Hi > >>> > >>> I have a testbench that needs to do some asserts at the end of a > >>> simulation. However, I couldn't find an elegant way to do it. Right > >>> now I'm passing to the testbench generator the same duration as in > >>> "Simulation.run(duration)" , so I can do a "yield delay(duration-1)" > >>> and do the final asserts (by the way, in my case all my simulations > >>> have a defined duration). I tried to catch the StopSimulation > >>> exception, but it doesn't work inside a generator. Any ideas? Thanks! > >>> > >>> Best regards > >>> > >> > >> I believe you can catch exceptions in generators. At least the > >> generator PEP says so and the following works. > >> > >> ~~~ [Code Snip] ~~~ > >> from myhdl import * > >> def test(): > >> @instance > >> def ex_in_g(): > >> try: > >> for ii in xrange(10): > >> yield delay(7) > >> raise StopSimulation > >> > >> except Exception, e: > >> print("Caught exception %s" % (str(e))) > >> raise StopSimulation > >> > >> return ex_in_g > >> > >> if __name__ == '__main__': > >> Simulation(test()).run() > >> ~~~~~~~~~~~~~~~~~~~~~~~ > > > > That's the case when the exception is raised inside the generator, > > which is not my case. I'm trying to something like this: > > > > ~~~ [Code Snip] ~~~ > > from myhdl import * > > def test(): > > @instance > > def ex_in_g(): > > try: > > for ii in xrange(10): > > yield delay(7) > > # ideally it shouldn't got here > > return > > > > except Exception, e: > > # or maybe better "except StopSimulation" ? > > print("Caught exception %s" % (str(e))) > > raise StopSimulation > > > > return ex_in_g > > > > if __name__ == '__main__': > > # fixed simulation time > > Simulation(test()).run(50) > > ~~~~~~~~~~~~~~~~~~~~~~~ > > > > It doesn't work because the exception is raised inside the run() > > method. Right now my project store the simulation duration to yield > > before raising StopSimulation, like this: > > ~~~ [Code Snip] ~~~ > > from myhdl import * > > sim_duration = 100 > > def test(): > > @instance > > def main_block(): > > # do some stuff > > return > > > > @instance > > def last_check(): > > yield delay(sim_duration - 1) > > print "do some final asserts..." > > return > > > > return instances() > > > > if __name__ == '__main__': > > Simulation(test()).run(sim_duration) > > ~~~~~~~~~~~~~~~~~~~~~~~ > > > > Any ideas to improve this issue? > > > > Best regards > > > >> > >> Regards, > >> Chris > >> > >> > > Another option you could try is to run the simulation from the test > function. After the simulation completes the final state is preserved and > you can do the final checks. > > I haven't tried it. In the above example, the test function you could do > the following. > > Def test(): > ... > Simulation((ex_in_g)).run() > #checks > # nothing to return > > Regards, > Chris > > ------------------------------------------------------------------------------ > Write once. Port to many. > Get the SDK and tools to simplify cross-platform app development. Create > new or port existing apps to sell to consumers worldwide. Explore the > Intel AppUpSM program developer opportunity. appdeveloper.intel.com/join > http://p.sf.net/sfu/intel-appdev > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > Hi, Perhaps something like the following is suitable: the stimulus generator halts the simulation once the vector is exhausted. No need to catch anything. I did need to use an object to store the result, since the Signals go dead at the end of the simulation. Cheers, Uri ~~~ [Code Snip] ~~~ #! /usr/bin/python import unittest import myhdl from myhdl import Signal, always, instance, delay 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 Monitor(): def __init__(self): self.sample = 0 def update(self, clk, din): @always(clk.posedge) def logic(): self.sample = din.val 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) self.monitor = Monitor() self.monitor_inst = self.monitor.update(self.clk, self.dout) def tearDown(self): pass # specific test methods (scenarios) def test_3(self): def stimulus(stimVector): @instance def logic(): for data in stimVector: self.din.next = data yield self.clk.posedge raise myhdl.StopSimulation return logic stimulus_inst = stimulus(range(1,7)) sim = myhdl.Simulation(self.dut_inst, self.clk_inst, self.monitor_inst, stimulus_inst) sim.run() self.assert_(self.monitor.sample == 5) if __name__ == '__main__': mytests = unittest.TestLoader().loadTestsFromTestCase(TestDUT) unittest.TextTestRunner(verbosity=2).run(mytests) |