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 |
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 :: SSymbol sym -> a -> a
- deDup :: forall a. a -> a
- noDeDup :: forall a. a -> a
- clashSimulation :: Bool
- data SimOnly a = SimOnly a
- clashCompileError :: forall a. 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.
:: 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 :: forall a. 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 :: forall a. 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:
- The deduplicated function is in the critical path, and the addition of the multiplexers further increased the propagation delay.
- 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
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.
SimOnly a |
Instances
Static assertions
clashCompileError :: forall a. 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.