Hardcaml_test_harness helps with common boilerplate when writing Hardcaml tests using Cyclesim or the Step test library. The harness handles constructing a test environment from a circuit and producing waveforms for debugging.
See src/waves_config.mli for the full up-to-date API.
(* Do not save any waves *)
let waves_config = Waves_config.no_waves
(* Save waves to the current working directory of the test *)
let waves_config = Waves_config.to_test_directory ()
(* Save waves to a specified directory *)
let waves_config = Waves_config.to_directory "/work/hardcaml/waves/"
(* Run the simulation for extra cycles after a failure, useful for capturing context when
the test is terminated early due to an assertion failure *)
let waves_config =
Waves_config.to_test_directory ()
|> Waves_config.with_extra_cycles_after_test ~n:10
;;
(* Control the waveform file-format *)
let waves_config =
Waves_config.to_test_directory ()
|> Waves_config.as_wavefile_format ~format:Waves_config.Wavefile_format.Vcd
;;See src/harness_base.mli for the full up-to-date API
open Core
open Hardcaml
open Hardcaml_test_harness
(* Your hardcaml design module to be tested, should provide:
[module I : Interface.S],
[module O : Interface.S],
[val create : Scope.t -> Signal.t I.t -> Signal.t O.t] *)
module Dut = ...
module Harness = Cyclesim_harness.Make (Dut.I) (Dut.O)
let waves_config = Waves_config.to_directory "/work/hardcaml/waves/"
let%expect_test "demo" =
Harness.run
~here:[%here]
(* Whether to randomize the initial state of registers (optional) *)
~random_initial_state:`All
(* Config for where to save waves (optional, defaults to no waves) *)
~waves_config
(* Create function for the design *)
~create:Dut.create
(* Name to apply to the waveform filename. The rules for naming the waveforms is as follows:
- Always prefixed with the filename from [%here]
- Uses the provided name if given, otherwise tries to use the name of the
currently-running expect-test, otherwise falls back to just the line number *)
~test_name:"cyclesim_demo"
(* Your actual cyclesim testbench *)
(fun ~inputs ~outputs sim ->
let open Bits in
inputs.a <--. 1;
inputs.b <--. 2;
Cyclesim.cycle sim;
assert (Bits.to_int_trunc !(outputs.s) = 3);
());
[%expect {| Saved waves to /work/hardcaml/waves/test_cyclesim_ml_cyclesim_demo.hardcamlwaveform |}]
;;Hardcaml_step_testbench (Functional version)open Core
open Hardcaml
open Hardcaml_test_harness
(* Your hardcaml design module to be tested, should provide:
[module I : Interface.S],
[module O : Interface.S],
[val create : Scope.t -> Signal.t I.t -> Signal.t O.t] *)
module Dut = ...
module Harness = Step_harness.Make (Dut.I) (Dut.O)
let waves_config = Waves_config.to_directory "/work/hardcaml/waves/"
let%expect_test "demo" =
Harness.run
~here:[%here]
~random_initial_state:`All
~waves_config
~create:Dut.create
~test_name:"functional_step_demo"
(* Your actual step testbench *)
(fun () ->
let module Step = Harness.Step in
let open Step.Let_syntax in
let%bind o = Step.cycle { Dut.I.a = Bits.zero 64; b = Bits.zero 64 } in
assert (Bits.to_int_trunc o.after_edge.s = 0);
return ());
[%expect {| Saved waves to /work/hardcaml/waves/test_step_ml_functional_step_demo.hardcamlwaveform |}]
;;Hardcaml_step_testbench (Imperative version)open Core
open Hardcaml
open Hardcaml_test_harness
(* Your hardcaml design module to be tested, should provide:
[module I : Interface.S],
[module O : Interface.S],
[val create : Scope.t -> Signal.t I.t -> Signal.t O.t] *)
module Dut = ...
module Harness = Step_harness.Make (Dut.I) (Dut.O)
let waves_config = Waves_config.to_directory "/work/hardcaml/waves/"
let%expect_test "demo" =
Harness.run
~here:[%here]
~random_initial_state:`All
~waves_config
~create:Dut.create
~test_name:"imperative_step_demo"
(* Your actual step testbench *)
(fun ~inputs ~outputs ->
let module Step = Harness.Step in
let open Step.Let_syntax in
let open Bits in
inputs.a <--. 1;
inputs.b <--. 2;
let%bind () = Step.cycle () in
assert (Bits.to_int_trunc !(outputs.s) = 3);
return ());
[%expect {| Saved waves to /work/hardcaml/waves/test_step_imperative_ml_imperative_step_demo.hardcamlwaveform |}]
;;