# 2.2. Example: Multiply and Accumulate¶

## 2.2.1. Combinatorial MAC¶

With Clash installed, it is now possible to begin creating hardware designs. To give a brief overview of Clash, we will define a simple multiply-and-accumulate circuit. Make a new file called `MAC.hs`, and enter the following preamble:

```module MAC where

import Clash.Prelude
import Clash.Explicit.Testbench
```

This declares the module and imports some useful modules from the Clash standard library. The standard library contains necessary functions and data types for writing circuit descriptions. As with Haskell, module identifiers in Clash must always start with a capital letter and correspond to the name of the file.

The logic of our circuit is expressed as a function which takes an accumulator and two extra inputs, and outputs the new value of the accumulator – which is the old value plus the product of the two other inputs.

```mac :: (Num a) => a -> (a, a) -> a
mac acc (x, y) = acc + x * y
```

The type of the function is given after the `::`, and says that the type `a` is some numeric type (e.g. `Int`, `Signed 8`, `Double`), the first argument is a number, the second value is a pair of numbers, and the result is a number.

## 2.2.2. Synchronous MAC¶

By adding another output parameter to this function, with the previous value of the accumulator, we can define the function as a Mealy machine. This allows us to use our combinatorial definition of `mac` to create a synchronous circuit (which we call `macS`).

```mac :: (Num a) => a -> (a, a) -> (a, a)
mac acc (x, y) = (acc + x * y, acc)

macS :: (HiddenClockResetEnable dom, Num a, NFDataX a) => Signal dom (a, a) -> Signal dom a
macS = mealy mac 0
```

The input and output of `macS` are values of the `Signal` type. This type represents synchronous values (functions without signals are combinatorial). There is also an additional `dom` type, for synthesis domain, and a constraint `HiddenClockResetEnable` – which says the synthesis domain has a clock, reset and enable line. These are implicit, although they can be exposed using the `exposeClockResetEnable` funcion.

## 2.2.3. HDL Generation and Testing¶

To generate HDL from a synchronous circuit, a function needs to be marked as a `topEntity`. The simplest way to achieve this is to create a function with this name, as Clash will use this definition automatically (similar to how `main` is a special function in other languages).

```topEntity
:: Clock System
-> Reset System
-> Enable System
-> Signal System (Int, Int)
-> Signal System Int
topEntity = exposeClockResetEnable macS
```

It is now possible to generate HDL for this circuit description, by running either `clash --HDL` from the command line, or running `:HDL` in `clashi` (where `HDL` is either `vhdl`, `verilog` or `systemverilog`). This will generate the HDL in a subdirectory named after the HDL being output.

Warning

Any function used to generate HDL from must have a monomorphic type. This means there can be no type variables in the type signature (i.e. for the circuit defined so far you need to specify both `dom` and `a`.

We can test that this circuit works as expected by defining a test bench. This allows an input to be used and the actual output to be compared against an expected output.

```testBench :: Signal System Bool
testBench = done
where
testInput    = stimuliGenerator clk rst ((1,1) :> (2,2) :> (3,3) :> (4,4) :> Nil)
expectOutput = outputVerifier' clk rst (0 :> 1 :> 5 :> 14 :> 30 :> 46 :> 62 :> Nil)
done         = expectOutput (topEntity clk rst en testInput)
en           = enableGen
clk          = tbSystemClockGen (fmap not done)
rst          = systemResetGen
```

From `clashi` it is possible to sample this test bench, using the `sampleN` function, which takes in the number of samples to draw and the signal which generates samples.

```>>> sampleN 8 testBench
[False, False, False, False, False, False, False, False]
```