Module Imperative.Cyclesim

include Imperative.S
module I_data : Digital_components.Data.S with type t = unit
module Handler : sig ... end
val cycle : Handler.t @ local -> (?num_cycles:int -> (unit -> unit) @ local) @ local

cycle i_data ~num_cycles waits for num_cycles cycles of the simulator to run. cycle raises if num_cycles < 1.

val start : Handler.t @ local -> ((Handler.t @ local -> ('a -> 'b) @ local) -> ('a -> ('b, I_data.t) Hardcaml_step_testbench_kernel.Step_effect.Component_finished.t) @ local) @ local
val spawn : ?period:int -> Handler.t @ local -> ((Handler.t @ local -> (unit -> 'a) @ local) -> ('a, unit) finished_event) @ local

Launch a new task within the current simulation step.

val wait_for : Handler.t @ local -> (('a, 'i) finished_event -> 'a) @ local

Wait for the given event to occur, and extract its return value.

val wait_for_with_timeout : Handler.t @ local -> (('a, 'i) finished_event -> (timeout_in_cycles:int -> 'a option) @ local) @ local

Like wait_for except it stops waiting after timeout_in_cycles and returns None. Note that the spawned task continues to execute.

val forever : Handler.t @ local -> ((Handler.t @ local -> (unit -> unit) @ local) -> Core.never_returns) @ local

Runs the given step function forever.

val run_monadic_computation : Handler.t @ local -> (('a, O_data.t, I_data.t) Hardcaml_step_testbench_kernel.Step_monad.t -> 'a) @ local
module As_monad : sig ... end
module Expert : sig ... end
val run_with_timeout : ?update_children_after_finish:bool -> ?show_steps:bool -> ?timeout:int -> unit -> simulator:(_, _) Hardcaml.Cyclesim.t -> testbench:(Handler.t @ local -> 'a) -> 'a option

Run the testbench until the main task finishes.

The optional timeout argument stops the simulation after the given number of steps and returns None. Otherwise it will continue until the testbech completes.

val run_with_timeout' : ?update_children_after_finish:bool -> ?show_steps:bool -> ?timeout:int -> unit -> simulator:('i, 'o) Hardcaml.Cyclesim.t -> testbench:(Handler.t @ local -> (('i, 'o) Hardcaml.Cyclesim.t -> 'a) @ local) -> 'a option

Identical to run_with_timeout, but the testbench function takes the simulator object. There is no semantical difference at all -- this is just a convenience function.

val run_until_finished : ?update_children_after_finish:bool -> ?show_steps:bool -> unit -> simulator:(_, _) Hardcaml.Cyclesim.t -> testbench:(Handler.t @ local -> 'a) -> 'a

Run the testbench until completion.

val wrap : ?show_steps:bool -> when_to_evaluate_testbenches:[ `Before_cycle | `After_cycle ] -> testbenches:(Handler.t @ local -> unit) list -> ('i, 'o) Hardcaml.Cyclesim.t -> ('i, 'o) Hardcaml.Cyclesim.t

wrap constructs a Sim.t instances such that calling Cyclesim.cycle sim will step the testbenches by one a cycle. The testbench will stop executing if it's completed, but the user will not receive any notification if this happens. The provided testbenches are executed sequentially.

Note that there is no safety gurantees on the main simulation loop and the testbenches accessing the ports. It's the programmer's responsibility to think about how the port access. For most use cases, it's expected that the testbenches and the main simulation loop should be modifying different input ports.

val wrap_never_returns : ?show_steps:bool -> when_to_evaluate_testbenches:[ `Before_cycle | `After_cycle ] -> testbenches:(Handler.t @ local -> Core.never_returns) list -> ('i, 'o) Hardcaml.Cyclesim.t -> ('i, 'o) Hardcaml.Cyclesim.t

Exactly the same as wrap, but accepts a never_returns testbench in the signature.