Re: [myhdl-list] yield before the end of a simulation
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2011-12-27 13:20:54
|
On 12/23/2011 8:48 AM, Christopher Felton 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 > > > > Here is a complete example that I briefly mentioned previously. The following, there is a simple module that will stop counting at some value. The simulation is run for some period of steps and the state is maintained for variables/objects that are active (? don't know the correct programming lingo for variables/objects that are in scope and have not been discarded). ~~~[Code Snip]~~~ from myhdl import * def incr(clk, rst, x): @always(clk.posedge) def hdlg_incr(): if rst: x.next = 0 else: if x < 12: x.next = x + 1 return hdlg_incr def test(): clk = Signal(False) rst = Signal(False) x = Signal(intbv(0, min=0, max=20)) dut = incr(clk, rst, x) @always(delay(1)) def tb_clk_gen(): clk.next = not clk @instance def tb_stim(): rst.next = True yield delay(3) rst.next = False # Run the simulation Simulation((dut, tb_clk_gen, tb_stim)).run(44) # Check final state assert x == 12, "Final state incorrect" assert x != 12, "Final state correct" if __name__ == '__main__': test() ~~~[End Code Snip]~~~ ~~~[CLI exec]~~~ In [2]: run end_state.py <class 'myhdl._SuspendSimulation'>: Simulated 44 timesteps --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) end_state.py in <module>() 40 41 if __name__ == '__main__': ---> 42 test() 43 \\sppdgfs\users\felton\misc\test\end_state.py in test() 36 37 assert x == 12, "Final state incorrect" ---> 38 assert x != 12, "Final state correct" 39 40 AssertionError: Final state correct ~~~[End CLI exec]~~~ Now, I don't think you can dig down and check internal variables this way (at least I do not know how to). Regards, Chris |