clash-prelude-0.10.3: CAES Language for Synchronous Hardware - Prelude library

Copyright (C) 2013-2015, University of Twente BSD2 (see the file LICENSE) Christiaan Baaij Safe Haskell2010 DataKindsFlexibleContextsTypeOperatorsExplicitNamespaces

CLaSH.Prelude.Safe

Description

This is the Safe API only of CLaSH.Prelude

CλaSH (pronounced ‘clash’) is a functional hardware description language that borrows both its syntax and semantics from the functional programming language Haskell. The merits of using a functional language to describe hardware comes from the fact that combinational circuits can be directly modeled as mathematical functions and that functional languages lend themselves very well at describing and (de-)composing mathematical functions.

This package provides:

• Prelude library containing datatypes and functions for circuit design

To use the library:

For now, CLaSH.Prelude is also the best starting point for exploring the library. A preliminary version of a tutorial can be found in CLaSH.Tutorial. Some circuit examples can be found in CLaSH.Examples.

Synopsis

# Creating synchronous sequential circuits

Arguments

 :: (s -> i -> (s, o)) Transfer function in mealy machine form: `state -> input -> (newstate,output)` -> s Initial state -> Signal i -> Signal o Synchronous sequential function with input and output matching that of the mealy machine

Create a synchronous function from a combinational function describing a mealy machine

```mac :: Int        -- Current state
-> (Int,Int)  -- Input
-> (Int,Int)  -- (Updated state, output)
mac s (x,y) = (s',s)
where
s' = x * y + s

topEntity :: `Signal` (Int, Int) -> `Signal` Int
topEntity = `mealy` mac 0
```
````>>> ````simulate topEntity [(1,1),(2,2),(3,3),(4,4)]
```[0,1,5,14...
```

Synchronous sequential functions can be composed just like their combinational counterpart:

```dualMac :: (`Signal` Int, `Signal` Int)
-> (`Signal` Int, `Signal` Int)
-> `Signal` Int
dualMac (a,b) (x,y) = s1 + s2
where
s1 = `mealy` mac 0 (`bundle` (a,x))
s2 = `mealy` mac 0 (`bundle` (b,y))
```

Arguments

 :: (Bundle i, Bundle o) => (s -> i -> (s, o)) Transfer function in mealy machine form: `state -> input -> (newstate,output)` -> s Initial state -> Unbundled i -> Unbundled o Synchronous sequential function with input and output matching that of the mealy machine

A version of `mealy` that does automatic `Bundle`ing

Given a function `f` of type:

```f :: Int -> (Bool, Int) -> (Int, (Int, Bool))
```

When we want to make compositions of `f` in `g` using `mealy`, we have to write:

```g a b c = (b1,b2,i2)
where
(i1,b1) = `unbundle` (`mealy` f 0 (`bundle` (a,b)))
(i2,b2) = `unbundle` (`mealy` f 3 (`bundle` (i1,c)))
```

Using `mealyB` however we can write:

```g a b c = (b1,b2,i2)
where
(i1,b1) = `mealyB` f 0 (a,b)
(i2,b2) = `mealyB` f 3 (i1,c)
```

Arguments

 :: (Bundle i, Bundle o) => (s -> i -> (s, o)) Transfer function in mealy machine form: `state -> input -> (newstate,output)` -> s Initial state -> Unbundled i -> Unbundled o Synchronous sequential function with input and output matching that of the mealy machine

Infix version of `mealyB`

Arguments

 :: (s -> i -> s) Transfer function in moore machine form: `state -> input -> newstate` -> (s -> o) Output function in moore machine form: `state -> output` -> s Initial state -> Signal i -> Signal o Synchronous sequential function with input and output matching that of the moore machine

Create a synchronous function from a combinational function describing a moore machine

```mac :: Int        -- Current state
-> (Int,Int)  -- Input
-> Int        -- Updated state
mac s (x,y) = x * y + s

topEntity :: `Signal` (Int, Int) -> `Signal` Int
topEntity = `moore` mac id 0
```
````>>> ````simulate topEntity [(1,1),(2,2),(3,3),(4,4)]
```[0,1,5,14...
```

Synchronous sequential functions can be composed just like their combinational counterpart:

```dualMac :: (`Signal` Int, `Signal` Int)
-> (`Signal` Int, `Signal` Int)
-> `Signal` Int
dualMac (a,b) (x,y) = s1 + s2
where
s1 = `moore` mac id 0 (`bundle` (a,x))
s2 = `moore` mac id 0 (`bundle` (b,y))
```

Arguments

 :: (Bundle i, Bundle o) => (s -> i -> s) Transfer function in moore machine form: `state -> input -> newstate` -> (s -> o) Output function in moore machine form: `state -> output` -> s Initial state -> Unbundled i -> Unbundled o Synchronous sequential function with input and output matching that of the moore machine

A version of `moore` that does automatic `Bundle`ing

Given a functions `t` and `o` of types:

```t :: Int -> (Bool, Int) -> Int
o :: Int -> (Int, Bool)
```

When we want to make compositions of `t` and `o` in `g` using `moore`, we have to write:

```g a b c = (b1,b2,i2)
where
(i1,b1) = `unbundle` (`moore` t o 0 (`bundle` (a,b)))
(i2,b2) = `unbundle` (`moore` t o 3 (`bundle` (i1,c)))
```

