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

Copyright(C) 2013-2016 University of Twente
2017 Myrtle Software Ltd Google Inc.
LicenseBSD2 (see the file LICENSE)
MaintainerChristiaan Baaij <christiaan.baaij@gmail.com>
Safe HaskellUnsafe
LanguageHaskell2010
Extensions
  • Cpp
  • DataKinds
  • FlexibleContexts
  • TypeOperators
  • ExplicitNamespaces

Clash.Prelude

Contents

Description

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:

  • Import Clash.Prelude; by default clock and reset lines are implicitly routed for all the components found in Clash.Prelude. You can read more about implicit clock and reset lines in Clash.Signal
  • Alternatively, if you want to explicitly route clock and reset ports, for more straightforward multi-clock designs, you can import the Clash.Explicit.Prelude module. Note that you should not import Clash.Prelude and Clash.Explicit.Prelude at the same time as they have overlapping definitions.

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

mealy Source #

Arguments

:: HiddenClockReset domain gated synchronous 
=> (s -> i -> (s, o))

Transfer function in mealy machine form: state -> input -> (newstate,output)

-> s

Initial state

-> Signal domain i -> Signal domain 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

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

mac :: HiddenClockReset domain gated synchronous => Signal domain (Int, Int) -> Signal domain Int
mac = mealy macT 0
>>> simulate mac [(1,1),(2,2),(3,3),(4,4)]
[0,1,5,14...
...

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

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

mealyB Source #

Arguments

:: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) 
=> (s -> i -> (s, o))

Transfer function in mealy machine form: state -> input -> (newstate,output)

-> s

Initial state

-> Unbundled domain i -> Unbundled domain o

Synchronous sequential function with input and output matching that of the mealy machine

A version of mealy that does automatic Bundleing

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)

(<^>) Source #

Arguments

:: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) 
=> (s -> i -> (s, o))

Transfer function in mealy machine form: state -> input -> (newstate,output)

-> s

Initial state

-> Unbundled domain i -> Unbundled domain o

Synchronous sequential function with input and output matching that of the mealy machine

Infix version of mealyB

moore Source #

Arguments

:: HiddenClockReset domain gated synchronous 
=> (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 domain i -> Signal domain 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

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

mac :: HiddenClockReset domain gated synchronous => Signal domain (Int, Int) -> Signal domain Int
mac = moore mac id 0
>>> simulate mac [(1,1),(2,2),(3,3),(4,4)]
[0,1,5,14...
...

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

dualMac
  :: HiddenClockReset domain gated synchronous
  => (Signal domain Int, Signal domain Int)
  -> (Signal domain Int, Signal domain Int)
  -> Signal domain 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))

mooreB Source #

Arguments

