With standard Hardcaml simulations we are forced to manage input and output ports manually using the strings Interfaces allow us to automate much of this work and are particularly useful as circuits get more complex The following is a common pattern for specifying a hardware circuit It consists of an input and output interface and a function over these interfaces which constructs the logic To simulate this we can use the functor This will automatically create a circuit with the input and output ports labeled build a simulator and then construct input and output records for driving the simulator All this and we never have to worry about the underlying string names of ports Notice the type signature of The parametric type arguments to encode the types returned when retrieving the inputs and output values from the simulator object Driving the inputs and reading outputs can be performed via the convenience of record fields open Base open Hardcaml * Input interface * module I struct type a t clock a foo a @bits 8 bar a @bits 8 @@deriving hardcaml end * Output interface * module O struct type a t baz a @bits 8 baz_delayed a @bits 8 @@deriving hardcaml end let create i Signal t I t Signal t O t let open Signal in let spec Reg_spec create clock i clock in let baz i foo i bar in let baz_delayed reg enable vdd spec baz in O baz baz_delayed Cyclesim With_interface # let create_sim let module Sim Cyclesim With_interface I O in Sim create create val create_sim unit > Bits t ref I t Bits t ref O t Cyclesim t <fun> _ _ Cyclesim t Cyclesim t # let run_sim let sim create_sim in let inputs Cyclesim inputs sim in let outputs Cyclesim outputs sim in let print_outputs Stdio print_s %sexp_of int O t O map outputs f fun p > Bits to_unsigned_int p in inputs foo Bits of_unsigned_int width 8 1 inputs bar Bits of_unsigned_int width 8 2 Cyclesim cycle sim print_outputs inputs foo Bits of_unsigned_int width 8 7 inputs bar Bits of_unsigned_int width 8 9 Cyclesim cycle sim print_outputs val run_sim unit > unit <fun> # run_sim baz 3 baz_delayed 3 baz 16 baz_delayed 16 unit