Module Imperative.Cyclesim

module Step_monad = Digital_components.Step_monad
include module type of Imperative
module I_data : Digital_components.Data.S with type t = unit
include Core.Monad.S with type 'a t := 'a t
val return : 'a 'i 'p 'q. 'a -> 'a t

Convert a value to a t.

val map : 'a 'b 'i 'j 'p 'q. 'a t -> f:('a -> 'b) -> 'b t

Transforms the contents of a t.

val bind : 'a 'b 'i 'j 'k 'p 'q. 'a t -> f:('a -> 'b t) -> 'b t

Sequences computations. bind t ~f computes f v for value(s) v in t. Well-behaved monads satisfy these "laws" (where ( >>= ) is the infix bind operator):

  • map t ~f is equivalent to bind t ~f:(fun x -> return (f x))
  • return x >>= f is equivalent to f x
  • t >>= return is equivalent to t
  • (t >>= f) >>= g is equivalent to t >>= fun x -> f x >>= g
val join : 'a 'i 'j 'k 'p 'q. 'a t t -> 'a t

Combines nested t into just one layer. Equivalent to bind t ~f:Fn.id.

val ignore_m : 'a 'i 'j 'p 'q. 'a t -> unit t

Ignores contained values of t. Equivalent to map t ~f:ignore.

val all : 'a 'i 'p 'q. 'a t list -> 'a list t

Combines a list of t.

val all_unit : 'i 'p 'q. unit t list -> unit t

Combines a list of t whose contents are unimportant.

val (>>=) : 'a 'b 'i 'j 'k 'p 'q. 'a t -> ('a -> 'b t) -> 'b t

Infix bind.

val (>>|) : 'a 'b 'i 'j 'p 'q. 'a t -> ('a -> 'b) -> 'b t

Infix map.

module Monad_infix : sig ... end
module Let_syntax : sig ... end
val cycle : ?num_cycles:int -> unit -> unit t

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

val for_ : int -> int -> (int -> unit t) -> unit t

for_ i j f does f i, f (i+1), ... f j in sequence. If j < i, then for_ i j immediately returns unit.

val spawn : ?period:int -> (unit -> 'a t) -> ('a, unit) finished_event t

Launch a new task within the current simulation step.

val wait_for : ('a, 'i) finished_event -> 'a t

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

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

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

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

Runs the given step function forever.

val run_effectful_computation : ((O_data.t, I_data.t) Hardcaml_step_testbench_kernel.Step_effect.Handler.t @ local -> 'a) -> 'a t
module List : sig ... end
module Array : sig ... end
val run_with_timeout : ?update_children_after_finish:bool -> ?show_steps:bool -> ?timeout:int -> unit -> simulator:(_, _) Hardcaml.Cyclesim.t -> testbench:(unit -> 'a t) -> '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:(('i, 'o) Hardcaml.Cyclesim.t -> 'a t) -> '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:(unit -> 'a t) -> 'a

Run the testbench until completion.

val wrap : ?show_steps:bool -> when_to_evaluate_testbenches:[ `Before_cycle | `After_cycle ] -> testbenches:(unit -> unit t) 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:(unit -> Core.never_returns t) 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.