:: (Bundle i, Bundle o, HiddenClockReset domain gated synchronous) 
=> (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 domain i -> Unbundled domain o

Synchronous sequential function with input and output matching that of the moore machine

A version of moore that does automatic Bundleing

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 :: (HiddenClockReset domain gated synchronous, Bundle a) => a -> Unbundled domain a -> Unbundled domain a infixr 3 Source #

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

rP :: HiddenClockReset domain gated synchronous
   => (Signal domain Int, Signal domain Int)
   -> (Signal domain Int, Signal domain Int)
rP = registerB (8,8)
>>> simulateB rP [(1,1),(2,2),(3,3)] :: [(Int,Int)]
[(8,8),(1,1),(2,2),(3,3)...
...

ROMs

asyncRom Source #

Arguments

:: (KnownNat n, Enum addr) 
=> Vec n a

ROM content

NB: 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:

asyncRomPow2 Source #

Arguments

:: KnownNat n 
=> Vec (2 ^ n) a

ROM content

NB: 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:

rom Source #

Arguments

:: (KnownNat n, KnownNat m, HiddenClock domain gated) 
=> Vec n a

ROM content

NB: must be a constant

-> Signal domain (Unsigned m)

Read address rd

-> Signal domain 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:

romPow2 Source #

Arguments

:: (KnownNat n, HiddenClock domain gated) 
=> Vec (2 ^ n) a

ROM content

NB: must be a constant

-> Signal domain (Unsigned n)

Read address rd

-> Signal domain 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:

ROMs initialised with a data file

asyncRomFile Source #

Arguments

:: (KnownNat m, Enum addr) 
=> SNat n

Size of the ROM

-> FilePath

File describing the content of the ROM

-> addr

Read address rd

-> BitVector m

The value of the ROM at address rd

An asynchronous/combinational ROM with space for n elements

  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

  • See Clash.Prelude.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
  • See Clash.Sized.Fixed for ideas on how to create your own data files.
  • When you notice that asyncRomFile is significantly slowing down your simulation, give it a monomorphic type signature. So instead of leaving the type to be inferred:

    myRomData = asyncRomFile d512 "memory.bin"
    

    or giving it a polymorphic type signature:

    myRomData :: Enum addr => addr -> BitVector 16
    myRomData = asyncRomFile d512 "memory.bin"
    

    you should give it a monomorphic type signature:

    myRomData :: Unsigned 9 -> BitVector 16
    myRomData = asyncRomFile d512 "memory.bin"
    

asyncRomFilePow2 Source #

Arguments

:: (KnownNat m, KnownNat n) 
=> FilePath

File describing the content of the ROM

-> Unsigned n

Read address rd

-> BitVector m

The value of the ROM at address rd

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

  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

  • See Clash.Prelude.ROM.File for more information on how to instantiate a ROM with the contents of a data file.
  • See Clash.Sized.Fixed for ideas on how to create your own data files.
  • When you notice that asyncRomFilePow2 is significantly slowing down your simulation, give it a monomorphic type signature. So instead of leaving the type to be inferred:

    myRomData = asyncRomFilePow2 "memory.bin"
    

    you should give it a monomorphic type signature:

    myRomData :: Unsigned 9 -> BitVector 16
    myRomData = asyncRomFilePow2 "memory.bin"
    

romFile Source #

Arguments

:: (KnownNat m, KnownNat n, HiddenClock domain gated) 
=> SNat n

Size of the ROM

-> FilePath

File describing the content of the ROM

-> Signal domain (Unsigned n)

Read address rd

-> Signal domain (BitVector m)

The value of the ROM at address rd from the previous clock cycle

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
  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

romFilePow2 Source #

Arguments

:: (KnownNat m, KnownNat n, HiddenClock domain gated) 
=> FilePath

File describing the content of the ROM

-> Signal domain (Unsigned n)

Read address rd

-> Signal domain (BitVector m)

The value of the ROM at address rd from the previous clock cycle

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
  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

RAM primitives with a combinational read port

asyncRam Source #

Arguments

:: (Enum addr, HiddenClock domain gated, HasCallStack) 
=> SNat n

Size n of the RAM

-> Signal domain addr

Read address r

-> Signal domain (Maybe (addr, a))

(write address w, value to write)

-> Signal domain a

Value of the RAM at address r

Create a RAM with space for n elements.

Additional helpful information:

asyncRamPow2 Source #

Arguments

:: (KnownNat n, HiddenClock domain gated, HasCallStack) 
=> Signal domain (Unsigned n)

Read address r

-> Signal domain (Maybe (Unsigned n, a))

(write address w, value to write)

-> Signal domain a

Value of the RAM at address r

Create a RAM with space for 2^n elements

Additional helpful information:

BlockRAM primitives

blockRam Source #

Arguments

:: (Enum addr, HiddenClock domain gated, HasCallStack) 
=> Vec n a

Initial content of the BRAM, also determines the size, n, of the BRAM.

NB: MUST be a constant.

-> Signal domain addr

Read address r

-> Signal domain (Maybe (addr, a))

(write address w, value to write)

-> Signal domain 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
  :: HiddenClock domain
  => Signal domain (Unsigned 6)
  -> Signal domain (Maybe (Unsigned 6, Bit))
  -> Signal domain Bit
bram40 = blockRam (replicate d40 1)

Additional helpful information:

  • See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
  • Use the adapter readNew for obtaining write-before-read semantics like this: readNew (blockRam inits) rd wrM.

blockRamPow2 Source #

Arguments

:: (KnownNat n, HiddenClock domain gated, HasCallStack) 
=> Vec (2 ^ n) a

Initial content of the BRAM, also determines the size, 2^n, of the BRAM.

NB: MUST be a constant.

-> Signal domain (Unsigned n)

Read address r

-> Signal domain (Maybe (Unsigned n, a))

(write address w, value to write)

-> Signal domain 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
  :: HiddenClock domain
  => Signal domain (Unsigned 5)
  -> Signal domain (Maybe (Unsigned 5, Bit))
  -> Signal domain Bit
bram32 = blockRamPow2 (replicate d32 1)

Additional helpful information:

  • See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
  • Use the adapter readNew for obtaining write-before-read semantics like this: readNew (blockRamPow2 inits) rd wrM.

BlockRAM primitives initialised with a data file

blockRamFile Source #

Arguments

:: (KnownNat m, Enum addr, HiddenClock domain gated, HasCallStack) 
=> SNat n

Size of the blockRAM

-> FilePath

File describing the initial content of the blockRAM

-> Signal domain addr

Read address r

-> Signal domain (Maybe (addr, BitVector m))

(write address w, value to write)

-> Signal domain (BitVector m)

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
  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

  • See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
  • Use the adapter readNew' for obtaining write-before-read semantics like this: readNew' clk (blockRamFile' clk size file) rd wrM.
  • See Clash.Prelude.BlockRam.File for more information on how to instantiate a Block RAM with the contents of a data file.
  • See Clash.Sized.Fixed for ideas on how to create your own data files.

blockRamFilePow2 Source #

Arguments

:: (KnownNat m, KnownNat n, HiddenClock domain gated, HasCallStack) 
=> FilePath

File describing the initial content of the blockRAM

-> Signal domain (Unsigned n)

Read address r

-> Signal domain (Maybe (Unsigned n, BitVector m))

(write address w, value to write)

-> Signal domain (BitVector m)

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
  • NB: This function might not work for specific combinations of code-generation backends and hardware targets. Please check the support table below:

                   | VHDL     | Verilog  | SystemVerilog |
    ===============+==========+==========+===============+
    Altera/Quartus | Broken   | Works    | Works         |
    Xilinx/ISE     | Works    | Works    | Works         |
    ASIC           | Untested | Untested | Untested      |
    ===============+==========+==========+===============+
    

Additional helpful information:

  • See Clash.Prelude.BlockRam for more information on how to use a Block RAM.
  • Use the adapter readNew' for obtaining write-before-read semantics like this: readNew' clk (blockRamFilePow2' clk file) rd wrM.
  • See Clash.Prelude.BlockRam.File for more information on how to instantiate a Block RAM with the contents of a data file.
  • See Clash.Sized.Fixed for ideas on how to create your own data files.

BlockRAM read/write conflict resolution

readNew Source #

Arguments

:: (Eq addr, HiddenClockReset domain gated synchronous) 
=> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a)

The ram component

-> Signal domain addr

Read address r

-> Signal domain (Maybe (addr, a))

(Write address w, value to write)

-> Signal domain a

Value of the ram at address r from the previous clock cycle

Create read-after-write blockRAM from a read-before-write one (synchronised to system clock)

>>> import Clash.Prelude
>>> :t readNew (blockRam (0 :> 1 :> Nil))
readNew (blockRam (0 :> 1 :> Nil))
  :: ...
     ... =>
     Signal domain addr
     -> Signal domain (Maybe (addr, a)) -> Signal domain a

Utility functions

window Source #

Arguments

:: (KnownNat n, Default a, HiddenClockReset domain gated synchronous) 
=> Signal domain a

Signal to create a window over

-> Vec (n + 1) (Signal domain a)

Window of at least size 1

Give a window over a Signal

window4 :: HiddenClockReset domain gated synchronous
        => Signal domain Int -> Vec 4 (Signal domain Int)
window4 = window
>>> simulateB window4 [1::Int,2,3,4,5] :: [Vec 4 Int]
[<1,0,0,0>,<2,1,0,0>,<3,2,1,0>,<4,3,2,1>,<5,4,3,2>...
...

windowD Source #

Arguments

:: (KnownNat n, Default a, HiddenClockReset domain gated synchronous) 
=> Signal domain a

Signal to create a window over

-> Vec (n + 1) (Signal domain a)

Window of at least size 1

Give a delayed window over a Signal

windowD3 :: HiddenClockReset domain gated synchronous
         => Signal domain Int -> Vec 3 (Signal domain Int)
windowD3 = windowD
>>> simulateB windowD3 [1::Int,2,3,4] :: [Vec 3 Int]
[<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>...
...

isRising Source #

Arguments

:: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) 
=> a

Starting value

-> Signal domain a 
-> Signal domain Bool 

Give a pulse when the Signal goes from minBound to maxBound

isFalling Source #

Arguments

:: (HiddenClockReset domain gated synchronous, Bounded a, Eq a) 
=> a

Starting value

-> Signal domain a 
-> Signal domain Bool 

Give a pulse when the Signal goes from maxBound to minBound

Exported modules

Synchronous signals

DataFlow interface

Datatypes

Bit vectors

Arbitrary-width numbers

Fixed point numbers

Fixed size vectors

Perfect depth trees

Annotations

Type-level natural numbers

Template Haskell

class Lift t where #

A Lift instance can have any of its values turned into a Template Haskell expression. This is needed when a value used within a Template Haskell quotation is bound outside the Oxford brackets ([| ... |]) but not at the top level. As an example:

add1 :: Int -> Q Exp
add1 x = [| x + 1 |]

Template Haskell has no way of knowing what value x will take on at splice-time, so it requires the type of x to be an instance of Lift.

Lift instances can be derived automatically by use of the -XDeriveLift GHC language extension:

{-# LANGUAGE DeriveLift #-}
module Foo where

import Language.Haskell.TH.Syntax

data Bar a = Bar1 a (Bar a) | Bar2 String
  deriving Lift

Methods

lift :: t -> Q Exp #

Turn a value into a Template Haskell expression, suitable for use in a splice.

Instances

Lift Bool 

Methods

lift :: Bool -> Q Exp #

Lift Char 

Methods

lift :: Char -> Q Exp #

Lift Double 

Methods

lift :: Double -> Q Exp #

Lift Float 

Methods

lift :: Float -> Q Exp #

Lift Int 

Methods

lift :: Int -> Q Exp #

Lift Int8 

Methods

lift :: Int8 -> Q Exp #

Lift Int16 

Methods

lift :: Int16 -> Q Exp #

Lift Int32 

Methods

lift :: Int32 -> Q Exp #

Lift Int64 

Methods

lift :: Int64 -> Q Exp #

Lift Integer 

Methods

lift :: Integer -> Q Exp #

Lift Natural 

Methods

lift :: Natural -> Q Exp #

Lift Word 

Methods

lift :: Word -> Q Exp #

Lift Word8 

Methods

lift :: Word8 -> Q Exp #

Lift Word16 

Methods

lift :: Word16 -> Q Exp #

Lift Word32 

Methods

lift :: Word32 -> Q Exp #

Lift Word64 

Methods

lift :: Word64 -> Q Exp #

Lift () 

Methods

lift :: () -> Q Exp #

Lift Bit # 

Methods

lift :: Bit -> Q Exp #

Lift a => Lift [a] 

Methods

lift :: [a] -> Q Exp #

Lift a => Lift (Maybe a) 

Methods

lift :: Maybe a -> Q Exp #

Integral a => Lift (Ratio a) 

Methods

lift :: Ratio a -> Q Exp #

KnownNat n => Lift (BitVector n) # 

Methods

lift :: BitVector n -> Q Exp #

KnownNat n => Lift (Index n) # 

Methods

lift :: Index n -> Q Exp #

Lift (SNat n) # 

Methods

lift :: SNat n -> Q Exp #

KnownNat n => Lift (Unsigned n) # 

Methods

lift :: Unsigned n -> Q Exp #

KnownNat n => Lift (Signed n) # 

Methods

lift :: Signed n -> Q Exp #

(Lift a, Lift b) => Lift (Either a b) 

Methods

lift :: Either a b -> Q Exp #

(Lift a, Lift b) => Lift (a, b) 

Methods

lift :: (a, b) -> Q Exp #

Lift a => Lift (Vec n a) # 

Methods

lift :: Vec n a -> Q Exp #

Lift a => Lift (Signal domain a) # 

Methods

lift :: Signal domain a -> Q Exp #

Lift a => Lift (RTree d a) # 

Methods

lift :: RTree d a -> Q Exp #

(Lift a, Lift b, Lift c) => Lift (a, b, c) 

Methods

lift :: (a, b, c) -> Q Exp #

(Lift (rep ((+) int frac)), KnownNat frac, KnownNat int, Typeable (Nat -> *) rep) => Lift (Fixed rep int frac) # 

Methods

lift :: Fixed rep int frac -> Q Exp #

Lift a => Lift (DSignal domain delay a) # 

Methods

lift :: DSignal domain delay a -> Q Exp #

(Lift a, Lift b, Lift c, Lift d) => Lift (a, b, c, d) 

Methods

lift :: (a, b, c, d) -> Q Exp #

(Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (a, b, c, d, e) 

Methods

lift :: (a, b, c, d, e) -> Q Exp #

(Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (a, b, c, d, e, f) 

Methods

lift :: (a, b, c, d, e, f) -> Q Exp #

(Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (a, b, c, d, e, f, g) 

Methods

lift :: (a, b, c, d, e, f, g) -> Q Exp #

Type classes

Clash

Other

module Data.Bits

Exceptions

Named types

Hidden arguments

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