Hi all, I have made several changes to the Migen simulation API:
1) Proxy object passed to simulation functions The parameter passed to simulation functions is no longer the Simulator, but a special object that gives access to the values of the signals of the current module using the regular Python read/write syntax. Nested objects, lists and dictionaries containing signals are supported, as well as Migen memories, for reading and writing. Examples of the old/new syntax: s.wr(self.foo, 42) -> selfp.foo = 42 s.rd(self.foo) -> selfp.foo s.wr(self.dut.banks[2].bar["foo"], 1) -> selfp.dut.banks[2].bar["foo"] = 1 s.rd(self.dut.mem, idx) -> selfp.dut.mem[idx] The simulator object can be accessed as selfp.simulator, and still supports the lower-level rd and wr methods as well as the cycle_counter attribute. 2) Generator-style simulation code Instead of defining the do_simulation function that gets executed at every cycle, Modules can declare a gen_simulation generator that takes one proxy parameter to access signals and memories (as explained in #1) and yields to proceed to the next simulation cycle. Simulation generators can yield an integer in order to wait for that number of cycles, or yield nothing (None) to wait for 1 cycle. This feature is demonstrated in the ChopperTB test bench here: https://github.com/m-labs/misoc/blob/master/misoclib/videostream/downscaler.py 3) Simulation termination management With the previous API, the simulation was terminated when any simulation function set the simulator property "interrupt" to True. This was often inconvenient to use. This property has been removed, and instead, simulation functions and generators can raise the StopSimulation exception. It is automatically raised when a simulation generator is exhausted. This exception disables the current simulation function, i.e. it is no longer run by the simulator. The simulation is over when all simulation functions are disabled. Some simulation modules only respond to external stimuli - e.g. the bus.wishbone.Tap that snoops on bus transactions and prints them on the console - and have simulation functions that never end. To deal with those, the new API introduces "passive" simulation functions that are not taken into account when deciding to continue to run the simulation. A simulation function is declared passive by setting a "passive" attribute on it that evaluates to True. Raising StopSimulation in such a function still makes the simulator stop running it for the rest of the simulation. 4) run_simulation function Most simulations are run in the same way and do not need the slightly heavy syntax needed to create and run a Simulator object. There is now a function that exposes the most common features with a simpler syntax: run_simulation(fragment, ncycles=None, vcd_name=None, keep_files=False) Sébastien _______________________________________________ Devel mailing list Devel@lists.milkymist.org https://ssl.serverraum.org/lists/listinfo/devel