Cheatsheet / Reference
TLDR of Hardcaml
Installation and Setup
Package Installation
opam install hardcaml ppx_hardcaml hardcaml_waveterm
opam install hardcaml_c hardcaml_verilator hardcaml_step_testbenchProject Structure
project/
βββ src/
β βββ interfaces.ml (* Interface definitions *)
β βββ components/ (* Reusable components *)
β βββ top.ml (* Top-level module *)
β βββ utils.ml (* Utility functions *)
βββ test/
β βββ unit_tests.ml (* Unit tests *)
β βββ integration_tests.ml
βββ bin/
βββ main.ml (* RTL Code Generation *)Core Concepts and Fundamentals
What is Hardcaml?
Hardcaml is an embedded hardware design domain-specific language (DSL) implemented in OCaml by Jane Street. It provides low-level control over hardware while abstracting away tedious aspects of traditional HDLs like Verilog/VHDL.
Key Design Principles
Full Control DSL: Direct instantiation of hardware primitives (registers, memories, multiplexers)
Type Safety: OCaml's type system prevents connection errors and width mismatches
Fast Elaboration: Circuit construction happens entirely within OCaml at elaboration time
Embedded Approach: No secondary abstraction layersβpurely OCaml
Graph-Based Representation
Hardcaml represents circuits as directed graphs where:
Nodes = hardware operations (registers, logic gates, arithmetic)
Edges = signal connections
Cycles = supported via wires for feedback loops
Signal Types and Operations
Primary Signal Type
Bits vs Signals
Bits.t: Concrete values for simulation and testingSignal.t: Abstract representation for circuit description
Basic Operations
Module Definitions and Interfaces
Interface Pattern (ppx_deriving_hardcaml)
Interface Attributes
Parameterized Modules with Functors
Combinational Logic Constructs
Adder Example
Tree Operations
Sequential Logic (Registers, Memories, State Machines)
Register Creation
Memory Primitives
State Machines with Always DSL
Simulation and Testing
Basic Simulation
Expect Test with Waveforms
High-Performance Simulation Backends
Synthesis and Compilation
RTL Generation
Circuit Creation
Common Patterns and Idioms
Pipeline Pattern
Counter Pattern
FIFO Pattern
Error Handling and Debugging
Width Validation
Assertion-based Debugging
Interactive Debugging
Performance Considerations
Memory Usage Optimization
Timing Optimization
Code Examples for Major Concepts
FIR Filter
Linear Feedback Shift Register (LFSR)
Quick Reference Syntax
Essential Operations
Register and Memory
Best Practices and Conventions
Code Organization
Separate interfaces from implementations
Use modules for logical grouping
Keep create functions pure and deterministic
Use descriptive names for signals and modules
Type Safety
Testing Strategy
Write unit tests for all combinational logic
Use property-based testing with hardcaml_verify
Test edge cases and boundary conditions
Include waveform verification in tests
Naming Conventions
Use
snake_casefor signal namesPrefix with
i_for inputs,o_for outputsUse meaningful names that describe the signal's purpose
Advanced Features and Techniques
Hierarchical Design
Custom Types
Verification and Formal Methods
Ecosystem Libraries
Core Libraries
hardcaml_circuits: Arbiters, multipliers, sorting networks, DSP
hardcaml_fixed_point: Fixed-point arithmetic with rounding/overflow control
hardcaml_verify: SAT-based formal verification tools
Simulation Libraries
hardcaml_verilator: Ultra-high speed simulation using Verilator
hardcaml_c: C-based simulation for improved performance
hardcaml_waveterm: ASCII waveform visualization
hardcaml_step_testbench: Monadic testbench API
Xilinx Libraries
hardcaml_xilinx: Xilinx-specific FPGA components
hardcaml_xilinx_components: Tool to generate OCaml from Xilinx libraries
Integration Libraries
hardcaml_of_verilog: Import Verilog designs into Hardcaml
Last updated