clash-prelude-1.8.4: Clash: a functional hardware description language - Prelude library

Copyright | (C) 2019-2023 Myrtle Software Ltd
License | BSD2 (see the file LICENSE)
Maintainer | QBayLogic B.V. <devops@qbaylogic.com>
Safe Haskell | None
Language | Haskell2010

Clash.Magic

Contents

- Functions to control names of identifiers in HDL
- Functions to control Clash's (de)duplication mechanisms
- Utilities to differentiate between simulation and generating HDL
- Static assertions

Description

Control naming and deduplication in the generated HDL code. Explicitly nameable things include:

- Component (VHDL) / module ((System)Verilog) instances
- Registers
- Terms

Refer to Clash.Annotations.TopEntity for controlling naming of entities (VHDL) / modules ((System)Verilog) and their ports.

Synopsis

- prefixName :: forall (name :: Symbol) a. a -> name ::: a
- suffixName :: forall (name :: Symbol) a. a -> name ::: a
- suffixNameP :: forall (name :: Symbol) a. a -> name ::: a
- suffixNameFromNat :: forall (name :: Nat) a. a -> name ::: a
- suffixNameFromNatP :: forall (name :: Nat) a. a -> name ::: a
- setName :: forall (name :: Symbol) a. a -> name ::: a
- nameHint :: forall (sym :: Symbol) a. SSymbol sym -> a -> a
- deDup :: a -> a
- noDeDup :: a -> a
- clashSimulation :: Bool
- data SimOnly a = SimOnly a
- clashCompileError :: HasCallStack => String -> a

## Functions to control names of identifiers in HDL

prefixName :: forall (name :: Symbol) a. a -> name ::: a Source #

Prefix instance and register names with the given `Symbol`

suffixName :: forall (name :: Symbol) a. a -> name ::: a Source #

Suffix instance and register names with the given `Symbol`

suffixNameP :: forall (name :: Symbol) a. a -> name ::: a Source #

Suffix instance and register names with the given `Symbol`, but add it in front of other suffixes.

When you write

    suffixName @"A" (suffixName @"B" f))

you get register and instance names inside f with the suffix: "_B_A"

However, if you want them in the other order you can write:

    suffixNameP @"A" (suffixName @"B" f))

so that names inside f will have the suffix "_A_B"

suffixNameFromNat :: forall (name :: Nat) a. a -> name ::: a Source #

Suffix instance and register names with the given `Nat`

suffixNameFromNatP :: forall (name :: Nat) a. a -> name ::: a Source #

Suffix instance and register names with the given `Nat`, but add it in front of other suffixes.

When you write

    suffixNameNat @1 (suffixName @"B" f))

you get register and instance names inside f with the suffix: "_B_1"

However, if you want them in the other order you can write:

    suffixNameNatP @1 (suffixName @"B" f))

so that names inside f will have the suffix "_1_B"

setName :: forall (name :: Symbol) a. a -> name ::: a Source #

Name the instance or register with the given `Symbol`, instead of using an auto-generated name. Pre- and suffixes annotated with `prefixName` and `suffixName` will be added to both instances and registers named with `setName` and instances and registers that are auto-named.

nameHint Source #

Arguments

:: forall (sym :: Symbol) a. SSymbol sym | A hint for a name
-> a |
-> a |

Name a given term, such as one of type `Signal`, using the given `SSymbol`. Results in a declaration with the name used as the identifier in the generated HDL code.

Example usage:

    nameHint (SSymbol @"identifier") term

NB: The given name should be considered a hint as it may be expanded, e.g. if it collides with existing identifiers.

## Functions to control Clash's (de)duplication mechanisms

deDup :: a -> a Source #

Force deduplication, i.e. share a function or operator between multiple branches.

By default Clash converts

    case x of
      A -> 3 * y
      B -> x * x

to

    let f_arg0 = case x of {A -> 3; _ -> x}
        f_arg1 = case x of {A -> y; _ -> x}
        f_out  = f_arg0 * f_arg1
    in  case x of
          A -> f_out
          B -> f_out

