Copyright | (C) 2012-2016 University of Twente 2017 Myrtle Software Ltd 2017-2018 Google Inc. 2021 QBayLogic B.V. |
---|---|
License | BSD2 (see the file LICENSE) |
Maintainer | QBayLogic B.V. <devops@qbaylogic.com> |
Safe Haskell | None |
Language | Haskell2010 |
Utilities for converting Core Type/Term to Netlist datatypes
Synopsis
- hmFindWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
- instPort :: Text -> Expr
- stripFiltered :: FilteredHWType -> HWType
- stripVoid :: HWType -> HWType
- flattenFiltered :: FilteredHWType -> [[Bool]]
- isVoidMaybe :: Bool -> Maybe HWType -> Bool
- isVoid :: HWType -> Bool
- isFilteredVoid :: FilteredHWType -> Bool
- squashLets :: Term -> Term
- splitNormalized :: TyConMap -> Term -> Either String ([Id], [LetBinding], Id)
- unsafeCoreTypeToHWType :: SrcSpan -> String -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap FilteredHWType
- unsafeCoreTypeToHWTypeM' :: String -> Type -> NetlistMonad HWType
- unsafeCoreTypeToHWTypeM :: String -> Type -> NetlistMonad FilteredHWType
- coreTypeToHWTypeM' :: Type -> NetlistMonad (Maybe HWType)
- coreTypeToHWTypeM :: Type -> NetlistMonad (Maybe FilteredHWType)
- unexpectedProjectionErrorMsg :: DataRepr' -> Int -> Int -> String
- convertToCustomRepr :: HasCallStack => CustomReprs -> DataRepr' -> HWType -> HWType
- maybeConvertToCustomRepr :: CustomReprs -> Type -> FilteredHWType -> FilteredHWType
- coreTypeToHWType' :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap (Either String HWType)
- coreTypeToHWType :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap (Either String FilteredHWType)
- originalIndices :: [Bool] -> [Int]
- mkADT :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> String -> TyConName -> [Type] -> ExceptT String (State HWMap) FilteredHWType
- hasUnconstrainedExistential :: TyConMap -> DataCon -> Bool
- isRecursiveTy :: TyConMap -> TyConName -> Bool
- representableType :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> Bool -> TyConMap -> Type -> Bool
- typeSize :: HWType -> Int
- conSize :: HWType -> Int
- termHWType :: String -> Term -> NetlistMonad HWType
- termHWTypeM :: Term -> NetlistMonad (Maybe FilteredHWType)
- isBiSignalIn :: HWType -> Bool
- isBiSignalOut :: HWType -> Bool
- containsBiSignalIn :: HWType -> Bool
- mkUniqueNormalized :: HasCallStack => InScopeSet -> Maybe (Maybe TopEntity) -> ([Id], [LetBinding], Id) -> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], [(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id)
- orNothing :: Bool -> a -> Maybe a
- renameBinder :: (Id, Term) -> NetlistMonad [(Id, Id)]
- evalBlackBox :: HasCallStack => SomeBackend -> BlackBoxContext -> BlackBox -> Text
- mkUniqueArguments :: Subst -> Maybe (ExpandedTopEntity Identifier) -> [Id] -> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], Subst)
- mkUniqueResult :: Subst -> Maybe (ExpandedTopEntity Identifier) -> Id -> NetlistMonad (Maybe ([(Identifier, HWType)], [Declaration], Id, Subst))
- idToInPort :: Id -> NetlistMonad (Maybe (Identifier, HWType))
- idToOutPort :: Id -> NetlistMonad (Maybe (Identifier, HWType))
- idToPort :: Id -> NetlistMonad (Maybe (Identifier, HWType))
- id2identifier :: Id -> Identifier
- setRepName :: Text -> Name a -> Name a
- mkUnique :: Subst -> [Id] -> NetlistMonad ([Id], Subst)
- preserveState :: NetlistMonad a -> NetlistMonad a
- preserveVarEnv :: NetlistMonad a -> NetlistMonad a
- dcToLiteral :: HWType -> Int -> Literal
- extendPorts :: [PortName] -> [Maybe PortName]
- prefixParent :: String -> PortName -> PortName
- mkAssign :: Identifier -> HWType -> Expr -> [Declaration]
- convPrimitiveType :: HWType -> a -> NetlistMonad a -> NetlistMonad a
- toPrimitiveType :: Identifier -> HWType -> NetlistMonad ([Declaration], Identifier, Expr, HWType)
- fromPrimitiveType :: Identifier -> HWType -> NetlistMonad ([Declaration], Identifier, Expr, HWType)
- mkTopInput :: ExpandedPortName Identifier -> NetlistMonad ([(Identifier, HWType)], [Declaration], Expr, Identifier)
- portProductError :: String -> HWType -> ExpandedPortName Identifier -> a
- mkVectorChain :: Int -> HWType -> [Expr] -> Expr
- mkRTreeChain :: Int -> HWType -> [Expr] -> Expr
- genComponentName :: Bool -> Maybe Text -> Id -> Text
- genTopName :: IdentifierSetMonad m => Maybe Text -> TopEntity -> m Identifier
- stripAttributes :: HWType -> ([Attr'], HWType)
- mkTopOutput :: ExpandedPortName Identifier -> NetlistMonad ([(Identifier, HWType)], [Declaration], Identifier)
- mkTopCompDecl :: Maybe Text -> [Attr'] -> Identifier -> Identifier -> [(Expr, HWType, Expr)] -> [InstancePort] -> [InstancePort] -> Declaration
- mkTopUnWrapper :: Id -> ExpandedTopEntity Identifier -> (Identifier, HWType) -> [(Expr, HWType)] -> [Declaration] -> NetlistMonad [Declaration]
- data InstancePort = InstancePort {
- ip_id :: Identifier
- ip_type :: HWType
- mkTopInstInput :: ExpandedPortName Identifier -> NetlistMonad ([InstancePort], [Declaration], Identifier)
- throwAnnotatedSplitError :: String -> String -> NetlistMonad a
- mkTopInstOutput :: HasCallStack => ExpandedPortName Identifier -> NetlistMonad ([InstancePort], [Declaration], Identifier)
- nestM :: Modifier -> Modifier -> Maybe Modifier
- bindsExistentials :: [TyVar] -> [Var a] -> Bool
- iteAlts :: HWType -> [Alt] -> Maybe (Term, Term)
- withTicks :: [TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a
- affixName :: Text -> NetlistMonad Text
- data ExpandError
- = AttrError [Attr']
- | PortProductError PortName HWType
- expandTopEntityOrErrM :: (HasCallStack, IdentifierSetMonad m) => [(Maybe Id, FilteredHWType)] -> (Maybe Id, FilteredHWType) -> Maybe TopEntity -> m (ExpandedTopEntity Identifier)
- expandTopEntityOrErr :: HasCallStack => IdentifierSet -> [(Maybe Id, FilteredHWType)] -> (Maybe Id, FilteredHWType) -> Maybe TopEntity -> ExpandedTopEntity Identifier
- expandTopEntity :: HasCallStack => [(Maybe Id, FilteredHWType)] -> (Maybe Id, FilteredHWType) -> Maybe TopEntity -> Either ExpandError (ExpandedTopEntity (Either Text Text))
Documentation
instPort :: Text -> Expr Source #
Generate a simple port_name expression. See:
https://www.hdlworks.com/hdl_corner/vhdl_ref/VHDLContents/PortMap.htm
This function will simply make the left part of a single port map, e.g. Rst in:
Rst => Reset
If you need more complex constructions, e.g.
Q(3 downto 1)
you can build an Expr manually.
stripFiltered :: FilteredHWType -> HWType Source #
Throw away information indicating which constructor fields were filtered due to being void.
stripVoid :: HWType -> HWType Source #
Strip as many Void layers as possible. Might still return a Void if the void doesn't contain a hwtype.
flattenFiltered :: FilteredHWType -> [[Bool]] Source #
isFilteredVoid :: FilteredHWType -> Bool Source #
Same as isVoid
, but on FilteredHWType
instead of HWType
squashLets :: Term -> Term Source #
splitNormalized :: TyConMap -> Term -> Either String ([Id], [LetBinding], Id) Source #
Split a normalized term into: a list of arguments, a list of let-bindings, and a variable reference that is the body of the let-binding. Returns a String containing the error if the term was not in a normalized form.
unsafeCoreTypeToHWType Source #
:: SrcSpan | Approximate location in original source file |
-> String | |
-> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) | |
-> CustomReprs | |
-> TyConMap | |
-> Type | |
-> State HWMap FilteredHWType |
Converts a Core type to a HWType given a function that translates certain builtin types. Errors if the Core type is not translatable.
unsafeCoreTypeToHWTypeM' :: String -> Type -> NetlistMonad HWType Source #
Same as unsafeCoreTypeToHWTypeM
, but discards void filter information
unsafeCoreTypeToHWTypeM :: String -> Type -> NetlistMonad FilteredHWType Source #
Converts a Core type to a HWType within the NetlistMonad; errors on failure
:: Type | Type to convert to HWType |
-> NetlistMonad (Maybe HWType) |
Same as coreTypeToHWTypeM
, but discards void filter information
:: Type | Type to convert to HWType |
-> NetlistMonad (Maybe FilteredHWType) |
Converts a Core type to a HWType within the NetlistMonad; Nothing
on failure
unexpectedProjectionErrorMsg Source #
Constructs error message for unexpected projections out of a type annotated with a custom bit representation.
convertToCustomRepr :: HasCallStack => CustomReprs -> DataRepr' -> HWType -> HWType Source #
Helper function of maybeConvertToCustomRepr
maybeConvertToCustomRepr Source #
:: CustomReprs | Map containing all custom representations index on its type |
-> Type | Custom reprs are index on type, so we need the clash core type to look it up. |
-> FilteredHWType | Type of previous argument represented as a HWType |
-> FilteredHWType |
Given a map containing custom bit representation, a type, and the same type represented as HWType, convert the HWType to a CustomSP/CustomSum if it has a custom bit representation.
:: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) | |
-> CustomReprs | |
-> TyConMap | |
-> Type | Type to convert to HWType |
-> State HWMap (Either String HWType) |
Same as coreTypeToHWType
, but discards void filter information
:: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) | |
-> CustomReprs | |
-> TyConMap | |
-> Type | Type to convert to HWType |
-> State HWMap (Either String FilteredHWType) |
Converts a Core type to a HWType given a function that translates certain builtin types. Returns a string containing the error message when the Core type is not translatable.
Generates original indices in list before filtering, given a list of removed indices.
>>>
originalIndices [False, False, True, False]
[0,1,3]
:: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) | Hardcoded Type -> HWType translator |
-> CustomReprs | |
-> TyConMap | TyCon cache |
-> String | String representation of the Core type for error messages |
-> TyConName | The TyCon |
-> [Type] | Its applied arguments |
-> ExceptT String (State HWMap) FilteredHWType | An error string or a tuple with the type and possibly a list of removed arguments. |
Converts an algebraic Core type (split into a TyCon and its argument) to a HWType.
hasUnconstrainedExistential :: TyConMap -> DataCon -> Bool Source #
Determine whether a data constructor has unconstrained existential type variables, i.e. those that cannot be inferred by the (potential) constraints between the existential type variables and universal type variables.
So here we have an example of a constrained existential:
data Vec :: Nat -> Type -> Type where Nil :: Vec 0 a Cons :: forall m . (n ~ m + 1) => a -> Vec m a -> Vec n a
where we can generate a type for m
when we know n
(by doing `n-1`).
And here is an example of an unconstrained existential:
data SomeSNat where where SomeSNat :: forall m . SNat m -> SomeSNat
where there is no way to generate a type for m
from any context.
So why do we care? Because terms need to be completely monomorphic in order to be translated to circuits. And having a topEntity lambda-bound variable with an unconstrained existential type prevents us from achieving a fully monomorphic term.
isRecursiveTy :: TyConMap -> TyConName -> Bool Source #
Simple check if a TyCon is recursively defined.
Note [Look through type families in recursivity check]
Consider:
data SList :: [Type] -> Type where SNil :: SList [] CSons :: a -> Sing (as :: [k]) -> SList (a:as) type family Sing [a] = SList [a]
Without looking through type families, we would think that SList is not recursive. This lead to issue #1921
:: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) | |
-> CustomReprs | |
-> Bool | String considered representable |
-> TyConMap | |
-> Type | |
-> Bool |
Determines if a Core type is translatable to a HWType given a function that translates certain builtin types.
typeSize :: HWType -> Int Source #
Determines the bitsize of a type. For types that don't get turned into real values in hardware (string, integer) the size is 0.
termHWType :: String -> Term -> NetlistMonad HWType Source #
Gives the HWType corresponding to a term. Returns an error if the term has a Core type that is not translatable to a HWType.
:: Term | Term to convert to HWType |
-> NetlistMonad (Maybe FilteredHWType) |
Gives the HWType corresponding to a term. Returns Nothing
if the term has
a Core type that is not translatable to a HWType.
isBiSignalIn :: HWType -> Bool Source #
isBiSignalOut :: HWType -> Bool Source #
containsBiSignalIn :: HWType -> Bool Source #
:: HasCallStack | |
=> InScopeSet | |
-> Maybe (Maybe TopEntity) | Top entity annotation where:
|
-> ([Id], [LetBinding], Id) | |
-> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], [(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id) |
Uniquely rename all the variables and their references in a normalized term
renameBinder :: (Id, Term) -> NetlistMonad [(Id, Id)] Source #
Set the name of the binder if the given term is a blackbox requesting a specific name for the result binder. It might return multiple names in case of a multi result primitive.
evalBlackBox :: HasCallStack => SomeBackend -> BlackBoxContext -> BlackBox -> Text Source #
Render a blackbox given its context. Renders _just_ the blackbox, not any corresponding includes, libraries, and so forth.
:: Subst | |
-> Maybe (ExpandedTopEntity Identifier) | Top entity annotation where:
|
-> [Id] | |
-> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], Subst) |
:: Subst | |
-> Maybe (ExpandedTopEntity Identifier) | Top entity annotation where:
|
-> Id | |
-> NetlistMonad (Maybe ([(Identifier, HWType)], [Declaration], Id, Subst)) |
idToInPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) Source #
Same as idToPort, but * Throws an error if the port is a composite type with a BiSignalIn
idToOutPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) Source #
Same as idToPort, but: * Throws an error if port is of type BiSignalIn
idToPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) Source #
id2identifier :: Id -> Identifier Source #
:: Subst | Existing substitution |
-> [Id] | IDs to make unique |
-> NetlistMonad ([Id], Subst) | (Unique IDs, update substitution) |
Make a set of IDs unique; also returns a substitution from old ID to new updated unique ID.
preserveState :: NetlistMonad a -> NetlistMonad a Source #
Preserve the complete state before running an action, and restore it afterwards.
preserveVarEnv :: NetlistMonad a -> NetlistMonad a Source #
Preserve the Netlist _curCompNm
,_seenIds
when executing
a monadic action
TopEntity Annotations
extendPorts :: [PortName] -> [Maybe PortName] Source #
prefixParent :: String -> PortName -> PortName Source #
Prefix given string before portnames except when this string is empty.
mkAssign :: Identifier -> HWType -> Expr -> [Declaration] Source #
convPrimitiveType :: HWType -> a -> NetlistMonad a -> NetlistMonad a Source #
toPrimitiveType :: Identifier -> HWType -> NetlistMonad ([Declaration], Identifier, Expr, HWType) Source #
Top entities only expose primitive types or types that don't need explicit
conversion to a primitive type (i.e., no types from the _types
module). This
function converts from a custom type to a primitive type if needed.
See HWKind
for more info on primitive type kinds.
fromPrimitiveType :: Identifier -> HWType -> NetlistMonad ([Declaration], Identifier, Expr, HWType) Source #
Top entities only expose primitive types or types that don't need explicit
conversion to a primitive type (i.e., no types from the _types
module). This
function converts from a primitive type to a custom type if needed.
See HWKind
for more info on primitive type kinds.
:: ExpandedPortName Identifier | Port name description |
-> NetlistMonad ([(Identifier, HWType)], [Declaration], Expr, Identifier) | (port names, signal decls for intermediate signals, argument expr, argument id) |
Create port names for the declaration of a top entity. For instantiation
see mkTopInstInput
.
portProductError :: String -> HWType -> ExpandedPortName Identifier -> a Source #
mkVectorChain :: Int -> HWType -> [Expr] -> Expr Source #
Create a Vector chain for a list of Identifier
s
mkRTreeChain :: Int -> HWType -> [Expr] -> Expr Source #
Create a RTree chain for a list of Identifier
s
:: IdentifierSetMonad m | |
=> Maybe Text | Top entity name prefix |
-> TopEntity | Top entity annotation |
-> m Identifier | New identifier |
stripAttributes :: HWType -> ([Attr'], HWType) Source #
Strips one or more layers of attributes from a HWType; stops at first non-Annotated. Accumulates all attributes of nested annotations.
mkTopOutput :: ExpandedPortName Identifier -> NetlistMonad ([(Identifier, HWType)], [Declaration], Identifier) Source #
Create output port names for the declaration of a top entity. For
instantiation see mkTopInstOutput
.
:: Maybe Text | Library entity is defined in |
-> [Attr'] | Attributes to add to generate code |
-> Identifier | The component's (or entity's) name |
-> Identifier | Instance label |
-> [(Expr, HWType, Expr)] | List of parameters for this component (param name, param type, param value) |
-> [InstancePort] | Input port assignments |
-> [InstancePort] | Output port assignments |
-> Declaration |
:: Id | Name of the TopEntity component |
-> ExpandedTopEntity Identifier | A corresponding |
-> (Identifier, HWType) | The name and type of the signal to which to assign the result |
-> [(Expr, HWType)] | The arguments with voids filtered. |
-> [Declaration] | Tick declarations |
-> NetlistMonad [Declaration] |
Instantiate a TopEntity, and add the proper type-conversions where needed
data InstancePort Source #
InstancePort | |
|
:: ExpandedPortName Identifier | The |
-> NetlistMonad ([InstancePort], [Declaration], Identifier) | (ports to assign, declarations for intermediate signals, argument signal) |
Generate input port(s) associated with a single argument for an instantiation of a top entity. This function composes the input ports into a single signal and returns its name.
throwAnnotatedSplitError :: String -> String -> NetlistMonad a Source #
Consider the following type signature:
f :: Signal dom (Vec 6 A) `Annotate` Attr "keep" -> Signal dom (Vec 6 B)
What does the annotation mean, considering that Clash will split these vectors into multiple in- and output ports? Should we apply the annotation to all individual ports? How would we handle pin mappings? For now, we simply throw an error. This is a helper function to do so.
:: HasCallStack | |
=> ExpandedPortName Identifier | The |
-> NetlistMonad ([InstancePort], [Declaration], Identifier) | (ports to assign, declarations for intermediate signals, result signal) |
Generate output port(s) for an instantiation of a top entity. This function combines all output ports into a signal identifier and returns its name.
nestM :: Modifier -> Modifier -> Maybe Modifier Source #
Try to merge nested modifiers into a single modifier, needed by the VHDL and SystemVerilog backend.
bindsExistentials :: [TyVar] -> [Var a] -> Bool Source #
Determines if any type variables (exts) are bound in any of the given type or term variables (tms). It's currently only used to detect bound existentials, hence the name.
:: [TickInfo] | |
-> ([Declaration] -> NetlistMonad a) | The source ticks are turned into |
-> NetlistMonad a |
Run a NetlistMonad computation in the context of the given source ticks and name modifier ticks
affixName :: Text -> NetlistMonad Text Source #
Add the pre- and suffix names in the current environment to the given identifier
data ExpandError Source #
Errors expandTopEntity
might yield
AttrError [Attr'] | Synthesis attributes are not supported on PortProducts |
PortProductError PortName HWType | Something was annotated as being a PortProduct, but wasn't one |
expandTopEntityOrErrM Source #
:: (HasCallStack, IdentifierSetMonad m) | |
=> [(Maybe Id, FilteredHWType)] | Arguments. Ids are used as name hints. |
-> (Maybe Id, FilteredHWType) | Result. Id is used as name hint. |
-> Maybe TopEntity | If Nothing, an expanded top entity will be generated as if defSyn was passed. |
-> m (ExpandedTopEntity Identifier) | Either some error (see ExpandError) or and expanded top entity. All identifiers in the expanded top entity will be added to NetlistState's IdentifierSet. |
Same as expandTopEntity
, but also adds identifiers to the identifier
set of the monad.
:: HasCallStack | |
=> IdentifierSet | Settings of this IdentifierSet will be used to generate valid identifiers. Note that the generated identifiers are not guaranteed to be unique w.r.t. this set. |
-> [(Maybe Id, FilteredHWType)] | Arguments. Ids are used as name hints. |
-> (Maybe Id, FilteredHWType) | Result. Id is used as name hint. |
-> Maybe TopEntity | If Nothing, an expanded top entity will be generated as if defSyn was passed. |
-> ExpandedTopEntity Identifier | Either some error (see ExpandError) or and expanded top entity. All identifiers in the expanded top entity will be added to NetlistState's IdentifierSet. |
Take a top entity and expand its port names. I.e., make sure that every port that should be generated in the HDL is part of the data structure.
:: HasCallStack | |
=> [(Maybe Id, FilteredHWType)] | Arguments. Ids are used as name hints. |
-> (Maybe Id, FilteredHWType) | Result. Id is used as name hint. |
-> Maybe TopEntity | Top entity to expand |
-> Either ExpandError (ExpandedTopEntity (Either Text Text)) | Either some error (see ExpandError) or and expanded top entity. The expanded top entity in turn contains an Either too. Left means that the name was supplied by the user and should be inserted at verbatim, Right is a name generated by Clash. |
Take a top entity and expand its port names. I.e., make sure that every port that should be generated in the HDL is part of the data structure. It works on FilteredHWType in order to generate stable port names.