Using `mooreB` however we can write:

```g a b c = (b1,b2,i2)
where
(i1,b1) = `mooreB` t o 0 (a,b)
(i2,b2) = `mooreB` t o 3 (i1,c)
```

registerB :: Bundle a => a -> Unbundled a -> Unbundled a Source

Create a `register` function for product-type like signals (e.g. '(Signal a, Signal b)')

```rP :: (Signal Int,Signal Int) -> (Signal Int, Signal Int)
rP = registerB (8,8)```
````>>> ````simulateB rP [(1,1),(2,2),(3,3)] :: [(Int,Int)]
```[(8,8),(1,1),(2,2),(3,3)...
```

# ROMs

Arguments

 :: (KnownNat n, Enum addr) => Vec n a ROM contentNB: must be a constant -> addr Read address `rd` -> a The value of the ROM at address `rd`

An asynchronous/combinational ROM with space for `n` elements

Additional helpful information:

Arguments

 :: (KnownNat (2 ^ n), KnownNat n) => Vec (2 ^ n) a ROM contentNB: must be a constant -> Unsigned n Read address `rd` -> a The value of the ROM at address `rd`

An asynchronous/combinational ROM with space for 2^`n` elements

Additional helpful information:

Arguments

 :: (KnownNat n, KnownNat m) => Vec n a ROM contentNB: must be a constant -> Signal (Unsigned m) Read address `rd` -> Signal a The value of the ROM at address `rd`

A ROM with a synchronous read port, with space for `n` elements

• NB: Read value is delayed by 1 cycle
• NB: Initial output value is `undefined`

Additional helpful information:

Arguments

 :: (KnownNat (2 ^ n), KnownNat n) => Vec (2 ^ n) a ROM contentNB: must be a constant -> Signal (Unsigned n) Read address `rd` -> Signal a The value of the ROM at address `rd`

A ROM with a synchronous read port, with space for 2^`n` elements

• NB: Read value is delayed by 1 cycle
• NB: Initial output value is `undefined`

Additional helpful information:

# RAM primitives with a combinational read port

Arguments

 :: Enum addr => SNat n Size `n` of the RAM -> Signal addr Write address `w` -> Signal addr Read address `r` -> Signal Bool Write enable -> Signal a Value to write (at address `w`) -> Signal a Value of the `RAM` at address `r`

Create a RAM with space for `n` elements.

• NB: Initial content of the RAM is `undefined`

Additional helpful information:

Arguments

 :: (KnownNat (2 ^ n), KnownNat n) => Signal (Unsigned n) Write address `w` -> Signal (Unsigned n) Read address `r` -> Signal Bool Write enable -> Signal a Value to write (at address `w`) -> Signal a Value of the `RAM` at address `r`

Create a RAM with space for 2^`n` elements

• NB: Initial content of the RAM is `undefined`

Additional helpful information:

# BlockRAM primitives

Arguments

 :: (KnownNat n, Enum addr) => Vec n a Initial content of the BRAM, also determines the size, `n`, of the BRAM.NB: MUST be a constant. -> Signal addr Write address `w` -> Signal addr Read address `r` -> Signal Bool Write enable -> Signal a Value to write (at address `w`) -> Signal a Value of the `blockRAM` at address `r` from the previous clock cycle

Create a blockRAM with space for `n` elements.

• NB: Read value is delayed by 1 cycle
• NB: Initial output value is `undefined`
```bram40 :: `Signal` (`Unsigned` 6) -> Signal (`Unsigned` 6) -> `Signal` Bool
-> `Signal` `Bit` -> Signal `Bit`
bram40 = `blockRam` (`replicate` d40 1)
```

Additional helpful information:

Arguments

 :: (KnownNat (2 ^ n), KnownNat n) => Vec (2 ^ n) a Initial content of the BRAM, also determines the size, `2^n`, of the BRAM.NB: MUST be a constant. -> Signal (Unsigned n) Write address `w` -> Signal (Unsigned n) Read address `r` -> Signal Bool Write enable -> Signal a Value to write (at address `w`) -> Signal a Value of the `blockRAM` at address `r` from the previous clock cycle

Create a blockRAM with space for 2^`n` elements

• NB: Read value is delayed by 1 cycle
• NB: Initial output value is `undefined`
```bram32 :: `Signal` (`Unsigned` 5) -> Signal (`Unsigned` 5) -> `Signal` Bool
-> `Signal` `Bit` -> `Signal` `Bit`
bram32 = `blockRamPow2` (`replicate` d32 1)
```

Additional helpful information:

# Utility functions

Arguments

 :: (Bounded a, Eq a) => a Starting value -> Signal a -> Signal Bool

Give a pulse when the `Signal` goes from `minBound` to `maxBound`

Arguments

 :: (Bounded a, Eq a) => a Starting value -> Signal a -> Signal Bool

Give a pulse when the `Signal` goes from `maxBound` to `minBound`

# Exported modules

module Data.Bits

## Haskell Prelude

CLaSH.Prelude re-exports most of the Haskell Prelude with the exception of the following: (++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head, init, iterate, last, length, map, repeat, replicate, reverse, scanl, scanr, splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3.

It instead exports the identically named functions defined in terms of `Vec` at CLaSH.Sized.Vector.

module Prelude