However, it won't do this for:

    case x of
      A -> 3 + y
      B -> x + x

Because according to the internal heuristics the multiplexer introduced for the deduplication are more expensive than the addition. This might not be the case for your particular platform.

In these cases you can force Clash to deduplicate by:

    case x of
      A -> deDup (3 + y)
      B -> deDup (x + x)

noDeDup :: a -> a Source #

Do not deduplicate, i.e. keep, an applied function inside a case-alternative; do not try to share the function between multiple branches.

By default Clash converts

    case x of
      A -> f 3 y
      B -> f x x
      C -> h x

to

    let f_arg0 = case x of {A -> 3; _ -> x}
        f_arg1 = case x of {A -> y; _ -> x}
        f_out  = f f_arg0 f_arg1
    in  case x of
          A -> f_out
          B -> f_out
          C -> h x

i.e. it deduplicates functions (and operators such as multiplication) between case-alternatives to save on area. This comes at the cost of multiplexing the arguments for the deduplicated function.

There are two reasons you would want to stop Clash from doing this:

1. The deduplicated function is in the critical path, and the addition of the multiplexers further increased the propagation delay.
2. Clash's heuristics were off, and the addition of the multiplexers actually made the final circuit larger instead of smaller.

In these cases you want to tell Clash not to deduplicate:

    case x of
      A -> noDeDup f 3 y
      B -> f x x
      C -> h x

Where the application of f in the A-alternative is now explicitly not deduplicated, and given that the f in the B-alternative is the only remaining application of f in the case-expression it is also not deduplicated.

Note that if the C-alternative also had an application of f, then the applications of f in the B- and C-alternatives would have been deduplicated; i.e. the final circuit would have had two application of f.

## Utilities to differentiate between simulation and generating HDL

clashSimulation :: Bool Source #

`True` in Haskell/Clash simulation. Replaced by `False` when generating HDL.

data SimOnly a Source #

A container for data you only want to have around during simulation and is ignored during synthesis. Useful for carrying around things such as:

- A map of simulation/vcd traces
- Co-simulation state or meta-data
- etc.

Constructors

SimOnly a |

#### Instances

Instances details

Applicative SimOnly Source # |
Instance details Defined in Clash.Magic Methods pure :: a -> SimOnly a Source # (<*>) :: SimOnly (a -> b) -> SimOnly a -> SimOnly b Source # liftA2 :: (a -> b -> c) -> SimOnly a -> SimOnly b -> SimOnly c Source # (*>) :: SimOnly a -> SimOnly b -> SimOnly b Source # (<*) :: SimOnly a -> SimOnly b -> SimOnly a Source #
Functor SimOnly Source # |
Instance details Defined in Clash.Magic Methods fmap :: (a -> b) -> SimOnly a -> SimOnly b Source # (<$) :: a -> SimOnly b -> SimOnly a Source #
Monad SimOnly Source # |
Instance details Defined in Clash.Magic Methods (>>=) :: SimOnly a -> (a -> SimOnly b) -> SimOnly b Source # (>>) :: SimOnly a -> SimOnly b -> SimOnly b Source # return :: a -> SimOnly a Source #
Foldable SimOnly Source # |

Instance details

Defined in Clash.Magic

Methods

fold :: Monoid m => SimOnly m -> m Source #

foldMap :: Monoid m => (a -> m) -> SimOnly a -> m Source #

foldMap' :: Monoid m => (a -> m) -> SimOnly a -> m Source #

foldr :: (a -> b -> b) -> b -> SimOnly a -> b Source #

foldr' :: (a -> b -> b) -> b -> SimOnly a -> b Source #

foldl :: (b -> a -> b) -> b -> SimOnly a -> b Source #

foldl' :: (b -> a -> b) -> b -> SimOnly a -> b Source #

foldr1 :: (a -> a -> a) -> SimOnly a -> a Source #

