-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | CAES Language for Synchronous Hardware - As a Library -- -- Clash is a functional hardware description language that borrows both -- its syntax and semantics from the functional programming language -- Haskell. The Clash compiler transforms these high-level descriptions -- to low-level synthesizable VHDL, Verilog, or SystemVerilog. -- -- Features of Clash: -- -- -- -- This package provides: -- -- -- -- Front-ends (for: parsing, typecheck, etc.) are provided by separate -- packages: -- -- -- -- Prelude library: -- https://hackage.haskell.org/package/clash-prelude @package clash-lib @version 1.2.3 module Clash.Debug debugIsOn :: Bool -- | Performs trace when first argument evaluates to True traceIf :: Bool -> String -> a -> a traceWith :: (a -> String) -> a -> a traceShowWith :: Show b => (a -> b) -> a -> a -- | Transform/format a Netlist Identifier so that it is acceptable as a -- HDL identifier module Clash.Netlist.Id data IdType Basic :: IdType Extended :: IdType mkBasicId' :: HDL -> Bool -> Text -> Text stripDollarPrefixes :: Text -> Text -- | Collection of utilities module Clash.Util.Graph -- | See: https://en.wikipedia.org/wiki/Topological_sorting. This -- function errors if edges mention nodes not mentioned in the node list -- or if the given graph contains cycles. topSort :: [(Int, a)] -> [(Int, Int)] -> Either String [a] -- | Same as `reverse (topSort nodes edges)` if alternative representations -- are considered the same. That is, topSort might produce multiple -- answers and still deliver on its promise of yielding a topologically -- sorted node list. Likewise, this function promises one of those -- lists in reverse, but not necessarily the reverse of topSort itself. reverseTopSort :: [(Int, a)] -> [(Int, Int)] -> Either String [a] module Clash.Util.Interpolate i :: QuasiQuoter instance GHC.Show.Show Clash.Util.Interpolate.Node instance GHC.Show.Show Clash.Util.Interpolate.Line module Clash.Pretty unsafeLookupEnvWord :: HasCallStack => String -> Word -> Word defaultPprWidth :: Int showDoc :: Doc ann -> String removeAnnotations :: Doc ann -> Doc () -- | A variant of Pretty that is not polymorphic on the type of -- annotations. This is needed to derive instances from Clash's pretty -- printer (PrettyPrec), which annotates documents with Clash-specific -- information and, therefore, fixes the type of annotations. class ClashPretty a clashPretty :: ClashPretty a => a -> Doc () fromPretty :: Pretty a => a -> Doc () module Clash.Unique type Unique = Int class Uniquable a getUnique :: Uniquable a => a -> Unique setUnique :: Uniquable a => a -> Unique -> a -- | Map indexed by a Uniquable key data UniqMap a -- | Check whether the map is empty nullUniqMap :: UniqMap a -> Bool -- | Look up a value in the map lookupUniqMap :: Uniquable a => a -> UniqMap b -> Maybe b -- | Like lookupUniqMap', but errors out when the key is not present lookupUniqMap' :: (HasCallStack, Uniquable a) => UniqMap b -> a -> b -- | The empty map emptyUniqMap :: UniqMap a -- | Map with a single key-value pair unitUniqMap :: Uniquable a => a -> b -> UniqMap b -- | Extend the map with a new key-value pair. If the key already exists in -- the associated value will be overwritten extendUniqMap :: Uniquable a => a -> b -> UniqMap b -> UniqMap b -- | Extend the map with a new key-value pair. If the key already exists in -- the associated value will be combined with the new value using the -- function provided extendUniqMapWith :: Uniquable a => a -> b -> (b -> b -> b) -> UniqMap b -> UniqMap b -- | Extend the map with a list of key-value pairs. Positions with existing -- keys will be overwritten with the new values extendListUniqMap :: Uniquable a => UniqMap b -> [(a, b)] -> UniqMap b -- | Remove a key-value pair from the map delUniqMap :: Uniquable a => UniqMap b -> a -> UniqMap b -- | Remove a list of key-value pairs from the map delListUniqMap :: Uniquable a => UniqMap b -> [a] -> UniqMap b -- | A (left-biased) union of two maps unionUniqMap :: UniqMap a -> UniqMap a -> UniqMap a -- | A union of two maps, key-value pairs with the same key will be merged -- using the given function unionUniqMapWith :: (a -> a -> a) -> UniqMap a -> UniqMap a -> UniqMap a -- | Get the difference between two maps differenceUniqMap :: UniqMap a -> UniqMap a -> UniqMap a -- | Apply a function to every element in the map mapUniqMap :: (a -> b) -> UniqMap a -> UniqMap b -- | Apply a function to every element in the map. When the function -- returns Nothing, the key-value pair will be removed mapMaybeUniqMap :: (a -> Maybe b) -> UniqMap a -> UniqMap b -- | Derive a map where all the elements adhere to the predicate filterUniqMap :: (b -> Bool) -> UniqMap b -> UniqMap b -- | Check whether a key is in the map elemUniqMap :: Uniquable a => a -> UniqMap b -> Bool -- | Check whether a key is not in the map notElemUniqMap :: Uniquable a => a -> UniqMap b -> Bool -- | Check whether an element exists in the uniqmap based on a given -- Unique elemUniqMapDirectly :: Unique -> UniqMap b -> Bool -- | Right-fold over a map using both the key and value foldrWithUnique :: (Unique -> a -> b -> b) -> b -> UniqMap a -> b -- | Strict left-fold over a map using both the key and the value foldlWithUnique' :: (a -> Unique -> b -> a) -> a -> UniqMap b -> a -- | Extract the elements of a map into a list eltsUniqMap :: UniqMap a -> [a] -- | Extract the keys of a map into a list keysUniqMap :: UniqMap a -> [Unique] -- | Convert a list of key-value pairs to a map listToUniqMap :: Uniquable a => [(a, b)] -> UniqMap b -- | Convert a map to a list of key-value pairs toListUniqMap :: UniqMap a -> [(Unique, a)] -- | Convert a UniqMap to a UniqSet uniqMapToUniqSet :: UniqMap a -> UniqSet a -- | Set of things that have a Unique -- -- Invariant: they keys in the map are the uniques of the values data UniqSet a -- | Look up an element in the set, returns it if it exists lookupUniqSet :: Uniquable a => a -> UniqSet b -> Maybe b -- | The empty set emptyUniqSet :: UniqSet a -- | Set with a single element unitUniqSet :: Uniquable a => a -> UniqSet a -- | Add an element to the set extendUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a -- | Union two sets unionUniqSet :: UniqSet a -> UniqSet a -> UniqSet a -- | Remove an element based on the Unique it contains delUniqSetDirectly :: Unique -> UniqSet b -> UniqSet b -- | Check whether an element exists in the set elemUniqSet :: Uniquable a => a -> UniqSet a -> Bool -- | Check whether an element does not exist in the set notElemUniqSet :: Uniquable a => a -> UniqSet a -> Bool -- | Check whether an element exists in the set based on the Unique -- contained in that element elemUniqSetDirectly :: Unique -> UniqSet a -> Bool -- | Check whether a A is a subset of B subsetUniqSet :: UniqSet a -> UniqSet a -> Bool -- | Create a set out of a list of elements that contain a Unique mkUniqSet :: Uniquable a => [a] -> UniqSet a -- | Get the elements of the set as a list eltsUniqSet :: UniqSet a -> [a] instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Clash.Unique.UniqMap a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Clash.Unique.UniqMap a) instance GHC.Base.Monoid (Clash.Unique.UniqMap a) instance GHC.Base.Semigroup (Clash.Unique.UniqMap a) instance Data.Traversable.Traversable Clash.Unique.UniqMap instance Data.Foldable.Foldable Clash.Unique.UniqMap instance GHC.Base.Functor Clash.Unique.UniqMap instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Clash.Unique.UniqSet a) instance GHC.Base.Monoid (Clash.Unique.UniqSet a) instance GHC.Base.Semigroup (Clash.Unique.UniqSet a) instance Data.Foldable.Foldable Clash.Unique.UniqSet instance Clash.Pretty.ClashPretty a => Clash.Pretty.ClashPretty (Clash.Unique.UniqSet a) instance Clash.Pretty.ClashPretty a => Clash.Pretty.ClashPretty (Clash.Unique.UniqMap a) instance Clash.Pretty.ClashPretty a => GHC.Show.Show (Clash.Unique.UniqMap a) instance Clash.Unique.Uniquable GHC.Types.Int module Data.Text.Prettyprint.Doc.Extra type Doc = Doc () layoutOneLine :: Doc ann -> SimpleDocStream ann renderOneLine :: Doc ann -> Text int :: Applicative f => Int -> f Doc integer :: Applicative f => Integer -> f Doc char :: Applicative f => Char -> f Doc lbrace :: Applicative f => f Doc rbrace :: Applicative f => f Doc colon :: Applicative f => f Doc semi :: Applicative f => f Doc equals :: Applicative f => f Doc comma :: Applicative f => f Doc dot :: Applicative f => f Doc lparen :: Applicative f => f Doc rparen :: Applicative f => f Doc space :: Applicative f => f Doc brackets :: Functor f => f Doc -> f Doc braces :: Functor f => f Doc -> f Doc tupled :: Functor f => f [Doc] -> f Doc (<+>) :: Applicative f => f Doc -> f Doc -> f Doc infixr 6 <+> vcat :: Functor f => f [Doc] -> f Doc hcat :: Functor f => f [Doc] -> f Doc nest :: Functor f => Int -> f Doc -> f Doc indent :: Functor f => Int -> f Doc -> f Doc parens :: Functor f => f Doc -> f Doc emptyDoc :: Applicative f => f Doc punctuate :: Applicative f => f Doc -> f [Doc] -> f [Doc] encloseSep :: Applicative f => f Doc -> f Doc -> f Doc -> f [Doc] -> f Doc line :: Applicative f => f Doc line' :: Applicative f => f Doc softline :: Applicative f => f Doc softline' :: Applicative f => f Doc pretty :: (Applicative f, Pretty a) => a -> f Doc stringS :: Applicative f => Text -> f Doc string :: Applicative f => Text -> f Doc squotes :: Applicative f => f Doc -> f Doc dquotes :: Functor f => f Doc -> f Doc align :: Functor f => f Doc -> f Doc hsep :: Functor f => f [Doc] -> f Doc vsep :: Functor f => f [Doc] -> f Doc isEmpty :: Doc -> Bool fill :: Applicative f => Int -> f Doc -> f Doc column :: Functor f => f (Int -> Doc) -> f Doc nesting :: Functor f => f (Int -> Doc) -> f Doc flatAlt :: Applicative f => f Doc -> f Doc -> f Doc comment :: Applicative f => Text -> Text -> f Doc squote :: Applicative f => f Doc -- | Options to influence the layout algorithms. newtype LayoutOptions LayoutOptions :: PageWidth -> LayoutOptions [layoutPageWidth] :: LayoutOptions -> PageWidth -- | Maximum number of characters that fit in one line. The layout -- algorithms will try not to exceed the set limit by inserting line -- breaks when applicable (e.g. via softline'). data PageWidth -- | Layouters should not exceed the specified space per line. -- -- AvailablePerLine :: Int -> Double -> PageWidth -- | Layouters should not introduce line breaks on their own. Unbounded :: PageWidth -- | (layoutCompact x) lays out the document x without -- adding any indentation. Since no 'pretty' printing is involved, this -- layouter is very fast. The resulting output contains fewer characters -- than a prettyprinted version and can be used for output that is read -- by other programs. -- --
--   >>> let doc = hang 4 (vsep ["lorem", "ipsum", hang 4 (vsep ["dolor", "sit"])])
--   
--   >>> doc
--   lorem
--       ipsum
--       dolor
--           sit
--   
-- --
--   >>> let putDocCompact = renderIO System.IO.stdout . layoutCompact
--   
--   >>> putDocCompact doc
--   lorem
--   ipsum
--   dolor
--   sit
--   
layoutCompact :: Doc ann -> SimpleDocStream ann -- | This is the default layout algorithm, and it is used by show, -- putDoc and hPutDoc. -- -- layoutPretty commits to rendering something in a -- certain way if the next element fits the layout constraints; in other -- words, it has one SimpleDocStream element lookahead when -- rendering. Consider using the smarter, but a bit less performant, -- layoutSmart algorithm if the results seem to run off -- to the right before having lots of line breaks. layoutPretty :: LayoutOptions -> Doc ann -> SimpleDocStream ann -- | (renderLazy sdoc) takes the output sdoc from -- a rendering function and transforms it to lazy text. -- --
--   >>> let render = TL.putStrLn . renderLazy . layoutPretty defaultLayoutOptions
--   
--   >>> let doc = "lorem" <+> align (vsep ["ipsum dolor", parens "foo bar", "sit amet"])
--   
--   >>> render doc
--   lorem ipsum dolor
--         (foo bar)
--         sit amet
--   
renderLazy :: SimpleDocStream ann -> Text instance GHC.Base.Applicative f => Data.String.IsString (f Data.Text.Prettyprint.Doc.Extra.Doc) -- | Names module Clash.Core.Name data NameSort User :: NameSort System :: NameSort Internal :: NameSort type OccName = Text data Name a Name :: NameSort -> !OccName -> {-# UNPACK #-} !Unique -> !SrcSpan -> Name a [nameSort] :: Name a -> NameSort [nameOcc] :: Name a -> !OccName [nameUniq] :: Name a -> {-# UNPACK #-} !Unique [nameLoc] :: Name a -> !SrcSpan mkUnsafeName :: NameSort -> Text -> Unique -> Name a mkUnsafeSystemName :: Text -> Unique -> Name a mkUnsafeInternalName :: Text -> Unique -> Name a appendToName :: Name a -> Text -> Name a -- | Built-in "bad" SrcSpans for common sources of location -- uncertainty noSrcSpan :: SrcSpan instance Data.Binary.Class.Binary Clash.Core.Name.NameSort instance Data.Hashable.Class.Hashable Clash.Core.Name.NameSort instance Control.DeepSeq.NFData Clash.Core.Name.NameSort instance GHC.Generics.Generic Clash.Core.Name.NameSort instance GHC.Show.Show Clash.Core.Name.NameSort instance GHC.Classes.Ord Clash.Core.Name.NameSort instance GHC.Classes.Eq Clash.Core.Name.NameSort instance Data.Binary.Class.Binary (Clash.Core.Name.Name a) instance Control.DeepSeq.NFData (Clash.Core.Name.Name a) instance GHC.Generics.Generic (Clash.Core.Name.Name a) instance GHC.Show.Show (Clash.Core.Name.Name a) instance GHC.Classes.Eq (Clash.Core.Name.Name a) instance GHC.Classes.Ord (Clash.Core.Name.Name a) instance Data.Hashable.Class.Hashable (Clash.Core.Name.Name a) instance Clash.Unique.Uniquable (Clash.Core.Name.Name a) -- | Variables in CoreHW module Clash.Core.Var -- | Interal version of Clash.Annotations.SynthesisAttributes.Attr. -- -- Needed because Clash.Annotations.SynthesisAttributes.Attr uses the -- Symbol kind for names, which do not have a term-level representation data Attr' BoolAttr' :: String -> Bool -> Attr' IntegerAttr' :: String -> Integer -> Attr' StringAttr' :: String -> String -> Attr' Attr' :: String -> Attr' -- | Variables in CoreHW data Var a -- | Constructor for type variables TyVar :: !Name a -> {-# UNPACK #-} !Unique -> Kind -> Var a [varName] :: Var a -> !Name a -- | Invariant: forall x . varUniq x ~ nameUniq (varName x) [varUniq] :: Var a -> {-# UNPACK #-} !Unique [varType] :: Var a -> Kind -- | Constructor for term variables Id :: !Name a -> {-# UNPACK #-} !Unique -> Type -> IdScope -> Var a [varName] :: Var a -> !Name a -- | Invariant: forall x . varUniq x ~ nameUniq (varName x) [varUniq] :: Var a -> {-# UNPACK #-} !Unique [varType] :: Var a -> Type [idScope] :: Var a -> IdScope data IdScope GlobalId :: IdScope LocalId :: IdScope -- | Term variable type Id = Var Term -- | Type variable type TyVar = Var Type -- | Make a term variable mkId :: Type -> IdScope -> TmName -> Id mkLocalId :: Type -> TmName -> Id mkGlobalId :: Type -> TmName -> Id -- | Make a type variable mkTyVar :: Kind -> TyName -> TyVar setVarUnique :: Var a -> Unique -> Var a setVarType :: Var a -> Type -> Var a setIdScope :: IdScope -> Var a -> Var a -- | Change the name of a variable modifyVarName :: (Name a -> Name a) -> Var a -> Var a isGlobalId :: Var a -> Bool isLocalId :: Var a -> Bool attrName :: Attr' -> String instance Data.Binary.Class.Binary Clash.Core.Var.Attr' instance GHC.Classes.Ord Clash.Core.Var.Attr' instance Data.Hashable.Class.Hashable Clash.Core.Var.Attr' instance GHC.Generics.Generic Clash.Core.Var.Attr' instance Control.DeepSeq.NFData Clash.Core.Var.Attr' instance GHC.Show.Show Clash.Core.Var.Attr' instance GHC.Classes.Eq Clash.Core.Var.Attr' instance GHC.Classes.Ord Clash.Core.Var.IdScope instance GHC.Classes.Eq Clash.Core.Var.IdScope instance Data.Binary.Class.Binary Clash.Core.Var.IdScope instance Data.Hashable.Class.Hashable Clash.Core.Var.IdScope instance Control.DeepSeq.NFData Clash.Core.Var.IdScope instance GHC.Generics.Generic Clash.Core.Var.IdScope instance GHC.Show.Show Clash.Core.Var.IdScope instance Data.Binary.Class.Binary (Clash.Core.Var.Var a) instance Data.Hashable.Class.Hashable (Clash.Core.Var.Var a) instance Control.DeepSeq.NFData (Clash.Core.Var.Var a) instance GHC.Generics.Generic (Clash.Core.Var.Var a) instance GHC.Show.Show (Clash.Core.Var.Var a) instance GHC.Classes.Eq (Clash.Core.Var.Var a) instance GHC.Classes.Ord (Clash.Core.Var.Var a) instance Clash.Unique.Uniquable (Clash.Core.Var.Var a) -- | Assortment of utility function used in the Clash library module Clash.Util -- | A class that can generate unique numbers class Monad m => MonadUnique m -- | Get a new unique getUniqueM :: MonadUnique m => m Int data ClashException ClashException :: SrcSpan -> String -> Maybe String -> ClashException assertPanic :: String -> Int -> a assertPprPanic :: HasCallStack => String -> Int -> Doc ann -> a pprPanic :: String -> Doc ann -> a callStackDoc :: HasCallStack => Doc ann warnPprTrace :: HasCallStack => Bool -> String -> Int -> Doc ann -> a -> a pprTrace :: String -> Doc ann -> a -> a pprTraceDebug :: String -> Doc ann -> a -> a pprDebugAndThen :: (String -> a) -> Doc ann -> Doc ann -> a -- | Create a TH expression that returns the a formatted string containing -- the name of the module curLoc is spliced into, and the line -- where it was spliced. curLoc :: Q Exp -- | Cache the result of a monadic action makeCached :: (MonadState s m, Hashable k, Eq k) => k -> Lens' s (HashMap k v) -> m v -> m v -- | Cache the result of a monadic action using a UniqMap makeCachedU :: (MonadState s m, Uniquable k) => k -> Lens' s (UniqMap v) -> m v -> m v combineM :: Applicative f => (a -> f b) -> (c -> f d) -> (a, c) -> f (b, d) -- | Same as indexNote with last two arguments swapped indexNote' :: HasCallStack => String -> Int -> [a] -> a -- | Unsafe indexing, return a custom error message when indexing fails indexNote :: HasCallStack => String -> [a] -> Int -> a clashLibVersion :: Version -- | x y -> floor (logBase x y), x > 1 && y > 0 flogBase :: Integer -> Integer -> Maybe Int -- | x y -> ceiling (logBase x y), x > 1 && y > 0 clogBase :: Integer -> Integer -> Maybe Int -- | Get the package id of the type of a value >>> -- pkgIdFromTypeable (undefined :: TopEntity) -- "clash-prelude-0.99.3-64904d90747cb49e17166bbc86fec8678918e4ead3847193a395b258e680373c" pkgIdFromTypeable :: Typeable a => a -> String reportTimeDiff :: UTCTime -> UTCTime -> String -- | Left-biased choice on maybes orElse :: Maybe a -> Maybe a -> Maybe a -- | Left-biased choice on maybes orElses :: [Maybe a] -> Maybe a wantedLanguageExtensions :: [Extension] unwantedLanguageExtensions :: [Extension] -- | Right-to-left composition of Kleisli arrows. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
--   (.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
--   (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
--   
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 <=< -- | Left-to-right composition of Kleisli arrows. -- -- '(bs >=> cs) a' can be understood as the -- do expression -- --
--   do b <- bs a
--      cs b
--   
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 >=> -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& -- | A mirror image of first. -- -- The default definition may be overridden with a more efficient version -- if desired. second :: Arrow a => a b c -> a (d, b) (d, c) -- | Send the first component of the input through the argument arrow, and -- copy the rest unchanged to the output. first :: Arrow a => a b c -> a (b, d) (c, d) -- | Split the input between the two argument arrows and combine their -- output. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient version -- if desired. (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c') infixr 3 *** -- | on b u x y runs the binary function b -- on the results of applying unary function u to two -- arguments x and y. From the opposite perspective, it -- transforms two inputs and combines the outputs. -- --
--   ((+) `on` f) x y = f x + f y
--   
-- -- Typical usage: sortBy (compare `on` -- fst). -- -- Algebraic properties: -- -- on :: (b -> b -> c) -> (a -> b) -> a -> a -> c infixl 0 `on` -- | Build lenses (and traversals) with a sensible default configuration. -- -- e.g. -- --
--   data FooBar
--     = Foo { _x, _y :: Int }
--     | Bar { _x :: Int }
--   makeLenses ''FooBar
--   
-- -- will create -- --
--   x :: Lens' FooBar Int
--   x f (Foo a b) = (\a' -> Foo a' b) <$> f a
--   x f (Bar a)   = Bar <$> f a
--   y :: Traversal' FooBar Int
--   y f (Foo a b) = (\b' -> Foo a  b') <$> f b
--   y _ c@(Bar _) = pure c
--   
-- --
--   makeLenses = makeLensesWith lensRules
--   
makeLenses :: Name -> DecsQ -- | Source Span -- -- A SrcSpan identifies either a specific portion of a text file -- or a human-readable description of a location. data SrcSpan -- | Built-in "bad" SrcSpans for common sources of location -- uncertainty noSrcSpan :: SrcSpan -- | Request a CallStack. -- -- NOTE: The implicit parameter ?callStack :: CallStack is an -- implementation detail and should not be considered part of the -- CallStack API, we may decide to change the implementation in -- the future. type HasCallStack = ?callStack :: CallStack instance GHC.Base.Monad m => Clash.Util.MonadUnique (Control.Monad.Trans.State.Lazy.StateT GHC.Types.Int m) instance GHC.Show.Show Clash.Util.ClashException instance GHC.Exception.Type.Exception Clash.Util.ClashException -- | Data Constructors in CoreHW module Clash.Core.DataCon -- | Data Constructor data DataCon MkData :: !DcName -> {-# UNPACK #-} !Unique -> !ConTag -> !Type -> [TyVar] -> [TyVar] -> [Type] -> [Text] -> DataCon -- | Name of the DataCon [dcName] :: DataCon -> !DcName -- | Invariant: forall x . dcUniq x ~ nameUniq (dcName x) [dcUniq] :: DataCon -> {-# UNPACK #-} !Unique -- | Syntactical position in the type definition [dcTag] :: DataCon -> !ConTag -- | Type of the 'DataCon [dcType] :: DataCon -> !Type -- | Universally quantified type-variables, these type variables are also -- part of the result type of the DataCon [dcUnivTyVars] :: DataCon -> [TyVar] -- | Existentially quantified type-variables, these type variables are not -- part of the result of the DataCon, but only of the arguments. [dcExtTyVars] :: DataCon -> [TyVar] -- | Argument types [dcArgTys] :: DataCon -> [Type] -- | Names of fields. Used when data constructor is referring to a record -- type. [dcFieldLabels] :: DataCon -> [Text] -- | DataCon reference type DcName = Name DataCon -- | Syntactical position of the DataCon in the type definition type ConTag = Int instance Data.Binary.Class.Binary Clash.Core.DataCon.DataCon instance Data.Hashable.Class.Hashable Clash.Core.DataCon.DataCon instance Control.DeepSeq.NFData Clash.Core.DataCon.DataCon instance GHC.Generics.Generic Clash.Core.DataCon.DataCon instance GHC.Show.Show Clash.Core.DataCon.DataCon instance GHC.Classes.Eq Clash.Core.DataCon.DataCon instance GHC.Classes.Ord Clash.Core.DataCon.DataCon instance Clash.Unique.Uniquable Clash.Core.DataCon.DataCon -- | Type Constructors in CoreHW module Clash.Core.TyCon -- | Type Constructor data TyCon -- | Algorithmic DataCons AlgTyCon :: {-# UNPACK #-} !Unique -> !TyConName -> !Kind -> !Int -> !AlgTyConRhs -> !Bool -> TyCon [tyConUniq] :: TyCon -> {-# UNPACK #-} !Unique -- | Name of the TyCon [tyConName] :: TyCon -> !TyConName -- | Kind of the TyCon [tyConKind] :: TyCon -> !Kind -- | Number of type arguments [tyConArity] :: TyCon -> !Int -- | DataCon definitions [algTcRhs] :: TyCon -> !AlgTyConRhs -- | Is this a class dictionary? [isClassTc] :: TyCon -> !Bool -- | Function TyCons (e.g. type families) FunTyCon :: {-# UNPACK #-} !Unique -> !TyConName -> !Kind -> !Int -> [([Type], Type)] -> TyCon [tyConUniq] :: TyCon -> {-# UNPACK #-} !Unique -- | Name of the TyCon [tyConName] :: TyCon -> !TyConName -- | Kind of the TyCon [tyConKind] :: TyCon -> !Kind -- | Number of type arguments [tyConArity] :: TyCon -> !Int -- | List of: ([LHS match types], RHS type) [tyConSubst] :: TyCon -> [([Type], Type)] -- | Primitive TyCons PrimTyCon :: {-# UNPACK #-} !Unique -> !TyConName -> !Kind -> !Int -> TyCon [tyConUniq] :: TyCon -> {-# UNPACK #-} !Unique -- | Name of the TyCon [tyConName] :: TyCon -> !TyConName -- | Kind of the TyCon [tyConKind] :: TyCon -> !Kind -- | Number of type arguments [tyConArity] :: TyCon -> !Int -- | To close the loop on the type hierarchy SuperKindTyCon :: {-# UNPACK #-} !Unique -> !TyConName -> TyCon [tyConUniq] :: TyCon -> {-# UNPACK #-} !Unique -- | Name of the TyCon [tyConName] :: TyCon -> !TyConName -- | TyCon reference type TyConName = Name TyCon type TyConMap = UniqMap TyCon -- | The RHS of an Algebraic Datatype data AlgTyConRhs DataTyCon :: [DataCon] -> AlgTyConRhs -- | The DataCons of a TyCon [dataCons] :: AlgTyConRhs -> [DataCon] NewTyCon :: !DataCon -> ([TyVar], Type) -> AlgTyConRhs -- | The newtype DataCon [dataCon] :: AlgTyConRhs -> !DataCon -- | The argument type of the newtype DataCon in eta-reduced form, which is -- just the representation of the TyCon. The TyName's are the -- type-variables from the corresponding TyCon. [ntEtadRhs] :: AlgTyConRhs -> ([TyVar], Type) -- | Create a Kind out of a TyConName mkKindTyCon :: TyConName -> Kind -> TyCon -- | Does the TyCon look like a tuple TyCon isTupleTyConLike :: TyConName -> Bool isNewTypeTc :: TyCon -> Bool -- | Get the DataCons belonging to a TyCon tyConDataCons :: TyCon -> [DataCon] instance Data.Binary.Class.Binary Clash.Core.TyCon.AlgTyConRhs instance Control.DeepSeq.NFData Clash.Core.TyCon.AlgTyConRhs instance GHC.Generics.Generic Clash.Core.TyCon.AlgTyConRhs instance GHC.Show.Show Clash.Core.TyCon.AlgTyConRhs instance Data.Binary.Class.Binary Clash.Core.TyCon.TyCon instance Control.DeepSeq.NFData Clash.Core.TyCon.TyCon instance GHC.Generics.Generic Clash.Core.TyCon.TyCon instance GHC.Show.Show Clash.Core.TyCon.TyCon instance GHC.Classes.Eq Clash.Core.TyCon.TyCon instance Clash.Unique.Uniquable Clash.Core.TyCon.TyCon -- | Builtin Type and Kind definitions module Clash.Core.TysPrim liftedTypeKind :: Type typeNatKind :: Type typeSymbolKind :: Type intPrimTy :: Type integerPrimTy :: Type charPrimTy :: Type stringPrimTy :: Type voidPrimTy :: Type wordPrimTy :: Type int64PrimTy :: Type word64PrimTy :: Type floatPrimTy :: Type doublePrimTy :: Type naturalPrimTy :: Type byteArrayPrimTy :: Type tysPrimMap :: TyConMap -- | Term Literal module Clash.Core.Literal -- | Term Literal data Literal IntegerLiteral :: !Integer -> Literal IntLiteral :: !Integer -> Literal WordLiteral :: !Integer -> Literal Int64Literal :: !Integer -> Literal Word64Literal :: !Integer -> Literal StringLiteral :: !String -> Literal FloatLiteral :: !Rational -> Literal DoubleLiteral :: !Rational -> Literal CharLiteral :: !Char -> Literal NaturalLiteral :: !Integer -> Literal ByteArrayLiteral :: !Vector Word8 -> Literal -- | Determines the Type of a Literal literalType :: Literal -> Type instance Data.Binary.Class.Binary Clash.Core.Literal.Literal instance Data.Hashable.Class.Hashable Clash.Core.Literal.Literal instance Control.DeepSeq.NFData Clash.Core.Literal.Literal instance GHC.Generics.Generic Clash.Core.Literal.Literal instance GHC.Show.Show Clash.Core.Literal.Literal instance GHC.Classes.Ord Clash.Core.Literal.Literal instance GHC.Classes.Eq Clash.Core.Literal.Literal -- | Types in CoreHW module Clash.Core.Type -- | Types in CoreHW: function and polymorphic types data Type -- | Type variable VarTy :: !TyVar -> Type -- | Type constant ConstTy :: !ConstTy -> Type -- | Polymorphic Type ForAllTy :: !TyVar -> !Type -> Type -- | Type Application AppTy :: !Type -> !Type -> Type -- | Type literal LitTy :: !LitTy -> Type -- | Annotated type, see Clash.Annotations.SynthesisAttributes AnnType :: [Attr'] -> !Type -> Type -- | An easier view on types data TypeView -- | Function type FunTy :: !Type -> !Type -> TypeView -- | Applied TyCon TyConApp :: !TyConName -> [Type] -> TypeView -- | Neither of the above OtherType :: !Type -> TypeView -- | Type Constants data ConstTy -- | TyCon type TyCon :: !TyConName -> ConstTy -- | Function type Arrow :: ConstTy -- | Literal Types data LitTy NumTy :: !Integer -> LitTy SymTy :: !String -> LitTy -- | The level above types type Kind = Type -- | Either a Kind or a Type type KindOrType = Type -- | Reference to a Kind type KiName = Name Kind -- | Reference to a Type type TyName = Name Type -- | Type variable type TyVar = Var Type -- | An easier view on types -- -- Note [Arrow arguments] -- -- Clash' Arrow type can either have 2 or 4 arguments, depending on who -- created it. By default it has two arguments: the argument type of a -- function, and the result type of a function. -- -- So when do we have 4 arguments? When in Haskell/GHC land the arrow was -- unsaturated. This can happen in instance heads, or in the eta-reduced -- representation of newtypes. So what are those additional 2 arguments -- compared to the "normal" function type? They're the kinds of argument -- and result type. tyView :: Type -> TypeView -- | A view on types in which newtypes are transparent, the Signal type is -- transparent, and type functions are evaluated to WHNF (when possible). -- -- Strips away ALL layers. If no layers are found it returns the given -- type. coreView :: TyConMap -> Type -> Type -- | A view on types in which newtypes are transparent, the Signal type is -- transparent, and type functions are evaluated to WHNF (when possible). -- -- Only strips away one "layer". coreView1 :: TyConMap -> Type -> Maybe Type -- | Determine the kind of a type typeKind :: TyConMap -> Type -> Kind -- | Make a Type out of a TyCon mkTyConTy :: TyConName -> Type -- | Make a function type of an argument and result type mkFunTy :: Type -> Type -> Type -- | Make a polymorphic function type out of a result type and a list of -- quantifiers and function argument types mkPolyFunTy :: Type -> [Either TyVar Type] -> Type -- | Make a TyCon Application out of a TyCon and a list of argument types mkTyConApp :: TyConName -> [Type] -> Type -- | Split a function type in an argument and result type splitFunTy :: TyConMap -> Type -> Maybe (Type, Type) splitFunTys :: TyConMap -> Type -> ([Type], Type) -- | Split a poly-function type in a: list of type-binders and argument -- types, and the result type splitFunForallTy :: Type -> ([Either TyVar Type], Type) -- | Split a poly-function type in a: list of type-binders and argument -- types, and the result type. Looks through Signal and type -- functions. splitCoreFunForallTy :: TyConMap -> Type -> ([Either TyVar Type], Type) -- | Split a TyCon Application in a TyCon and its arguments splitTyConAppM :: Type -> Maybe (TyConName, [Type]) -- | Is a type a polymorphic or function type? isPolyFunTy :: Type -> Bool -- | Is a type a polymorphic or function type under coreView1? isPolyFunCoreTy :: TyConMap -> Type -> Bool -- | Is a type polymorphic? isPolyTy :: Type -> Bool isTypeFamilyApplication :: TyConMap -> Type -> Bool -- | Is a type a function type? isFunTy :: TyConMap -> Type -> Bool isClassTy :: TyConMap -> Type -> Bool -- | Apply a function type to an argument type and get the result type applyFunTy :: TyConMap -> Type -> Type -> Type findFunSubst :: TyConMap -> [([Type], Type)] -> [Type] -> Maybe Type reduceTypeFamily :: TyConMap -> Type -> Maybe Type -- | The type forall a . a undefinedTy :: Type isIntegerTy :: Type -> Bool -- | Normalize a type, looking through Signals and newtypes -- -- For example: Signal a (Vec (6-1) (Unsigned (3+1))) normalizes -- to Vec 5 (Unsigned 4) normalizeType :: TyConMap -> Type -> Type varAttrs :: Var a -> [Attr'] -- | Extract attributes from type. Will return an empty list if this is an -- AnnType with an empty list AND if this is not an AnnType at all. typeAttrs :: Type -> [Attr'] instance Data.Binary.Class.Binary Clash.Core.Type.ConstTy instance Data.Hashable.Class.Hashable Clash.Core.Type.ConstTy instance Control.DeepSeq.NFData Clash.Core.Type.ConstTy instance GHC.Generics.Generic Clash.Core.Type.ConstTy instance GHC.Show.Show Clash.Core.Type.ConstTy instance GHC.Classes.Ord Clash.Core.Type.ConstTy instance GHC.Classes.Eq Clash.Core.Type.ConstTy instance Data.Binary.Class.Binary Clash.Core.Type.LitTy instance Data.Hashable.Class.Hashable Clash.Core.Type.LitTy instance Control.DeepSeq.NFData Clash.Core.Type.LitTy instance GHC.Generics.Generic Clash.Core.Type.LitTy instance GHC.Show.Show Clash.Core.Type.LitTy instance GHC.Classes.Ord Clash.Core.Type.LitTy instance GHC.Classes.Eq Clash.Core.Type.LitTy instance Data.Binary.Class.Binary Clash.Core.Type.Type instance Data.Hashable.Class.Hashable Clash.Core.Type.Type instance Control.DeepSeq.NFData Clash.Core.Type.Type instance GHC.Generics.Generic Clash.Core.Type.Type instance GHC.Show.Show Clash.Core.Type.Type instance GHC.Show.Show Clash.Core.Type.TypeView -- | Term representation in the CoreHW language: System F + LetRec + Case module Clash.Core.Term -- | Term representation in the CoreHW language: System F + LetRec + Case data Term -- | Variable reference Var :: !Id -> Term -- | Datatype constructor Data :: !DataCon -> Term -- | Literal Literal :: !Literal -> Term -- | Primitive Prim :: !PrimInfo -> Term -- | Term-abstraction Lam :: !Id -> Term -> Term -- | Type-abstraction TyLam :: !TyVar -> Term -> Term -- | Application App :: !Term -> !Term -> Term -- | Type-application TyApp :: !Term -> !Type -> Term -- | Recursive let-binding Letrec :: [LetBinding] -> Term -> Term -- | Case-expression: subject, type of alternatives, list of alternatives Case :: !Term -> !Type -> [Alt] -> Term -- | Cast a term from one type to another Cast :: !Term -> !Type -> !Type -> Term -- | Annotated term Tick :: !TickInfo -> !Term -> Term -- | Abstract a term over a list of term and type variables mkAbstraction :: Term -> [Either Id TyVar] -> Term -- | Abstract a term over a list of term variables mkTyLams :: Term -> [TyVar] -> Term -- | Abstract a term over a list of type variables mkLams :: Term -> [Id] -> Term -- | Apply a list of types and terms to a term mkApps :: Term -> [Either Term Type] -> Term -- | Apply a list of types to a term mkTyApps :: Term -> [Type] -> Term -- | Apply a list of terms to a term mkTmApps :: Term -> [Term] -> Term mkTicks :: Term -> [TickInfo] -> Term -- | Term reference type TmName = Name Term -- | Make variable reference out of term variable idToVar :: Id -> Term -- | Make a term variable out of a variable reference varToId :: Term -> Id -- | Binding in a LetRec construct type LetBinding = (Id, Term) -- | Patterns in the LHS of a case-decomposition data Pat -- | Datatype pattern, '[TyVar]' bind existentially-quantified -- type-variables of a DataCon DataPat :: !DataCon -> [TyVar] -> [Id] -> Pat -- | Literal pattern LitPat :: !Literal -> Pat -- | Default pattern DefaultPat :: Pat -- | Get the list of term-binders out of a DataType pattern patIds :: Pat -> ([TyVar], [Id]) patVars :: Pat -> [Var a] type Alt = (Pat, Term) data TickInfo -- | Source tick, will get added by GHC by running clash with `-g` SrcSpan :: !SrcSpan -> TickInfo -- | Modifier for naming module instantiations and registers, are added by -- the user by using the functions -- Clash.Magic.[prefixName,suffixName,setName] NameMod :: !NameMod -> !Type -> TickInfo -- | Deduplicate, i.e. try to share expressions between multiple branches. DeDup :: TickInfo -- | Do not deduplicate, i.e. keep, an expression inside a -- case-alternative; do not try to share expressions between multiple -- branches. NoDeDup :: TickInfo stripTicks :: Term -> Term -- | Partition ticks in source ticks and nameMod ticks partitionTicks :: [TickInfo] -> ([TickInfo], [TickInfo]) -- | Tag to indicate which instance/register name modifier was used data NameMod -- |
--   Clash.Magic.prefixName
--   
PrefixName :: NameMod -- |
--   Clash.Magic.suffixName
--   
SuffixName :: NameMod -- |
--   Clash.Magic.suffixNameP
--   
SuffixNameP :: NameMod -- |
--   Clash.Magic.setName
--   
SetName :: NameMod data PrimInfo PrimInfo :: !Text -> !Type -> !WorkInfo -> PrimInfo [primName] :: PrimInfo -> !Text [primType] :: PrimInfo -> !Type [primWorkInfo] :: PrimInfo -> !WorkInfo data WorkInfo -- | Ignores its arguments, and outputs a constant WorkConstant :: WorkInfo -- | Never adds any work WorkNever :: WorkInfo -- | Does work when the arguments are variable WorkVariable :: WorkInfo -- | Performs work regardless of whether the variables are constant or -- variable; these are things like clock or reset generators WorkAlways :: WorkInfo -- | Context in which a term appears data CoreContext -- | Function position of an application AppFun :: CoreContext -- | Argument position of an application. If this is an argument applied to -- a primitive, a tuple is defined containing (name of the primitive, -- #type args, #term args) AppArg :: Maybe (Text, Int, Int) -> CoreContext -- | Function position of a type application TyAppC :: CoreContext -- | RHS of a Let-binder with the sibling LHS' LetBinding :: Id -> [Id] -> CoreContext -- | Body of a Let-binding with the bound LHS' LetBody :: [Id] -> CoreContext -- | Body of a lambda-term with the abstracted variable LamBody :: Id -> CoreContext -- | Body of a TyLambda-term with the abstracted type-variable TyLamBody :: TyVar -> CoreContext -- | RHS of a case-alternative with the bound pattern on the LHS CaseAlt :: Pat -> CoreContext -- | Subject of a case-decomposition CaseScrut :: CoreContext -- | Body of a Cast CastBody :: CoreContext -- | Body of a Tick TickC :: TickInfo -> CoreContext -- | A list of CoreContext describes the complete navigation path -- from the top-level to a specific sub-expression. type Context = [CoreContext] -- | Is the Context a Lambda/Term-abstraction context? isLambdaBodyCtx :: CoreContext -> Bool -- | Is the Context a Tick context? isTickCtx :: CoreContext -> Bool -- | Visit all terms in a term, testing it with a predicate, and returning -- a list of predicate yields. walkTerm :: forall a. (Term -> Maybe a) -> Term -> [a] -- | Split a (Type)Application in the applied term and it arguments collectArgs :: Term -> (Term, [Either Term Type]) collectArgsTicks :: Term -> (Term, [Either Term Type], [TickInfo]) collectTicks :: Term -> (Term, [TickInfo]) collectTermIds :: Term -> [Id] -- | Split a (Type)Abstraction in the bound variables and the abstracted -- term collectBndrs :: Term -> ([Either Id TyVar], Term) -- | Given a function application, find the primitive it's applied. Yields -- Nothing if given term is not an application or if it is not a -- primitive. primArg :: Term -> Maybe (Text, Int, Int) instance Data.Binary.Class.Binary Clash.Core.Term.NameMod instance Data.Hashable.Class.Hashable Clash.Core.Term.NameMod instance Control.DeepSeq.NFData Clash.Core.Term.NameMod instance GHC.Generics.Generic Clash.Core.Term.NameMod instance GHC.Show.Show Clash.Core.Term.NameMod instance GHC.Classes.Eq Clash.Core.Term.NameMod instance Data.Binary.Class.Binary Clash.Core.Term.TickInfo instance Data.Hashable.Class.Hashable Clash.Core.Term.TickInfo instance Control.DeepSeq.NFData Clash.Core.Term.TickInfo instance GHC.Generics.Generic Clash.Core.Term.TickInfo instance GHC.Show.Show Clash.Core.Term.TickInfo instance GHC.Classes.Eq Clash.Core.Term.TickInfo instance Data.Binary.Class.Binary Clash.Core.Term.WorkInfo instance Data.Hashable.Class.Hashable Clash.Core.Term.WorkInfo instance Control.DeepSeq.NFData Clash.Core.Term.WorkInfo instance GHC.Generics.Generic Clash.Core.Term.WorkInfo instance GHC.Show.Show Clash.Core.Term.WorkInfo instance Data.Binary.Class.Binary Clash.Core.Term.PrimInfo instance Data.Hashable.Class.Hashable Clash.Core.Term.PrimInfo instance Control.DeepSeq.NFData Clash.Core.Term.PrimInfo instance GHC.Generics.Generic Clash.Core.Term.PrimInfo instance GHC.Show.Show Clash.Core.Term.PrimInfo instance Data.Binary.Class.Binary Clash.Core.Term.Pat instance Data.Hashable.Class.Hashable Clash.Core.Term.Pat instance Control.DeepSeq.NFData Clash.Core.Term.Pat instance GHC.Generics.Generic Clash.Core.Term.Pat instance GHC.Show.Show Clash.Core.Term.Pat instance GHC.Classes.Ord Clash.Core.Term.Pat instance GHC.Classes.Eq Clash.Core.Term.Pat instance Data.Binary.Class.Binary Clash.Core.Term.Term instance Data.Hashable.Class.Hashable Clash.Core.Term.Term instance Control.DeepSeq.NFData Clash.Core.Term.Term instance GHC.Generics.Generic Clash.Core.Term.Term instance GHC.Show.Show Clash.Core.Term.Term instance Data.Binary.Class.Binary Clash.Core.Term.CoreContext instance Data.Hashable.Class.Hashable Clash.Core.Term.CoreContext instance Control.DeepSeq.NFData Clash.Core.Term.CoreContext instance GHC.Generics.Generic Clash.Core.Term.CoreContext instance GHC.Show.Show Clash.Core.Term.CoreContext instance GHC.Classes.Eq Clash.Core.Term.CoreContext -- | Types used in BlackBox modules module Clash.Netlist.BlackBox.Types -- | See Clash.Primitives.Types.BlackBox for documentation on this -- record's fields. (They are intentionally renamed to prevent name -- clashes.) data BlackBoxMeta BlackBoxMeta :: Bool -> TemplateKind -> [BlackBoxTemplate] -> [BlackBoxTemplate] -> [(Int, Int)] -> [((Text, Text), BlackBox)] -> RenderVoid -> BlackBoxMeta [bbOutputReg] :: BlackBoxMeta -> Bool [bbKind] :: BlackBoxMeta -> TemplateKind [bbLibrary] :: BlackBoxMeta -> [BlackBoxTemplate] [bbImports] :: BlackBoxMeta -> [BlackBoxTemplate] [bbFunctionPlurality] :: BlackBoxMeta -> [(Int, Int)] [bbIncludes] :: BlackBoxMeta -> [((Text, Text), BlackBox)] [bbRenderVoid] :: BlackBoxMeta -> RenderVoid -- | Use this value in your blackbox template function if you do want to -- accept the defaults as documented in -- Clash.Primitives.Types.BlackBox. emptyBlackBoxMeta :: BlackBoxMeta -- | A BlackBox function generates a blackbox template, given the inputs -- and result type of the function it should provide a blackbox for. This -- is useful when having a need for blackbox functions, ... TODO: docs type BlackBoxFunction = Bool " Indicates whether caller needs a declaration. If set, the function is still free to return an expression, but the caller will convert it to a declaration." -> Text " Name of primitive" -> [Either Term Type] " Arguments" -> Type " Result type" -> NetlistMonad (Either String (BlackBoxMeta, BlackBox)) -- | A BlackBox Template is a List of Elements TODO: Add name of function -- for better error messages type BlackBoxTemplate = [Element] data TemplateKind TDecl :: TemplateKind TExpr :: TemplateKind -- | Elements of a blackbox context. If you extend this list, make sure to -- update the following functions: -- -- data Element -- | Dumps given text without processing in HDL Text :: !Text -> Element -- | Component instantiation hole Component :: !Decl -> Element -- | Output hole; Bool asserts escape marker stripping Result :: !Bool -> Element -- | Input hole; Bool asserts escape marker stripping Arg :: !Bool -> !Int -> Element -- | Like Arg, but its first argument is the scoping level. For use in in -- generated code only. ArgGen :: !Int -> !Int -> Element -- | Like Arg, but input hole must be a constant. Const :: !Int -> Element -- | Like Arg, but input hole must be a literal Lit :: !Int -> Element -- | Name hole Name :: !Int -> Element -- | Like Arg but only insert variable reference (creating an assignment -- elsewhere if necessary). ToVar :: [Element] -> !Int -> Element -- | Symbol hole Sym :: !Text -> !Int -> Element -- | Type declaration hole Typ :: !Maybe Int -> Element -- | Type root hole TypM :: !Maybe Int -> Element -- | Error value hole Err :: !Maybe Int -> Element -- | Select element type from a vector type TypElem :: !Element -> Element -- | Hole for the name of the component in which the blackbox is -- instantiated CompName :: Element IncludeName :: !Int -> Element -- | Index data type hole, the field is the (exclusive) maximum index IndexType :: !Element -> Element -- | Size of a type hole Size :: !Element -> Element -- | Length of a vector hole Length :: !Element -> Element -- | Depth of a tree hole Depth :: !Element -> Element -- | Max index into a vector MaxIndex :: !Element -> Element -- | Hole containing a filepath for a data file FilePath :: !Element -> Element -- | Create data file HOLE0 with contents HOLE1 Template :: [Element] -> [Element] -> Element -- | Hole marking beginning (True) or end (False) of a generative construct Gen :: !Bool -> Element IF :: !Element -> [Element] -> [Element] -> Element And :: [Element] -> Element -- | Hole indicating whether IntWordInteger are 64-Bit IW64 :: Element -- | Compare less-or-equal CmpLE :: !Element -> !Element -> Element -- | Hole indicating which synthesis tool we're generating HDL for HdlSyn :: HdlSyn -> Element -- | Convert to (True)/from(False) a bit-vector BV :: !Bool -> [Element] -> !Element -> Element -- | Record selector of a type Sel :: !Element -> !Int -> Element IsLit :: !Int -> Element IsVar :: !Int -> Element -- | Whether a domain's reset lines are synchronous. IsActiveHigh :: !Int -> Element -- | Tag of a domain. Tag :: !Int -> Element -- | Period of a domain. Period :: !Int -> Element -- | Test active edge of memory elements in a certain domain ActiveEdge :: !ActiveEdge -> !Int -> Element -- | Whether a domain's reset lines are synchronous. Errors if not applied -- to a KnownDomain. IsSync :: !Int -> Element IsInitDefined :: !Int -> Element -- | Whether given enable line is active. More specifically, whether the -- enable line is NOT set to a constant True. IsActiveEnable :: !Int -> Element StrCmp :: [Element] -> !Int -> Element OutputWireReg :: !Int -> Element Vars :: !Int -> Element GenSym :: [Element] -> !Int -> Element -- | Repeat hole n times Repeat :: [Element] -> [Element] -> Element -- | Evaluate hole but swallow output DevNull :: [Element] -> Element SigD :: [Element] -> !Maybe Int -> Element -- | The "context name", name set by setName, defaults to the name -- of the closest binder CtxName :: Element -- | Component instantiation hole. First argument indicates which function -- argument to instantiate. Second argument corresponds to output and -- input assignments, where the first element is the output assignment, -- and the subsequent elements are the consecutive input assignments. -- -- The LHS of the tuple is the name of the signal, while the RHS of the -- tuple is the type of the signal data Decl Decl :: !Int -> !Int -> [(BlackBoxTemplate, BlackBoxTemplate)] -> Decl data HdlSyn Vivado :: HdlSyn Quartus :: HdlSyn Other :: HdlSyn -- | Whether this primitive should be rendered when its result type is -- void. Defaults to NoRenderVoid. data RenderVoid -- | Render blackbox, even if result type is void RenderVoid :: RenderVoid -- | Don't render blackbox result type is void. Default for all blackboxes. NoRenderVoid :: RenderVoid instance Data.Aeson.Types.FromJSON.FromJSON Clash.Netlist.BlackBox.Types.RenderVoid instance Data.Hashable.Class.Hashable Clash.Netlist.BlackBox.Types.RenderVoid instance Data.Binary.Class.Binary Clash.Netlist.BlackBox.Types.RenderVoid instance Control.DeepSeq.NFData Clash.Netlist.BlackBox.Types.RenderVoid instance GHC.Generics.Generic Clash.Netlist.BlackBox.Types.RenderVoid instance GHC.Show.Show Clash.Netlist.BlackBox.Types.RenderVoid instance Data.Hashable.Class.Hashable Clash.Netlist.BlackBox.Types.TemplateKind instance Data.Binary.Class.Binary Clash.Netlist.BlackBox.Types.TemplateKind instance Control.DeepSeq.NFData Clash.Netlist.BlackBox.Types.TemplateKind instance GHC.Generics.Generic Clash.Netlist.BlackBox.Types.TemplateKind instance GHC.Classes.Eq Clash.Netlist.BlackBox.Types.TemplateKind instance GHC.Show.Show Clash.Netlist.BlackBox.Types.TemplateKind instance Data.Hashable.Class.Hashable Clash.Netlist.BlackBox.Types.HdlSyn instance Data.Binary.Class.Binary Clash.Netlist.BlackBox.Types.HdlSyn instance Control.DeepSeq.NFData Clash.Netlist.BlackBox.Types.HdlSyn instance GHC.Generics.Generic Clash.Netlist.BlackBox.Types.HdlSyn instance GHC.Read.Read Clash.Netlist.BlackBox.Types.HdlSyn instance GHC.Show.Show Clash.Netlist.BlackBox.Types.HdlSyn instance GHC.Classes.Eq Clash.Netlist.BlackBox.Types.HdlSyn instance Data.Hashable.Class.Hashable Clash.Netlist.BlackBox.Types.Decl instance Data.Binary.Class.Binary Clash.Netlist.BlackBox.Types.Decl instance Control.DeepSeq.NFData Clash.Netlist.BlackBox.Types.Decl instance GHC.Generics.Generic Clash.Netlist.BlackBox.Types.Decl instance GHC.Show.Show Clash.Netlist.BlackBox.Types.Decl instance Data.Hashable.Class.Hashable Clash.Netlist.BlackBox.Types.Element instance Data.Binary.Class.Binary Clash.Netlist.BlackBox.Types.Element instance Control.DeepSeq.NFData Clash.Netlist.BlackBox.Types.Element instance GHC.Generics.Generic Clash.Netlist.BlackBox.Types.Element instance GHC.Show.Show Clash.Netlist.BlackBox.Types.Element -- | Type and instance definitions for Primitive module Clash.Primitives.Types data TemplateSource -- | Template source stored in file on filesystem TFile :: FilePath -> TemplateSource -- | Template stored inline TInline :: Text -> TemplateSource data TemplateKind TDecl :: TemplateKind TExpr :: TemplateKind data TemplateFormat TTemplate :: TemplateFormat THaskell :: TemplateFormat -- | A BBFN is a parsed version of a fully qualified function name. It is -- guaranteed to have at least one module name which is not Main. data BlackBoxFunctionName BlackBoxFunctionName :: [String] -> String -> BlackBoxFunctionName -- | Externally defined primitive data Primitive a b c d -- | Primitive template written in a Clash specific templating language BlackBox :: !Text -> WorkInfo -> RenderVoid -> TemplateKind -> c -> Bool -> [a] -> [a] -> [(Int, Int)] -> [((Text, Text), b)] -> Maybe b -> Maybe b -> b -> Primitive a b c d -- | Name of the primitive [name] :: Primitive a b c d -> !Text -- | Whether the primitive does any work, i.e. takes chip area [workInfo] :: Primitive a b c d -> WorkInfo -- | Whether this primitive should be rendered when its result type is -- void. Defaults to NoRenderVoid. [renderVoid] :: Primitive a b c d -> RenderVoid -- | Whether this results in an expression or a declaration [kind] :: Primitive a b c d -> TemplateKind -- | A warning to be outputted when the primitive is instantiated. This is -- intended to be used as a warning for primitives that are not -- synthesizable, but may also be used for other purposes. [warning] :: Primitive a b c d -> c -- | Verilog only: whether the result should be a reg(True) -- or wire (False); when not specified in the -- .json file, the value will default to False (i.e. -- wire). [outputReg] :: Primitive a b c d -> Bool -- | VHDL only: add library declarations for the given names [libraries] :: Primitive a b c d -> [a] -- | VHDL only: add use declarations for the given names [imports] :: Primitive a b c d -> [a] -- | Indicates how often a function will be instantiated in a blackbox. For -- example, consider the following higher-order function that creates a -- tree structure: -- -- fold :: (a -> a -> a) -> Vec n a -> a -- -- In order to generate HDL for an instance of fold we need log2(n) calls -- to the first argument, `a -> a -> a` (plus a few more if n is -- not a power of two). Note that this only targets multiple textual -- instances of the function. If you can generate the HDL using a -- for-loop and only need to call ~INST once, you don't have to worry -- about this option. See the blackbox for map for an example of -- this. -- -- Right now, option can only be generated by BlackBoxHaskell. It cannot -- be used within JSON primitives. To see how to use this, see the -- Haskell blackbox for fold. [functionPlurality] :: Primitive a b c d -> [(Int, Int)] -- | Create files to be included with the generated primitive. The fields -- are ((name, extension), content), where content is a template of the -- file Defaults to [] when not specified in the .json -- file [includes] :: Primitive a b c d -> [((Text, Text), b)] -- | (Maybe) Control the generated name of the result [resultName] :: Primitive a b c d -> Maybe b -- | (Maybe) Control the initial/power-up value of the result [resultInit] :: Primitive a b c d -> Maybe b -- | Used to indiciate type of template (declaration or expression). Will -- be filled with Template or an Either decl expr. [template] :: Primitive a b c d -> b -- | Primitive template rendered by a Haskell function (given as raw source -- code) BlackBoxHaskell :: !Text -> WorkInfo -> UsedArguments -> BlackBoxFunctionName -> d -> Primitive a b c d -- | Name of the primitive [name] :: Primitive a b c d -> !Text -- | Whether the primitive does any work, i.e. takes chip area [workInfo] :: Primitive a b c d -> WorkInfo -- | Arguments used by blackbox. Used to remove arguments during -- normalization. [usedArguments] :: Primitive a b c d -> UsedArguments [functionName] :: Primitive a b c d -> BlackBoxFunctionName -- | Holds blackbox function and its hash, (Int, BlackBoxFunction), in a -- CompiledPrimitive. [function] :: Primitive a b c d -> d -- | A primitive that carries additional information. These are "real" -- primitives, hardcoded in the compiler. For example: mapSignal -- in GHC2Core.coreToTerm. Primitive :: !Text -> WorkInfo -> !Text -> Primitive a b c d -- | Name of the primitive [name] :: Primitive a b c d -> !Text -- | Whether the primitive does any work, i.e. takes chip area [workInfo] :: Primitive a b c d -> WorkInfo -- | Additional information [primSort] :: Primitive a b c d -> !Text -- | Data type to indicate what arguments are in use by a BlackBox data UsedArguments -- | Only these are used UsedArguments :: [Int] -> UsedArguments -- | All but these are used IgnoredArguments :: [Int] -> UsedArguments type GuardedCompiledPrimitive = PrimitiveGuard CompiledPrimitive type GuardedResolvedPrimitive = PrimitiveGuard ResolvedPrimitive -- | A PrimMap maps primitive names to a Primitive type PrimMap a = HashMap Text a -- | An unresolved primitive still contains pointers to files. type UnresolvedPrimitive = Primitive Text ((TemplateFormat, BlackBoxFunctionName), Maybe TemplateSource) (Maybe Text) (Maybe TemplateSource) -- | A parsed primitive does not contain pointers to filesystem files -- anymore, but holds uncompiled BlackBoxTemplates and -- BlackBoxFunctions. type ResolvedPrimitive = Primitive Text ((TemplateFormat, BlackBoxFunctionName), Maybe Text) () (Maybe Text) type ResolvedPrimMap = PrimMap GuardedResolvedPrimitive -- | A compiled primitive has compiled all templates and functions from its -- ResolvedPrimitive counterpart. The Int in the tuple is a hash -- of the (uncompiled) BlackBoxFunction. type CompiledPrimitive = Primitive BlackBoxTemplate BlackBox () (Int, BlackBoxFunction) type CompiledPrimMap = PrimMap GuardedCompiledPrimitive instance Data.Hashable.Class.Hashable Clash.Primitives.Types.BlackBoxFunctionName instance Data.Binary.Class.Binary Clash.Primitives.Types.BlackBoxFunctionName instance Control.DeepSeq.NFData Clash.Primitives.Types.BlackBoxFunctionName instance GHC.Generics.Generic Clash.Primitives.Types.BlackBoxFunctionName instance GHC.Classes.Eq Clash.Primitives.Types.BlackBoxFunctionName instance Control.DeepSeq.NFData Clash.Primitives.Types.TemplateSource instance GHC.Generics.Generic Clash.Primitives.Types.TemplateSource instance GHC.Classes.Eq Clash.Primitives.Types.TemplateSource instance GHC.Show.Show Clash.Primitives.Types.TemplateSource instance Control.DeepSeq.NFData Clash.Primitives.Types.TemplateFormat instance Data.Hashable.Class.Hashable Clash.Primitives.Types.TemplateFormat instance GHC.Generics.Generic Clash.Primitives.Types.TemplateFormat instance GHC.Show.Show Clash.Primitives.Types.TemplateFormat instance Data.Binary.Class.Binary Clash.Primitives.Types.UsedArguments instance Control.DeepSeq.NFData Clash.Primitives.Types.UsedArguments instance Data.Hashable.Class.Hashable Clash.Primitives.Types.UsedArguments instance GHC.Generics.Generic Clash.Primitives.Types.UsedArguments instance GHC.Show.Show Clash.Primitives.Types.UsedArguments instance GHC.Base.Functor (Clash.Primitives.Types.Primitive a b c) instance (Data.Hashable.Class.Hashable c, Data.Hashable.Class.Hashable a, Data.Hashable.Class.Hashable b, Data.Hashable.Class.Hashable d) => Data.Hashable.Class.Hashable (Clash.Primitives.Types.Primitive a b c d) instance (Data.Binary.Class.Binary c, Data.Binary.Class.Binary a, Data.Binary.Class.Binary b, Data.Binary.Class.Binary d) => Data.Binary.Class.Binary (Clash.Primitives.Types.Primitive a b c d) instance (Control.DeepSeq.NFData c, Control.DeepSeq.NFData a, Control.DeepSeq.NFData b, Control.DeepSeq.NFData d) => Control.DeepSeq.NFData (Clash.Primitives.Types.Primitive a b c d) instance GHC.Generics.Generic (Clash.Primitives.Types.Primitive a b c d) instance (GHC.Show.Show c, GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show d) => GHC.Show.Show (Clash.Primitives.Types.Primitive a b c d) instance Data.Aeson.Types.FromJSON.FromJSON Clash.Primitives.Types.UnresolvedPrimitive instance GHC.Show.Show Clash.Primitives.Types.BlackBoxFunctionName -- | Parser definitions for BlackBox templates module Clash.Netlist.BlackBox.Parser -- | Parse a text as a BlackBoxTemplate, returns a list of errors in case -- parsing fails runParse :: Text -> (BlackBoxTemplate, [Error -- LineColPos]) runParse = PCC.parse ((,) $ pBlackBoxD * -- pEnd) . createStr (LineColPos 0 0 0) runParse :: Text -> Result BlackBoxTemplate module Clash.Core.EqSolver -- | Data type that indicates what kind of solution (if any) was found data TypeEqSolution -- | Solution was found. Variable equals some integer. Solution :: (TyVar, Type) -> TypeEqSolution -- | A solution was found, but it involved negative naturals. AbsurdSolution :: TypeEqSolution -- | Given type wasn't an equation, or it was unsolvable. NoSolution :: TypeEqSolution catSolutions :: [TypeEqSolution] -> [(TyVar, Type)] -- | Solve given equations and return all non-absurd solutions solveNonAbsurds :: TyConMap -> [(Type, Type)] -> [(TyVar, Type)] -- | Solve simple equalities such as: -- -- solveEq :: TyConMap -> (Type, Type) -> [TypeEqSolution] -- | Solve equations supported by normalizeAdd. See documentation -- of TypeEqSolution to understand the return value. solveAdd :: (Type, Type) -> TypeEqSolution -- | Given the left and right side of an equation, normalize it such that -- equations of the following forms: -- -- -- -- are returned as (5, 2, n) normalizeAdd :: (Type, Type) -> Maybe (Integer, Integer, Type) -- | Tests for unreachable alternative due to types being "absurd". See -- isAbsurdEq for more info. isAbsurdAlt :: TyConMap -> Alt -> Bool -- | Determines if an "equation" obtained through altEqs or -- typeEq is absurd. That is, it tests if two types that are -- definitely not equal are asserted to be equal OR if the computation of -- the types yield some absurd (intermediate) result such as -1. isAbsurdEq :: TyConMap -> (Type, Type) -> Bool -- | Get constraint equations altEqs :: TyConMap -> Alt -> [(Type, Type)] -- | If type is an equation, return LHS and RHS. typeEq :: TyConMap -> Type -> Maybe (Type, Type) instance GHC.Classes.Eq Clash.Core.EqSolver.TypeEqSolution instance GHC.Show.Show Clash.Core.EqSolver.TypeEqSolution -- | PrettyPrec printing class and instances for CoreHW module Clash.Core.Pretty -- | PrettyPrec printing Show-like typeclass class PrettyPrec p pprPrec :: (PrettyPrec p, Monad m) => Rational -> p -> m ClashDoc pprPrec' :: (PrettyPrec p, Monad m) => PrettyOptions -> Rational -> p -> m ClashDoc -- | Options for the pretty-printer, controlling which elements to hide. data PrettyOptions PrettyOptions :: Bool -> Bool -> Bool -> PrettyOptions -- | whether to display unique identifiers [displayUniques] :: PrettyOptions -> Bool -- | whether to display type information [displayTypes] :: PrettyOptions -> Bool -- | whether to display module qualifiers [displayQualifiers] :: PrettyOptions -> Bool -- | Clash's specialized Doc type holds metadata of type -- ClashAnnotation. type ClashDoc = Doc ClashAnnotation -- | Annotations carried on pretty-printed code. data ClashAnnotation -- | marking navigation to a different context AnnContext :: CoreContext -> ClashAnnotation -- | marking a specific sort of syntax AnnSyntax :: SyntaxElement -> ClashAnnotation -- | Specific places in the program syntax. data SyntaxElement Keyword :: SyntaxElement LitS :: SyntaxElement Type :: SyntaxElement Unique :: SyntaxElement Qualifier :: SyntaxElement ppr :: PrettyPrec p => p -> ClashDoc ppr' :: PrettyPrec p => PrettyOptions -> p -> ClashDoc -- | Print a PrettyPrec thing to a String showPpr :: PrettyPrec p => p -> String showPpr' :: PrettyPrec p => PrettyOptions -> p -> String tracePprId :: PrettyPrec p => p -> p tracePpr :: PrettyPrec p => p -> a -> a fromPpr :: PrettyPrec a => a -> Doc () instance GHC.Show.Show Clash.Core.Pretty.SyntaxElement instance GHC.Classes.Eq Clash.Core.Pretty.SyntaxElement instance GHC.Classes.Eq Clash.Core.Pretty.ClashAnnotation instance GHC.Classes.Ord Clash.Core.Pretty.TypePrec instance GHC.Classes.Eq Clash.Core.Pretty.TypePrec instance Clash.Core.Pretty.PrettyPrec Clash.Core.Term.Pat instance Clash.Core.Pretty.PrettyPrec (Clash.Core.Name.Name a) instance Clash.Core.Pretty.PrettyPrec a => Clash.Core.Pretty.PrettyPrec [a] instance Clash.Core.Pretty.PrettyPrec (Clash.Core.Var.Id, Clash.Core.Term.Term) instance Clash.Core.Pretty.PrettyPrec Data.Text.Internal.Text instance Clash.Core.Pretty.PrettyPrec Clash.Core.Type.Type instance Clash.Core.Pretty.PrettyPrec Clash.Core.TyCon.TyCon instance Clash.Core.Pretty.PrettyPrec Clash.Core.Type.LitTy instance Clash.Core.Pretty.PrettyPrec Clash.Core.Term.Term instance Clash.Core.Pretty.PrettyPrec Clash.Core.Term.TickInfo instance Clash.Core.Pretty.PrettyPrec SrcLoc.SrcSpan instance Clash.Core.Pretty.PrettyPrec (Clash.Core.Var.Var a) instance Clash.Core.Pretty.PrettyPrec Clash.Core.DataCon.DataCon instance Clash.Core.Pretty.PrettyPrec Clash.Core.Literal.Literal instance Data.Default.Class.Default Clash.Core.Pretty.PrettyOptions instance Clash.Pretty.ClashPretty (Clash.Core.Name.Name a) instance Clash.Pretty.ClashPretty Clash.Core.Type.Type instance Data.Text.Prettyprint.Doc.Internal.Pretty Clash.Core.Type.LitTy instance Clash.Pretty.ClashPretty Clash.Core.Term.Term instance Clash.Pretty.ClashPretty (Clash.Core.Var.Var a) module Clash.Core.VarEnv -- | Map indexed by variables type VarEnv a = UniqMap a -- | Is the environment empty nullVarEnv :: VarEnv a -> Bool -- | Look up a value based on the variable lookupVarEnv :: Var b -> VarEnv a -> Maybe a -- | Lookup a value based on the variable -- -- Errors out when the variable is not present lookupVarEnv' :: VarEnv a -> Var b -> a -- | Lookup a value based on the unique of a variable lookupVarEnvDirectly :: Unique -> VarEnv a -> Maybe a -- | Empty map emptyVarEnv :: VarEnv a -- | Environment containing a single variable-value pair unitVarEnv :: Var b -> a -> VarEnv a -- | Create an environment given a list of var-value pairs mkVarEnv :: [(Var a, b)] -> VarEnv b -- | Add a variable-value pair to the environment; overwrites the value if -- the variable already exists extendVarEnv :: Var b -> a -> VarEnv a -> VarEnv a -- | Add a list of variable-value pairs; the values of existing keys will -- be overwritten extendVarEnvList :: VarEnv a -> [(Var b, a)] -> VarEnv a -- | Add a variable-value pair to the environment; if the variable already -- exists, the two values are merged with the given function extendVarEnvWith :: Var b -> a -> (a -> a -> a) -> VarEnv a -> VarEnv a -- | Remove a variable-value pair from the environment delVarEnv :: VarEnv a -> Var b -> VarEnv a -- | Remove a list of variable-value pairs from the environment delVarEnvList :: VarEnv a -> [Var b] -> VarEnv a -- | Get the (left-biased) union of two environments unionVarEnv :: VarEnv a -> VarEnv a -> VarEnv a -- | Get the union of two environments, mapped values existing in both -- environments will be merged with the given function. unionVarEnvWith :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a -- | Apply a function to every element in the environment mapVarEnv :: (a -> b) -> VarEnv a -> VarEnv b -- | Apply a function to every element in the environment; values for which -- the function returns Nothing are removed from the environment mapMaybeVarEnv :: (a -> Maybe b) -> VarEnv a -> VarEnv b -- | Strict left-fold over an environment using both the unique of the the -- variable and the value foldlWithUniqueVarEnv' :: (a -> Unique -> b -> a) -> a -> VarEnv b -> a -- | Does the variable exist in the environment elemVarEnv :: Var a -> VarEnv b -> Bool -- | Does the variable not exist in the environment notElemVarEnv :: Var a -> VarEnv b -> Bool -- | Extract the elements eltsVarEnv :: VarEnv a -> [a] -- | Set of variables type VarSet = UniqSet (Var Any) -- | The empty set emptyVarSet :: VarSet -- | The set of a single variable unitVarSet :: Var a -> VarSet -- | Remove a variable from the set based on its Unique delVarSetByKey :: Unique -> VarSet -> VarSet -- | Union two sets unionVarSet :: VarSet -> VarSet -> VarSet -- | Is the variable an element in the set elemVarSet :: Var a -> VarSet -> Bool -- | Is the variable not an element in the set notElemVarSet :: Var a -> VarSet -> Bool -- | Create a set from a list of variables mkVarSet :: [Var a] -> VarSet eltsVarSet :: VarSet -> [Var Any] -- | Set of variables that is in scope at some point -- -- The Int is a kind of hash-value used to generate new uniques. -- It should never be zero -- -- See "Secrets of the Glasgow Haskell Compiler inliner" Section 3.2 for -- the motivation data InScopeSet -- | The empty set emptyInScopeSet :: InScopeSet -- | Look up a variable in the InScopeSet. This gives you the -- canonical version of the variable lookupInScope :: InScopeSet -> Var a -> Maybe (Var Any) -- | Create a set of variables in scope mkInScopeSet :: VarSet -> InScopeSet -- | The empty set extendInScopeSet :: InScopeSet -> Var a -> InScopeSet -- | Add a list of variables in scope extendInScopeSetList :: InScopeSet -> [Var a] -> InScopeSet -- | Union two sets of in scope variables unionInScope :: InScopeSet -> InScopeSet -> InScopeSet -- | Is the variable in scope elemInScopeSet :: Var a -> InScopeSet -> Bool -- | Check whether an element exists in the set based on the Unique -- contained in that element elemUniqInScopeSet :: Unique -> InScopeSet -> Bool -- | Is the variable not in scope notElemInScopeSet :: Var a -> InScopeSet -> Bool -- | Is the set of variables in scope varSetInScope :: VarSet -> InScopeSet -> Bool -- | Ensure that the Unique of a variable does not occur in the -- InScopeSet uniqAway :: (Uniquable a, ClashPretty a) => InScopeSet -> a -> a uniqAway' :: (Uniquable a, ClashPretty a) => (Unique -> Bool) -> Int -> a -> a -- | Rename environment for e.g. alpha equivalence -- -- When going under binders for e.g. -- --
--   x -> e1  aeq y -> e2
--   
-- -- We want to rename [x -> y] or [y -> x], but we -- have to pick a binder that is neither free in e1 nor -- e2 or we risk accidental capture. -- -- So we must maintain: -- --
    --
  1. A renaming for the left term
  2. --
  3. A renaming for the right term
  4. --
  5. A set of in scope variables
  6. --
data RnEnv -- | Create an empty renaming environment mkRnEnv :: InScopeSet -> RnEnv -- | Simultaneously go under the binder bL and binder bR, -- finds a new binder newTvB, and return an environment mapping -- [bL -> newB] and [bR -> newB] rnTmBndr :: RnEnv -> Id -> Id -> RnEnv -- | Simultaneously go under the type-variable binder bTvL and -- type-variable binder bTvR, finds a new binder newTvB, -- and return an environment mapping [bTvL -> newB] and -- [bTvR -> newB] rnTyBndr :: RnEnv -> TyVar -> TyVar -> RnEnv -- | Applies rnTmBndr to several variables: the two variable lists -- must be of equal length. rnTmBndrs :: RnEnv -> [Id] -> [Id] -> RnEnv -- | Applies rnTyBndr to several variables: the two variable lists -- must be of equal length. rnTyBndrs :: RnEnv -> [TyVar] -> [TyVar] -> RnEnv -- | Look up the renaming of an occurrence in the left term rnOccLId :: RnEnv -> Id -> Id -- | Look up the renaming of an occurrence in the left term rnOccRId :: RnEnv -> Id -> Id -- | Look up the renaming of an type-variable occurrence in the left term rnOccLTy :: RnEnv -> TyVar -> TyVar -- | Look up the renaming of an type-variable occurrence in the right term rnOccRTy :: RnEnv -> TyVar -> TyVar instance Data.Binary.Class.Binary Clash.Core.VarEnv.InScopeSet instance GHC.Generics.Generic Clash.Core.VarEnv.InScopeSet instance Clash.Pretty.ClashPretty Clash.Core.VarEnv.InScopeSet -- | Type definitions used by the Driver module module Clash.Driver.Types data Binding Binding :: Id -> SrcSpan -> InlineSpec -> Term -> Binding [bindingId] :: Binding -> Id [bindingLoc] :: Binding -> SrcSpan [bindingSpec] :: Binding -> InlineSpec [bindingTerm] :: Binding -> Term -- | Global function binders -- -- Global functions cannot be mutually recursive, only self-recursive. type BindingMap = VarEnv Binding -- | Debug Message Verbosity data DebugLevel -- | Don't show debug messages DebugNone :: DebugLevel -- | Run invariant checks and err if violated (enabled by any debug flag) DebugSilent :: DebugLevel -- | Show completely normalized expressions DebugFinal :: DebugLevel -- | Show names of applied transformations DebugName :: DebugLevel -- | Show names of tried AND applied transformations DebugTry :: DebugLevel -- | Show sub-expressions after a successful rewrite DebugApplied :: DebugLevel -- | Show all sub-expressions on which a rewrite is attempted DebugAll :: DebugLevel data ClashOpts ClashOpts :: Int -> Int -> Word -> Word -> DebugLevel -> Set String -> Int -> Int -> Bool -> Bool -> Bool -> OverridingBool -> Int -> Maybe String -> HdlSyn -> Bool -> Bool -> [FilePath] -> Maybe String -> Bool -> Bool -> Bool -> Maybe (Maybe Int) -> Bool -> Bool -> Word -> ClashOpts [opt_inlineLimit] :: ClashOpts -> Int [opt_specLimit] :: ClashOpts -> Int [opt_inlineFunctionLimit] :: ClashOpts -> Word [opt_inlineConstantLimit] :: ClashOpts -> Word [opt_dbgLevel] :: ClashOpts -> DebugLevel [opt_dbgTransformations] :: ClashOpts -> Set String -- | Only output debug information from (applied) transformation n [opt_dbgTransformationsFrom] :: ClashOpts -> Int -- | Only output debug information for n (applied) transformations. If this -- limit is exceeded, Clash will stop normalizing. [opt_dbgTransformationsLimit] :: ClashOpts -> Int [opt_cachehdl] :: ClashOpts -> Bool [opt_cleanhdl] :: ClashOpts -> Bool [opt_primWarn] :: ClashOpts -> Bool [opt_color] :: ClashOpts -> OverridingBool [opt_intWidth] :: ClashOpts -> Int -- | Directory to store temporary files in. Will be cleaned after Clash has -- finished executing. [opt_hdlDir] :: ClashOpts -> Maybe String [opt_hdlSyn] :: ClashOpts -> HdlSyn [opt_errorExtra] :: ClashOpts -> Bool [opt_floatSupport] :: ClashOpts -> Bool [opt_importPaths] :: ClashOpts -> [FilePath] [opt_componentPrefix] :: ClashOpts -> Maybe String [opt_newInlineStrat] :: ClashOpts -> Bool [opt_escapedIds] :: ClashOpts -> Bool -- | Perform a high-effort compile, trading improved performance for -- potentially much longer compile times. -- -- Name inspired by Design Compiler's compile_ultra flag. [opt_ultra] :: ClashOpts -> Bool -- | [opt_forceUndefined] :: ClashOpts -> Maybe (Maybe Int) [opt_checkIDir] :: ClashOpts -> Bool -- | Enable aggressive X optimization, which may remove undefineds from -- generated HDL by replaced with defined alternatives. [opt_aggressiveXOpt] :: ClashOpts -> Bool -- | At what size do we cache normalized work-free top-level binders. [opt_inlineWFCacheLimit] :: ClashOpts -> Word defClashOpts :: ClashOpts -- | Information about the generated HDL between (sub)runs of the compiler data Manifest Manifest :: (Int, Maybe Int) -> (Int, Int, Bool) -> [Text] -> [Text] -> [Text] -> [Text] -> [Text] -> Manifest -- | Hash of the TopEntity and all its dependencies + (maybe) Hash of the -- TestBench and all its dependencies [manifestHash] :: Manifest -> (Int, Maybe Int) -- | Compiler flags used to achieve successful compilation: -- -- [successFlags] :: Manifest -> (Int, Int, Bool) [portInNames] :: Manifest -> [Text] -- | The rendered versions of the types of the input ports of the TopEntity -- -- Used when dealing with multiple TopEntitys who have different -- names for types which are structurally equal [portInTypes] :: Manifest -> [Text] [portOutNames] :: Manifest -> [Text] -- | The rendered versions of the types of the output ports of the -- TopEntity -- -- Used when dealing with multiple TopEntitys who have different -- names for types which are structurally equal [portOutTypes] :: Manifest -> [Text] -- | Names of all the generated components for the TopEntity (does -- not include the names of the components of the TestBench -- accompanying the TopEntity). [componentNames] :: Manifest -> [Text] instance GHC.Show.Show Clash.Driver.Types.Binding instance Control.DeepSeq.NFData Clash.Driver.Types.Binding instance GHC.Generics.Generic Clash.Driver.Types.Binding instance Data.Binary.Class.Binary Clash.Driver.Types.Binding instance Data.Hashable.Class.Hashable Clash.Driver.Types.DebugLevel instance GHC.Generics.Generic Clash.Driver.Types.DebugLevel instance GHC.Enum.Enum Clash.Driver.Types.DebugLevel instance GHC.Read.Read Clash.Driver.Types.DebugLevel instance GHC.Classes.Ord Clash.Driver.Types.DebugLevel instance GHC.Classes.Eq Clash.Driver.Types.DebugLevel instance GHC.Read.Read Clash.Driver.Types.Manifest instance GHC.Show.Show Clash.Driver.Types.Manifest instance Data.Hashable.Class.Hashable Clash.Driver.Types.ClashOpts -- | Free variable calculations module Clash.Core.FreeVars -- | Gives the free type-variables in a Type, implemented as a Fold -- -- The Fold is closed over the types of its variables, so: -- --
--   foldMapOf typeFreeVars unitVarSet ((a:* -> k) Int) = {a, k}
--   
typeFreeVars :: Fold Type TyVar -- | Gives the free identifiers of a Term, implemented as a Fold freeIds :: Fold Term Id -- | Calculate the local free variable of an expression: the free -- type variables and the free identifiers that are not bound in the -- global environment. freeLocalVars :: Fold Term (Var a) -- | Calculate the local free identifiers of an expression: the free -- identifiers that are not bound in the global environment. freeLocalIds :: Fold Term Id -- | Calculate the global free identifiers of an expression: the -- free identifiers that are bound in the global environment. globalIds :: Fold Term Id -- | Gives the free type-variables of a Term, implemented as a Fold -- -- The Fold is closed over the types of variables, so: -- --
--   foldMapOf termFreeTyVars unitVarSet (case (x : (a:* -> k) Int)) of {}) = {a, k}
--   
termFreeTyVars :: Fold Term TyVar -- | Collect the free variables of a collection of type into a set tyFVsOfTypes :: Foldable f => f Type -> VarSet -- | Collect the free variables of a collection of terms into a set localFVsOfTerms :: Foldable f => f Term -> VarSet -- | Determines if term has any locally free variables. That is, the free -- type variables and the free identifiers that are not bound in the -- global scope. hasLocalFreeVars :: Term -> Bool -- | Determine whether a type has no free type variables. noFreeVarsOfType :: Type -> Bool -- | Check whether a local identifier occurs free in a term localIdOccursIn :: Id -> Term -> Bool -- | Check whether a local identifier occurs free in a term globalIdOccursIn :: Id -> Term -> Bool -- | Check whether an identifier does not occur free in a term localIdDoesNotOccurIn :: Id -> Term -> Bool -- | Check whether a set of identifiers does not occur free in a term localIdsDoNotOccurIn :: [Id] -> Term -> Bool -- | Check whether a set of variables does not occur free in a term localVarsDoNotOccurIn :: [Var a] -> Term -> Bool -- | Get the free variables of an expression and count the number of -- occurrences countFreeOccurances :: Term -> VarEnv Int -- | Gives the "interesting" free variables in a Type, implemented as a -- Fold -- -- The Fold is closed over the types of variables, so: -- --
--   foldMapOf (typeFreeVars' (const True) IntSet.empty) unitVarSet ((a:* -> k) Int) = {a, k}
--   
-- -- Note [Closing over kind variables] -- -- Consider the type -- --
--   forall k . b -> k
--   
-- -- where -- --
--   b :: k -> Type
--   
-- -- When we close over the free variables of forall k . b -> -- k, i.e. b, then the k in b :: k -> -- Type is most definitely not the k in forall k -- . b -> k. So when a type variable is free, i.e. not in the -- inScope set, its kind variables also aren´t; so in order to prevent -- collisions due to shadowing we close using an empty inScope set. -- -- See also: -- https://git.haskell.org/ghc.git/commitdiff/503514b94f8dc7bd9eab5392206649aee45f140b typeFreeVars' :: (Contravariant f, Applicative f) => (forall b. Var b -> Bool) -> IntSet -> (Var a -> f (Var a)) -> Type -> f Type -- | Gives the "interesting" free variables in a Term, implemented as a -- Fold -- -- The Fold is closed over the types of variables, so: -- --
--   foldMapOf (termFreeVars' (const True)) unitVarSet (case (x : (a:* -> k) Int)) of {}) = {x, a, k}
--   
-- -- Note [Closing over type variables] -- -- Consider the term -- --
--   /\(k :: Type) -> \(b :: k) -> a
--   
-- -- where -- --
--   a :: k
--   
-- -- When we close over the free variables of /k -> (b :: k) -> -- (a :: k), i.e. a, then the k in a :: k -- is most definitely not the k in introduced by the -- /k ->. So when a term variable is free, i.e. not in the -- inScope set, its type variables also aren´t; so in order to prevent -- collisions due to shadowing we close using an empty inScope set. -- -- See also: -- https://git.haskell.org/ghc.git/commitdiff/503514b94f8dc7bd9eab5392206649aee45f140b termFreeVars' :: (Contravariant f, Applicative f) => (forall b. Var b -> Bool) -> (Var a -> f (Var a)) -> Term -> f Term -- | Capture-free substitution function for CoreHW module Clash.Core.Subst -- | Type substitution -- -- The following invariants must hold: -- --
    --
  1. The InScopeSet is needed only to guide the generation of -- fresh uniques
  2. --
  3. In particular, the kind of the type variables in the -- InScopeSet is not relevant.
  4. --
  5. The substitution is only applied once
  6. --
-- -- Note [Apply Once] -- -- We might instantiate forall a b. ty with the types [a, -- b] or [b, a]. So the substitution might go like [a -- -> b, b -> a]. A similar situation arises in terms when we -- find a redex like (a -> b -> e) b a. Then we -- also end up with a substitution that permutes variables. Other -- variations happen to; for example [a -> (a,b)]. -- -- SO A TvSubst MUST BE APPLIED PRECISELY ONCE, OR THINGS MIGHT LOOP -- -- Note [The substitution invariant] -- -- When calling (substTy subst ty) it should be the case that the -- InScopeSet is a superset of both: -- -- data TvSubst TvSubst :: InScopeSet -> TvSubstEnv -> TvSubst -- | A substitution of Types for TyVars -- -- Note [Extending the TvSubstEnv] See TvSubst for the invariants -- that must hold -- -- This invariant allows a short-cut when the subst env is empty: if the -- TvSubstEnv is empty, i.e. nullVarEnv TvSubstEnv holds, then -- (substTy subst ty) does nothing. -- -- For example, consider: -- -- (a -> b(a ~ Int) -> ... b ...) Int -- -- We substitute Int for a. The Unique of b does not -- change, but nevertheless we add b to the TvSubstEnv -- because b's kind does change -- -- This invariant has several consequences: -- -- type TvSubstEnv = VarEnv Type -- | Extend the substitution environment with a new TyVar -- substitution extendTvSubst :: Subst -> TyVar -> Type -> Subst -- | Extend the substitution environment with a list of TyVar -- substitutions extendTvSubstList :: Subst -> [(TyVar, Type)] -> Subst -- | Substitute within a Type -- -- The substitution has to satisfy the invariant described in -- TvSubsts Note [The substitution environment] substTy :: HasCallStack => Subst -> Type -> Type -- | Type substitution, see zipTvSubst -- -- Works only if the domain of the substitution is superset of the type -- being substituted into substTyWith :: HasCallStack => [TyVar] -> [Type] -> Type -> Type -- | Substitute within a TyVar. See substTy. substTyInVar :: HasCallStack => Subst -> Var a -> Var a substGlobalsInExistentials :: HasCallStack => InScopeSet -> [TyVar] -> [(TyVar, Type)] -> [TyVar] -- | Safely substitute a type variable in a list of existentials. This -- function will account for cases where existentials shadow each other. substInExistentials :: HasCallStack => InScopeSet -> [TyVar] -> (TyVar, Type) -> [TyVar] -- | Safely substitute type variables in a list of existentials. This -- function will account for cases where existentials shadow each other. substInExistentialsList :: HasCallStack => InScopeSet -> [TyVar] -> [(TyVar, Type)] -> [TyVar] -- | A substitution environment containing containing both Id and -- TyVar substitutions. -- -- Some invariants apply to how you use the substitution: -- --
    --
  1. The InScopeSet contains at least those Ids and -- TyVars that will be in scope after applying the -- substitution to a term. Precisely, the in-scope set must be a superset -- of the free variables of the substitution range that might possibly -- clash with locally-bound variables in the thing being substituted -- in.
  2. --
  3. You may only apply the substitution once. See TvSubst
  4. --
-- -- There are various ways of setting up the in-scope set such that the -- first of of these invariants holds: -- -- data Subst Subst :: InScopeSet -> IdSubstEnv -> TvSubstEnv -> IdSubstEnv -> Subst [substInScope] :: Subst -> InScopeSet [substTmEnv] :: Subst -> IdSubstEnv [substTyEnv] :: Subst -> TvSubstEnv [substGblEnv] :: Subst -> IdSubstEnv -- | An empty substitution, starting the variables currently in scope mkSubst :: InScopeSet -> Subst -- | Create a type substitution mkTvSubst :: InScopeSet -> VarEnv Type -> Subst -- | Add an Id to the in-scope set: as a side effect, remove any -- existing substitutions for it. extendInScopeId :: Subst -> Id -> Subst -- | Add Ids to the in-scope set. See also extendInScopeId extendInScopeIdList :: Subst -> [Id] -> Subst -- | Extend the substitution environment with a new Id substitution extendIdSubst :: Subst -> Id -> Term -> Subst -- | Extend the substitution environment with a list of Id -- substitutions extendIdSubstList :: Subst -> [(Id, Term)] -> Subst -- | Extend the substitution environment with a list of global Id -- substitutions extendGblSubstList :: Subst -> [(Id, Term)] -> Subst -- | Substitute within a Term substTm :: HasCallStack => Doc () -> Subst -> Term -> Term -- | Substitute within a Term. Just return original term if given -- substitution is Nothing. maybeSubstTm :: HasCallStack => Doc () -> Maybe Subst -> Term -> Term -- | Substitute within a case-alternative substAlt :: HasCallStack => Doc () -> Subst -> (Pat, Term) -> (Pat, Term) substId :: HasCallStack => Subst -> Id -> Id -- | Ensure that non of the binders in an expression shadow each-other, nor -- conflict with he in-scope set deShadowTerm :: HasCallStack => InScopeSet -> Term -> Term -- | Ensure that non of the binders in an alternative shadow each-other, -- nor conflict with the in-scope set deShadowAlt :: HasCallStack => InScopeSet -> (Pat, Term) -> (Pat, Term) -- | A much stronger variant of deShadowTerm that ensures that all -- bound variables are unique. -- -- Also returns an extended InScopeSet additionally containing the -- (renamed) unique bound variables of the term. freshenTm :: InScopeSet -> Term -> (InScopeSet, Term) -- | Ensure that non of the let-bindings of a let-expression shadow w.r.t -- the in-scope set deshadowLetExpr :: HasCallStack => InScopeSet -> [LetBinding] -> Term -> ([LetBinding], Term) -- | Alpha equality for types aeqType :: Type -> Type -> Bool -- | Alpha equality for terms aeqTerm :: Term -> Term -> Bool instance Clash.Pretty.ClashPretty Clash.Core.Subst.TvSubst instance GHC.Classes.Eq Clash.Core.Type.Type instance GHC.Classes.Ord Clash.Core.Type.Type instance GHC.Classes.Eq Clash.Core.Term.Term instance GHC.Classes.Ord Clash.Core.Term.Term -- | Smart constructor and destructor functions for CoreHW module Clash.Core.Util -- | Create a vector of supplied elements mkVec :: DataCon -> DataCon -> Type -> Integer -> [Term] -> Term -- | Append elements to the supplied vector appendToVec :: DataCon -> Type -> Term -> Integer -> [Term] -> Term -- | Create let-bindings with case-statements that select elements out of a -- vector. Returns both the variables to which element-selections are -- bound and the let-bindings extractElems :: Supply -> InScopeSet -> DataCon -> Type -> Char -> Integer -> Term -> (Supply, [(Term, [LetBinding])]) -- | Create let-bindings with case-statements that select elements out of a -- tree. Returns both the variables to which element-selections are bound -- and the let-bindings extractTElems :: Supply -> InScopeSet -> DataCon -> DataCon -> Type -> Char -> Integer -> Term -> (Supply, ([Term], [LetBinding])) -- | Create a vector of supplied elements mkRTree :: DataCon -> DataCon -> Type -> Integer -> [Term] -> Term -- | Determine whether a type is isomorphic to -- Clash.Signal.Internal.Signal -- -- It is i.e.: -- -- -- -- This also includes BiSignals, i.e.: -- -- isSignalType :: TyConMap -> Type -> Bool -- | Determines whether given type is an (alias of en) Enable line. isEnable :: TyConMap -> Type -> Bool -- | Determines whether given type is an (alias of en) Clock or Reset line isClockOrReset :: TyConMap -> Type -> Bool tyNatSize :: TyConMap -> Type -> Except String Integer mkUniqSystemTyVar :: (Supply, InScopeSet) -> (OccName, Kind) -> ((Supply, InScopeSet), TyVar) mkUniqSystemId :: (Supply, InScopeSet) -> (OccName, Type) -> ((Supply, InScopeSet), Id) mkUniqInternalId :: (Supply, InScopeSet) -> (OccName, Type) -> ((Supply, InScopeSet), Id) -- | Same as dataConInstArgTys, but it tries to compute -- existentials too, hence the extra argument TyConMap. WARNING: -- It will return the types of non-existentials only dataConInstArgTysE :: HasCallStack => InScopeSet -> TyConMap -> DataCon -> [Type] -> Maybe [Type] -- | Given a DataCon and a list of types, the type variables of the DataCon -- type are substituted for the list of types. The argument types are -- returned. -- -- The list of types should be equal to the number of type variables, -- otherwise Nothing is returned. dataConInstArgTys :: DataCon -> [Type] -> Maybe [Type] -- | Make a coercion primCo :: Type -> Term -- | Make an undefined term undefinedTm :: Type -> Term substArgTys :: DataCon -> [Type] -> [Type] -- | Try to reduce an arbitrary type to a literal type (Symbol or Nat), and -- subsequently extract its String representation tyLitShow :: TyConMap -> Type -> Except String String -- | Determine whether we should split away types from a product type, i.e. -- clocks should always be separate arguments, and not part of a product. shouldSplit :: TyConMap -> Type -> Maybe (Term, [Type]) -- | Worker of shouldSplit, works on TypeView instead of -- Type shouldSplit0 :: TyConMap -> TypeView -> Maybe (Term, [Type]) -- | Potentially split apart a list of function argument types. e.g. given: -- --
--   [Int,(Clock,(Reset,Bool)),Char]
--   
-- -- we return -- --
--   [Int,Clock,Reset,Bool,Char]
--   
-- -- But we would leave -- --
--   [Int, (Bool,Int), Char]
--   
-- -- unchanged. splitShouldSplit :: TyConMap -> [Type] -> [Type] -- | Strip implicit parameter wrappers (IP) stripIP :: Type -> Type -- | Do an inverse topological sorting of the let-bindings in a -- let-expression inverseTopSortLetBindings :: HasCallStack => Term -> Term -- | Group let-bindings into cyclic groups and acyclic individual bindings sccLetBindings :: HasCallStack => [LetBinding] -> [SCC LetBinding] module Clash.Core.TermLiteral.TH deriveTermToData :: Name -> Q Exp -- | Tools to convert a Term into its "real" representation module Clash.Core.TermLiteral -- | Tools to deal with literals encoded as a Term. class TermLiteral a -- | Convert Term to the constant it represents. Will return an -- error if (one of the subterms) fail to translate. termToData :: (TermLiteral a, HasCallStack) => Term -> Either Term a -- | Same as termToData, but returns printable error message if it -- couldn't translate a term. termToDataError :: TermLiteral a => Term -> Either String a -- | Same as termToData, but errors hard if it can't translate a -- given term to data. uncheckedTermToData :: TermLiteral a => Term -> a instance Clash.Core.TermLiteral.TermLiteral Clash.Core.Term.Term instance Clash.Core.TermLiteral.TermLiteral GHC.Base.String instance Clash.Core.TermLiteral.TermLiteral Data.Text.Internal.Text instance Clash.Core.TermLiteral.TermLiteral GHC.Types.Int instance Clash.Core.TermLiteral.TermLiteral GHC.Integer.Type.Integer instance Clash.Core.TermLiteral.TermLiteral GHC.Types.Char instance Clash.Core.TermLiteral.TermLiteral GHC.Natural.Natural instance (Clash.Core.TermLiteral.TermLiteral a, Clash.Core.TermLiteral.TermLiteral b) => Clash.Core.TermLiteral.TermLiteral (a, b) instance Clash.Core.TermLiteral.TermLiteral a => Clash.Core.TermLiteral.TermLiteral (GHC.Maybe.Maybe a) instance Clash.Core.TermLiteral.TermLiteral GHC.Types.Bool module Clash.Core.TermInfo termSize :: Term -> Word -- | Determine the type of a term termType :: TyConMap -> Term -> Type -- | Get the result type of a polymorphic function given a list of -- arguments applyTypeToArgs :: Term -> TyConMap -> Type -> [Either Term Type] -> Type -- | Like piResultTyMaybe, but errors out when a type application is -- not valid. -- -- Do not iterate piResultTy, because it's inefficient to -- substitute one variable at a time; instead use piResultTys piResultTy :: HasCallStack => TyConMap -> Type -> Type -> Type -- | Like piResultTys but for a single argument. -- -- Do not iterate piResultTyMaybe, because it's inefficient to -- substitute one variable at a time; instead use piResultTys piResultTyMaybe :: HasCallStack => TyConMap -> Type -> Type -> Maybe Type -- | (piResultTys f_ty [ty1, ..., tyn]) give sthe type of (f -- ty1 .. tyn) where f :: f_ty -- -- piResultTys is interesting because: -- --
    --
  1. f_ty may have more foralls than there are args
  2. --
  3. Less obviously, it may have fewer foralls
  4. --
-- -- Fore case 2. think of: -- -- piResultTys (forall a . a) [forall b.b, Int] -- -- This really can happen, such as situations involving undefineds -- type: -- -- undefined :: forall a. a -- -- undefined (forall b. b -> b) Int -- -- This term should have the type (Int -> Int), but notice -- that there are more type args than foralls in undefineds type. -- -- For efficiency reasons, when there are no foralls, we simply drop -- arrows from a function type/kind. piResultTys :: HasCallStack => TyConMap -> Type -> [Type] -> Type -- | Does a term have a function type? isFun :: TyConMap -> Term -> Bool -- | Does a term have a function or polymorphic type? isPolyFun :: TyConMap -> Term -> Bool -- | Is a term a term-abstraction? isLam :: Term -> Bool -- | Is a term a recursive let-binding? isLet :: Term -> Bool -- | Is a term a variable reference? isVar :: Term -> Bool isLocalVar :: Term -> Bool -- | Is a term a datatype constructor? isCon :: Term -> Bool -- | Is a term a primitive? isPrim :: Term -> Bool -- | Types for the Partial Evaluator module Clash.Core.Evaluator.Types type PrimStep = TyConMap -> Bool -> PrimInfo -> [Type] -> [Value] -> Machine -> Maybe Machine type PrimUnwind = TyConMap -> PrimInfo -> [Type] -> [Value] -> Value -> [Term] -> Machine -> Maybe Machine type PrimEvaluator = (PrimStep, PrimUnwind) data Machine Machine :: PrimStep -> PrimUnwind -> PrimHeap -> PureHeap -> PureHeap -> Stack -> Supply -> InScopeSet -> Term -> Machine [mPrimStep] :: Machine -> PrimStep [mPrimUnwind] :: Machine -> PrimUnwind [mHeapPrim] :: Machine -> PrimHeap [mHeapGlobal] :: Machine -> PureHeap [mHeapLocal] :: Machine -> PureHeap [mStack] :: Machine -> Stack [mSupply] :: Machine -> Supply [mScopeNames] :: Machine -> InScopeSet [mTerm] :: Machine -> Term type PrimHeap = (IntMap Term, Int) type PureHeap = VarEnv Term type Stack = [StackFrame] data StackFrame Update :: IdScope -> Id -> StackFrame Apply :: Id -> StackFrame Instantiate :: Type -> StackFrame PrimApply :: PrimInfo -> [Type] -> [Value] -> [Term] -> StackFrame Scrutinise :: Type -> [Alt] -> StackFrame Tickish :: TickInfo -> StackFrame data Value -- | Functions Lambda :: Id -> Term -> Value -- | Type abstractions TyLambda :: TyVar -> Term -> Value -- | Data constructors DC :: DataCon -> [Either Term Type] -> Value -- | Literals Lit :: Literal -> Value -- | Clash's number types are represented by their "fromInteger#" primitive -- function. So some primitives are values. PrimVal :: PrimInfo -> [Type] -> [Value] -> Value -- | Used by lazy primitives Suspend :: Term -> Value -- | Preserve ticks from Terms in Values TickValue :: TickInfo -> Value -> Value -- | Preserve casts from Terms in Values CastValue :: Value -> Type -> Type -> Value valToTerm :: Value -> Term collectValueTicks :: Value -> (Value, [TickInfo]) -- | Are we in a context where special primitives must be forced. -- -- See [Note: forcing special primitives] forcePrims :: Machine -> Bool primCount :: Machine -> Int primLookup :: Int -> Machine -> Maybe Term primInsert :: Int -> Term -> Machine -> Machine primUpdate :: Int -> Term -> Machine -> Machine heapLookup :: IdScope -> Id -> Machine -> Maybe Term heapContains :: IdScope -> Id -> Machine -> Bool heapInsert :: IdScope -> Id -> Term -> Machine -> Machine heapDelete :: IdScope -> Id -> Machine -> Machine stackPush :: StackFrame -> Machine -> Machine stackPop :: Machine -> Maybe (Machine, StackFrame) stackClear :: Machine -> Machine stackNull :: Machine -> Bool getTerm :: Machine -> Term setTerm :: Term -> Machine -> Machine instance GHC.Show.Show Clash.Core.Evaluator.Types.Value instance GHC.Show.Show Clash.Core.Evaluator.Types.StackFrame instance GHC.Show.Show Clash.Core.Evaluator.Types.Machine instance Clash.Pretty.ClashPretty Clash.Core.Evaluator.Types.StackFrame -- | Call-by-need evaluator based on the evaluator described in: -- -- Maximilian Bolingbroke, Simon Peyton Jones, "Supercompilation by -- evaluation", Haskell '10, Baltimore, Maryland, USA. module Clash.Core.Evaluator isUndefinedPrimVal :: Value -> Bool whnf' :: PrimStep -> PrimUnwind -> BindingMap -> TyConMap -> PrimHeap -> Supply -> InScopeSet -> Bool -> Term -> (PrimHeap, PureHeap, Term) -- | Evaluate to WHNF given an existing Heap and Stack whnf :: TyConMap -> Bool -> Machine -> Machine -- | Completely unwind the stack to get back the complete term unwindStack :: Machine -> Maybe Machine -- | A single step in the partial evaluator. The result is the new heap and -- stack, and the next expression to be reduced. type Step = Machine -> TyConMap -> Maybe Machine stepVar :: Id -> Step stepData :: DataCon -> Step stepLiteral :: Literal -> Step stepPrim :: PrimInfo -> Step stepLam :: Id -> Term -> Step stepTyLam :: TyVar -> Term -> Step stepApp :: Term -> Term -> Step stepTyApp :: Term -> Type -> Step stepLetRec :: [LetBinding] -> Term -> Step stepCase :: Term -> Type -> [Alt] -> Step stepCast :: Term -> Type -> Type -> Step stepTick :: TickInfo -> Term -> Step -- | Small-step operational semantics. step :: Step -- | Take a list of types or type variables and create a lambda / type -- lambda for each one around the given term. newBinder :: [Either TyVar Type] -> Term -> Step newLetBinding :: TyConMap -> Machine -> Term -> (Machine, Id) -- | Unwind the stack by 1 unwind :: TyConMap -> Machine -> Value -> Maybe Machine -- | Update the Heap with the evaluated term update :: IdScope -> Id -> Value -> Machine -> Machine -- | Apply a value to a function apply :: TyConMap -> Value -> Id -> Machine -> Machine -- | Instantiate a type-abstraction instantiate :: TyConMap -> Value -> Type -> Machine -> Machine -- | Evaluate a case-expression scrutinise :: Value -> Type -> [Alt] -> Machine -> Machine substInAlt :: DataCon -> [TyVar] -> [Id] -> [Either Term Type] -> Term -> Term -- | Allocate let-bindings on the heap allocate :: [LetBinding] -> Term -> Machine -> Machine -- | Create a unique name and substitution for a let-binder letSubst :: PureHeap -> Supply -> Id -> (Supply, (Id, (Id, Term))) module Clash.Backend primsRoot :: IO FilePath clashVer :: String type ModName = Identifier -- | Is a type used for internal or external use data Usage -- | Internal use Internal :: Usage -- | External use, field indicates the library name External :: Text -> Usage class Backend state -- | Initial state for state monad initBackend :: Backend state => Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> state -- | What HDL is the backend generating hdlKind :: Backend state => state -> HDL -- | Location for the primitive definitions primDirs :: Backend state => state -> IO [FilePath] -- | Name of backend, used for directory to put output files in. Should be -- constant function / ignore argument. name :: Backend state => state -> String -- | File extension for target langauge extension :: Backend state => state -> String -- | Get the set of types out of state extractTypes :: Backend state => state -> HashSet HWType -- | Generate HDL for a Netlist component genHDL :: Backend state => Identifier -> SrcSpan -> HashMap Identifier Word -> Component -> Mon (State state) ((String, Doc), [(String, Doc)]) -- | Generate a HDL package containing type definitions for the given -- HWTypes mkTyPackage :: Backend state => Identifier -> [HWType] -> Mon (State state) [(String, Doc)] -- | Convert a Netlist HWType to a target HDL type hdlType :: Backend state => Usage -> HWType -> Mon (State state) Doc -- | Convert a Netlist HWType to an HDL error value for that type hdlTypeErrValue :: Backend state => HWType -> Mon (State state) Doc -- | Convert a Netlist HWType to the root of a target HDL type hdlTypeMark :: Backend state => HWType -> Mon (State state) Doc -- | Create a record selector hdlRecSel :: Backend state => HWType -> Int -> Mon (State state) Doc -- | Create a signal declaration from an identifier (Text) and Netlist -- HWType hdlSig :: Backend state => Text -> HWType -> Mon (State state) Doc -- | Create a generative block statement marker genStmt :: Backend state => Bool -> State state Doc -- | Turn a Netlist Declaration to a HDL concurrent block inst :: Backend state => Declaration -> Mon (State state) (Maybe Doc) -- | Turn a Netlist expression into a HDL expression expr :: Backend state => Bool -> Expr -> Mon (State state) Doc -- | Bit-width of Int,Word,Integer iwWidth :: Backend state => State state Int -- | Convert to a bit-vector toBV :: Backend state => HWType -> Text -> Mon (State state) Doc -- | Convert from a bit-vector fromBV :: Backend state => HWType -> Text -> Mon (State state) Doc -- | Synthesis tool we're generating HDL for hdlSyn :: Backend state => State state HdlSyn -- | mkIdentifier mkIdentifier :: Backend state => State state (IdType -> Identifier -> Identifier) -- | mkIdentifier extendIdentifier :: Backend state => State state (IdType -> Identifier -> Identifier -> Identifier) -- | setModName setModName :: Backend state => ModName -> state -> state -- | setSrcSpan setSrcSpan :: Backend state => SrcSpan -> State state () -- | getSrcSpan getSrcSpan :: Backend state => State state SrcSpan -- | Block of declarations blockDecl :: Backend state => Text -> [Declaration] -> Mon (State state) Doc -- | unextend/unescape identifier unextend :: Backend state => State state (Identifier -> Identifier) addIncludes :: Backend state => [(String, Doc)] -> State state () addLibraries :: Backend state => [Text] -> State state () addImports :: Backend state => [Text] -> State state () addAndSetData :: Backend state => FilePath -> State state String getDataFiles :: Backend state => State state [(String, FilePath)] addMemoryDataFile :: Backend state => (String, String) -> State state () getMemoryDataFiles :: Backend state => State state [(String, String)] seenIdentifiers :: Backend state => Lens' state (HashMap Identifier Word) ifThenElseExpr :: Backend state => state -> Bool -- | Replace a normal HDL template placeholder with an unescaped/unextended -- template placeholder. -- -- Needed when the the place-holder is filled with an escaped/extended -- identifier inside an escaped/extended identifier and we want to strip -- the escape /extension markers. Otherwise we end up with illegal -- identifiers. escapeTemplate :: Identifier -> Identifier mkUniqueIdentifier :: Backend s => IdType -> Identifier -> State s Identifier preserveSeen :: Backend s => Mon (State s) a -> Mon (State s) a -- | Type and instance definitions for Netlist modules module Clash.Netlist.Types -- | Internals of a Component data Declaration -- | Signal assignment Assignment :: !Identifier -> !Expr -> Declaration -- | Conditional signal assignment: CondAssignment :: !Identifier -> !HWType -> !Expr -> !HWType -> [(Maybe Literal, Expr)] -> Declaration -- | Instantiation of another component: InstDecl :: EntityOrComponent -> Maybe Comment -> !Identifier -> !Identifier -> [(Expr, HWType, Expr)] -> [(Expr, PortDirection, HWType, Expr)] -> Declaration -- | Instantiation of blackbox declaration BlackBoxD :: !Text -> [BlackBoxTemplate] -> [BlackBoxTemplate] -> [((Text, Text), BlackBox)] -> !BlackBox -> BlackBoxContext -> Declaration -- | Signal declaration NetDecl' :: Maybe Comment -> WireOrReg -> !Identifier -> Either Identifier HWType -> Maybe Expr -> Declaration -- | HDL tick corresponding to a Core tick | Sequential statement TickDecl :: Comment -> Declaration Seq :: [Seq] -> Declaration pattern NetDecl :: Maybe Comment -> Identifier -> HWType -> Declaration -- | Monad that caches generated components (StateT) and remembers hidden -- inputs of components that are being generated (WriterT) newtype NetlistMonad a NetlistMonad :: StateT NetlistState (ReaderT NetlistEnv IO) a -> NetlistMonad a [runNetlist] :: NetlistMonad a -> StateT NetlistState (ReaderT NetlistEnv IO) a data BlackBox BBTemplate :: BlackBoxTemplate -> BlackBox BBFunction :: BBName -> BBHash -> TemplateFunction -> BlackBox -- | Expression used in RHS of a declaration data Expr -- | Literal expression Literal :: !Maybe (HWType, Size) -> !Literal -> Expr -- | DataCon application DataCon :: !HWType -> !Modifier -> [Expr] -> Expr -- | Signal reference Identifier :: !Identifier -> !Maybe Modifier -> Expr -- | Left e: tagToEnum#, Right e: dataToTag# DataTag :: !HWType -> !Either Identifier Identifier -> Expr -- | Instantiation of a BlackBox expression BlackBoxE :: !Text -> [BlackBoxTemplate] -> [BlackBoxTemplate] -> [((Text, Text), BlackBox)] -> !BlackBox -> !BlackBoxContext -> !Bool -> Expr ConvBV :: Maybe Identifier -> HWType -> Bool -> Expr -> Expr IfThenElse :: Expr -> Expr -> Expr -> Expr -- | Do nothing Noop :: Expr -- | Component: base unit of a Netlist data Component Component :: !Identifier -> [(Identifier, HWType)] -> [(WireOrReg, (Identifier, HWType), Maybe Expr)] -> [Declaration] -> Component -- | Name of the component [componentName] :: Component -> !Identifier -- | Input ports [inputs] :: Component -> [(Identifier, HWType)] -- | Output ports [outputs] :: Component -> [(WireOrReg, (Identifier, HWType), Maybe Expr)] -- | Internal declarations [declarations] :: Component -> [Declaration] -- | Internals of a Component data Declaration -- | Signal assignment Assignment :: !Identifier -> !Expr -> Declaration -- | Conditional signal assignment: CondAssignment :: !Identifier -> !HWType -> !Expr -> !HWType -> [(Maybe Literal, Expr)] -> Declaration -- | Instantiation of another component: InstDecl :: EntityOrComponent -> Maybe Comment -> !Identifier -> !Identifier -> [(Expr, HWType, Expr)] -> [(Expr, PortDirection, HWType, Expr)] -> Declaration -- | Instantiation of blackbox declaration BlackBoxD :: !Text -> [BlackBoxTemplate] -> [BlackBoxTemplate] -> [((Text, Text), BlackBox)] -> !BlackBox -> BlackBoxContext -> Declaration -- | Signal declaration NetDecl' :: Maybe Comment -> WireOrReg -> !Identifier -> Either Identifier HWType -> Maybe Expr -> Declaration -- | HDL tick corresponding to a Core tick | Sequential statement TickDecl :: Comment -> Declaration Seq :: [Seq] -> Declaration -- | Representable hardware types data HWType -- | Empty type. Just Size for "empty" Vectors so we can still -- have primitives that can traverse e.g. Vectors of unit and know the -- length of that vector. Void :: Maybe HWType -> HWType -- | String type String :: HWType -- | Integer type (for parameters only) Integer :: HWType -- | Boolean type Bool :: HWType -- | Bit type Bit :: HWType -- | BitVector of a specified size BitVector :: !Size -> HWType -- | Unsigned integer with specified (exclusive) upper bounder Index :: !Integer -> HWType -- | Signed integer of a specified size Signed :: !Size -> HWType -- | Unsigned integer of a specified size Unsigned :: !Size -> HWType -- | Vector type Vector :: !Size -> !HWType -> HWType -- | RTree type RTree :: !Size -> !HWType -> HWType -- | Sum type: Name and Constructor names Sum :: !Identifier -> [Identifier] -> HWType -- | Product type: Name, field names, and field types. Field names will be -- populated when using records. Product :: !Identifier -> Maybe [Text] -> [HWType] -> HWType -- | Sum-of-Product type: Name and Constructor names + field types SP :: !Identifier -> [(Identifier, [HWType])] -> HWType -- | Clock type corresponding to domain Identifier Clock :: !Identifier -> HWType -- | Reset type corresponding to domain Identifier Reset :: !Identifier -> HWType -- | Tagging type indicating a bidirectional (inout) port BiDirectional :: !PortDirection -> !HWType -> HWType -- | Same as Sum-Of-Product, but with a user specified bit representation. -- For more info, see: Clash.Annotations.BitRepresentations. CustomSP :: !Identifier -> !DataRepr' -> !Size -> [(ConstrRepr', Identifier, [HWType])] -> HWType -- | Same as Sum, but with a user specified bit representation. For more -- info, see: Clash.Annotations.BitRepresentations. CustomSum :: !Identifier -> !DataRepr' -> !Size -> [(ConstrRepr', Identifier)] -> HWType -- | Same as Product, but with a user specified bit representation. For -- more info, see: Clash.Annotations.BitRepresentations. CustomProduct :: !Identifier -> !DataRepr' -> !Size -> Maybe [Text] -> [(FieldAnn, HWType)] -> HWType -- | Annotated with HDL attributes Annotated :: [Attr'] -> !HWType -> HWType -- | Domain name, period, active edge, reset kind, initial value behavior KnownDomain :: !Identifier -> !Integer -> !ActiveEdge -> !ResetKind -> !InitBehavior -> !ResetPolarity -> HWType -- | File type for simulation-level I/O FileType :: HWType -- | Signal reference type Identifier = Text -- | Type of declaration, concurrent or sequential data DeclarationType Concurrent :: DeclarationType Sequential :: DeclarationType -- | Netlist-level identifier data NetlistId -- | Identifier generated in the NetlistMonad, always derived from another -- NetlistId NetlistId :: Identifier -> Type -> NetlistId -- | An original Core identifier CoreId :: Id -> NetlistId -- | A split identifier (into several sub-identifiers), needed to assign -- expressions of types that have to be split apart (e.g. tuples of -- Files) MultiId :: [Id] -> NetlistId data TemplateFunction [TemplateFunction] :: [Int] -> (BlackBoxContext -> Bool) -> (forall s. Backend s => BlackBoxContext -> State s Doc) -> TemplateFunction type BBHash = Int type BBName = String -- | Context used to fill in the holes of a BlackBox template data BlackBoxContext Context :: Text -> (Expr, HWType) -> [(Expr, HWType, Bool)] -> IntMap [(Either BlackBox (Identifier, [Declaration]), WireOrReg, [BlackBoxTemplate], [BlackBoxTemplate], [((Text, Text), BlackBox)], BlackBoxContext)] -> [Identifier] -> Int -> Identifier -> Maybe Identifier -> BlackBoxContext -- | Blackbox function name (for error reporting) [bbName] :: BlackBoxContext -> Text -- | Result name and type [bbResult] :: BlackBoxContext -> (Expr, HWType) -- | Argument names, types, and whether it is a literal [bbInputs] :: BlackBoxContext -> [(Expr, HWType, Bool)] -- | Function arguments (subset of inputs): -- -- [bbFunctions] :: BlackBoxContext -> IntMap [(Either BlackBox (Identifier, [Declaration]), WireOrReg, [BlackBoxTemplate], [BlackBoxTemplate], [((Text, Text), BlackBox)], BlackBoxContext)] [bbQsysIncName] :: BlackBoxContext -> [Identifier] -- | The scoping level this context is associated with, ensures that -- ~ARGN[k][n] holes are only filled with values from this -- context if k is equal to the scoping level of this context. [bbLevel] :: BlackBoxContext -> Int -- | The component the BlackBox is instantiated in [bbCompName] :: BlackBoxContext -> Identifier -- | The "context name", name set by setName, defaults to the name -- of the closest binder [bbCtxName] :: BlackBoxContext -> Maybe Identifier -- | Bit literal data Bit -- | High H :: Bit -- | Low L :: Bit -- | Undefined U :: Bit -- | High-impedance Z :: Bit -- | Literals used in an expression data Literal -- | Number literal NumLit :: !Integer -> Literal -- | Bit literal BitLit :: !Bit -> Literal -- | BitVector literal BitVecLit :: !Integer -> !Integer -> Literal -- | Boolean literal BoolLit :: !Bool -> Literal -- | Vector literal VecLit :: [Literal] -> Literal -- | String literal StringLit :: !String -> Literal -- | Expression Modifier data Modifier -- | Index the expression: (Type of expression,DataCon tag,Field Tag) Indexed :: (HWType, Int, Int) -> Modifier -- | See expression in a DataCon context: (Type of the expression, DataCon -- tag) DC :: (HWType, Int) -> Modifier -- | See the expression in the context of a Vector append operation VecAppend :: Modifier -- | See the expression in the context of a Tree append operation RTreeAppend :: Modifier -- | Slice the identifier of the given type from start to end Sliced :: (HWType, Int, Int) -> Modifier Nested :: Modifier -> Modifier -> Modifier data PortDirection In :: PortDirection Out :: PortDirection data WireOrReg Wire :: WireOrReg Reg :: WireOrReg data EntityOrComponent Entity :: EntityOrComponent Comp :: EntityOrComponent Empty :: EntityOrComponent -- | Sequential statements data Seq -- | Clocked sequential statements AlwaysClocked :: ActiveEdge -> Expr -> [Seq] -> Seq -- | Statements to run at simulator start | Statements to run always Initial :: [Seq] -> Seq -- | Statements to run always | Declaration in sequential form AlwaysComb :: [Seq] -> Seq -- | The declaration | Branching statement SeqDecl :: Declaration -> Seq Branch :: !Expr -> !HWType -> [(Maybe Literal, [Seq])] -> Seq -- | Tree structure indicating which constructor fields were filtered from -- a type due to them being void. We need this information to generate -- stable and/or user-defined port mappings. data FilteredHWType FilteredHWType :: HWType -> [[(IsVoid, FilteredHWType)]] -> FilteredHWType type IsVoid = Bool -- | Size indication of a type (e.g. bit-size or number of elements) type Size = Int type Comment = Text -- | Existentially quantified backend data SomeBackend [SomeBackend] :: Backend backend => backend -> SomeBackend data ComponentPrefix ComponentPrefix :: Maybe Identifier -> Maybe Identifier -> ComponentPrefix -- | Prefix for top-level components [componentPrefixTop] :: ComponentPrefix -> Maybe Identifier -- | Prefix for all other components [componentPrefixOther] :: ComponentPrefix -> Maybe Identifier -- | State of the NetlistMonad data NetlistState NetlistState :: BindingMap -> !Int -> VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component) -> CompiledPrimMap -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> TyConMap -> !(Identifier, SrcSpan) -> Int -> (IdType -> Identifier -> Identifier) -> (IdType -> Identifier -> Identifier -> Identifier) -> HashMap Identifier Word -> HashMap Identifier Word -> Set Text -> VarEnv Identifier -> VarEnv TopEntityT -> FilePath -> Int -> ComponentPrefix -> CustomReprs -> ClashOpts -> Bool -> Bool -> SomeBackend -> HWMap -> NetlistState -- | Global binders [_bindings] :: NetlistState -> BindingMap -- | Number of signal declarations [_varCount] :: NetlistState -> !Int -- | Cached components [_components] :: NetlistState -> VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component) -- | Primitive Definitions [_primitives] :: NetlistState -> CompiledPrimMap -- | Hardcoded Type -> HWType translator [_typeTranslator] :: NetlistState -> CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType)) -- | TyCon cache [_tcCache] :: NetlistState -> TyConMap [_curCompNm] :: NetlistState -> !(Identifier, SrcSpan) [_intWidth] :: NetlistState -> Int [_mkIdentifierFn] :: NetlistState -> IdType -> Identifier -> Identifier [_extendIdentifierFn] :: NetlistState -> IdType -> Identifier -> Identifier -> Identifier [_seenIds] :: NetlistState -> HashMap Identifier Word [_seenComps] :: NetlistState -> HashMap Identifier Word -- | Keeps track of invocations of ´mkPrimitive´. It is currently used to -- filter duplicate warning invocations for dubious blackbox -- instantiations, see GitHub pull request #286. [_seenPrimitives] :: NetlistState -> Set Text [_componentNames] :: NetlistState -> VarEnv Identifier [_topEntityAnns] :: NetlistState -> VarEnv TopEntityT [_hdlDir] :: NetlistState -> FilePath -- | The current scoping level assigned to black box contexts [_curBBlvl] :: NetlistState -> Int [_componentPrefix] :: NetlistState -> ComponentPrefix [_customReprs] :: NetlistState -> CustomReprs -- | Settings Clash was called with [_clashOpts] :: NetlistState -> ClashOpts -- | Whether we're compiling a testbench (suppresses some warnings) [_isTestBench] :: NetlistState -> Bool -- | Whether the backend supports ifThenElse expressions [_backEndITE] :: NetlistState -> Bool -- | The current HDL backend [_backend] :: NetlistState -> SomeBackend [_htyCache] :: NetlistState -> HWMap -- | Environment of the NetlistMonad data NetlistEnv NetlistEnv :: Identifier -> Identifier -> Maybe Identifier -> NetlistEnv -- | Prefix for instance/register names [_prefixName] :: NetlistEnv -> Identifier -- | Postfix for instance/register names [_suffixName] :: NetlistEnv -> Identifier -- | (Maybe) user given instance/register name [_setName] :: NetlistEnv -> Maybe Identifier type HWMap = HashMap Type (Either String FilteredHWType) -- | Structure describing a top entity: it's id, its port annotations, and -- associated testbench. data TopEntityT TopEntityT :: Id -> Maybe TopEntity -> Maybe Id -> TopEntityT -- | Id of top entity [topId] :: TopEntityT -> Id -- | (Maybe) a topentity annotation [topAnnotation] :: TopEntityT -> Maybe TopEntity -- | (Maybe) a test bench associated with the topentity [associatedTestbench] :: TopEntityT -> Maybe Id pattern NetDecl :: Maybe Comment -> Identifier -> HWType -> Declaration -- | Extract hardware attributes from Annotated. Returns an empty list if -- non-Annotated given or if Annotated has an empty list of attributes. hwTypeAttrs :: HWType -> [Attr'] toBit :: Integer -> Integer -> Bit -- | Eliminator for NetlistId netlistId :: (Identifier -> r) -> (Id -> r) -> NetlistId -> [r] -- | Eliminator for NetlistId, fails on MultiId netlistId1 :: HasCallStack => (Identifier -> r) -> (Id -> r) -> NetlistId -> r -- | Return the type(s) of a NetListId, returns multiple types -- when given a MultiId netlistTypes :: NetlistId -> [Type] -- | Return the type of a NetlistId, fails on MultiId netlistTypes1 :: HasCallStack => NetlistId -> Type emptyBBContext :: Text -> BlackBoxContext prefixName :: Lens' NetlistEnv Identifier setName :: Lens' NetlistEnv (Maybe Identifier) suffixName :: Lens' NetlistEnv Identifier backEndITE :: Lens' NetlistState Bool backend :: Lens' NetlistState SomeBackend bindings :: Lens' NetlistState BindingMap clashOpts :: Lens' NetlistState ClashOpts componentNames :: Lens' NetlistState (VarEnv Identifier) componentPrefix :: Lens' NetlistState ComponentPrefix components :: Lens' NetlistState (VarEnv ([Bool], SrcSpan, HashMap Identifier Word, Component)) curBBlvl :: Lens' NetlistState Int curCompNm :: Lens' NetlistState (Identifier, SrcSpan) customReprs :: Lens' NetlistState CustomReprs extendIdentifierFn :: Lens' NetlistState (IdType -> Identifier -> Identifier -> Identifier) hdlDir :: Lens' NetlistState FilePath htyCache :: Lens' NetlistState HWMap intWidth :: Lens' NetlistState Int isTestBench :: Lens' NetlistState Bool mkIdentifierFn :: Lens' NetlistState (IdType -> Identifier -> Identifier) primitives :: Lens' NetlistState CompiledPrimMap seenComps :: Lens' NetlistState (HashMap Identifier Word) seenIds :: Lens' NetlistState (HashMap Identifier Word) seenPrimitives :: Lens' NetlistState (Set Text) tcCache :: Lens' NetlistState TyConMap topEntityAnns :: Lens' NetlistState (VarEnv TopEntityT) typeTranslator :: Lens' NetlistState (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) varCount :: Lens' NetlistState Int instance GHC.Generics.Generic Clash.Netlist.Types.TopEntityT instance GHC.Show.Show Clash.Netlist.Types.ComponentPrefix instance GHC.Show.Show Clash.Netlist.Types.EntityOrComponent instance GHC.Generics.Generic Clash.Netlist.Types.WireOrReg instance GHC.Show.Show Clash.Netlist.Types.WireOrReg instance Data.Hashable.Class.Hashable Clash.Netlist.Types.PortDirection instance Control.DeepSeq.NFData Clash.Netlist.Types.PortDirection instance GHC.Generics.Generic Clash.Netlist.Types.PortDirection instance GHC.Show.Show Clash.Netlist.Types.PortDirection instance GHC.Classes.Ord Clash.Netlist.Types.PortDirection instance GHC.Classes.Eq Clash.Netlist.Types.PortDirection instance Data.Hashable.Class.Hashable Clash.Netlist.Types.HWType instance Control.DeepSeq.NFData Clash.Netlist.Types.HWType instance GHC.Generics.Generic Clash.Netlist.Types.HWType instance GHC.Show.Show Clash.Netlist.Types.HWType instance GHC.Classes.Ord Clash.Netlist.Types.HWType instance GHC.Classes.Eq Clash.Netlist.Types.HWType instance GHC.Show.Show Clash.Netlist.Types.FilteredHWType instance GHC.Classes.Eq Clash.Netlist.Types.FilteredHWType instance GHC.Show.Show Clash.Netlist.Types.Modifier instance Language.Haskell.TH.Syntax.Lift Clash.Netlist.Types.Bit instance GHC.Show.Show Clash.Netlist.Types.Bit instance GHC.Classes.Eq Clash.Netlist.Types.Bit instance GHC.Show.Show Clash.Netlist.Types.Literal instance GHC.Classes.Eq Clash.Netlist.Types.Literal instance GHC.Show.Show Clash.Netlist.Types.Seq instance GHC.Show.Show Clash.Netlist.Types.Declaration instance GHC.Show.Show Clash.Netlist.Types.Expr instance Data.Binary.Class.Binary Clash.Netlist.Types.BlackBox instance Control.DeepSeq.NFData Clash.Netlist.Types.BlackBox instance GHC.Generics.Generic Clash.Netlist.Types.BlackBox instance GHC.Show.Show Clash.Netlist.Types.BlackBoxContext instance GHC.Show.Show Clash.Netlist.Types.Component instance Control.Monad.Fail.MonadFail Clash.Netlist.Types.NetlistMonad instance Control.Monad.IO.Class.MonadIO Clash.Netlist.Types.NetlistMonad instance Control.Monad.State.Class.MonadState Clash.Netlist.Types.NetlistState Clash.Netlist.Types.NetlistMonad instance Control.Monad.Reader.Class.MonadReader Clash.Netlist.Types.NetlistEnv Clash.Netlist.Types.NetlistMonad instance GHC.Base.Applicative Clash.Netlist.Types.NetlistMonad instance GHC.Base.Monad Clash.Netlist.Types.NetlistMonad instance GHC.Base.Functor Clash.Netlist.Types.NetlistMonad instance GHC.Show.Show Clash.Netlist.Types.NetlistId instance Control.DeepSeq.NFData Clash.Netlist.Types.Component instance Control.DeepSeq.NFData Clash.Netlist.Types.Declaration instance Control.DeepSeq.NFData Clash.Netlist.Types.Expr instance GHC.Show.Show Clash.Netlist.Types.BlackBox instance Control.DeepSeq.NFData Clash.Netlist.Types.TemplateFunction instance Data.Binary.Class.Binary Clash.Netlist.Types.TemplateFunction instance Control.DeepSeq.NFData Clash.Netlist.Types.WireOrReg -- | Type and instance definitions for Rewrite modules module Clash.Rewrite.Types -- | State used by the inspection mechanism for recording rewrite steps. data RewriteStep RewriteStep :: Context -> String -> String -> Term -> Term -> RewriteStep -- | current context [t_ctx] :: RewriteStep -> Context -- | Name of the transformation [t_name] :: RewriteStep -> String -- | Name of the current binder [t_bndrS] :: RewriteStep -> String -- | Term before apply [t_before] :: RewriteStep -> Term -- | Term after apply [t_after] :: RewriteStep -> Term -- | State of a rewriting session data RewriteState extra RewriteState :: {-# UNPACK #-} !Int -> !BindingMap -> !Supply -> (Id, SrcSpan) -> {-# UNPACK #-} !Int -> PrimHeap -> VarEnv Bool -> !extra -> RewriteState extra -- | Number of applied transformations [_transformCounter] :: RewriteState extra -> {-# UNPACK #-} !Int -- | Global binders [_bindings] :: RewriteState extra -> !BindingMap -- | Supply of unique numbers [_uniqSupply] :: RewriteState extra -> !Supply -- | Function which is currently normalized [_curFun] :: RewriteState extra -> (Id, SrcSpan) -- | Used for Fresh [_nameCounter] :: RewriteState extra -> {-# UNPACK #-} !Int -- | Used as a heap for compile-time evaluation of primitives that live in -- I/O [_globalHeap] :: RewriteState extra -> PrimHeap -- | Map telling whether a binder's definition is work-free [_workFreeBinders] :: RewriteState extra -> VarEnv Bool -- | Additional state [_extra] :: RewriteState extra -> !extra workFreeBinders :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) (VarEnv Bool) uniqSupply :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) Supply transformCounter :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) Int nameCounter :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) Int globalHeap :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) PrimHeap extra :: forall extra_a3f2X extra_a3fbq. Lens (RewriteState extra_a3f2X) (RewriteState extra_a3fbq) extra_a3f2X extra_a3fbq curFun :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) (Id, SrcSpan) bindings :: forall extra_a3f2X. Lens' (RewriteState extra_a3f2X) BindingMap -- | Read-only environment of a rewriting session data RewriteEnv RewriteEnv :: DebugLevel -> Set String -> Int -> Int -> Bool -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> TyConMap -> IntMap TyConName -> (PrimStep, PrimUnwind) -> VarSet -> CustomReprs -> RewriteEnv -- | Level at which we print debugging messages [_dbgLevel] :: RewriteEnv -> DebugLevel -- | See ClashOpts.dbgTransformations [_dbgTransformations] :: RewriteEnv -> Set String -- | See ClashOpts.opt_dbgTransformationsFrom [_dbgTransformationsFrom] :: RewriteEnv -> Int -- | See ClashOpts.opt_dbgTransformationsLimit [_dbgTransformationsLimit] :: RewriteEnv -> Int -- | Transformations to print debugging info for [_aggressiveXOpt] :: RewriteEnv -> Bool -- | Hardcode Type -> FilteredHWType translator [_typeTranslator] :: RewriteEnv -> CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType)) -- | TyCon cache [_tcCache] :: RewriteEnv -> TyConMap -- | Tuple TyCon cache [_tupleTcCache] :: RewriteEnv -> IntMap TyConName -- | Hardcoded evaluator (delta-reduction)} [_evaluator] :: RewriteEnv -> (PrimStep, PrimUnwind) -- | Functions that are considered TopEntities [_topEntities] :: RewriteEnv -> VarSet -- | Custom bit representations [_customReprs] :: RewriteEnv -> CustomReprs typeTranslator :: Lens' RewriteEnv (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) tupleTcCache :: Lens' RewriteEnv (IntMap TyConName) topEntities :: Lens' RewriteEnv VarSet tcCache :: Lens' RewriteEnv TyConMap evaluator :: Lens' RewriteEnv (PrimStep, PrimUnwind) dbgTransformationsLimit :: Lens' RewriteEnv Int dbgTransformationsFrom :: Lens' RewriteEnv Int dbgTransformations :: Lens' RewriteEnv (Set String) dbgLevel :: Lens' RewriteEnv DebugLevel customReprs :: Lens' RewriteEnv CustomReprs aggressiveXOpt :: Lens' RewriteEnv Bool -- | Monad that keeps track how many transformations have been applied and -- can generate fresh variables and unique identifiers. In addition, it -- keeps track if a transformation/rewrite has been successfully applied. newtype RewriteMonad extra a R :: (RewriteEnv -> RewriteState extra -> Any -> (a, RewriteState extra, Any)) -> RewriteMonad extra a [unR] :: RewriteMonad extra a -> RewriteEnv -> RewriteState extra -> Any -> (a, RewriteState extra, Any) -- | Run the computation in the RewriteMonad runR :: RewriteMonad extra a -> RewriteEnv -> RewriteState extra -> (a, RewriteState extra, Any) censor :: (Any -> Any) -> RewriteMonad extra a -> RewriteMonad extra a data TransformContext TransformContext :: !InScopeSet -> Context -> TransformContext [tfInScope] :: TransformContext -> !InScopeSet [tfContext] :: TransformContext -> Context -- | Monadic action that transforms a term given a certain context type Transform m = TransformContext -> Term -> m Term -- | A Transform action in the context of the RewriteMonad type Rewrite extra = Transform (RewriteMonad extra) instance Control.Monad.Fail.MonadFail (Clash.Rewrite.Types.RewriteMonad extra) instance GHC.Base.Functor (Clash.Rewrite.Types.RewriteMonad extra) instance GHC.Base.Applicative (Clash.Rewrite.Types.RewriteMonad extra) instance GHC.Base.Monad (Clash.Rewrite.Types.RewriteMonad extra) instance Control.Monad.State.Class.MonadState (Clash.Rewrite.Types.RewriteState extra) (Clash.Rewrite.Types.RewriteMonad extra) instance Clash.Util.MonadUnique (Clash.Rewrite.Types.RewriteMonad extra) instance Control.Monad.Writer.Class.MonadWriter Data.Semigroup.Internal.Any (Clash.Rewrite.Types.RewriteMonad extra) instance Control.Monad.Reader.Class.MonadReader Clash.Rewrite.Types.RewriteEnv (Clash.Rewrite.Types.RewriteMonad extra) instance Control.Monad.Fix.MonadFix (Clash.Rewrite.Types.RewriteMonad extra) instance Data.Binary.Class.Binary Clash.Rewrite.Types.RewriteStep instance Data.Hashable.Class.Hashable Clash.Rewrite.Types.RewriteStep instance Control.DeepSeq.NFData Clash.Rewrite.Types.RewriteStep instance GHC.Generics.Generic Clash.Rewrite.Types.RewriteStep instance GHC.Show.Show Clash.Rewrite.Types.RewriteStep -- | Rewriting combinators and traversals module Clash.Rewrite.Combinators -- | Apply a transformation on the subtrees of an term allR :: forall m. Monad m => Transform m -> Transform m -- | Only apply the second transformation if the first one succeeds. (!->) :: Rewrite m -> Rewrite m -> Rewrite m infixr 5 !-> -- | Only apply the second transformation if the first one fails. (>-!) :: Rewrite m -> Rewrite m -> Rewrite m infixr 5 >-! -- | Apply two transformations in succession, and perform a deepseq in -- between. (>-!->) :: Monad m => Transform m -> Transform m -> Transform m infixr 6 >-!-> -- | Apply two transformations in succession (>->) :: Monad m => Transform m -> Transform m -> Transform m infixr 6 >-> -- | Apply a transformation in a bottomup traversal bottomupR :: Monad m => Transform m -> Transform m -- | Keep applying a transformation until it fails. repeatR :: Rewrite m -> Rewrite m -- | Apply a transformation in a topdown traversal topdownR :: Rewrite m -> Rewrite m whenR :: Monad m => (TransformContext -> Term -> m Bool) -> Transform m -> Transform m -- | Only traverse downwards when the assertion evaluates to true bottomupWhenR :: Monad m => (TransformContext -> Term -> m Bool) -> Transform m -> Transform m -- | Types used in Normalize modules module Clash.Normalize.Types -- | State of the NormalizeMonad data NormalizeState NormalizeState :: BindingMap -> Map (Id, Int, Either Term Type) Id -> VarEnv Int -> !Int -> VarEnv (VarEnv Int) -> !Int -> !Word -> !Word -> CompiledPrimMap -> Map Text (Set Int) -> VarEnv Bool -> Bool -> Bool -> !Word -> NormalizeState -- | Global binders [_normalized] :: NormalizeState -> BindingMap -- | Cache of previously specialized functions: -- -- [_specialisationCache] :: NormalizeState -> Map (Id, Int, Either Term Type) Id -- | Cache of how many times a function was specialized [_specialisationHistory] :: NormalizeState -> VarEnv Int -- | Number of time a function f can be specialized [_specialisationLimit] :: NormalizeState -> !Int -- | Cache of function where inlining took place: -- -- [_inlineHistory] :: NormalizeState -> VarEnv (VarEnv Int) -- | Number of times a function f can be inlined in a function -- g [_inlineLimit] :: NormalizeState -> !Int -- | Size of a function below which it is always inlined if it is not -- recursive [_inlineFunctionLimit] :: NormalizeState -> !Word -- | Size of a constant below which it is always inlined; 0 = no limit [_inlineConstantLimit] :: NormalizeState -> !Word -- | Primitive Definitions [_primitives] :: NormalizeState -> CompiledPrimMap -- | Cache for looking up constantness of blackbox arguments [_primitiveArgs] :: NormalizeState -> Map Text (Set Int) -- | Map telling whether a components is recursively defined. -- -- NB: there are only no mutually-recursive component, only -- self-recursive ones. [_recursiveComponents] :: NormalizeState -> VarEnv Bool -- | Flattening stage should use the new (no-)inlining strategy [_newInlineStrategy] :: NormalizeState -> Bool -- | High-effort normalization session, trading performance improvement for -- potentially much longer compile times. Follows the opt_ultra -- flag. [_normalizeUltra] :: NormalizeState -> Bool -- | At what size do we cache normalized work-free top-level binders. [_inlineWFCacheLimit] :: NormalizeState -> !Word specialisationLimit :: Lens' NormalizeState Int specialisationHistory :: Lens' NormalizeState (VarEnv Int) specialisationCache :: Lens' NormalizeState (Map (Id, Int, Either Term Type) Id) recursiveComponents :: Lens' NormalizeState (VarEnv Bool) primitives :: Lens' NormalizeState CompiledPrimMap primitiveArgs :: Lens' NormalizeState (Map Text (Set Int)) normalized :: Lens' NormalizeState BindingMap normalizeUltra :: Lens' NormalizeState Bool newInlineStrategy :: Lens' NormalizeState Bool inlineWFCacheLimit :: Lens' NormalizeState Word inlineLimit :: Lens' NormalizeState Int inlineHistory :: Lens' NormalizeState (VarEnv (VarEnv Int)) inlineFunctionLimit :: Lens' NormalizeState Word inlineConstantLimit :: Lens' NormalizeState Word -- | State monad that stores specialisation and inlining information type NormalizeMonad = State NormalizeState -- | RewriteSession with extra Normalisation information type NormalizeSession = RewriteMonad NormalizeState -- | A Transform action in the context of the RewriteMonad -- and NormalizeMonad type NormRewrite = Rewrite NormalizeState -- | Description of a Term in terms of the type "components" the -- Term has. -- -- Is used as a performance/size metric. data TermClassification TermClassification :: !Int -> !Int -> !Int -> TermClassification -- | Number of functions [_function] :: TermClassification -> !Int -- | Number of primitives [_primitive] :: TermClassification -> !Int -- | Number of selections/multiplexers [_selection] :: TermClassification -> !Int selection :: Lens' TermClassification Int primitive :: Lens' TermClassification Int function :: Lens' TermClassification Int instance GHC.Show.Show Clash.Normalize.Types.TermClassification module Clash.Primitives.Sized.ToInteger bvToIntegerVerilog :: BlackBoxFunction bvToIntegerVHDL :: BlackBoxFunction indexToIntegerVerilog :: BlackBoxFunction indexToIntegerVHDL :: BlackBoxFunction signedToIntegerVerilog :: BlackBoxFunction signedToIntegerVHDL :: BlackBoxFunction unsignedToIntegerVerilog :: BlackBoxFunction unsignedToIntegerVHDL :: BlackBoxFunction -- | Blackbox generation for literal data constructors. (System)Verilog -- only! module Clash.Primitives.GHC.Literal assign :: Element -> [Element] -> [Element] signed :: Element -> [Element] signedLiteral :: Int -> Integer -> Element unsigned :: Element -> [Element] unsignedLiteral :: Int -> Integer -> Element -- | Constructs "clean" literals. literalTF :: Text -> (Bool -> [Either Term Type] -> Int -> (BlackBoxMeta, BlackBox)) -> BlackBoxFunction -- | Blackbox generation for GHC.Word.WordX# data constructors. -- (System)Verilog only! module Clash.Primitives.GHC.Word -- | Template function for Word8,Word16,.. Constructs "clean" literals. -- This function generates valid (System)Verilog only! wordTF :: BlackBoxFunction -- | Blackbox generation for GHC.Int.IntX# data constructors. -- (System)Verilog only! module Clash.Primitives.GHC.Int -- | Template function for Int8,Int16,.. Constructs "clean" literals. intTF :: BlackBoxFunction -- | Houses internal BitRepresentation code which cannot be housed in -- clash-prelude due to its dependencies. module Clash.Annotations.BitRepresentation.ClashLib coreToType' :: Type -> Either String Type' -- | Converts a list of BitRepresentation.Bits to their Netlist -- counterpart. bitsToBits :: [Bit] -> [Bit] -- | Utilities for converting Core Type/Term to Netlist datatypes module Clash.Netlist.Util -- | Throw away information indicating which constructor fields were -- filtered due to being void. stripFiltered :: FilteredHWType -> HWType -- | Strip as many Void layers as possible. Might still return a -- Void if the void doesn't contain a hwtype. stripVoid :: HWType -> HWType flattenFiltered :: FilteredHWType -> [[Bool]] isVoidMaybe :: Bool -> Maybe HWType -> Bool -- | Determines if type is a zero-width construct ("void") isVoid :: HWType -> Bool -- | Same as isVoid, but on FilteredHWType instead of -- HWType isFilteredVoid :: FilteredHWType -> Bool mkIdentifier :: IdType -> Identifier -> NetlistMonad Identifier extendIdentifier :: IdType -> Identifier -> Identifier -> NetlistMonad Identifier -- | 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. splitNormalized :: TyConMap -> Term -> Either String ([Id], [LetBinding], Id) -- | Same as unsafeCoreTypeToHWType, but discards void filter -- information unsafeCoreTypeToHWType' :: SrcSpan -> String -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap HWType -- | Converts a Core type to a HWType given a function that translates -- certain builtin types. Errors if the Core type is not translatable. unsafeCoreTypeToHWType :: SrcSpan -> String -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap FilteredHWType -- | Same as unsafeCoreTypeToHWTypeM, but discards void filter -- information unsafeCoreTypeToHWTypeM' :: String -> Type -> NetlistMonad HWType -- | Converts a Core type to a HWType within the NetlistMonad; errors on -- failure unsafeCoreTypeToHWTypeM :: String -> Type -> NetlistMonad FilteredHWType -- | Same as coreTypeToHWTypeM, but discards void filter -- information coreTypeToHWTypeM' :: Type -> NetlistMonad (Maybe HWType) -- | Converts a Core type to a HWType within the NetlistMonad; -- Nothing on failure coreTypeToHWTypeM :: Type -> NetlistMonad (Maybe FilteredHWType) -- | Constructs error message for unexpected projections out of a type -- annotated with a custom bit representation. unexpectedProjectionErrorMsg :: DataRepr' -> Int -> Int -> String -- | Helper function of maybeConvertToCustomRepr convertToCustomRepr :: HasCallStack => CustomReprs -> DataRepr' -> HWType -> HWType -- | 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. maybeConvertToCustomRepr :: CustomReprs -> Type -> HWType -> HWType -- | Same as coreTypeToHWType, but discards void filter -- information coreTypeToHWType' :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap (Either String HWType) -- | 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. coreTypeToHWType :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> Type -> State HWMap (Either String FilteredHWType) -- | Generates original indices in list before filtering, given a list of -- removed indices. -- --
--   >>> originalIndices [False, False, True, False]
--   [0,1,3]
--   
originalIndices :: [Bool] -> [Int] -- | Converts an algebraic Core type (split into a TyCon and its argument) -- to a HWType. mkADT :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> String -> TyConName -> [Type] -> ExceptT String (State HWMap) FilteredHWType -- | 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. hasUnconstrainedExistential :: TyConMap -> DataCon -> Bool -- | Simple check if a TyCon is recursively defined. isRecursiveTy :: TyConMap -> TyConName -> Bool -- | Determines if a Core type is translatable to a HWType given a function -- that translates certain builtin types. representableType :: (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> Bool -> TyConMap -> Type -> Bool -- | Determines the bitsize of a type. For types that don't get turned into -- real values in hardware (string, integer) the size is 0. typeSize :: HWType -> Int -- | Determines the bitsize of the constructor of a type conSize :: HWType -> Int -- | Gives the length of length-indexed types typeLength :: HWType -> Int -- | Gives the HWType corresponding to a term. Returns an error if the term -- has a Core type that is not translatable to a HWType. termHWType :: String -> Term -> NetlistMonad HWType -- | Gives the HWType corresponding to a term. Returns Nothing if -- the term has a Core type that is not translatable to a HWType. termHWTypeM :: Term -> NetlistMonad (Maybe FilteredHWType) isBiSignalIn :: HWType -> Bool containsBiSignalIn :: HWType -> Bool -- | Helper function of collectPortNames, which operates on a -- PortName instead of a TopEntity. collectPortNames' :: [String] -> PortName -> [Identifier] -- | Recursively get all port names from top entity annotations. The result -- is a list of user defined port names, which should not be used by -- routines generating unique function names. Only completely qualified -- names are returned, as it does not (and cannot) account for any -- implicitly named ports under a PortProduct. collectPortNames :: TopEntity -> [Identifier] -- | Remove ports having a void-type from user supplied PortName annotation filterVoidPorts :: FilteredHWType -> PortName -> PortName -- | Uniquely rename all the variables and their references in a normalized -- term mkUniqueNormalized :: HasCallStack => InScopeSet -> Maybe (Maybe TopEntity) -> ([Id], [LetBinding], Id) -> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], [(Identifier, HWType)], [Declaration], [LetBinding], Maybe Id) -- | Set the name of the binder -- -- Normally, it just keeps the existing name, but there are two -- exceptions: -- --
    --
  1. It's the binding for the result which is also referenced by -- another binding; in this case it's suffixed with _rec
  2. --
  3. The binding binds a primitive that has a name control field
  4. --
  5. takes priority over 1. Additionally, we create an additional -- binder when the return value gets a new name.
  6. --
setBinderName :: Subst -> Id -> Bool -> (Id, Subst, [(Id, Term)]) -> (Id, Term) -> NetlistMonad ((Id, Subst, [(Id, Term)]), Id) mkUniqueArguments :: Subst -> Maybe (Maybe TopEntity) -> [Id] -> NetlistMonad ([Bool], [(Identifier, HWType)], [Declaration], Subst) mkUniqueResult :: Subst -> Maybe (Maybe TopEntity) -> Id -> NetlistMonad (Maybe ([(Identifier, HWType)], [Declaration], Id, Subst)) -- | Same as idToPort, but * Throws an error if the port is a composite -- type with a BiSignalIn idToInPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) -- | Same as idToPort, but: * Throws an error if port is of type BiSignalIn idToOutPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) idToPort :: Id -> NetlistMonad (Maybe (Identifier, HWType)) id2type :: Id -> Type id2identifier :: Id -> Identifier repName :: Text -> Name a -> Name a -- | Make a set of IDs unique; also returns a substitution from old ID to -- new updated unique ID. mkUnique :: Subst -> [Id] -> NetlistMonad ([Id], Subst) mkUniqueIdentifier :: IdType -> Identifier -> NetlistMonad Identifier -- | Preserve the complete state before running an action, and restore it -- afterwards. preserveState :: NetlistMonad a -> NetlistMonad a -- | Preserve the Netlist -- _varCount,_curCompNm,_seenIds when executing a -- monadic action preserveVarEnv :: NetlistMonad a -> NetlistMonad a dcToLiteral :: HWType -> Int -> Literal extendPorts :: [PortName] -> [Maybe PortName] portName :: String -> Identifier -> Identifier -- | Prefix given string before portnames except when this string is -- empty. prefixParent :: String -> PortName -> PortName appendIdentifier :: (Identifier, HWType) -> Int -> NetlistMonad (Identifier, HWType) -- | In addition to the original port name (where the user should assert -- that it's a valid identifier), we also add the version of the port -- name that has gone through the 'mkIdentifier Basic' process. Why? so -- that the provided port name is copied verbatim into the generated HDL, -- but that in e.g. case-insensitive HDLs, a case-variant of the port -- name is not used as one of the signal names. uniquePortName :: String -> Identifier -> NetlistMonad Identifier mkInput :: Maybe PortName -> (Identifier, HWType) -> NetlistMonad ([(Identifier, HWType)], [Declaration], Expr, Identifier) -- | Create a Vector chain for a list of Identifiers mkVectorChain :: Int -> HWType -> [Expr] -> Expr -- | Create a RTree chain for a list of Identifiers mkRTreeChain :: Int -> HWType -> [Expr] -> Expr genComponentName :: Bool -> HashMap Identifier Word -> (IdType -> Identifier -> Identifier) -> ComponentPrefix -> Id -> Identifier genTopComponentName :: Bool -> (IdType -> Identifier -> Identifier) -> ComponentPrefix -> Maybe TopEntity -> Id -> Identifier -- | Strips one or more layers of attributes from a HWType; stops at first -- non-Annotated. Accumilates all attributes of nested annotations. stripAttributes :: HWType -> ([Attr'], HWType) -- | Generate output port mappings mkOutput :: Maybe PortName -> (Identifier, HWType) -> NetlistMonad (Maybe ([(Identifier, HWType)], [Declaration], Identifier)) -- | Generate output port mappings. Will yield Nothing if the only output -- is Void. mkOutput' :: Maybe PortName -> (Identifier, HWType) -> NetlistMonad ([(Identifier, HWType)], [Declaration], Identifier) -- | Instantiate a TopEntity, and add the proper type-conversions where -- needed mkTopUnWrapper :: Id -> Maybe TopEntity -> Manifest -> (Identifier, HWType) -> [(Expr, HWType)] -> [Declaration] -> NetlistMonad [Declaration] -- | Convert between BitVector for an argument argBV :: Maybe Identifier -> Either Identifier (Identifier, HWType) -> Expr -> Declaration -- | Convert between BitVector for the result resBV :: Maybe Identifier -> Either Identifier (Identifier, HWType) -> Expr -- | Add to/from-BitVector conversion logic doConv :: HWType -> Maybe (Maybe Identifier) -> Bool -> Expr -> Expr -- | Generate input port mappings for the TopEntity mkTopInput :: Maybe Identifier -> [(Identifier, Identifier)] -> Maybe PortName -> (Identifier, HWType) -> NetlistMonad ([(Identifier, Identifier)], ([(Identifier, Identifier, HWType)], [Declaration], Either Identifier (Identifier, HWType))) -- | 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. throwAnnotatedSplitError :: String -> String -> NetlistMonad a -- | Generate output port mappings for the TopEntity. Yields Nothing -- if the output is Void mkTopOutput :: Maybe Identifier -> [(Identifier, Identifier)] -> Maybe PortName -> (Identifier, HWType) -> NetlistMonad (Maybe ([(Identifier, Identifier)], ([(Identifier, Identifier, HWType)], [Declaration], Either Identifier (Identifier, HWType)))) -- | Generate output port mappings for the TopEntity mkTopOutput' :: Maybe Identifier -> [(Identifier, Identifier)] -> Maybe PortName -> (Identifier, HWType) -> NetlistMonad ([(Identifier, Identifier)], ([(Identifier, Identifier, HWType)], [Declaration], Either Identifier (Identifier, HWType))) concatPortDecls3 :: [([(Identifier, Identifier, HWType)], [Declaration], Either Identifier (Identifier, HWType))] -> ([(Identifier, Identifier, HWType)], [Declaration], [Either Identifier (Identifier, HWType)]) -- | Try to merge nested modifiers into a single modifier, needed by the -- VHDL and SystemVerilog backend. nestM :: Modifier -> Modifier -> Maybe Modifier -- | 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. bindsExistentials :: [TyVar] -> [Var a] -> Bool iteAlts :: HWType -> [Alt] -> Maybe (Term, Term) -- | Run a NetlistMonad computation in the context of the given source -- ticks and name modifier ticks withTicks :: [TickInfo] -> ([Declaration] -> NetlistMonad a) -> NetlistMonad a -- | Add the pre- and suffix names in the current environment to the given -- identifier affixName :: Identifier -> NetlistMonad Identifier -- | Utilities for rewriting: e.g. inlining, specialisation, etc. module Clash.Rewrite.Util -- | Lift an action working in the _extra state to the -- RewriteMonad zoomExtra :: State extra a -> RewriteMonad extra a -- | Some transformations might erroneously introduce shadowing. For -- example, a transformation might result in: -- -- let a = ... b = ... a = ... -- -- where the last a, shadows the first, while Clash assumes that -- this can't happen. This function finds those constructs and a list of -- found duplicates. findAccidentialShadows :: Term -> [[Id]] -- | Record if a transformation is successfully applied apply :: String -> Rewrite extra -> Rewrite extra applyDebug :: DebugLevel -> Set String -> Maybe (Int, Int) -> String -> Term -> Bool -> Term -> RewriteMonad extra Term -- | Perform a transformation on a Term runRewrite :: String -> InScopeSet -> Rewrite extra -> Term -> RewriteMonad extra Term -- | Evaluate a RewriteSession to its inner monad. runRewriteSession :: RewriteEnv -> RewriteState extra -> RewriteMonad extra a -> a -- | Notify that a transformation has changed the expression setChanged :: RewriteMonad extra () -- | Identity function that additionally notifies that a transformation has -- changed the expression changed :: a -> RewriteMonad extra a closestLetBinder :: Context -> Maybe Id mkDerivedName :: TransformContext -> OccName -> TmName -- | Make a new binder and variable reference for a term mkTmBinderFor :: (MonadUnique m, MonadFail m) => InScopeSet -> TyConMap -> Name a -> Term -> m Id -- | Make a new binder and variable reference for either a term or a type mkBinderFor :: (MonadUnique m, MonadFail m) => InScopeSet -> TyConMap -> Name a -> Either Term Type -> m (Either Id TyVar) -- | Make a new, unique, identifier mkInternalVar :: MonadUnique m => InScopeSet -> OccName -> KindOrType -> m Id -- | Inline the binders in a let-binding that have a certain property inlineBinders :: (Term -> LetBinding -> RewriteMonad extra Bool) -> Rewrite extra -- | Determine whether a binder is a join-point created for a complex case -- expression. -- -- A join-point is when a local function only occurs in tail-call -- positions, and when it does, more than once. isJoinPointIn :: Id -> Term -> Bool -- | Count the number of (only) tail calls of a function in an expression. -- Nothing indicates that the function was used in a non-tail call -- position. tailCalls :: Id -> Term -> Maybe Int -- | Determines whether a function has the following shape: -- --
--   \(w :: Void) -> f a b c
--   
-- -- i.e. is a wrapper around a (partially) applied function f, -- where the introduced argument w is not used by f isVoidWrapper :: Term -> Bool -- | Inline the first set of binder into the second set of binders and into -- the body of the original let expression. substituteBinders :: InScopeSet -> [LetBinding] -> [LetBinding] -> Term -> ([LetBinding], ([LetBinding], Term)) -- | Lift the first set of binders to the level of global bindings, and -- substitute these lifted bindings into the second set of binders and -- the body of the original let expression. liftAndSubsituteBinders :: InScopeSet -> [LetBinding] -> [LetBinding] -> Term -> RewriteMonad extra ([LetBinding], Term) -- | Determines whether a global binder is work free. Errors if binder does -- not exist. isWorkFreeBinder :: HasCallStack => Id -> RewriteMonad extra Bool -- | Determine whether a term does any work, i.e. adds to the size of the -- circuit isWorkFree :: Term -> RewriteMonad extra Bool isFromInt :: Text -> Bool -- | Determine if a term represents a constant isConstant :: Term -> Bool isConstantNotClockReset :: Term -> RewriteMonad extra Bool isWorkFreeClockOrResetOrEnable :: TyConMap -> Term -> Maybe Bool -- | A conservative version of isWorkFree. Is used to determine in -- bindConstantVar to determine whether an expression can be -- "bound" (locally inlined). While binding workfree expressions won't -- result in extra work for the circuit, it might very well cause extra -- work for Clash. In fact, using isWorkFree in -- bindConstantVar makes Clash two orders of magnitude slower -- for some of our test cases. -- -- In effect, this function is a version of isConstant that also -- considers references to clocks and resets constant. This allows us to -- bind HiddenClock(ResetEnable) constructs, allowing Clash to constant -- spec subconstants - most notably KnownDomain. Doing that enables Clash -- to eliminate any case-constructs on it. isWorkFreeIsh :: Term -> RewriteMonad extra Bool inlineOrLiftBinders :: (LetBinding -> RewriteMonad extra Bool) -> (Term -> LetBinding -> Bool) -> Rewrite extra -- | Create a global function for a Let-binding and return a Let-binding -- where the RHS is a reference to the new global function applied to the -- free variables of the original RHS liftBinding :: LetBinding -> RewriteMonad extra LetBinding -- | Ensure that the Unique of a variable does not occur in the -- BindingMap uniqAwayBinder :: BindingMap -> Name a -> Name a -- | Make a global function for a name-term tuple mkFunction :: TmName -> SrcSpan -> InlineSpec -> Term -> RewriteMonad extra Id -- | Add a function to the set of global binders addGlobalBind :: TmName -> Type -> SrcSpan -> InlineSpec -> Term -> RewriteMonad extra () -- | Create a new name out of the given name, but with another unique. -- Resulting unique is guaranteed to not be in the given InScopeSet. cloneNameWithInScopeSet :: MonadUnique m => InScopeSet -> Name a -> m (Name a) -- | Create a new name out of the given name, but with another unique. -- Resulting unique is guaranteed to not be in the given BindingMap. cloneNameWithBindingMap :: MonadUnique m => BindingMap -> Name a -> m (Name a) -- | Determine if a term cannot be represented in hardware isUntranslatable :: Bool -> Term -> RewriteMonad extra Bool -- | Determine if a type cannot be represented in hardware isUntranslatableType :: Bool -> Type -> RewriteMonad extra Bool -- | Make a binder that should not be referenced mkWildValBinder :: MonadUnique m => InScopeSet -> Type -> m Id -- | Make a case-decomposition that extracts a field out of a -- (Sum-of-)Product type mkSelectorCase :: HasCallStack => (Functor m, MonadUnique m) => String -> InScopeSet -> TyConMap -> Term -> Int -> Int -> m Term -- | Specialise an application on its argument specialise :: Lens' extra (Map (Id, Int, Either Term Type) Id) -> Lens' extra (VarEnv Int) -> Lens' extra Int -> Rewrite extra -- | Specialise an application on its argument specialise' :: Lens' extra (Map (Id, Int, Either Term Type) Id) -> Lens' extra (VarEnv Int) -> Lens' extra Int -> TransformContext -> Term -> (Term, [Either Term Type], [TickInfo]) -> Either Term Type -> RewriteMonad extra Term normalizeTermTypes :: TyConMap -> Term -> Term normalizeId :: TyConMap -> Id -> Id -- | Create binders and variable references for free variables in -- specArg specArgBndrsAndVars :: Either Term Type -> ([Either Id TyVar], [Either Term Type]) -- | Evaluate an expression to weak-head normal form (WHNF), and apply a -- transformation on the expression in WHNF. whnfRW :: Bool -> TransformContext -> Term -> Rewrite extra -> RewriteMonad extra Term -- | Binds variables on the PureHeap over the result of the rewrite -- -- To prevent unnecessary rewrites only do this when rewrite changed -- something. bindPureHeap :: TyConMap -> PureHeap -> Rewrite extra -> Rewrite extra -- | Remove unused binders in given let-binding. Returns Nothing if -- no unused binders were found. removeUnusedBinders :: [LetBinding] -> Term -> Maybe Term -- | Reductions of primitives -- -- Currently, it contains reductions for: -- -- -- -- Partially handles: -- -- module Clash.Normalize.PrimitiveReductions typeNatAdd :: TyConName typeNatMul :: TyConName typeNatSub :: TyConName vecHeadPrim :: TyConName -> Term vecLastPrim :: TyConName -> Term vecHeadTy :: TyConName -> Type vecTailPrim :: TyConName -> Term vecInitPrim :: TyConName -> Term vecTailTy :: TyConName -> Type -- | Makes two case statements: the first one extract the _head_ from the -- given vector, the latter the tail. extractHeadTail :: DataCon -> Type -> Integer -> Term -> (Term, Term) extractHead :: DataCon -> Type -> Integer -> Term -> Term extractTail :: DataCon -> Type -> Integer -> Term -> Term -- | Create a vector of supplied elements mkVecCons :: HasCallStack => DataCon -> Type -> Integer -> Term -> Term -> Term -- | Create an empty vector mkVecNil :: DataCon -> Type -> Term -- | Replace an application of the Clash.Sized.Vector.reverse -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.reverse reduceReverse :: InScopeSet -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.zipWith -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.zipWith reduceZipWith :: TransformContext -> PrimInfo -> Integer -> Type -> Type -> Type -> Term -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.map -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.map reduceMap :: TransformContext -> PrimInfo -> Integer -> Type -> Type -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.imap -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.imap reduceImap :: TransformContext -> Integer -> Type -> Type -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.iterateI -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of -- Clash.Sized.Vector.iterateI reduceIterateI :: TransformContext -> Integer -> Type -> Type -> Term -> Term -> RewriteMonad NormalizeState Term -- | Replace an application of the Clash.Sized.Vector.traverse# -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of -- Clash.Sized.Vector.traverse# reduceTraverse :: TransformContext -> Integer -> Type -> Type -> Type -> Term -> Term -> Term -> NormalizeSession Term -- | Create the traversable vector -- -- e.g. for a length '2' input vector, we get -- --
--   (:>) <$> x0 <*> ((:>) <$> x1 <*> pure Nil)
--   
mkTravVec :: TyConName -> DataCon -> DataCon -> Term -> Term -> Term -> Type -> Integer -> [Term] -> Term -- | Replace an application of the Clash.Sized.Vector.foldr -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.foldr reduceFoldr :: TransformContext -> PrimInfo -> Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.fold -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.fold reduceFold :: TransformContext -> Integer -> Type -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.dfold -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.dfold reduceDFold :: InScopeSet -> Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.head -- primitive on vectors of a known length n, by a projection of -- the first element of a vector. reduceHead :: InScopeSet -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.tail -- primitive on vectors of a known length n, by a projection of -- the tail of a vector. reduceTail :: InScopeSet -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.last -- primitive on vectors of a known length n, by a projection of -- the last element of a vector. reduceLast :: InScopeSet -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.init -- primitive on vectors of a known length n, by a projection of -- the init of a vector. reduceInit :: InScopeSet -> PrimInfo -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.(++) -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.(++) reduceAppend :: InScopeSet -> Integer -> Integer -> Type -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.unconcat -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of -- Clash.Sized.Vector.unconcat reduceUnconcat :: Integer -> Integer -> Type -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.transpose -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of -- Clash.Sized.Vector.transpose reduceTranspose :: Integer -> Integer -> Type -> Term -> NormalizeSession Term reduceReplicate :: Integer -> Type -> Type -> Term -> NormalizeSession Term reduceReplace_int :: InScopeSet -> Integer -> Type -> Type -> Term -> Term -> Term -> NormalizeSession Term reduceIndex_int :: InScopeSet -> Integer -> Type -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.Vector.dtfold -- primitive on vectors of a known length n, by the fully -- unrolled recursive "definition" of Clash.Sized.Vector.dtfold reduceDTFold :: InScopeSet -> Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term -- | Replace an application of the Clash.Sized.RTree.tdfold -- primitive on trees of a known depth n, by the fully unrolled -- recursive "definition" of Clash.Sized.RTree.tdfold reduceTFold :: InScopeSet -> Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term reduceTReplicate :: Integer -> Type -> Type -> Term -> NormalizeSession Term buildSNat :: DataCon -> Integer -> Term -- | Helper functions for the disjointExpressionConsolidation -- transformation -- -- The disjointExpressionConsolidation transformation lifts -- applications of global binders out of alternatives of case-statements. -- -- e.g. It converts: -- --
--   case x of
--     A -> f 3 y
--     B -> f x x
--     C -> h x
--   
-- -- into: -- --
--   let f_arg0 = case x of {A -> 3; B -> x}
--       f_arg1 = case x of {A -> y; B -> x}
--       f_out  = f f_arg0 f_arg1
--   in  case x of
--         A -> f_out
--         B -> f_out
--         C -> h x
--   
module Clash.Normalize.DEC -- | Collect CaseTrees for (potentially) disjoint applications of -- globals out of an expression. Also substitute truly disjoint -- applications of globals by a reference to a lifted out application. collectGlobals :: InScopeSet -> [(Term, Term)] -> [Term] -> Term -> RewriteMonad NormalizeState (Term, InScopeSet, [(Term, ([Term], CaseTree [Either Term Type]))]) -- | Collect CaseTrees for (potentially) disjoint applications of -- globals out of a list of application arguments. Also substitute truly -- disjoint applications of globals by a reference to a lifted out -- application. collectGlobalsArgs :: InScopeSet -> [(Term, Term)] -> [Term] -> [Either Term Type] -> RewriteMonad NormalizeState ([Either Term Type], InScopeSet, [(Term, ([Term], CaseTree [Either Term Type]))]) -- | Test if a CaseTree collected from an expression indicates that -- application of a global binder is disjoint: occur in separate branches -- of a case-expression. isDisjoint :: CaseTree [Either Term Type] -> Bool -- | Given a case-tree corresponding to a disjoint interesting "term-in-a- -- function-position", return a let-expression: where the let-binding -- holds a case-expression selecting between the distinct arguments of -- the case-tree, and the body is an application of the term applied to -- the shared arguments of the case tree, and projections of let-binding -- corresponding to the distinct argument positions. mkDisjointGroup :: InScopeSet -> (Term, ([Term], CaseTree [Either Term Type])) -> RewriteMonad NormalizeState (Term, [Term]) instance Data.Foldable.Foldable Clash.Normalize.DEC.CaseTree instance GHC.Base.Functor Clash.Normalize.DEC.CaseTree instance GHC.Show.Show a => GHC.Show.Show (Clash.Normalize.DEC.CaseTree a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Clash.Normalize.DEC.CaseTree a) -- | Utilties to verify blackbox contexts against templates and rendering -- filled in templates module Clash.Netlist.BlackBox.Util inputHole :: Element -> Maybe Int -- | Determine if the number of normalliteralfunction inputs of a -- blackbox context at least matches the number of argument that is -- expected by the template. verifyBlackBoxContext :: BlackBoxContext -> BlackBox -> Maybe String extractLiterals :: BlackBoxContext -> [Expr] -- | Update all the symbol references in a template, and increment the -- symbol counter for every newly encountered symbol. setSym :: forall m. Monad m => (IdType -> Identifier -> m Identifier) -> BlackBoxContext -> BlackBoxTemplate -> m (BlackBoxTemplate, [Declaration]) selectNewName :: Foldable t => t String -> FilePath -> String renderFilePath :: [(String, FilePath)] -> String -> ([(String, FilePath)], String) -- | Render a blackbox given a certain context. Returns a filled out -- template and a list of hidden inputs that must be added to -- the encompassing component. renderTemplate :: Backend backend => BlackBoxContext -> BlackBoxTemplate -> State backend (Int -> Text) renderBlackBox :: Backend backend => [BlackBoxTemplate] -> [BlackBoxTemplate] -> [((Text, Text), BlackBox)] -> BlackBox -> BlackBoxContext -> State backend (Int -> Doc) -- | Render a single template element renderElem :: HasCallStack => Backend backend => BlackBoxContext -> Element -> State backend (Int -> Text) parseFail :: Text -> BlackBoxTemplate idToExpr :: (Text, HWType) -> (Expr, HWType, Bool) -- | Fill out the template corresponding to an output/input assignment of a -- component instantiation, and turn it into a single identifier so it -- can be used for a new blackbox context. lineToIdentifier :: Backend backend => BlackBoxContext -> BlackBoxTemplate -> State backend Text lineToType :: BlackBoxContext -> BlackBoxTemplate -> HWType -- | Give a context and a tagged hole (of a template), returns part of the -- context that matches the tag of the hole. renderTag :: Backend backend => BlackBoxContext -> Element -> State backend Text -- | Compute string from a list of elements. Can interpret ~NAME string -- literals on template level (constants). elementsToText :: BlackBoxContext -> [Element] -> Either String Text elementToText :: BlackBoxContext -> Element -> Either String Text -- | Extracts string from SSymbol or string literals exprToString :: Expr -> Maybe String prettyBlackBox :: Monad m => BlackBoxTemplate -> Mon m Text prettyElem :: (HasCallStack, Monad m) => Element -> Mon m Text -- | Recursively walk Element, applying f to each element -- in the tree. walkElement :: (Element -> Maybe a) -> Element -> [a] -- | Determine variables used in an expression. Used for VHDL sensitivity -- list. Also see: -- https://github.com/clash-lang/clash-compiler/issues/365 usedVariables :: Expr -> [Identifier] -- | Collect arguments (e.g., ~ARG, ~LIT) used in this blackbox getUsedArguments :: BlackBox -> [Int] onBlackBox :: (BlackBoxTemplate -> r) -> (BBName -> BBHash -> TemplateFunction -> r) -> BlackBox -> r -- | Utility functions to generate Primitives module Clash.Primitives.Util -- | Generate a set of primitives that are found in the primitive -- definition files in the given directories. generatePrimMap :: HasCallStack => [UnresolvedPrimitive] -> [(Text, PrimitiveGuard ())] -> [FilePath] -> IO ResolvedPrimMap -- | Hash a compiled primitive map. It needs a separate function (as -- opposed to just hash) as it might contain (obviously -- unhashable) Haskell functions. This function takes the hash value -- stored with the function instead. hashCompiledPrimMap :: CompiledPrimMap -> Int -- | Determine what argument should be constant / literal constantArgs :: Text -> CompiledPrimitive -> Set Int -- | Parse a ByteString according to the given JSON template. Throws -- exception if it fails. decodeOrErr :: (HasCallStack, FromJSON a) => FilePath -> ByteString -> a -- | Looks up the plurality of a function's function argument. See -- functionPlurality for more information. If not set, the -- returned plurality will default to 1. getFunctionPlurality :: HasCallStack => CompiledPrimitive -> [Either Term Type] -> Type -> Int -> NetlistMonad Int -- | Utility functions used by the normalisation transformations module Clash.Normalize.Util data ConstantSpecInfo ConstantSpecInfo :: [(Id, Term)] -> !Term -> !Bool -> ConstantSpecInfo -- | New let-bindings to be created for all the non-constants found [csrNewBindings] :: ConstantSpecInfo -> [(Id, Term)] -- | A term where all the non-constant constructs are replaced by variable -- references (found in csrNewBindings) [csrNewTerm] :: ConstantSpecInfo -> !Term -- | Whether the algorithm found a constant at all. (If it didn't, it's no -- use creating any new let-bindings!) [csrFoundConstant] :: ConstantSpecInfo -> !Bool -- | Determine if argument should reduce to a constant given a primitive -- and an argument number. Caches results. isConstantArg :: Text -> Int -> RewriteMonad NormalizeState Bool -- | Given a list of transformation contexts, determine if any of the -- contexts indicates that the current arg is to be reduced to a constant -- / literal. shouldReduce :: Context -> RewriteMonad NormalizeState Bool -- | Determine if a function is already inlined in the context of the -- NetlistMonad alreadyInlined :: Id -> Id -> NormalizeMonad (Maybe Int) addNewInline :: Id -> Id -> NormalizeMonad () -- | Specialize under the Normalization Monad specializeNorm :: NormRewrite -- | Assert whether a name is a reference to a recursive binder. isRecursiveBndr :: Id -> NormalizeSession Bool -- | Determine if a term is closed isClosed :: TyConMap -> Term -> Bool -- | Create a call graph for a set of global binders, given a root callGraph :: BindingMap -> Id -> CallGraph -- | Collect all binders mentioned in CallGraph into a HashSet collectCallGraphUniques :: CallGraph -> HashSet Unique -- | Give a "performance/size" classification of a function in normal form. classifyFunction :: Term -> TermClassification -- | Determine whether a function adds a lot of hardware or not. -- -- It is considered expensive when it has 2 or more of the following -- components: -- -- isCheapFunction :: Term -> Bool -- | Test whether a given term represents a non-recursive global variable isNonRecursiveGlobalVar :: Term -> NormalizeSession Bool -- | Calculate constant spec info. The goal of this function is to analyze -- a given term and yield a new term that: -- -- -- -- The result structure will additionally contain: -- -- -- -- This can be used in functions wanting to constant specialize over -- partially constant data structures. constantSpecInfo :: TransformContext -> Term -> RewriteMonad NormalizeState ConstantSpecInfo normalizeTopLvlBndr :: Bool -> Id -> Binding -> NormalizeSession Binding -- | Rewrite a term according to the provided transformation rewriteExpr :: (String, NormRewrite) -> (String, Term) -> (Id, SrcSpan) -> NormalizeSession Term removedTm :: Type -> Term -- | A tick to prefix an inlined expression with it's original name. For -- example, given -- -- foo = bar -- ... bar = baz -- ... baz = quuz -- ... -- -- if bar is inlined into foo, then the name of the component should -- contain the name of the inlined component. This tick ensures that the -- component in foo is called bar_baz instead of just baz. mkInlineTick :: Id -> TickInfo -- | Turn type equality constraints into substitutions and apply them. -- -- So given: -- --
--   /\dom . \(eq : dom ~ "System") . \(eta : Signal dom Bool) . eta
--   
-- -- we create the substitution [dom := System] and apply it to -- create: -- --
--   \(eq : "System" ~ "System") . \(eta : Signal "System" Bool) . eta
--   
-- -- NB: Users of this function should ensure it's only applied to -- TopEntities substWithTyEq :: Term -> Term -- | The type equivalent of substWithTyEq tvSubstWithTyEq :: Type -> Type instance GHC.Show.Show Clash.Normalize.Util.ConstantSpecInfo -- | Blackbox template functions for -- Clash.Intel.ClockGen.{alteraPll,altpll} module Clash.Primitives.Intel.ClockGen altpllTF :: TemplateFunction altpllQsysTF :: TemplateFunction alteraPllTF :: TemplateFunction alteraPllQsysTF :: TemplateFunction alteraPllTemplate :: Backend s => BlackBoxContext -> State s Doc altpllTemplate :: Backend s => BlackBoxContext -> State s Doc altpllQsysTemplate :: Backend s => BlackBoxContext -> State s Doc alteraPllQsysTemplate :: Backend s => BlackBoxContext -> State s Doc -- | Transformations of the Normalization process module Clash.Normalize.Transformations -- | Lift the let-bindings out of the subject of a Case-decomposition caseLet :: HasCallStack => NormRewrite -- | Specialize a Case-decomposition (replace by the RHS of an alternative) -- if the subject is (an application of) a DataCon; or if there is only a -- single alternative that doesn't reference variables bound by the -- pattern. -- -- Note [CaseCon deshadow] -- -- Imagine: -- --
--   case D (f a b) (g x y) of
--     D a b -> h a
--   
-- -- rewriting this to: -- --
--   let a = f a b
--   in  h a
--   
-- -- is very bad because the newly introduced let-binding now captures the -- free variable a in 'f a b'. -- -- instead me must rewrite to: -- --
--   let a1 = f a b
--   in  h a1
--   
caseCon :: HasCallStack => NormRewrite -- | Move a Case-decomposition from the subject of a Case-decomposition to -- the alternatives caseCase :: HasCallStack => NormRewrite -- | Remove non-reachable alternatives. For example, consider: -- -- data STy ty where SInt :: Int -> STy Int SBool :: Bool -> STy -- Bool -- -- f :: STy ty -> ty f (SInt b) = b + 1 f (SBool True) = False f -- (SBool False) = True {--} -- -- g :: STy Int -> Int g = f -- -- f is always specialized on STy Int. The SBool -- alternatives are therefore unreachable. Additional information can be -- found at: https://github.com/clash-lang/clash-compiler/pull/465 caseElemNonReachable :: HasCallStack => NormRewrite -- | Tries to eliminate existentials by using heuristics to determine what -- the existential should be. For example, consider Vec: -- -- data Vec :: Nat -> Type -> Type where Nil :: Vec 0 a Cons x xs -- :: a -> Vec n a -> Vec (n + 1) a -- -- Thus, null (annotated with existentials) could look like: -- -- null :: forall n . Vec n Bool -> Bool null v = case v of Nil {n ~ -- 0} -> True Cons {n1:Nat} {n~n1+1} (x :: a) (xs :: Vec n1 a) -> -- False -- -- When it's applied to a vector of length 5, this becomes: -- -- null :: Vec 5 Bool -> Bool null v = case v of Nil {5 ~ 0} -> -- True Cons {n1:Nat} {5~n1+1} (x :: a) (xs :: Vec n1 a) -> False -- -- This function solves n1 and replaces every occurrence with -- its solution. A very limited number of solutions are currently -- recognized: only adds (such as in the example) will be solved. elemExistentials :: HasCallStack => NormRewrite -- | Inline function with a non-representable result if it's the subject of -- a Case-decomposition inlineNonRep :: HasCallStack => NormRewrite inlineOrLiftNonRep :: HasCallStack => NormRewrite -- | Specialize functions on their type typeSpec :: HasCallStack => NormRewrite -- | Specialize functions on their non-representable argument nonRepSpec :: HasCallStack => NormRewrite -- | Eta-expand top-level lambda's (DON'T use in a traversal!) etaExpansionTL :: HasCallStack => NormRewrite -- | Bring an application of a DataCon or Primitive in ANF, when the -- argument is is considered non-representable nonRepANF :: HasCallStack => NormRewrite -- | Inline let-bindings when the RHS is either a local variable reference -- or is constant (except clock or reset generators) bindConstantVar :: HasCallStack => NormRewrite -- | Specialise functions on arguments which are constant, except when they -- are clock, reset generators. constantSpec :: HasCallStack => NormRewrite -- | Turn an expression into a modified ANF-form. As opposed to standard -- ANF, constants do not become let-bound. makeANF :: HasCallStack => NormRewrite -- | Remove unused let-bindings deadCode :: HasCallStack => NormRewrite -- | Ensure that top-level lambda's eventually bind a let-expression of -- which the body is a variable-reference. topLet :: HasCallStack => NormRewrite -- | Turn a normalized recursive function, where the recursive calls only -- pass along the unchanged original arguments, into let-recursive -- function. This means that all recursive calls are replaced by the same -- variable reference as found in the body of the top-level -- let-expression. recToLetRec :: HasCallStack => NormRewrite -- | Inline work-free functions, i.e. fully applied functions that evaluate -- to a constant inlineWorkFree :: HasCallStack => NormRewrite -- | Inline a function with functional arguments inlineHO :: HasCallStack => NormRewrite -- | Inline small functions inlineSmall :: HasCallStack => NormRewrite -- | Simplified CSE, only works on let-bindings, does an inverse -- topological sort of the let-bindings and then works from top to bottom -- -- XXX: Check whether inverse top-sort followed by single traversal -- removes as many binders as the previous "apply-until-fixpoint" -- approach in the presence of recursive groups in the let-bindings. If -- not but just for checking whether changes to transformation affect the -- eventual size of the circuit, it would be really helpful if we tracked -- circuit size in the regression/test suite. On the two examples that -- were tested, Reducer and PipelinesViaFolds, this new version of CSE -- removed the same amount of let-binders. simpleCSE :: HasCallStack => NormRewrite reduceConst :: HasCallStack => NormRewrite -- | Replace primitives by their "definition" if they would lead to -- let-bindings with a non-representable type when a function is in ANF. -- This happens for example when Clash.Size.Vector.map consumes or -- produces a vector of non-representable elements. -- -- Basically what this transformation does is replace a primitive the -- completely unrolled recursive definition that it represents. e.g. -- --
--   zipWith ($) (xs :: Vec 2 (Int -> Int)) (ys :: Vec 2 Int)
--   
-- -- is replaced by: -- --
--   let (x0  :: (Int -> Int))       = case xs  of (:>) _ x xr -> x
--       (xr0 :: Vec 1 (Int -> Int)) = case xs  of (:>) _ x xr -> xr
--       (x1  :: (Int -> Int)(       = case xr0 of (:>) _ x xr -> x
--       (y0  :: Int)                = case ys  of (:>) _ y yr -> y
--       (yr0 :: Vec 1 Int)          = case ys  of (:>) _ y yr -> xr
--       (y1  :: Int                 = case yr0 of (:>) _ y yr -> y
--   in  (($) x0 y0 :> ($) x1 y1 :> Nil)
--   
-- -- Currently, it only handles the following functions: -- -- reduceNonRepPrim :: HasCallStack => NormRewrite -- | Flatten ridiculous case-statements generated by GHC -- -- For case-statements in haskell of the form: -- --
--   f :: Unsigned 4 -> Unsigned 4
--   f x = case x of
--     0 -> 3
--     1 -> 2
--     2 -> 1
--     3 -> 0
--   
-- -- GHC generates Core that looks like: -- --
--   f = (x :: Unsigned 4) -> case x == fromInteger 3 of
--                               False -> case x == fromInteger 2 of
--                                 False -> case x == fromInteger 1 of
--                                   False -> case x == fromInteger 0 of
--                                     False -> error "incomplete case"
--                                     True  -> fromInteger 3
--                                   True -> fromInteger 2
--                                 True -> fromInteger 1
--                               True -> fromInteger 0
--   
-- -- Which would result in a priority decoder circuit where a normal -- decoder circuit was desired. -- -- This transformation transforms the above Core to the saner: -- --
--   f = (x :: Unsigned 4) -> case x of
--          _ -> error "incomplete case"
--          0 -> fromInteger 3
--          1 -> fromInteger 2
--          2 -> fromInteger 1
--          3 -> fromInteger 0
--   
caseFlat :: HasCallStack => NormRewrite -- | This transformation lifts applications of global binders out of -- alternatives of case-statements. -- -- e.g. It converts: -- --
--   case x of
--     A -> f 3 y
--     B -> f x x
--     C -> h x
--   
-- -- into: -- --
--   let f_arg0 = case x of {A -> 3; B -> x}
--       f_arg1 = case x of {A -> y; B -> x}
--       f_out  = f f_arg0 f_arg1
--   in  case x of
--         A -> f_out
--         B -> f_out
--         C -> h x
--   
disjointExpressionConsolidation :: HasCallStack => NormRewrite removeUnusedExpr :: HasCallStack => NormRewrite -- | Given a function in the desired normal form, inline all the following -- let-bindings: -- -- Let-bindings with an internal name that is only used once, where it -- binds: * a primitive that will be translated to an HDL expression (as -- opposed to a HDL declaration) * a projection case-expression (1 -- alternative) * a data constructor * I/O actions inlineCleanup :: HasCallStack => NormRewrite -- | Used by inlineCleanup to inline binders that we want to inline -- into the binders that we want to keep. inlineBndrsCleanup :: HasCallStack => InScopeSet -> VarEnv ((Id, Term), VarEnv Int) -> VarEnv ((Id, Term), VarEnv Int, Mark) -> [((Id, Term), VarEnv Int)] -> [(Id, Term)] -- | Flatten's letrecs after inlineCleanup -- -- inlineCleanup sometimes exposes additional possibilities for -- caseCon, which then introduces let-bindings in what should be -- ANF. This transformation flattens those nested let-bindings again. -- -- NB: must only be called in the cleaning up phase. flattenLet :: HasCallStack => NormRewrite -- | Make a cast work-free by splitting the work of to a separate binding -- --
--   let x = cast (f a b)
--   ==>
--   let x  = cast x'
--       x' = f a b
--   
splitCastWork :: HasCallStack => NormRewrite -- | Only inline casts that just contain a Var, because these are -- guaranteed work-free. These are the result of the splitCastWork -- transformation. inlineCast :: HasCallStack => NormRewrite -- | Push a cast over a case into it's alternatives. caseCast :: HasCallStack => NormRewrite -- | Push a cast over a Letrec into it's body letCast :: HasCallStack => NormRewrite -- | Eliminate two back to back casts where the type going in and coming -- out are the same -- --
--   (cast :: b -> a) $ (cast :: a -> b) x   ==> x
--   
eliminateCastCast :: HasCallStack => NormRewrite -- | Push cast over an argument to a function into that function -- -- This is done by specializing on the casted argument. Example: y = -- f (cast a) where f x = g x transforms to: y = f' a where f' -- x' = (x -> g x) (cast x') -- -- The reason d'etre for this transformation is that we hope to end up -- with and expression where two casts are "back-to-back" after which we -- can eliminate them in eliminateCastCast. argCastSpec :: HasCallStack => NormRewrite -- | Eta-expand functions with a Synthesize annotation, needed to allow -- such functions to appear as arguments to higher-order primitives. etaExpandSyn :: HasCallStack => NormRewrite -- | Propagate arguments of application inwards; except for Lam -- where the argument becomes let-bound. appPropFast tries to -- propagate as many arguments as possible, down as many levels as -- possible; and should be called in a top-down traversal. -- -- The idea is that this reduces the number of traversals, which -- hopefully leads to shorter compile times. -- -- Note [AppProp no shadowing] -- -- Case 1. -- -- Imagine: -- --
--   (case x of
--      D a b -> h a) (f x y)
--   
-- -- rewriting this to: -- --
--   let b = f x y
--   in  case x of
--         D a b -> h a b
--   
-- -- is very bad because b in 'h a b' is now bound by the pattern -- instead of the newly introduced let-binding -- -- instead me must deshadow w.r.t. the new variable and rewrite to: -- --
--   let b = f x y
--   in  case x of
--         D a b1 -> h a b
--   
-- -- Case 2. -- -- Imagine -- --
--   (x -> e) u
--   
-- -- where u has a free variable named x, rewriting this -- to: -- --
--   let x = u
--   in  e
--   
-- -- would be very bad, because the let-binding suddenly captures the free -- variable in u. To prevent this from happening we -- over-approximate and check whether x is in the current -- InScopeSet, and deshadow if that's the case, i.e. we then rewrite to: -- -- let x1 = u in e [x:=x1] -- -- Case 3. -- -- The same for: -- --
--   (let x = w in e) u
--   
-- -- where u again has a free variable x, rewriting this -- to: -- --
--   let x = w in (e u)
--   
-- -- would be bad because the let-binding now captures the free variable in -- u. -- -- To prevent this from happening, we unconditionally deshadow the -- function part of the application w.r.t. the free variables in the -- argument part of the application. It is okay to over-approximate in -- this case and deshadow w.r.t the current InScopeSet. appPropFast :: HasCallStack => NormRewrite -- | Split apart (global) function arguments that contain types that we -- want to separate off, e.g. Clocks. Works on both the definition side -- (i.e. the lambda), and the call site (i.e. the application of the -- global variable). e.g. turns -- --
--   f :: (Clock System, Reset System) -> Signal System Int
--   
-- -- into -- --
--   f :: Clock System -> Reset System -> Signal System Int
--   
separateArguments :: HasCallStack => NormRewrite -- | Worker function of separateArguments. separateLambda :: TyConMap -> TransformContext -> Id -> Term -> Maybe Term -- | Remove all undefined alternatives from case expressions, replacing -- them with the value of another defined alternative. If there is one -- defined alternative, the entire expression is replaced with that -- alternative. If there are no defined alternatives, the entire -- expression is replaced with a call to errorX. -- -- e.g. It converts -- -- case x of D1 a -> f a D2 -> undefined D3 -> undefined -- -- to -- -- let subj = x a = case subj of D1 a -> field0 in f a -- -- where fieldN is an internal variable referring to the nth argument of -- a data constructor. xOptimize :: HasCallStack => NormRewrite -- | Transformation process for normalization module Clash.Normalize.Strategy -- | Normalisation transformation normalization :: NormRewrite constantPropagation :: NormRewrite -- | Topdown traversal, stops upon first success topdownSucR :: Rewrite extra -> Rewrite extra topdownRR :: Rewrite extra -> Rewrite extra innerMost :: Rewrite extra -> Rewrite extra applyMany :: [(String, Rewrite extra)] -> Rewrite extra -- | Turn CoreHW terms into normalized CoreHW Terms module Clash.Normalize -- | Run a NormalizeSession in a given environment runNormalization :: ClashOpts -> Supply -> BindingMap -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> CustomReprs -> TyConMap -> IntMap TyConName -> (PrimStep, PrimUnwind) -> CompiledPrimMap -> VarEnv Bool -> [Id] -> NormalizeSession a -> a normalize :: [Id] -> NormalizeSession BindingMap normalize' :: Id -> NormalizeSession ([Id], (Id, Binding)) -- | Check whether the normalized bindings are non-recursive. Errors when -- one of the components is recursive. checkNonRecursive :: BindingMap -> BindingMap -- | Perform general "clean up" of the normalized (non-recursive) function -- hierarchy. This includes: -- -- cleanupGraph :: Id -> BindingMap -> NormalizeSession BindingMap -- | A tree of identifiers and their bindings, with branches containing -- additional bindings which are used. See -- Clash.Driver.Types.Binding. data CallTree CLeaf :: (Id, Binding) -> CallTree CBranch :: (Id, Binding) -> [CallTree] -> CallTree mkCallTree :: [Id] -> BindingMap -> Id -> Maybe CallTree stripArgs :: [Id] -> [Id] -> [Either Term Type] -> Maybe [Either Term Type] flattenNode :: CallTree -> NormalizeSession (Either CallTree ((Id, Term), [CallTree])) flattenCallTree :: CallTree -> NormalizeSession CallTree callTreeToList :: [Id] -> CallTree -> ([Id], [(Id, Binding)]) -- | Functions to create BlackBox Contexts and fill in BlackBox templates module Clash.Netlist.BlackBox -- | Emits (colorized) warning to stderr warn :: ClashOpts -> String -> IO () -- | Generate the context for a BlackBox instantiation. mkBlackBoxContext :: Text -> Id -> [Either Term Type] -> NetlistMonad (BlackBoxContext, [Declaration]) prepareBlackBox :: Text -> BlackBox -> BlackBoxContext -> NetlistMonad (BlackBox, [Declaration]) -- | Determine if a term represents a literal isLiteral :: Term -> Bool mkArgument :: Text -> Identifier -> Int -> Term -> NetlistMonad ((Expr, HWType, Bool), [Declaration]) -- | Extract a compiled primitive from a guarded primitive. Emit a warning -- if the guard wants to, or fail entirely. extractPrimWarnOrFail :: HasCallStack => Text -> NetlistMonad CompiledPrimitive mkPrimitive :: Bool -> Bool -> NetlistId -> PrimInfo -> [Either Term Type] -> [Declaration] -> NetlistMonad (Expr, [Declaration]) -- | Turn a mealyIO expression into a two sequential processes, -- one "initial" process for the starting state, and one clocked -- sequential process. collectMealy :: HasCallStack => Identifier -> NetlistId -> TyConMap -> [Term] -> NetlistMonad [Declaration] -- | Collect the sequential declarations for bindIO collectBindIO :: NetlistId -> [Term] -> NetlistMonad (Expr, [Declaration]) -- | Collect the sequential declarations for appIO collectAppIO :: NetlistId -> [Term] -> [Term] -> NetlistMonad (Expr, [Declaration]) -- | Unwrap the new-type wrapper for things of type SimIO, this is needed -- to allow applications of the `State# World` token to the underlying IO -- type. -- -- XXX: this is most likely needed because Ghc2Core that threw away the -- cast that this unwrapping; we should really start to support casts. unSimIO :: TyConMap -> Term -> Term -- | Create an template instantiation text and a partial blackbox content -- for an argument term, given that the term is a function. Errors if the -- term is not a function mkFunInput :: HasCallStack => Id -> Term -> NetlistMonad ((Either BlackBox (Identifier, [Declaration]), WireOrReg, [BlackBoxTemplate], [BlackBoxTemplate], [((Text, Text), BlackBox)], BlackBoxContext), [Declaration]) -- | Create Netlists out of normalized CoreHW Terms module Clash.Netlist -- | Generate a hierarchical netlist out of a set of global binders with -- topEntity at the top. genNetlist :: Bool -> ClashOpts -> CustomReprs -> BindingMap -> [TopEntityT] -> CompiledPrimMap -> TyConMap -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> Int -> (IdType -> Identifier -> Identifier) -> (IdType -> Identifier -> Identifier -> Identifier) -> Bool -> SomeBackend -> HashMap Identifier Word -> FilePath -> ComponentPrefix -> Id -> IO ([([Bool], SrcSpan, HashMap Identifier Word, Component)], HashMap Identifier Word) -- | Run a NetlistMonad action in a given environment runNetlistMonad :: Bool -> ClashOpts -> CustomReprs -> BindingMap -> VarEnv TopEntityT -> CompiledPrimMap -> TyConMap -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> Int -> (IdType -> Identifier -> Identifier) -> (IdType -> Identifier -> Identifier -> Identifier) -> Bool -> SomeBackend -> HashMap Identifier Word -> FilePath -> ComponentPrefix -> NetlistMonad a -> IO (a, NetlistState) genNames :: Bool -> (IdType -> Identifier -> Identifier) -> ComponentPrefix -> HashMap Identifier Word -> VarEnv Identifier -> BindingMap -> (HashMap Identifier Word, VarEnv Identifier) -- | Generate a component for a given function (caching) genComponent :: HasCallStack => Id -> NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component) -- | Generate a component for a given function genComponentT :: HasCallStack => Id -> Term -> NetlistMonad ([Bool], SrcSpan, HashMap Identifier Word, Component) mkNetDecl :: (Id, Term) -> NetlistMonad (Maybe Declaration) -- | Generate a list of concurrent Declarations for a let-binder, return an -- empty list if the bound expression is represented by 0 bits mkDeclarations :: HasCallStack => Id -> Term -> NetlistMonad [Declaration] -- | Generate a list of Declarations for a let-binder, return an empty list -- if the bound expression is represented by 0 bits mkDeclarations' :: HasCallStack => DeclarationType -> Id -> Term -> NetlistMonad [Declaration] -- | Generate a declaration that selects an alternative based on the value -- of the scrutinee mkSelection :: DeclarationType -> NetlistId -> Term -> Type -> [Alt] -> [Declaration] -> NetlistMonad [Declaration] reorderDefault :: [(Pat, Term)] -> [(Pat, Term)] reorderCustom :: TyConMap -> CustomReprs -> Type -> [(Pat, Term)] -> [(Pat, Term)] patPos :: CustomReprs -> Pat -> Int -- | Generate a list of Declarations for a let-binder where the RHS is a -- function application mkFunApp :: HasCallStack => Identifier -> Id -> [Term] -> [Declaration] -> NetlistMonad [Declaration] toSimpleVar :: Identifier -> (Expr, Type) -> NetlistMonad (Expr, [Declaration]) -- | Generate an expression for a term occurring on the RHS of a let-binder mkExpr :: HasCallStack => Bool -> DeclarationType -> NetlistId -> Term -> NetlistMonad (Expr, [Declaration]) -- | Generate an expression that projects a field out of a -- data-constructor. -- -- Works for both product types, as sum-of-product types. mkProjection :: Bool -> NetlistId -> Term -> Type -> Alt -> NetlistMonad (Expr, [Declaration]) -- | Generate an expression for a DataCon application occurring on the RHS -- of a let-binder mkDcApplication :: HasCallStack => [HWType] -> NetlistId -> DataCon -> [Term] -> NetlistMonad (Expr, [Declaration]) -- | Generate Verilog for assorted Netlist datatypes module Clash.Backend.Verilog -- | State for the VerilogM monad: data VerilogState include :: Monad m => [Text] -> Mon m Doc uselibs :: Monad m => [Text] -> Mon m Doc encodingNote :: Applicative m => HWType -> m Doc exprLit :: Lens' s (Maybe (Maybe Int)) -> Maybe (HWType, Size) -> Literal -> Mon (State s) Doc bits :: Lens' s (Maybe (Maybe Int)) -> [Bit] -> Mon (State s) Doc bit_char :: Lens' s (Maybe (Maybe Int)) -> Bit -> Mon (State s) Doc noEmptyInit :: (Monad m, Semigroup (m Doc)) => m Doc -> m Doc -- | Range slice, can be contiguous, or split into multiple sub-ranges data Range Contiguous :: Int -> Int -> Range Split :: [(Int, Int, Provenance)] -> Range -- | Select a sub-range from a range continueWithRange :: [(Int, Int)] -> HWType -> Range -> (Range, HWType) instance Clash.Backend.Backend Clash.Backend.Verilog.VerilogState -- | Generate VHDL for assorted Netlist datatypes module Clash.Backend.VHDL -- | State for the VHDLM monad: data VHDLState instance Clash.Backend.Backend Clash.Backend.VHDL.VHDLState -- | This module contains a mini dsl for creating haskell blackbox -- instantiations. module Clash.Primitives.DSL -- | Create a blackBoxHaskell primitive. To be used as part of an -- annotation: -- --
--   {--}
--   
blackBoxHaskell :: [Int] -> HDL -> Name -> Name -> Primitive -- | The state of a block. Contains a list of declarations and a the -- backend state. data BlockState backend BlockState :: [Declaration] -> IntMap Int -> backend -> BlockState backend -- | Declarations store [_bsDeclarations] :: BlockState backend -> [Declaration] -- | Tracks how many times a higher order function has been instantiated. -- Needed to fill in the second field of -- Clash.Netlist.BlackBox.Types.Decl [_bsHigherOrderCalls] :: BlockState backend -> IntMap Int -- | Backend state [_bsBackend] :: BlockState backend -> backend -- | A typed expression. data TExpr -- | Run a block declaration. declaration :: Backend backend => Text -> State (BlockState backend) () -> State backend Doc -- | Run a block declaration. Assign the result of the block builder to the -- result variable in the given blackbox context. declarationReturn :: Backend backend => BlackBoxContext -> Text -> State (BlockState backend) TExpr -> State backend Doc -- | Instantiate a component/entity in a block state. instDecl :: Backend backend => EntityOrComponent -> Identifier -> Identifier -> [(Text, LitHDL)] -> [(Text, TExpr)] -> [(Text, TExpr)] -> State (BlockState backend) () -- | Instantiate/call a higher-order function. instHO :: Backend backend => BlackBoxContext -> Int -> (HWType, BlackBoxTemplate) -> [(TExpr, BlackBoxTemplate)] -> State (BlockState backend) TExpr -- | Wires the two given TExprs together using a newly declared -- signal with (exactly) the given name sigNm. The new signal -- has an annotated type, using the given attributes. viaAnnotatedSignal :: (HasCallStack, Backend backend) => Text -> TExpr -> TExpr -> [Attr'] -> State (BlockState backend) () -- | Construct a fully defined BitVector literal bvLit :: Int -> Integer -> TExpr -- | A literal that can be used for hdl attributes. It has a Num and -- IsString instances for convenience. data LitHDL B :: Bool -> LitHDL S :: String -> LitHDL I :: Integer -> LitHDL -- | The high literal bit. pattern High :: TExpr -- | The low literal bit. pattern Low :: TExpr -- | Create an n-tuple of TExpr tuple :: [TExpr] -> TExpr -- | Create a vector of TExprs vec :: (HasCallStack, Backend backend) => [TExpr] -> State (BlockState backend) TExpr -- | The TExp inputs from a blackbox context. tInputs :: BlackBoxContext -> [(TExpr, HWType)] -- | The TExp result of a blackbox context. tResult :: BlackBoxContext -> TExpr -- | Try to get the literal string value of an expression. getStr :: TExpr -> Maybe String -- | Try to get the literal bool value of an expression. getBool :: TExpr -> Maybe Bool exprToInteger :: Expr -> Maybe Integer -- | Try to get the literal nat value of an expression. tExprToInteger :: TExpr -> Maybe Integer -- | Extract the elements of a tuple expression and return expressions to -- them. These new expressions are given unique names and get declared -- the block scope. untuple :: (HasCallStack, Backend backend) => TExpr -> [Identifier] -> State (BlockState backend) [TExpr] -- | Extract the elements of a vector expression and return expressions to -- them. If given expression is not an identifier, an intermediate -- variable will be used to assign the given expression to which is -- subsequently indexed. unvec :: Backend backend => Identifier -> TExpr -> State (BlockState backend) [TExpr] -- | Assign an input bitvector to an expression. Declares a new bitvector -- if the expression is not already a bitvector. toBV :: Backend backend => Identifier -> TExpr -> State (BlockState backend) TExpr -- | Assign an output bitvector to an expression. Declares a new bitvector -- if the expression is not already a bitvector. fromBV :: (HasCallStack, Backend backend) => Identifier -> TExpr -> State (BlockState backend) TExpr -- | Convert a bool to a bit. boolToBit :: (HasCallStack, Backend backend) => Identifier -> TExpr -> State (BlockState backend) TExpr -- | Use to create an output Bool from a Bit. The expression -- given must be the identifier of the bool you wish to get assigned. -- Returns a reference to a declared Bit that should get assigned -- by something (usually the output port of an entity). boolFromBit :: Backend backend => Identifier -> TExpr -> State (BlockState backend) TExpr -- | Used to create an output Bool from a BitVector of given -- size. Works in a similar way to boolFromBit above. boolFromBitVector :: Backend backend => Size -> Identifier -> TExpr -> State (BlockState backend) TExpr -- | Used to create an output Unsigned from a BitVector of -- given size. Works in a similar way to boolFromBit above. -- -- TODO: Implement for (System)Verilog unsignedFromBitVector :: Size -> Identifier -> TExpr -> State (BlockState VHDLState) TExpr -- | Used to create an output Bool from a number of Bits, -- using conjunction. Similarly to untuple, it returns a list of -- references to declared values (the inputs to the function) which -- should get assigned by something---usually output ports of an entity. -- -- TODO: Implement for (System)Verilog boolFromBits :: [Identifier] -> TExpr -> State (BlockState VHDLState) [TExpr] -- | And together (&&) two expressions, assigning it to a -- new identifier. andExpr :: Backend backend => Identifier -> TExpr -> TExpr -> State (BlockState backend) TExpr -- | Negate (not) an expression, assigning it to a new identifier. notExpr :: Backend backend => Identifier -> TExpr -> State (BlockState backend) TExpr -- | Creates a BV that produces the following vhdl: -- --
--   (0 to n => ARG)
--   
-- -- TODO: Implement for (System)Verilog pureToBV :: Identifier -> Int -> TExpr -> State (BlockState VHDLState) TExpr -- | Creates a BV that produces the following vhdl: -- --
--   std_logic_vector(resize(ARG, Size))
--   
-- -- TODO: Implement for (System)Verilog pureToBVResized :: Identifier -> Int -> TExpr -> State (BlockState VHDLState) TExpr -- | Allows assignment of a port to be "open" open :: Backend backend => HWType -> State (BlockState backend) TExpr -- | Get an identifier to an expression, creating a new assignment if -- necessary. toIdentifier :: Backend backend => Identifier -> TExpr -> State (BlockState backend) TExpr tySize :: Num i => HWType -> i clog2 :: Num i => Integer -> i instance GHC.Show.Show Clash.Primitives.DSL.LitHDL instance GHC.Num.Num Clash.Primitives.DSL.LitHDL instance Data.String.IsString Clash.Primitives.DSL.LitHDL instance GHC.Show.Show Clash.Primitives.DSL.TExpr -- | Blackbox implementations for functions in Clash.Sized.Vector. module Clash.Primitives.Sized.Vector -- | Blackbox function for iterateI iterateBBF :: HasCallStack => BlackBoxFunction -- | Type signature of function we're generating netlist for: -- -- iterateI :: KnownNat n => (a -> a) -> a -> Vec n a iterateTF :: TemplateFunction iterateTF' :: forall s. (HasCallStack, Backend s) => BlackBoxContext -> State s Doc data FCall FCall :: Identifier -> Identifier -> Identifier -> FCall -- | Calculates the number of function calls needed for an evaluation of -- fold, given the length of the vector given to fold. foldFunctionPlurality :: HasCallStack => Int -> Int -- | Blackbox function for fold foldBBF :: HasCallStack => BlackBoxFunction -- | Type signature of function we're generating netlist for: -- -- fold :: (a -> a -> a) -> Vec (n + 1) a -> a -- -- The implementation promises to create a (balanced) tree structure. foldTF :: TemplateFunction foldTF' :: forall s. (HasCallStack, Backend s) => BlackBoxContext -> State s Doc indexIntVerilog :: BlackBoxFunction indexIntVerilogTF :: TemplateFunction indexIntVerilogTemplate :: Backend s => BlackBoxContext -> State s Doc -- | Module that connects all the parts of the Clash compiler library module Clash.Driver -- | Worker function of splitTopEntityT splitTopAnn :: TyConMap -> SrcSpan -> Type -> TopEntity -> TopEntity splitTopEntityT :: HasCallStack => TyConMap -> BindingMap -> TopEntityT -> TopEntityT -- | Get modification data of current clash binary. getClashModificationDate :: IO UTCTime -- | Create a set of target HDL files for a set of functions generateHDL :: forall backend. Backend backend => CustomReprs -> BindingMap -> Maybe backend -> CompiledPrimMap -> TyConMap -> IntMap TyConName -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> (PrimStep, PrimUnwind) -> [TopEntityT] -> Maybe (TopEntityT, [TopEntityT]) -> ClashOpts -> (UTCTime, UTCTime) -> IO () -- | Interpret a specific function from a specific module. This action -- tries two things: -- --
    --
  1. Interpret without explicitly loading the module. This will succeed -- if the module was already loaded through a package database (set using -- interpreterArgs).
  2. --
  3. If (1) fails, it does try to load it explicitly. If this also -- fails, an error is returned.
  4. --
loadImportAndInterpret :: (MonadIO m, MonadMask m) => [String] -> [String] -> String -> ModuleName -> String -> String -> m (Either InterpreterError a) -- | List of known BlackBoxFunctions used to prevent Hint from firing. This -- improves Clash startup times. knownBlackBoxFunctions :: HashMap String BlackBoxFunction -- | List of known TemplateFunctions used to prevent Hint from firing. This -- improves Clash startup times. knownTemplateFunctions :: HashMap String TemplateFunction -- | Compiles blackbox functions and parses blackbox templates. compilePrimitive :: [FilePath] -> [FilePath] -> FilePath -> ResolvedPrimitive -> IO CompiledPrimitive processHintError :: Monad m => String -> Text -> (t -> r) -> Either InterpreterError t -> m r -- | Pretty print Components to HDL Documents createHDL :: Backend backend => backend -> Identifier -> HashMap Identifier Word -> [([Bool], SrcSpan, HashMap Identifier Word, Component)] -> Component -> (Identifier, Either Manifest Manifest) -> ([(String, Doc)], Manifest, [(String, FilePath)], [(String, String)]) -- | Prepares the directory for writing HDL files. This means creating the -- dir if it does not exist and removing all existing .hdl files from it. prepareDir :: Bool -> String -> String -> IO () -- | Writes a HDL file to the given directory writeHDL :: FilePath -> (String, Doc) -> IO () -- | Copy given files writeMemoryDataFiles :: FilePath -> [(String, String)] -> IO () copyDataFiles :: [FilePath] -> FilePath -> [(String, FilePath)] -> IO () -- | Get all the terms corresponding to a call graph callGraphBindings :: BindingMap -> Id -> [Term] -- | Normalize a complete hierarchy normalizeEntity :: CustomReprs -> BindingMap -> CompiledPrimMap -> TyConMap -> IntMap TyConName -> (CustomReprs -> TyConMap -> Type -> State HWMap (Maybe (Either String FilteredHWType))) -> (PrimStep, PrimUnwind) -> [Id] -> ClashOpts -> Supply -> Id -> BindingMap -- | topologically sort the top entities sortTop :: BindingMap -> [TopEntityT] -> [TopEntityT] -- | Generate SystemVerilog for assorted Netlist datatypes module Clash.Backend.SystemVerilog -- | State for the SystemVerilogM monad: data SystemVerilogState instance Clash.Backend.Backend Clash.Backend.SystemVerilog.SystemVerilogState