HardCaml

From the OCaml Labs wiki
Jump to: navigation, search

HardCaml, Gates and All![edit]

HardCaml is a recently introduced library by Andy Ray for writing RTL hardware descriptions. For those familiar with hardware development, it serves a similar purpose to VHDL and Verilog but brings some of the benefits of OCaml. HardCaml provides a range of simulation tools to allow you to develop and test your designs -- to explore this a bit further, a recent OCamlLabs intern, Chaitanya Mangla, spent some time with HardCaml "closing the loop" to get a simple circuit, described in HardCaml synthesised and running on a physical FPGA. This post is based on Chaitanya's notes and examples.

The first step is thankfully straightforward -- install HardCaml using OPAM:

$ opam install hardcaml

The basic workflow is then to

  1. describe your circuit using HardCaml,
  2. to compile this description using the OCaml compiler, and then
  3. to run the resulting binary

to produce a Verilog circuit description. To actually put this onto a physical board you then must run it through the Verilog synthesis tools -- this step will vary based on the specific hardware you are using. Chaitanya's example describes how to do this in detail using the Altera Quartus development tools to target the Altera Cyclone V SoC Development Kit (from now on, the SoCkit board). This is a prototyping board, with an ARM processor, memory, an FPGA, peripherals, and comes with development tools and examples.

Of State Machines and Circuits[edit]

The SoCkit has four keys and four LEDs -- the simple example used here programs the FPGA on the board so that pressing `key0` turns on one of the LEDs, and pressing `key1` turns it off. This also neatly sidesteps the problem of needing to debounce the keypresses -- it does not matter if a single keypress by the user actually generates multiple signals as any one of them will turn the LED on or off (if key0, resp. key1).

More precisely, the state machine described above is:

LED switch state machine

Which corresponds to the following circuit:

Circuit diagram

We next describe this circuit directly using HardCaml.

Show Me the Code![edit]

boilerplate

open Core.Std
open HardCaml.Signal.Comb
open HardCaml.Signal.Seq

the combinatorial logic that handles keypresses of key0 and key1

let leds key0 key1 =
  let in0 = ~: key0 in
  let in1 = ~: key1 in
  reg_fb r_none empty 1 (fun d ->
    (d &: (~: in1)) |: ((~: d) &: in0)
  )

finally, tell HardCaml to generate Verilog output

let () =
  let key0 = input "key0" 1 in
  let key1 = input "key1" 1 in
  let circuit = HardCaml.Circuit.make "leds"
    [ output "q" (leds key0 key1) ]
  in
  HardCaml.Rtl.Verilog.write (output_string stdout) circuit

Andy Ray has written an extension to this example that uses some of the fancier features of HardCaml to describe the state machine.

Build this in the usual way, and run the resulting binary to generate the Verilog description:

$ ocamlfind ocamlc -linkpkg -thread -package hardcaml,core \
  leds.ml -o leds.native
$ ./leds.native > leds.v