foldl1 :: (a -> a -> a) -> SimOnly a -> a Source #

toList :: SimOnly a -> [a] Source #

null :: SimOnly a -> Bool Source #

length :: SimOnly a -> Int Source #

elem :: Eq a => a -> SimOnly a -> Bool Source #

maximum :: Ord a => SimOnly a -> a Source #

minimum :: Ord a => SimOnly a -> a Source #

sum :: Num a => SimOnly a -> a Source #

product :: Num a => SimOnly a -> a Source #

Traversable SimOnly Source # |
Instance details Defined in Clash.Magic Methods traverse :: Applicative f => (a -> f b) -> SimOnly a -> f (SimOnly b) Source # sequenceA :: Applicative f => SimOnly (f a) -> f (SimOnly a) Source # mapM :: Monad m => (a -> m b) -> SimOnly a -> m (SimOnly b) Source # sequence :: Monad m => SimOnly (m a) -> m (SimOnly a) Source #
NFDataX a => NFDataX (SimOnly a) Source # |
Instance details Defined in Clash.Magic Methods deepErrorX :: String -> SimOnly a Source # hasUndefined :: SimOnly a -> Bool Source # ensureSpine :: SimOnly a -> SimOnly a Source # rnfX :: SimOnly a -> () Source #
Monoid a => Monoid (SimOnly a) Source # |
Instance details Defined in Clash.Magic Methods mempty :: SimOnly a Source # mappend :: SimOnly a -> SimOnly a -> SimOnly a Source # mconcat :: [SimOnly a] -> SimOnly a Source #
Semigroup a => Semigroup (SimOnly a) Source # |
Instance details Defined in Clash.Magic Methods (<>) :: SimOnly a -> SimOnly a -> SimOnly a Source # sconcat :: NonEmpty (SimOnly a) -> SimOnly a Source # stimes :: Integral b => b -> SimOnly a -> SimOnly a Source #
Generic (SimOnly a) Source # |

Instance details

Defined in Clash.Magic

Associated Types

type Rep (SimOnly a) |
Instance details Defined in Clash.Magic type Rep (SimOnly a) = D1 ('MetaData "SimOnly" "Clash.Magic" "clash-prelude-1.8.4-1CKHk9HHRNIGPqhYHQsmcW" 'False) (C1 ('MetaCons "SimOnly" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

Methods

from :: SimOnly a -> Rep (SimOnly a) x Source #

to :: Rep (SimOnly a) x -> SimOnly a Source #

Eq a => Eq (SimOnly a) Source # |
Instance details Defined in Clash.Magic Methods (==) :: SimOnly a -> SimOnly a -> Bool Source # (/=) :: SimOnly a -> SimOnly a -> Bool Source #
Ord a => Ord (SimOnly a) Source # |
Instance details Defined in Clash.Magic Methods compare :: SimOnly a -> SimOnly a -> Ordering Source # (<) :: SimOnly a -> SimOnly a -> Bool Source # (<=) :: SimOnly a -> SimOnly a -> Bool Source # (>) :: SimOnly a -> SimOnly a -> Bool Source # (>=) :: SimOnly a -> SimOnly a -> Bool Source # max :: SimOnly a -> SimOnly a -> SimOnly a Source # min :: SimOnly a -> SimOnly a -> SimOnly a Source #
type Rep (SimOnly a) Source # |
Instance details Defined in Clash.Magic type Rep (SimOnly a) = D1 ('MetaData "SimOnly" "Clash.Magic" "clash-prelude-1.8.4-1CKHk9HHRNIGPqhYHQsmcW" 'False) (C1 ('MetaCons "SimOnly" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

# Static assertions

clashCompileError :: HasCallStack => String -> a Source #

Same as `error` but will make HDL generation fail if included in the final circuit.

This is useful for the error case of static assertions.

Note that the error message needs to be a literal, and during HDL generation the error message does not include a stack trace, so it had better be descriptive.