packages feed

clash-lib 0.6.21 → 0.7

raw patch · 32 files changed

+740/−199 lines, 32 filesdep +data-binary-ieee754dep ~aesondep ~clash-preludedep ~directoryPVP ok

version bump matches the API change (PVP)

Dependencies added: data-binary-ieee754

Dependency ranges changed: aeson, clash-prelude, directory, ghc, time

API changes (from Hackage documentation)

- CLaSH.Core.Literal: RationalLiteral :: !Rational -> Literal
+ CLaSH.Core.Literal: DoubleLiteral :: !Rational -> Literal
+ CLaSH.Core.Literal: FloatLiteral :: !Rational -> Literal
+ CLaSH.Core.TysPrim: doublePrimTy :: Type
+ CLaSH.Core.TysPrim: floatPrimTy :: Type
+ CLaSH.Core.Util: extractTElems :: DataCon -> DataCon -> Type -> Char -> Integer -> Term -> ([Term], [LetBinding])
+ CLaSH.Core.Util: mkRTree :: DataCon -> DataCon -> Type -> Integer -> [Term] -> Term
+ CLaSH.Driver.TopWrapper: mkRTreeChain :: Int -> HWType -> [Identifier] -> Expr
+ CLaSH.Driver.Types: [opt_allowZero] :: CLaSHOpts -> Bool
+ CLaSH.Driver.Types: [opt_floatSupport] :: CLaSHOpts -> Bool
+ CLaSH.Netlist.BlackBox.Types: Depth :: !Element -> Element
+ CLaSH.Netlist.BlackBox.Types: QSysIncludeName :: Element
+ CLaSH.Netlist.Types: RTree :: !Size -> !HWType -> HWType
+ CLaSH.Netlist.Types: RTreeAppend :: Modifier
+ CLaSH.Netlist.Types: [bbQsysIncName] :: BlackBoxContext -> Maybe Identifier
+ CLaSH.Normalize.PrimitiveReductions: reduceDTFold :: Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term
+ CLaSH.Normalize.PrimitiveReductions: reduceInit :: Integer -> Type -> Term -> NormalizeSession Term
+ CLaSH.Normalize.PrimitiveReductions: reduceLast :: Integer -> Type -> Term -> NormalizeSession Term
+ CLaSH.Normalize.PrimitiveReductions: reduceTFold :: Integer -> Type -> Term -> Term -> Term -> NormalizeSession Term
+ CLaSH.Normalize.PrimitiveReductions: reduceTReplicate :: Integer -> Type -> Type -> Term -> NormalizeSession Term
+ CLaSH.Primitives.Types: [imports] :: Primitive a -> [Text]
+ CLaSH.Primitives.Types: [library] :: Primitive a -> [Text]
+ CLaSH.Primitives.Types: [qsysInclude] :: Primitive a -> Maybe (Text, a)
+ CLaSH.Rewrite.Types: [_allowZero] :: RewriteEnv -> Bool
+ CLaSH.Rewrite.Types: allowZero :: Lens' RewriteEnv Bool
+ CLaSH.Rewrite.Util: isVoidWrapper :: Term -> Bool
+ CLaSH.Util: flogBase :: Integer -> Integer -> Maybe Int
- CLaSH.Backend: genHDL :: Backend state => String -> SrcSpan -> Component -> State state (String, Doc)
+ CLaSH.Backend: genHDL :: Backend state => String -> SrcSpan -> Component -> State state ((String, Doc), [(String, Doc)])
- CLaSH.Core.Pretty: ppr :: (Pretty p, Applicative m, LFresh m) => p -> m Doc
+ CLaSH.Core.Pretty: ppr :: (Pretty p, LFresh m) => p -> m Doc
- CLaSH.Core.Pretty: pprPrec :: (Pretty p, Applicative m, LFresh m) => Rational -> p -> m Doc
+ CLaSH.Core.Pretty: pprPrec :: (Pretty p, LFresh m) => Rational -> p -> m Doc
- CLaSH.Core.Util: isFun :: (Functor m, Fresh m) => HashMap TyConName TyCon -> Term -> m Bool
+ CLaSH.Core.Util: isFun :: Fresh m => HashMap TyConName TyCon -> Term -> m Bool
- CLaSH.Core.Util: isPolyFun :: (Functor m, Fresh m) => HashMap TyConName TyCon -> Term -> m Bool
+ CLaSH.Core.Util: isPolyFun :: Fresh m => HashMap TyConName TyCon -> Term -> m Bool
- CLaSH.Core.Util: termType :: (Functor m, Fresh m) => HashMap TyConName TyCon -> Term -> m Type
+ CLaSH.Core.Util: termType :: Fresh m => HashMap TyConName TyCon -> Term -> m Type
- CLaSH.Driver: writeHDL :: Backend backend => backend -> FilePath -> (String, Doc) -> IO ()
+ CLaSH.Driver: writeHDL :: FilePath -> (String, Doc) -> IO ()
- CLaSH.Driver.Types: CLaSHOpts :: Int -> Int -> Int -> DebugLevel -> Bool -> Int -> Maybe String -> HdlSyn -> Bool -> CLaSHOpts
+ CLaSH.Driver.Types: CLaSHOpts :: Int -> Int -> Int -> DebugLevel -> Bool -> Int -> Maybe String -> HdlSyn -> Bool -> Bool -> Bool -> CLaSHOpts
- CLaSH.Netlist.BlackBox.Util: setClocks :: (MonadWriter (Set (Identifier, HWType)) m, Applicative m) => BlackBoxContext -> BlackBoxTemplate -> m BlackBoxTemplate
+ CLaSH.Netlist.BlackBox.Util: setClocks :: MonadWriter (Set (Identifier, HWType)) m => BlackBoxContext -> BlackBoxTemplate -> m BlackBoxTemplate
- CLaSH.Netlist.Types: BlackBoxD :: !Text -> !BlackBoxTemplate -> BlackBoxContext -> Declaration
+ CLaSH.Netlist.Types: BlackBoxD :: !Text -> [Text] -> [Text] -> (Maybe (Text, BlackBoxTemplate)) -> !BlackBoxTemplate -> BlackBoxContext -> Declaration
- CLaSH.Netlist.Types: BlackBoxE :: !Text -> !BlackBoxTemplate -> !BlackBoxContext -> !Bool -> Expr
+ CLaSH.Netlist.Types: BlackBoxE :: !Text -> [Text] -> [Text] -> (Maybe (Text, BlackBoxTemplate)) -> !BlackBoxTemplate -> !BlackBoxContext -> !Bool -> Expr
- CLaSH.Netlist.Types: Context :: (SyncExpr, HWType) -> [(SyncExpr, HWType, Bool)] -> IntMap (Either BlackBoxTemplate Declaration, BlackBoxContext) -> BlackBoxContext
+ CLaSH.Netlist.Types: Context :: (SyncExpr, HWType) -> [(SyncExpr, HWType, Bool)] -> IntMap (Either BlackBoxTemplate Declaration, BlackBoxContext) -> Maybe Identifier -> BlackBoxContext
- CLaSH.Netlist.Util: representableType :: (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> Type -> Bool
+ CLaSH.Netlist.Util: representableType :: (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> Bool -> HashMap TyConName TyCon -> Type -> Bool
- CLaSH.Netlist.Util: splitNormalized :: (Fresh m, Functor m) => HashMap TyConName TyCon -> Term -> m (Either String ([Id], [LetBinding], Id))
+ CLaSH.Netlist.Util: splitNormalized :: Fresh m => HashMap TyConName TyCon -> Term -> m (Either String ([Id], [LetBinding], Id))
- CLaSH.Normalize.Util: isClosed :: (Functor m, Fresh m) => HashMap TyConName TyCon -> Term -> m Bool
+ CLaSH.Normalize.Util: isClosed :: Fresh m => HashMap TyConName TyCon -> Term -> m Bool
- CLaSH.Primitives.Types: BlackBox :: !Text -> !(Either a a) -> Primitive a
+ CLaSH.Primitives.Types: BlackBox :: !Text -> [Text] -> [Text] -> Maybe (Text, a) -> !(Either a a) -> Primitive a
- CLaSH.Rewrite.Combinators: (>-!->) :: (Monad m) => Transform m -> Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: (>-!->) :: Monad m => Transform m -> Transform m -> Transform m
- CLaSH.Rewrite.Combinators: (>->) :: (Monad m) => Transform m -> Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: (>->) :: Monad m => Transform m -> Transform m -> Transform m
- CLaSH.Rewrite.Combinators: allR :: forall m. (Functor m, Monad m, Fresh m) => Bool -> Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: allR :: forall m. (Monad m, Fresh m) => Bool -> Transform m -> Transform m
- CLaSH.Rewrite.Combinators: bottomupR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: bottomupR :: Fresh m => Transform m -> Transform m
- CLaSH.Rewrite.Combinators: bottomupWhenR :: (Monad m, Fresh m, Functor m) => ([CoreContext] -> Term -> m Bool) -> Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: bottomupWhenR :: Fresh m => ([CoreContext] -> Term -> m Bool) -> Transform m -> Transform m
- CLaSH.Rewrite.Combinators: topdownR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: topdownR :: Fresh m => Transform m -> Transform m
- CLaSH.Rewrite.Combinators: unsafeBottomupR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: unsafeBottomupR :: Fresh m => Transform m -> Transform m
- CLaSH.Rewrite.Combinators: unsafeTopdownR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m
+ CLaSH.Rewrite.Combinators: unsafeTopdownR :: Fresh m => Transform m -> Transform m
- CLaSH.Rewrite.Types: RewriteEnv :: DebugLevel -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> IntMap TyConName -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> RewriteEnv
+ CLaSH.Rewrite.Types: RewriteEnv :: DebugLevel -> (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)) -> HashMap TyConName TyCon -> IntMap TyConName -> (HashMap TyConName TyCon -> Bool -> Term -> Term) -> Bool -> RewriteEnv
- CLaSH.Rewrite.Types: bindings :: forall extra_a1K16. Lens' (RewriteState extra_a1K16) (HashMap TmName (Type, SrcSpan, Term))
+ CLaSH.Rewrite.Types: bindings :: forall extra_a3Z2r. Lens' (RewriteState extra_a3Z2r) (HashMap TmName (Type, SrcSpan, Term))
- CLaSH.Rewrite.Types: curFun :: forall extra_a1K16. Lens' (RewriteState extra_a1K16) (TmName, SrcSpan)
+ CLaSH.Rewrite.Types: curFun :: forall extra_a3Z2r. Lens' (RewriteState extra_a3Z2r) (TmName, SrcSpan)
- CLaSH.Rewrite.Types: extra :: forall extra_a1K16 extra_a1K54. Lens (RewriteState extra_a1K16) (RewriteState extra_a1K54) extra_a1K16 extra_a1K54
+ CLaSH.Rewrite.Types: extra :: forall extra_a3Z2r extra_a3Z6A. Lens (RewriteState extra_a3Z2r) (RewriteState extra_a3Z6A) extra_a3Z2r extra_a3Z6A
- CLaSH.Rewrite.Types: nameCounter :: forall extra_a1K16. Lens' (RewriteState extra_a1K16) Int
+ CLaSH.Rewrite.Types: nameCounter :: forall extra_a3Z2r. Lens' (RewriteState extra_a3Z2r) Int
- CLaSH.Rewrite.Types: transformCounter :: forall extra_a1K16. Lens' (RewriteState extra_a1K16) Int
+ CLaSH.Rewrite.Types: transformCounter :: forall extra_a3Z2r. Lens' (RewriteState extra_a3Z2r) Int
- CLaSH.Rewrite.Types: uniqSupply :: forall extra_a1K16. Lens' (RewriteState extra_a1K16) Supply
+ CLaSH.Rewrite.Types: uniqSupply :: forall extra_a3Z2r. Lens' (RewriteState extra_a3Z2r) Supply
- CLaSH.Rewrite.Util: mkBinderFor :: (Functor m, Monad m, MonadUnique m, Fresh m) => HashMap TyConName TyCon -> String -> Either Term Type -> m (Either (Id, Term) (TyVar, Type))
+ CLaSH.Rewrite.Util: mkBinderFor :: (Monad m, MonadUnique m, Fresh m) => HashMap TyConName TyCon -> String -> Either Term Type -> m (Either (Id, Term) (TyVar, Type))
- CLaSH.Rewrite.Util: mkInternalVar :: (Functor m, Monad m, MonadUnique m) => String -> KindOrType -> m (Id, Term)
+ CLaSH.Rewrite.Util: mkInternalVar :: (Monad m, MonadUnique m) => String -> KindOrType -> m (Id, Term)
- CLaSH.Rewrite.Util: mkTmBinderFor :: (Functor m, Fresh m, MonadUnique m) => HashMap TyConName TyCon -> String -> Term -> m (Id, Term)
+ CLaSH.Rewrite.Util: mkTmBinderFor :: (Fresh m, MonadUnique m) => HashMap TyConName TyCon -> String -> Term -> m (Id, Term)
- CLaSH.Rewrite.Util: mkWildValBinder :: (Functor m, Monad m, MonadUnique m) => Type -> m Id
+ CLaSH.Rewrite.Util: mkWildValBinder :: (Monad m, MonadUnique m) => Type -> m Id

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for the [`clash-lib`](http://hackage.haskell.org/package/clash-lib) package +## 0.7 *January 16th 2017*+* New features:+  * Support for `clash-prelude` 0.11+ ## 0.6.21 *August 18th 2016* * Fixes bugs:   * Type families are not currently being reduced correctly [#167](https://github.com/clash-lang/clash-compiler/issues/167)
LICENSE view
@@ -1,4 +1,5 @@-Copyright (c) 2012-2015, University of Twente+Copyright (c) 2012-2016, University of Twente,+              2017, QBayLogic All rights reserved.  Redistribution and use in source and binary forms, with or without
clash-lib.cabal view
@@ -1,5 +1,5 @@ Name:                 clash-lib-Version:              0.6.21+Version:              0.7 Synopsis:             CAES Language for Synchronous Hardware - As a Library Description:   CλaSH (pronounced ‘clash’) is a functional hardware description language that@@ -9,9 +9,8 @@   .   Features of CλaSH:   .-  * Strongly typed (like VHDL), yet with a very high degree of type inference,-    enabling both safe and fast prototying using consise descriptions (like-    Verilog).+  * Strongly typed, but with a very high degree of type inference, enabling both+    safe and fast prototyping using concise descriptions.   .   * Interactive REPL: load your designs in an interpreter and easily test all     your component without needing to setup a test bench.@@ -49,7 +48,7 @@ License-file:         LICENSE Author:               Christiaan Baaij Maintainer:           Christiaan Baaij <christiaan.baaij@gmail.com>-Copyright:            Copyright © 2012-2016 University of Twente+Copyright:            Copyright © 2012-2016, University of Twente, 2017, QBayLogic Category:             Hardware Build-type:           Simple @@ -87,28 +86,29 @@                       TupleSections                       ViewPatterns -  Build-depends:      aeson                   >= 0.6.2.0  && < 1.1,+  Build-depends:      aeson                   >= 0.6.2.0  && < 1.2,                       attoparsec              >= 0.10.4.0 && < 0.14,                       base                    >= 4.8      && < 5,                       bytestring              >= 0.10.0.2 && < 0.11,-                      clash-prelude           >= 0.10.4   && < 0.11,+                      clash-prelude           >= 0.11     && < 0.12,                       concurrent-supply       >= 0.1.7    && < 0.2,                       containers              >= 0.5.0.0  && < 0.6,+                      data-binary-ieee754     >= 0.4.4    && < 0.6,                       deepseq                 >= 1.3.0.2  && < 1.5,-                      directory               >= 1.2.0.1  && < 1.3,+                      directory               >= 1.2.0.1  && < 1.4,                       errors                  >= 1.4.2    && < 2.2,                       fgl                     >= 5.4.2.4  && < 5.6,                       filepath                >= 1.3.0.1  && < 1.5,-                      ghc                     >= 7.10.1   && < 8.1,+                      ghc                     >= 8.0.1    && < 8.2,                       hashable                >= 1.2.1.0  && < 1.3,                       integer-gmp             >= 1.0      && < 1.1,-                      lens                    >= 3.9.2    && < 4.15,+                      lens                    >= 3.9.2    && < 4.16,                       mtl                     >= 2.1.2    && < 2.3,                       pretty                  >= 1.1.1.0  && < 1.2,                       process                 >= 1.1.0.2  && < 1.5,                       template-haskell        >= 2.8.0.0  && < 2.12,                       text                    >= 0.11.3.1 && < 1.3,-                      time                    >= 1.4.0.1  && < 1.7,+                      time                    >= 1.4.0.1  && < 1.8,                       transformers            >= 0.3.0.0  && < 0.6,                       unbound-generics        >= 0.1      && < 0.4,                       unordered-containers    >= 0.2.3.3  && < 0.3,
src/CLaSH/Backend.hs view
@@ -36,7 +36,7 @@   extractTypes     :: state -> HashSet HWType    -- | Generate HDL for a Netlist component-  genHDL           :: String -> SrcSpan -> Component -> State state (String, Doc)+  genHDL           :: String -> SrcSpan -> Component -> State state ((String, Doc),[(String,Doc)])   -- | Generate a HDL package containing type definitions for the given HWTypes   mkTyPackage      :: String -> [HWType] -> State state [(String, Doc)]   -- | Convert a Netlist HWType to a target HDL type
src/CLaSH/Core/Literal.hs view
@@ -25,8 +25,9 @@ import {-# SOURCE #-} CLaSH.Core.Type         (Type) import CLaSH.Core.TysPrim                     (intPrimTy, integerPrimTy,                                                charPrimTy, stringPrimTy,-                                               voidPrimTy, wordPrimTy,-                                               int64PrimTy, word64PrimTy)+                                               wordPrimTy,+                                               int64PrimTy, word64PrimTy,+                                               floatPrimTy, doublePrimTy)  -- | Term Literal data Literal@@ -36,7 +37,8 @@   | Int64Literal    !Integer   | Word64Literal   !Integer   | StringLiteral   !String-  | RationalLiteral !Rational+  | FloatLiteral    !Rational+  | DoubleLiteral   !Rational   | CharLiteral     !Char   deriving (Eq,Ord,Show,Generic,NFData) @@ -54,7 +56,8 @@ literalType (IntLiteral      _) = intPrimTy literalType (WordLiteral     _) = wordPrimTy literalType (StringLiteral   _) = stringPrimTy-literalType (RationalLiteral _) = voidPrimTy+literalType (FloatLiteral    _) = floatPrimTy+literalType (DoubleLiteral   _) = doublePrimTy literalType (CharLiteral     _) = charPrimTy literalType (Int64Literal    _) = int64PrimTy literalType (Word64Literal   _) = word64PrimTy
src/CLaSH/Core/Pretty.hs view
@@ -19,10 +19,11 @@ import Data.Char                        (isSymbol, isUpper, ord) import Data.Text                        (unpack) import GHC.Show                         (showMultiLineString)+import Numeric                          (fromRat) import Text.PrettyPrint                 (Doc, char, comma, empty, equals, hang,                                          hsep, integer, parens, punctuate,                                          render, sep, text, vcat, ($$), ($+$),-                                         (<+>), (<>), rational, nest)+                                         (<+>), (<>), nest, float, double) import Unbound.Generics.LocallyNameless (Embed (..), LFresh, Name, lunbind,                                          name2String, runLFreshM, unembed,                                          unrebind, unrec)@@ -39,10 +40,10 @@  -- | Pretty printing Show-like typeclass class Pretty p where-  ppr :: (Applicative m, LFresh m) => p -> m Doc+  ppr :: LFresh m => p -> m Doc   ppr = pprPrec 0 -  pprPrec :: (Applicative m, LFresh m) => Rational -> p -> m Doc+  pprPrec :: LFresh m => Rational -> p -> m Doc  noPrec, opPrec, appPrec :: Num a => a noPrec = 0@@ -68,7 +69,7 @@ instance Pretty (Id, Term) where   pprPrec _ = pprTopLevelBndr -pprTopLevelBndr :: (Applicative m, LFresh m) => (Id,Term) -> m Doc+pprTopLevelBndr :: LFresh m => (Id,Term) -> m Doc pprTopLevelBndr (bndr,expr) = do   bndr' <- ppr bndr   bndrName <- ppr (varName bndr)@@ -137,7 +138,8 @@       | otherwise     -> return $ integer i     WordLiteral w     -> return $ integer w     Word64Literal w   -> return $ integer w-    RationalLiteral r -> return $ rational r+    FloatLiteral r    -> return $ float (fromRat r)+    DoubleLiteral r   -> return $ double (fromRat r)     CharLiteral c     -> return $ char c     StringLiteral s   -> return $ vcat $ map text $ showMultiLineString s @@ -152,33 +154,33 @@     LitPat l   -> ppr (unembed l)     DefaultPat -> return $ char '_' -pprPrecLam :: (Applicative m, LFresh m) => Rational -> [Id] -> Term -> m Doc+pprPrecLam :: LFresh m => Rational -> [Id] -> Term -> m Doc pprPrecLam prec xs e = do   xs' <- mapM (pprBndr LambdaBind) xs   e'  <- pprPrec noPrec e   return $ prettyParen (prec > noPrec) $     char 'λ' <> hsep xs' <+> rarrow $+$ e' -pprPrecTyLam :: (Applicative m, LFresh m) => Rational -> [TyVar] -> Term -> m Doc+pprPrecTyLam :: LFresh m => Rational -> [TyVar] -> Term -> m Doc pprPrecTyLam prec tvs e = do   tvs' <- mapM ppr tvs   e'   <- pprPrec noPrec e   return $ prettyParen (prec > noPrec) $     char 'Λ' <> hsep tvs' <+> rarrow $+$ e' -pprPrecApp :: (Applicative m, LFresh m) => Rational -> Term -> Term -> m Doc+pprPrecApp :: LFresh m => Rational -> Term -> Term -> m Doc pprPrecApp prec e1 e2 = do   e1' <- pprPrec opPrec e1   e2' <- pprPrec appPrec e2   return $ prettyParen (prec >= appPrec) $ e1' $$ (nest 2 e2') -pprPrecTyApp :: (Applicative m, LFresh m) => Rational -> Term -> Type -> m Doc+pprPrecTyApp :: LFresh m => Rational -> Term -> Type -> m Doc pprPrecTyApp prec e ty = do   e' <- pprPrec opPrec e   ty' <- pprParendType ty   return $ prettyParen (prec >= appPrec) $ e' $$ (char '@' <> ty') -pprPrecLetrec :: (Applicative m, LFresh m) => Rational -> [(Id, Embed Term)] -> Term+pprPrecLetrec :: LFresh m => Rational -> [(Id, Embed Term)] -> Term   -> m Doc pprPrecLetrec prec xes body   | [] <- xes = pprPrec prec body@@ -192,20 +194,20 @@     return $ prettyParen (prec > noPrec) $       hang (text "letrec") 2 (vcat xes') $$ text "in" <+> body' -pprPrecCase :: (Applicative m, LFresh m) => Rational -> Term -> [(Pat,Term)] -> m Doc+pprPrecCase :: LFresh m => Rational -> Term -> [(Pat,Term)] -> m Doc pprPrecCase prec e alts = do   e' <- pprPrec prec e   alts' <- mapM (pprPrecAlt noPrec) alts   return $ prettyParen (prec > noPrec) $     hang (text "case" <+> e' <+> text "of") 2 $ vcat alts' -pprPrecAlt :: (Applicative m, LFresh m) => Rational -> (Pat,Term) -> m Doc+pprPrecAlt :: LFresh m => Rational -> (Pat,Term) -> m Doc pprPrecAlt _ (altPat, altE) = do   altPat' <- pprPrec noPrec altPat   altE'   <- pprPrec noPrec altE   return $ hang (altPat' <+> rarrow) 2 altE' -pprBndr :: (Applicative m, LFresh m, Pretty a) => BindingSite -> a -> m Doc+pprBndr :: (LFresh m, Pretty a) => BindingSite -> a -> m Doc pprBndr bs x = prettyParen needsParen <$> ppr x   where     needsParen = case bs of@@ -222,13 +224,13 @@ maybeParen :: TypePrec -> TypePrec -> Doc -> Doc maybeParen ctxt_prec inner_prec = prettyParen (ctxt_prec >= inner_prec) -pprType :: (Applicative m, LFresh m) => Type -> m Doc+pprType :: LFresh m => Type -> m Doc pprType = ppr_type TopPrec -pprParendType :: (Applicative m, LFresh m) => Type -> m Doc+pprParendType :: LFresh m => Type -> m Doc pprParendType = ppr_type TyConPrec -ppr_type :: (Applicative m, LFresh m) => TypePrec -> Type -> m Doc+ppr_type :: LFresh m => TypePrec -> Type -> m Doc ppr_type _ (VarTy _ tv)                 = ppr tv ppr_type _ (LitTy tyLit)                = ppr tyLit ppr_type p ty@(ForAllTy _)              = pprForAllType p ty@@ -242,10 +244,10 @@ ppr_type p (AppTy ty1 ty2) = maybeParen p TyConPrec <$> ((<+>) <$> pprType ty1 <*> ppr_type TyConPrec ty2) ppr_type _ (ConstTy Arrow) = return (parens rarrow) -pprForAllType :: (Applicative m, LFresh m) => TypePrec -> Type -> m Doc+pprForAllType :: LFresh m => TypePrec -> Type -> m Doc pprForAllType p ty = maybeParen p FunPrec <$> pprSigmaType True ty -pprSigmaType :: (Applicative m, LFresh m) => Bool -> Type -> m Doc+pprSigmaType :: LFresh m => Bool -> Type -> m Doc pprSigmaType showForalls ty = do     (tvs, rho)     <- split1 [] ty     sep <$> sequenceA [ if showForalls then pprForAll tvs else pure empty@@ -256,13 +258,13 @@       lunbind b $ \(tv,resTy) -> split1 (tv:tvs) resTy     split1 tvs resTy = return (reverse tvs,resTy) -pprForAll :: (Applicative m, LFresh m) => [TyVar] -> m Doc+pprForAll :: LFresh m => [TyVar] -> m Doc pprForAll [] = return empty pprForAll tvs = do   tvs' <- mapM pprTvBndr tvs   return $ char '∀' <+> sep tvs' <> period -pprTvBndr :: (Applicative m, LFresh m) => TyVar -> m Doc+pprTvBndr :: LFresh m => TyVar -> m Doc pprTvBndr tv   = do       tv'   <- ppr tv@@ -271,10 +273,10 @@   where     kind = unembed $ varKind tv -pprKind :: (Applicative m, LFresh m) => Kind -> m Doc+pprKind :: LFresh m => Kind -> m Doc pprKind = pprType -pprTcApp :: (Applicative m, LFresh m) => TypePrec -> (TypePrec -> Type -> m Doc)+pprTcApp :: LFresh m => TypePrec -> (TypePrec -> Type -> m Doc)   -> TyConName -> [Type] -> m Doc pprTcApp _ _  tc []   = return . text $ name2String tc
src/CLaSH/Core/Term.hs view
@@ -12,8 +12,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell       #-} -{-# OPTIONS_GHC -fno-specialise #-}- module CLaSH.Core.Term   ( Term (..)   , TmName
src/CLaSH/Core/Type.hs view
@@ -9,12 +9,11 @@ {-# LANGUAGE DeriveAnyClass        #-} {-# LANGUAGE DeriveGeneric         #-} {-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MagicHash             #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell       #-} {-# LANGUAGE ViewPatterns          #-} -{-# OPTIONS_GHC -fno-specialise #-}- module CLaSH.Core.Type   ( Type (..)   , TypeView (..)@@ -50,11 +49,13 @@  -- External import import           Control.DeepSeq                         as DS-import           Control.Monad                           (zipWithM) import           Data.HashMap.Strict                     (HashMap) import qualified Data.HashMap.Strict                     as HashMap import           Data.Maybe                              (isJust, mapMaybe)+import           GHC.Base                                (isTrue#,(==#)) import           GHC.Generics                            (Generic(..))+import           GHC.Integer                             (smallInteger)+import           GHC.Integer.Logarithms                  (integerLogBase#) import           Unbound.Generics.LocallyNameless        (Alpha(..),Bind,Fresh,                                                           Subst(..),SubstName(..),                                                           acompare,aeq,bind,embed,@@ -338,23 +339,40 @@ -- a substituted RHS funSubsts :: HashMap TyConName TyCon -> ([Type],Type) -> [Type] -> Maybe Type funSubsts tcm (tcSubstLhs,tcSubstRhs) args = do-  tySubts <- concat <$> zipWithM (funSubst tcm) tcSubstLhs args+  tySubts <- foldl (funSubst tcm) (Just []) (zip tcSubstLhs args)   let tyRhs = substTys tySubts tcSubstRhs   return tyRhs  -- Given a LHS matching type, and a RHS to-match type, check if LHS and RHS -- are a match. If they do match, and the LHS is a variable, return a -- substitution-funSubst :: HashMap TyConName TyCon -> Type -> Type -> Maybe [(TyName,Type)]-funSubst _ (VarTy _ nmF) ty  = Just [(nmF,ty)]-funSubst tcm ty1 (reduceTypeFamily tcm -> Just ty2) = funSubst tcm ty1 ty2 -- See [Note: lazy type families]-funSubst _ tyL@(LitTy _) tyR = if tyL == tyR then Just [] else Nothing-funSubst tcm (tyView -> TyConApp tc argTys) (tyView -> TyConApp tc' argTys')-  | tc == tc'-  = do-    tySubts <- zipWithM (funSubst tcm) argTys argTys'-    return (concat tySubts)-funSubst _ _ _ = Nothing+funSubst :: HashMap TyConName TyCon -> Maybe [(TyName,Type)] -> (Type,Type) -> Maybe [(TyName,Type)]+funSubst _   Nothing  = const Nothing+funSubst tcm (Just s) = uncurry go+  where+    go (VarTy _ nmF) ty = case lookup nmF s of+      Nothing -> Just ((nmF,ty):s)+      -- Given, for example, the type family definition:+      --+      -- > type family Max x y where+      -- >   Max 0 b = b+      -- >   Max a 0 = a+      -- >   Max n n = n+      -- >   Max a b = If (a <=? b) b a+      --+      -- Then `Max 4 8` matches against the 4th clause.+      --+      -- So this is why, whenever we match against a type variable, we first+      -- check if there is already a substitution defined for this type variable,+      -- and if so, the applied type, and the type in the substitution should match.+      Just ty' | ty' == ty -> Just s+      _ -> Nothing+    go ty1 (reduceTypeFamily tcm -> Just ty2) = go ty1 ty2 -- See [Note: lazy type families]+    go ty1@(LitTy _) ty2 = if ty1 == ty2 then Just s else Nothing+    go (tyView -> TyConApp tc argTys) (tyView -> TyConApp tc' argTys')+      | tc == tc'+      = foldl (funSubst tcm) (Just s) (zip argTys argTys')+    go _ _ = Nothing  {- [Note: lazy type families] @@ -392,14 +410,47 @@     in  if i1 <= i2 then Just (mkTyConApp trueTc [] )                     else Just (mkTyConApp falseTc []) +  | name2String tc == "GHC.TypeLits.Extra.FLog"+  , [i1, i2] <- mapMaybe (litView tcm) tys+  , i1 > 1+  , i2 > 0+  = Just (LitTy (NumTy (smallInteger (integerLogBase# i1 i2))))+   | name2String tc == "GHC.TypeLits.Extra.CLog"   , [i1, i2] <- mapMaybe (litView tcm) tys   , Just k <- clogBase i1 i2   = Just (LitTy (NumTy (toInteger k))) +  | name2String tc == "GHC.TypeLits.Extra.Log"+  , [i1, i2] <- mapMaybe (litView tcm) tys+  , i1 > 1+  , i2 > 0+  = if i2 == 1+       then Just (LitTy (NumTy 0))+       else let z1 = integerLogBase# i1 i2+                z2 = integerLogBase# i1 (i2-1)+            in  if isTrue# (z1 ==# z2)+                   then Nothing+                   else Just (LitTy (NumTy (smallInteger z1)))++   | name2String tc == "GHC.TypeLits.Extra.GCD"   , [i1, i2] <- mapMaybe (litView tcm) tys   = Just (LitTy (NumTy (i1 `gcd` i2)))++  | name2String tc == "GHC.TypeLits.Extra.LCM"+  , [i1, i2] <- mapMaybe (litView tcm) tys+  = Just (LitTy (NumTy (i1 `lcm` i2)))++  | name2String tc == "GHC.TypeLits.Extra.Div"+  , [i1, i2] <- mapMaybe (litView tcm) tys+  , i2 > 0+  = Just (LitTy (NumTy (i1 `div` i2)))++  | name2String tc == "GHC.TypeLits.Extra.Mod"+  , [i1, i2] <- mapMaybe (litView tcm) tys+  , i2 > 0+  = Just (LitTy (NumTy (i1 `mod` i2)))    | Just (FunTyCon {tyConSubst = tcSubst}) <- HashMap.lookup tc tcm   = findFunSubst tcm tcSubst tys
src/CLaSH/Core/TysPrim.hs view
@@ -18,6 +18,8 @@   , wordPrimTy   , int64PrimTy   , word64PrimTy+  , floatPrimTy+  , doublePrimTy   , tysPrimMap   ) where@@ -52,7 +54,7 @@  intPrimTyConName, integerPrimTyConName, charPrimTyConName, stringPrimTyConName,   voidPrimTyConName, wordPrimTyConName, int64PrimTyConName,-  word64PrimTyConName :: TyConName+  word64PrimTyConName, floatPrimTyConName, doublePrimTyConName :: TyConName intPrimTyConName     = string2Name "GHC.Prim.Int#" integerPrimTyConName = string2Name "GHC.Integer.Type.Integer" stringPrimTyConName  = string2Name "String"@@ -61,6 +63,8 @@ wordPrimTyConName    = string2Name "GHC.Prim.Word#" int64PrimTyConName   = string2Name "GHC.Prim.Int64#" word64PrimTyConName  = string2Name "GHC.Prim.Word64#"+floatPrimTyConName   = string2Name "GHC.Prim.Float#"+doublePrimTyConName  = string2Name "GHC.Prim.Double#"  liftedPrimTC :: TyConName              -> TyCon@@ -68,7 +72,7 @@  -- | Builtin Type intPrimTc, integerPrimTc, charPrimTc, stringPrimTc, voidPrimTc, wordPrimTc,-  int64PrimTc, word64PrimTc :: TyCon+  int64PrimTc, word64PrimTc, floatPrimTc, doublePrimTc :: TyCon intPrimTc     = liftedPrimTC intPrimTyConName integerPrimTc = liftedPrimTC integerPrimTyConName charPrimTc    = liftedPrimTC charPrimTyConName@@ -77,9 +81,11 @@ wordPrimTc    = liftedPrimTC wordPrimTyConName int64PrimTc   = liftedPrimTC int64PrimTyConName word64PrimTc  = liftedPrimTC word64PrimTyConName+floatPrimTc   = liftedPrimTC floatPrimTyConName+doublePrimTc  = liftedPrimTC doublePrimTyConName  intPrimTy, integerPrimTy, charPrimTy, stringPrimTy, voidPrimTy, wordPrimTy,-  int64PrimTy, word64PrimTy :: Type+  int64PrimTy, word64PrimTy, floatPrimTy, doublePrimTy :: Type intPrimTy     = mkTyConTy intPrimTyConName integerPrimTy = mkTyConTy integerPrimTyConName charPrimTy    = mkTyConTy charPrimTyConName@@ -88,6 +94,8 @@ wordPrimTy    = mkTyConTy wordPrimTyConName int64PrimTy   = mkTyConTy int64PrimTyConName word64PrimTy  = mkTyConTy word64PrimTyConName+floatPrimTy   = mkTyConTy floatPrimTyConName+doublePrimTy  = mkTyConTy doublePrimTyConName  tysPrimMap :: HashMap TyConName TyCon tysPrimMap = HashMap.fromList@@ -103,4 +111,6 @@   , (wordPrimTyConName,wordPrimTc)   , (int64PrimTyConName,int64PrimTc)   , (word64PrimTyConName,word64PrimTc)+  , (floatPrimTyConName,floatPrimTc)+  , (doublePrimTyConName,doublePrimTc)   ]
src/CLaSH/Core/Util.hs view
@@ -45,7 +45,7 @@ type Delta = HashMap TyName Kind  -- | Determine the type of a term-termType :: (Functor m, Fresh m)+termType :: Fresh m          => HashMap TyConName TyCon          -> Term          -> m Type@@ -165,14 +165,14 @@ mkTyApps = foldl TyApp  -- | Does a term have a function type?-isFun :: (Functor m, Fresh m)+isFun :: Fresh m       => HashMap TyConName TyCon       -> Term       -> m Bool isFun m t = fmap (isFunTy m) $ (termType m) t  -- | Does a term have a function or polymorphic type?-isPolyFun :: (Functor m, Fresh m)+isPolyFun :: Fresh m           => HashMap TyConName TyCon           -> Term           -> m Bool@@ -327,6 +327,91 @@         [co,el,rest] = zipWith Id [string2Name "_co_",elPatNm, restPatNm]                                   (map embed idTys)         restTy = last (fromJust (dataConInstArgTys consCon tys))+++-- | 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 :: DataCon -- ^ The 'LR' constructor+              -> DataCon -- ^ The 'BR' constructor+              -> Type    -- ^ The element type+              -> Char    -- ^ Char to append to the bound variable names+              -> Integer -- ^ Depth of the tree+              -> Term    -- ^ The tree+              -> ([Term],[LetBinding])+extractTElems lrCon brCon resTy s maxN = go maxN [0..(2^(maxN+1))-2] [0..(2^maxN - 1)]+  where+    go :: Integer -> [Int] -> [Int] -> Term -> ([Term],[LetBinding])+    go 0 _ ks e = ([elVar],[(Id elBNm (embed resTy), embed lhs)])+      where+        elBNm   = string2Name ("el" ++ s:show (head ks))+        elVar   = Var resTy elBNm+        pat     = DataPat (embed lrCon) (rebind [] [co,el])+        elPatNm = string2Name "el"+        lhs     = Case e resTy [bind pat (Var resTy elPatNm)]++        tys          = [LitTy (NumTy 0),resTy]+        (Just idTys) = dataConInstArgTys lrCon tys+        [co,el]      = zipWith Id [string2Name "_co_",elPatNm]+                                  (map embed idTys)++    go n bs ks e = (lVars ++ rVars,(Id ltBNm (embed brTy),embed ltLhs):+                                   (Id rtBNm (embed brTy),embed rtLhs):+                                   (lBinds ++ rBinds))+      where+        ltBNm = string2Name ("lt" ++ s:show b0)+        rtBNm = string2Name ("rt" ++ s:show b1)+        ltVar = Var brTy ltBNm+        rtVar = Var brTy rtBNm+        pat   = DataPat (embed brCon) (rebind [mTV] [co,lt,rt])+        ltPatNm = string2Name "lt"+        rtPatNm = string2Name "rt"+        ltLhs   = Case e brTy [bind pat (Var brTy ltPatNm)]+        rtLhs   = Case e brTy [bind pat (Var brTy rtPatNm)]++        mName = string2Name "m"+        mTV = TyVar mName (embed typeNatKind)+        tys = [LitTy (NumTy n),resTy,LitTy (NumTy (n-1))]+        (Just idTys) = dataConInstArgTys brCon tys+        [co,lt,rt] = zipWith Id [string2Name "_co_",ltPatNm,rtPatNm]+                                (map embed idTys)+        brTy = last idTys+        (kL,kR) = splitAt (length ks `div` 2) ks+        (b0:bL,b1:bR) = splitAt (length bs `div` 2) bs++        (lVars,lBinds) = go (n-1) bL kL ltVar+        (rVars,rBinds) = go (n-1) bR kR rtVar++-- | Create a vector of supplied elements+mkRTree :: DataCon -- ^ The LR constructor+        -> DataCon -- ^ The BR constructor+        -> Type    -- ^ Element type+        -> Integer -- ^ Depth of the tree+        -> [Term]  -- ^ Elements to put in the tree+        -> Term+mkRTree lrCon brCon resTy = go+  where+    go _ [x] = mkApps (Data lrCon) [Right (LitTy (NumTy 0))+                                    ,Right resTy+                                    ,Left  (Prim "_CO_" lrCoTy)+                                    ,Left  x+                                    ]++    go n xs =+      let (xsL,xsR) = splitAt (length xs `div` 2) xs+      in  mkApps (Data brCon) [Right (LitTy (NumTy n))+                              ,Right resTy+                              ,Right (LitTy (NumTy (n-1)))+                              ,Left (Prim "_CO_" (brCoTy n))+                              ,Left (go (n-1) xsL)+                              ,Left (go (n-1) xsR)]++    lrCoTy   = head (fromJust $! dataConInstArgTys lrCon  [(LitTy (NumTy 0))+                                                         ,resTy])+    brCoTy n = head (fromJust $! dataConInstArgTys brCon+                                                   [(LitTy (NumTy n))+                                                   ,resTy+                                                   ,(LitTy (NumTy (n-1)))])  -- | Determine whether a type is isomorphic to "CLaSH.Signal.Internal.Signal'" --
src/CLaSH/Driver.hs view
@@ -49,7 +49,7 @@                                                    normalize, runNormalization) import           CLaSH.Normalize.Util             (callGraph, mkRecursiveComponents) import           CLaSH.Primitives.Types-import           CLaSH.Util                       (first)+import           CLaSH.Util                       (first, second)  -- | Create a set of target HDL files for a set of functions generateHDL :: forall backend . Backend backend@@ -129,7 +129,7 @@             CLaSH.Backend.name hdlState' </>             takeWhile (/= '.') (name2String topEntity)   prepareDir (opt_cleanhdl opts) (extension hdlState') dir-  mapM_ (writeHDL hdlState' dir) hdlDocs+  mapM_ (writeHDL dir) hdlDocs   copyDataFiles dir dfiles'    endTime <- hdlDocs `seq` Clock.getCurrentTime@@ -137,10 +137,13 @@   putStrLn $ "Total compilation took " ++ show startEndDiff  parsePrimitive :: Primitive Text -> Primitive BlackBoxTemplate-parsePrimitive (BlackBox pNm templT) =+parsePrimitive (BlackBox pNm libM imps inc templT) =   let (templ,err) = either (first Left . runParse) (first Right . runParse) templT+      inc'        = case fmap (second runParse) inc of+                      Just (x,(t,[])) -> Just (x,t)+                      _ -> Nothing   in  case err of-        [] -> BlackBox pNm templ+        [] -> BlackBox pNm libM imps inc' templ         _  -> error $ "Errors in template for: " ++ show pNm ++ ":\n" ++ show err parsePrimitive (Primitive pNm typ) = Primitive pNm typ @@ -153,10 +156,12 @@ createHDL backend modName components = flip evalState backend $ do   -- (hdlNms,hdlDocs) <- unzip <$> mapM genHDL components   -- let hdlNmDocs = zip hdlNms hdlDocs-  hdlNmDocs <- mapM (uncurry (genHDL modName)) components+  (hdlNmDocs,incs) <- unzip <$> mapM (uncurry (genHDL modName)) components   hwtys <- HashSet.toList <$> extractTypes <$> get   typesPkg <- mkTyPackage modName hwtys-  return (typesPkg ++ hdlNmDocs)+  let hdl   = map (first (<.> CLaSH.Backend.extension backend)) (typesPkg ++ hdlNmDocs)+      qincs = map (first (<.> "qsys")) (concat incs)+  return (hdl ++ qincs)  -- | 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.@@ -178,9 +183,9 @@     mapM_ Directory.removeFile abs_to_remove  -- | Writes a HDL file to the given directory-writeHDL :: Backend backend => backend -> FilePath -> (String, Doc) -> IO ()-writeHDL backend dir (cname, hdl) = do-  handle <- IO.openFile (dir </> cname <.> CLaSH.Backend.extension backend) IO.WriteMode+writeHDL :: FilePath -> (String, Doc) -> IO ()+writeHDL dir (cname, hdl) = do+  handle <- IO.openFile (dir </> cname) IO.WriteMode   hPutDoc handle hdl   IO.hPutStr handle "\n"   IO.hClose handle
src/CLaSH/Driver/TestbenchGen.hs view
@@ -73,7 +73,7 @@       Just stimuliNm               -> (\(v,w,x,y,z) -> (Just v,w,x,y,z)) <$>                  genStimuli seen primMap globals typeTrans mkId tcm normalizeSignal hidden inp modName dfiles iw stimuliNm-      Nothing -> let inpExpr = Assignment (fst inp) (BlackBoxE "" [Err Nothing] (emptyBBContext {bbResult = (undefined,snd inp)}) False)+      Nothing -> let inpExpr = Assignment (fst inp) (BlackBoxE "" [] [] Nothing [Err Nothing] (emptyBBContext {bbResult = (undefined,snd inp)}) False)                  in  return (Just inpExpr,[],seen,hidden,dfiles)     Nothing   -> return (Nothing,[],seen,hidden,dfiles) @@ -133,7 +133,7 @@          -> NetlistMonad (Maybe [Declaration]) genClock primMap (clkName,Clock clkSym rate) =   case HashMap.lookup "CLaSH.Driver.TestbenchGen.clockGen" primMap of-    Just (BlackBox _ (Left templ)) -> do+    Just (BlackBox _ lib imps Nothing (Left templ)) -> do       let (rising,rest) = divMod (toInteger rate) 2           falling       = rising + rest           ctx = emptyBBContext@@ -144,7 +144,7 @@                                ]                   }       templ' <- prepareBlackBox "CLaSH.Driver.TestbenchGen.clockGen" templ ctx-      let clkGenDecl = BlackBoxD "CLaSH.Driver.TestbenchGen.clockGen" templ' ctx+      let clkGenDecl = BlackBoxD "CLaSH.Driver.TestbenchGen.clockGen" lib imps Nothing templ' ctx           clkDecls   = [ NetDecl clkName (Clock clkSym rate)                        , clkGenDecl                        ]@@ -158,13 +158,13 @@          -> NetlistMonad (Maybe [Declaration]) genReset primMap (rstName,Reset clkSym rate) =   case HashMap.lookup "CLaSH.Driver.TestbenchGen.resetGen" primMap of-    Just (BlackBox _ (Left templ)) -> do+    Just (BlackBox _ lib imps Nothing (Left templ)) -> do       let ctx = emptyBBContext                   { bbResult = (Left (Identifier rstName Nothing), Reset clkSym rate)                   , bbInputs = [(Left (N.Literal Nothing (NumLit 2)),Signed 32,True)]                   }       templ' <- prepareBlackBox "CLaSH.Driver.TestbenchGen.resetGen" templ ctx-      let resetGenDecl =  BlackBoxD "CLaSH.Driver.TestbenchGen.resetGen" templ' ctx+      let resetGenDecl =  BlackBoxD "CLaSH.Driver.TestbenchGen.resetGen" lib imps Nothing templ' ctx           rstDecls     = [ NetDecl rstName (Reset clkSym rate)                        , resetGenDecl                        ]@@ -177,25 +177,25 @@ genFinish :: PrimMap BlackBoxTemplate           -> NetlistMonad Declaration genFinish primMap = case HashMap.lookup "CLaSH.Driver.TestbenchGen.finishedGen" primMap of-  Just (BlackBox _ (Left templ)) -> do+  Just (BlackBox _ lib imps Nothing (Left templ)) -> do     let ctx = emptyBBContext                 { bbResult = (Left (Identifier "finished" Nothing), Bool)                 , bbInputs = [ (Left (N.Literal Nothing (NumLit 100)),Signed 32,True) ]                 }     templ' <- prepareBlackBox "CLaSH.Driver.TestbenchGen.finishGen" templ ctx-    return $ BlackBoxD "CLaSH.Driver.TestbenchGen.finishGen" templ' ctx+    return $ BlackBoxD "CLaSH.Driver.TestbenchGen.finishGen" lib imps Nothing templ' ctx   pM -> error $ $(curLoc) ++ ("Can't make finish declaration for: " ++ show pM)  genDone :: PrimMap BlackBoxTemplate         -> NetlistMonad Declaration genDone primMap = case HashMap.lookup "CLaSH.Driver.TestbenchGen.doneGen" primMap of-  Just (BlackBox _ (Left templ)) -> do+  Just (BlackBox _ lib imps Nothing (Left templ)) -> do     let ctx = emptyBBContext                 { bbResult    = (Left (Identifier "done" Nothing), Bool)                 , bbInputs    = [(Left (Identifier "finished" Nothing),Bool,False)]                 }     templ' <- prepareBlackBox "CLaSH.Driver.TestbenchGen.doneGen" templ ctx-    return $ BlackBoxD "CLaSH.Driver.TestbenchGen.doneGen" templ' ctx+    return $ BlackBoxD "CLaSH.Driver.TestbenchGen.doneGen" lib imps Nothing templ' ctx   pM -> error $ $(curLoc) ++ ("Can't make done declaration for: " ++ show pM)  genStimuli :: [Identifier]
src/CLaSH/Driver/TopWrapper.hs view
@@ -126,6 +126,17 @@         netdecl  = NetDecl iName hwty         netassgn = Assignment iName (mkVectorChain sz hwty' ids)     in  (nms',(ports',(netdecl:decls' ++ [netassgn],iName)))+  RTree d hwty' ->+    let (nms',(ports',(decls',ids)))+                 = second ( (concat *** (first concat . unzip))+                          . unzip+                          )+                 $ mapAccumL+                    (\nm c -> mkInput nm (iName,hwty') c)+                    nms [0..((2^d)-1)]+        netdecl  = NetDecl iName hwty+        netassgn = Assignment iName (mkRTreeChain d hwty' ids)+    in  (nms',(ports',(netdecl:decls' ++ [netassgn],iName)))   Product _ hwtys ->     let (nms',(ports',(decls',ids)))                  = second ( (concat *** (first concat . unzip))@@ -158,6 +169,20 @@                                 , mkVectorChain (sz-1) elTy is                                 ] +-- | Create a RTree chain for a list of 'Identifier's+mkRTreeChain :: Int+             -> HWType+             -> [Identifier]+             -> Expr+mkRTreeChain _ elTy [i] = DataCon (RTree 0 elTy) RTreeAppend+                                  [Identifier i Nothing]+mkRTreeChain d elTy is =+  let (isL,isR) = splitAt (length is `div` 2) is+  in  DataCon (RTree d elTy) RTreeAppend+        [ mkRTreeChain (d-1) elTy isL+        , mkRTreeChain (d-1) elTy isR+        ]+ -- | Generate output port mappings mkOutput :: [Identifier]          -> (Identifier,HWType)@@ -185,6 +210,21 @@                     ids                     [0..]     in  (nms',(ports',(netdecl:assigns ++ decls',iName)))+  RTree d hwty' ->+    let (nms',(ports',(decls',ids)))+                 = second ( (concat *** (first concat . unzip))+                          . unzip+                          )+                 $ mapAccumL+                    (\nm c -> mkOutput nm (iName,hwty') c)+                    nms [0..((2^d)-1)]+        netdecl  = NetDecl iName hwty+        assigns = zipWith+                    (\id_ n -> Assignment id_+                                 (Identifier iName (Just (Indexed (hwty,10,n)))))+                    ids+                    [0..]+    in  (nms',(ports',(netdecl:assigns ++ decls',iName)))   Product _ hwtys ->     let (nms',(ports',(decls',ids)))                 = second ( (concat *** (first concat . unzip))@@ -287,9 +327,9 @@               }       bbName = "CLaSH.TopWrapper.syncReset"   resetGenDecl <- case HashMap.lookup bbName primMap of-        Just (BlackBox _ (Left templ)) -> do+        Just (BlackBox _ lib imps Nothing (Left templ)) -> do           templ' <- prepareBlackBox bbName templ ctx-          return (BlackBoxD bbName templ' ctx)+          return (BlackBoxD bbName lib imps Nothing templ' ctx)         pM -> error $ $(curLoc) ++ ("Can't make reset sync for: " ++ show pM)    return [NetDecl rst (Reset nm r),resetGenDecl]
src/CLaSH/Driver/Types.hs view
@@ -35,6 +35,8 @@                            , opt_hdlDir      :: Maybe String                            , opt_hdlSyn      :: HdlSyn                            , opt_errorExtra  :: Bool+                           , opt_floatSupport :: Bool+                           , opt_allowZero   :: Bool                            }  data CLaSHException = CLaSHException SrcSpan String (Maybe String)
src/CLaSH/Netlist.hs view
@@ -16,6 +16,7 @@ import qualified Control.Lens                     as Lens import           Control.Monad.State.Strict       (runStateT) import           Control.Monad.Writer.Strict      (listen, runWriterT, tell)+import           Data.Binary.IEEE754              (floatToWord, doubleToWord) import           Data.Char                        (ord) import           Data.Either                      (lefts,partitionEithers) import           Data.HashMap.Lazy                (HashMap)@@ -374,6 +375,12 @@     Int64Literal i   -> return (HW.Literal (Just (Signed 64,64)) $ NumLit i, [])     Word64Literal w  -> return (HW.Literal (Just (Unsigned 64,64)) $ NumLit w, [])     CharLiteral c    -> return (HW.Literal (Just (Unsigned 21,21)) . NumLit . toInteger $ ord c, [])+    FloatLiteral r   -> let f = fromRational r :: Float+                            i = toInteger (floatToWord f)+                        in  return (HW.Literal (Just (BitVector 32,32)) (NumLit i), [])+    DoubleLiteral r  -> let d = fromRational r :: Double+                            i = toInteger (doubleToWord d)+                        in  return (HW.Literal (Just (BitVector 64,64)) (NumLit i), [])     _ -> error $ $(curLoc) ++ "not an integer or char literal"  mkExpr bbEasD bndr ty app = do@@ -433,19 +440,16 @@                    tg -> error $ $(curLoc) ++ "unknown bool literal: " ++ showDoc dc ++ "(tag: " ++ show tg ++ ")"         in  return dc'       Vector 0 _ -> return (HW.DataCon dstHType VecAppend [])-      -- Note [Vector Wrapper]-      -- The Vector type has two versions of the cons constructor:-      --   * The 'normal' one, which takes a coercion as its first argument,-      --     followed by the element and the vector-      --   * The wrapper one, which just takes the element and vector argument-      ---      -- We need to account for both occurrences, that's why we have the two-      -- case statements below:       Vector 1 _ -> case argExprs of                       [_,e,_] -> return (HW.DataCon dstHType VecAppend [e])-                      _       -> return (HW.DataCon dstHType VecAppend [head argExprs])+                      _       -> error $ $(curLoc) ++ "Unexpected number of arguments for `Cons`: " ++ showDoc args       Vector _ _ -> case argExprs of                       [_,e1,e2] -> return (HW.DataCon dstHType VecAppend [e1,e2])-                      _         -> return (HW.DataCon dstHType VecAppend argExprs)-+                      _         -> error $ $(curLoc) ++ "Unexpected number of arguments for `Cons`: " ++ showDoc args+      RTree 0 _ -> case argExprs of+                      [_,e] -> return (HW.DataCon dstHType RTreeAppend [e])+                      _ -> error $ $(curLoc) ++ "Unexpected number of arguments for `LR`: " ++ showDoc args+      RTree _ _ -> case argExprs of+                      [_,e1,e2] -> return (HW.DataCon dstHType RTreeAppend [e1,e2])+                      _ -> error $ $(curLoc) ++ "Unexpected number of arguments for `BR`: " ++ showDoc args       _ -> error $ $(curLoc) ++ "mkDcApplication undefined for: " ++ show (dstHType,dc,args,argHWTys)
src/CLaSH/Netlist/BlackBox.hs view
@@ -15,7 +15,6 @@ import           Control.Exception             (throw) import           Control.Lens                  ((.=),(<<%=)) import qualified Control.Lens                  as Lens-import           Control.Monad                 (filterM) import           Data.Char                     (ord) import           Data.Either                   (lefts) import qualified Data.HashMap.Lazy             as HashMap@@ -65,7 +64,7 @@                 Nothing  -> Left . (`N.Identifier` Nothing)  <$> mkBasicId (pack $ name2String (V.varName resId))     resTy <- unsafeCoreTypeToHWTypeM $(curLoc) (unembed $ V.varType resId) -    return ( Context (res,resTy) imps funs+    return ( Context (res,resTy) imps funs Nothing            , concat impDecls ++ concat funDecls            )   where@@ -89,7 +88,8 @@           collectFilePaths bbCtx $ templ      else do        (_,sp) <- Lens.use curCompNm-       let msg = $(curLoc) ++ "Can't match template for " ++ show pNm ++ " :\n\n" ++ show templ +++       templ' <- prettyBlackBox templ+       let msg = $(curLoc) ++ "Can't match template for " ++ show pNm ++ " :\n\n" ++ Text.unpack templ' ++                 "\n\nwith context:\n\n" ++ show bbCtx        throw (CLaSHException sp msg Nothing) @@ -121,10 +121,8 @@             (Identifier _ _) -> return ((e',hwTy,False), d)             _                -> return ((e',hwTy,isConstant e), d)         (Data dc, args) -> do-            typeTrans <- Lens.use typeTranslator-            args' <- filterM (fmap (representableType typeTrans tcm) . termType tcm) (lefts args)-            (exprN,dcDecls) <- mkDcApplication hwTy (Left bndr) dc args'-            return ((exprN,hwTy,isConstant e),dcDecls)+          (exprN,dcDecls) <- mkDcApplication hwTy (Left bndr) dc (lefts args)+          return ((exprN,hwTy,isConstant e),dcDecls)         _ -> return ((Identifier "__VOID__" Nothing,hwTy,False),[])     return ((addClock tcm ty e',t,l),d)   where@@ -148,7 +146,7 @@           let pNm = name p           (dst',dstNm,dstDecl) <- resBndr True dst           (bbCtx,ctxDcls) <- mkBlackBoxContext dst' (lefts args)-          bbDecl <- N.BlackBoxD pNm <$> prepareBlackBox pNm tempD bbCtx <*> pure bbCtx+          bbDecl <- N.BlackBoxD pNm (library p) (imports p) (qsysInclude p) <$> prepareBlackBox pNm tempD bbCtx <*> pure bbCtx           return (Identifier dstNm Nothing,dstDecl ++ ctxDcls ++ [bbDecl])         (Right tempE) -> do           let pNm = name p@@ -157,13 +155,13 @@               (dst',dstNm,dstDecl) <- resBndr True dst               (bbCtx,ctxDcls) <- mkBlackBoxContext dst' (lefts args)               bbTempl <- prepareBlackBox pNm tempE bbCtx-              let tmpAssgn = Assignment dstNm (BlackBoxE pNm bbTempl bbCtx bbEParen)+              let tmpAssgn = Assignment dstNm (BlackBoxE pNm (library p) (imports p) (qsysInclude p) bbTempl bbCtx bbEParen)               return (Identifier dstNm Nothing, dstDecl ++ ctxDcls ++ [tmpAssgn])             else do               (dst',_,_) <- resBndr False dst               (bbCtx,ctxDcls) <- mkBlackBoxContext dst' (lefts args)               bbTempl <- prepareBlackBox pNm tempE bbCtx-              return (BlackBoxE pNm bbTempl bbCtx bbEParen,ctxDcls)+              return (BlackBoxE pNm (library p) (imports p) (qsysInclude p) bbTempl bbCtx bbEParen,ctxDcls)     Just (P.Primitive pNm _)       | pNm == "GHC.Prim.tagToEnum#" -> do           hwTy <- N.unsafeCoreTypeToHWTypeM $(curLoc) ty@@ -204,7 +202,7 @@                     netAssignRhs = Assignment tmpRhs scrutExpr                 return (DataTag scrutHTy (Right tmpRhs),[netDeclRhs,netAssignRhs] ++ scrutDecls)           _ -> error $ $(curLoc) ++ "dataToTag: " ++ show (map (either showDoc showDoc) args)-      | otherwise -> return (BlackBoxE "" [C $ mconcat ["NO_TRANSLATION_FOR:",fromStrict pNm]] emptyBBContext False,[])+      | otherwise -> return (BlackBoxE "" [] [] Nothing [C $ mconcat ["NO_TRANSLATION_FOR:",fromStrict pNm]] emptyBBContext False,[])     _ -> do       (_,sp) <- Lens.use curCompNm       throw (CLaSHException sp ($(curLoc) ++ "No blackbox found for: " ++ unpack nm) Nothing)@@ -261,7 +259,7 @@                       dcAss  = Assignment (pack "~RESULT") dcApp                   return (Right dcAss)                 Just resHTy@(Vector _ _) -> do-                  let dcInps = [ Identifier (pack ("~ARG[" ++ show x ++ "]")) Nothing | x <- [(0::Int)..1] ]+                  let dcInps = [ Identifier (pack ("~ARG[" ++ show x ++ "]")) Nothing | x <- [(1::Int)..2] ]                       dcApp  = DataCon resHTy (DC (resHTy,1)) dcInps                       dcAss  = Assignment (pack "~RESULT") dcApp                   return (Right dcAss)
src/CLaSH/Netlist/BlackBox/Parser.hs view
@@ -82,8 +82,10 @@      <|> TypElem           <$> (pToken "~TYPEL" *> pBrackets pTagE)      <|> IndexType         <$> (pToken "~INDEXTYPE" *> pBrackets pTagE)      <|> CompName          <$  pToken "~COMPNAME"+     <|> QSysIncludeName   <$  pToken "~QSYSINCLUDENAME"      <|> Size              <$> (pToken "~SIZE" *> pBrackets pTagE)      <|> Length            <$> (pToken "~LENGTH" *> pBrackets pTagE)+     <|> Depth             <$> (pToken "~DEPTH" *> pBrackets pTagE)      <|> FilePath          <$> (pToken "~FILE" *> pBrackets pTagE)      <|> Gen               <$> (True <$ pToken "~GENERATE")      <|> Gen               <$> (False <$ pToken "~ENDGENERATE")
src/CLaSH/Netlist/BlackBox/Types.hs view
@@ -29,10 +29,12 @@              | TypElem !Element  -- ^ Select element type from a vector type              | CompName          -- ^ Hole for the name of the component in which                                  -- the blackbox is instantiated+             | QSysIncludeName              | IndexType !Element -- ^ Index data type hole, the field is the                                   -- (exclusive) maximum index              | Size !Element     -- ^ Size of a type hole              | Length !Element   -- ^ Length of a vector hole+             | Depth !Element    -- ^ Depth of a tree hole              | FilePath !Element -- ^ Hole containing a filepath for a data file              | Gen !Bool         -- ^ Hole marking beginning (True) or end (False)                                  -- of a generative construct
src/CLaSH/Netlist/BlackBox/Util.hs view
@@ -21,6 +21,7 @@ import           Control.Monad.State                  (State, StateT, evalStateT,                                                        lift, modify, get) import           Control.Monad.Writer.Strict          (MonadWriter, tell)+import           Data.Bool                            (bool) import           Data.Foldable                        (foldrM) import qualified Data.IntMap                          as IntMap import           Data.List                            (mapAccumL, nub)@@ -43,7 +44,9 @@ import           CLaSH.Netlist.Types                  (HWType (..), Identifier,                                                        BlackBoxContext (..),                                                        SyncExpr, Expr (..),-                                                       Literal (..), NetlistMonad)+                                                       Literal (..), NetlistMonad,+                                                       Modifier (..))+import qualified CLaSH.Netlist.Types                  as N import           CLaSH.Netlist.Util                   (mkUniqueIdentifier,typeSize) import           CLaSH.Util @@ -125,9 +128,7 @@     setCompName' (BV t e m)     = BV t (setCompName nm e) (setCompName' m)     setCompName' e              = e -setClocks :: ( MonadWriter (Set (Identifier,HWType)) m-             , Applicative m-             )+setClocks :: MonadWriter (Set (Identifier,HWType)) m           => BlackBoxContext           -> BlackBoxTemplate           -> m BlackBoxTemplate@@ -164,7 +165,7 @@         let (s,_,_) = bbInputs bbCtx !! n             e'      = either id fst s         in case e' of-          BlackBoxE "GHC.CString.unpackCString#" _ bbCtx' _ -> case bbInputs bbCtx' of+          BlackBoxE "GHC.CString.unpackCString#" _ _ _ _ bbCtx' _ -> case bbInputs bbCtx' of             [(Left (Literal Nothing (StringLit s')),_,_)] -> renderFilePath fs s'             _ -> (fs',FilePath e)           _ -> (fs',FilePath e)@@ -238,8 +239,19 @@                        (Vector n _) -> n                        _ -> error $ $(curLoc) ++ "IF: veclen of a non-vector type"       (L n)      -> case bbInputs b !! n of-                      (either id fst -> Literal _ (NumLit i),_,_) -> fromInteger i+                      (either id fst -> Literal _ l,_,_) ->+                        case l of+                          NumLit i -> fromInteger i+                          BitLit bl -> case bl of+                            N.H -> 1+                            N.L -> 0+                            _   -> error $ $(curLoc) ++ "IF: LIT bit literal must be high or low"+                          BoolLit bl -> bool 0 1 bl+                          _ -> error $ $(curLoc) ++ "IF: LIT must be a numeric lit"                       _ -> error $ $(curLoc) ++ "IF: LIT must be a numeric lit"+      (Depth e)  -> case lineToType b [e] of+                      (RTree n _) -> n+                      _ -> error $ $(curLoc) ++ "IF: treedepth of non-tree type"       IW64       -> if iw == 64 then 1 else 0       (HdlSyn s) -> if s == syn then 1 else 0       (IsVar n)  -> let (s,_,_) = bbInputs b !! n@@ -314,6 +326,7 @@                               in  (displayT . renderOneLine) <$> expr False (mkLit e)   where     mkLit (Literal (Just (Signed _,_)) i) = Literal Nothing i+    mkLit (DataCon _ (DC (Void, _)) [Literal (Just (Signed _,_)) i]) = Literal Nothing i     mkLit i                               = i  renderTag _ (Sym t _) = return t@@ -341,6 +354,10 @@   where     vecLen (Vector n _) = n     vecLen _            = error $ $(curLoc) ++ "vecLen of a non-vector type"+renderTag b (Depth e)      = return . Text.pack . show . treeDepth $ lineToType b [e]+  where+    treeDepth (RTree n _) = n+    treeDepth _           = error $ $(curLoc) ++ "treeDepth of a non-tree type" renderTag b e@(TypElem _)   = let ty = lineToType b [e]                               in  (displayT . renderOneLine) <$> hdlType ty renderTag _ (Gen b)         = displayT . renderOneLine <$> genStmt b@@ -364,20 +381,23 @@       let hty = Index (fromInteger n')       in  fmap (displayT . renderOneLine) (hdlType hty)     x -> error $ $(curLoc) ++ "Index type not given a literal: " ++ show x-renderTag _ (IF _ _ _)      = error $ $(curLoc) ++ "Unexpected IF"-renderTag _ (D _)           = error $ $(curLoc) ++ "Unexpected component declaration"-renderTag _ (SigD _ _)      = error $ $(curLoc) ++ "Unexpected signal declaration"-renderTag _ (Clk _)         = error $ $(curLoc) ++ "Unexpected clock"-renderTag _ (Rst _)         = error $ $(curLoc) ++ "Unexpected reset"-renderTag _ CompName        = error $ $(curLoc) ++ "Unexpected component name"-renderTag _ (IndexType _)   = error $ $(curLoc) ++ "Unexpected index type"-renderTag _ (FilePath _)    = error $ $(curLoc) ++ "Unexpected file name"-renderTag _ IW64            = error $ $(curLoc) ++ "Unexpected IW64"-renderTag _ (HdlSyn s)      = error $ $(curLoc) ++ "Unexpected ~" ++ show s-renderTag _ (IsLit _)       = error $ $(curLoc) ++ "Unexpected ~ISLIT"-renderTag _ (IsVar _)       = error $ $(curLoc) ++ "Unexpected ~ISVAR"-renderTag _ (GenSym _ _)    = error $ $(curLoc) ++ "Unexpected ~GENSYM"-renderTag _ (And _)         = error $ $(curLoc) ++ "Unexpected ~AND"+renderTag b (FilePath e)    = case e of+  L n -> do+    let (s,_,_) = bbInputs b !! n+        e'      = either id fst s+    e2  <- prettyElem e+    case e' of+      BlackBoxE "GHC.CString.unpackCString#" _ _ _ _ bbCtx' _ -> case bbInputs bbCtx' of+        [(Left (Literal Nothing (StringLit _)),_,_)] -> error $ $(curLoc) ++ "argument of ~FILEPATH:" ++ show e2 ++  "does not reduce to a string"+        _ ->  error $ $(curLoc) ++ "argument of ~FILEPATH:" ++ show e2 ++  "does not reduce to a string"+      _ -> error $ $(curLoc) ++ "argument of ~FILEPATH:" ++ show e2 ++  "does not reduce to a string"+  _ -> do e' <- prettyElem e+          error $ $(curLoc) ++ "~FILEPATH expects a ~LIT[N] argument, but got: " ++ show e'+renderTag b QSysIncludeName = case bbQsysIncName b of+  Just nm -> return nm+  _ -> error $ $(curLoc) ++ "~QSYSINCLUDENAME used where no 'qysInclude' was specified in the primitive definition"+renderTag _ e = do e' <- prettyElem e+                   error $ $(curLoc) ++ "Unable to evaluate: " ++ show e'  prettyBlackBox :: Monad m                => BlackBoxTemplate@@ -404,7 +424,7 @@ prettyElem (Rst Nothing) = return "~RSTO" prettyElem (Rst (Just i)) = (displayT . renderOneLine) <$> (text "~RSTO" <> brackets (int i)) prettyElem (Typ Nothing) = return "~TYPO"-prettyElem (Typ (Just i)) = (displayT . renderOneLine) <$> (text "~TYPO" <> brackets (int i))+prettyElem (Typ (Just i)) = (displayT . renderOneLine) <$> (text "~TYP" <> brackets (int i)) prettyElem (TypM Nothing) = return "~TYPMO" prettyElem (TypM (Just i)) = (displayT . renderOneLine) <$> (text "~TYPM" <> brackets (int i)) prettyElem (Err Nothing) = return "~ERRORO"@@ -413,6 +433,7 @@   e' <- prettyElem e   (displayT . renderOneLine) <$> (text "~TYPEL" <> brackets (text e')) prettyElem CompName = return "~COMPNAME"+prettyElem QSysIncludeName = return "~QSYSINCLUDENAME" prettyElem (IndexType e) = do   e' <- prettyElem e   (displayT . renderOneLine) <$> (text "~INDEXTYPE" <> brackets (text e'))@@ -422,6 +443,9 @@ prettyElem (Length e) = do   e' <- prettyElem e   (displayT . renderOneLine) <$> (text "~LENGTH" <> brackets (text e'))+prettyElem (Depth e) = do+  e' <- prettyElem e+  (displayT . renderOneLine) <$> (text "~DEPTH" <> brackets (text e')) prettyElem (FilePath e) = do   e' <- prettyElem e   (displayT . renderOneLine) <$> (text "~FILE" <> brackets (text e'))@@ -431,10 +455,10 @@   esT' <- prettyBlackBox esT   esF' <- prettyBlackBox esF   (displayT . renderCompact) <$>-    (text "~IF" <+> text b' <+> text "~THEN" PP.<$>-     text esT' PP.<$>-     text "~ELSE" PP.<$>-     text esF' PP.<$>+    (text "~IF" <+> text b' <+> text "~THEN" <>+     text esT' <>+     text "~ELSE" <>+     text esF' <>      text "~FI") prettyElem (And es) =   (displayT . renderCompact) <$>
src/CLaSH/Netlist/Types.hs view
@@ -96,6 +96,7 @@   | Signed   !Size -- ^ Signed integer of a specified size   | Unsigned !Size -- ^ Unsigned integer of a specified size   | Vector   !Size       !HWType -- ^ Vector type+  | RTree    !Size       !HWType -- ^ RTree type   | Sum      !Identifier [Identifier] -- ^ Sum type: Name and Constructor names   | Product  !Identifier [HWType] -- ^ Product type: Name and field types   | SP       !Identifier [(Identifier,[HWType])] -- ^ Sum-of-Product type: Name and Constructor names + field types@@ -127,7 +128,7 @@   --   -- * List of: (Maybe expression scrutinized expression is compared with,RHS of alternative)   | InstDecl !Identifier !Identifier [(Identifier,PortDirection,HWType,Expr)] -- ^ Instantiation of another component-  | BlackBoxD !S.Text !BlackBoxTemplate BlackBoxContext -- ^ Instantiation of blackbox declaration+  | BlackBoxD !S.Text [S.Text] [S.Text] (Maybe (S.Text,BlackBoxTemplate)) !BlackBoxTemplate BlackBoxContext -- ^ Instantiation of blackbox declaration   | NetDecl !Identifier !HWType -- ^ Signal declaration   deriving Show @@ -142,6 +143,7 @@   = Indexed (HWType,Int,Int) -- ^ Index the expression: (Type of expression,DataCon tag,Field Tag)   | DC (HWType,Int) -- ^ See expression in a DataCon context: (Type of the expression, DataCon tag)   | VecAppend -- ^ See the expression in the context of a Vector append operation+  | RTreeAppend -- ^ See the expression in the context of a Tree append operation   deriving Show  -- | Expression used in RHS of a declaration@@ -150,7 +152,7 @@   | DataCon    !HWType       !Modifier  [Expr] -- ^ DataCon application   | Identifier !Identifier   !(Maybe Modifier) -- ^ Signal reference   | DataTag    !HWType       !(Either Identifier Identifier) -- ^ @Left e@: tagToEnum#, @Right e@: dataToTag#-  | BlackBoxE !S.Text !BlackBoxTemplate !BlackBoxContext !Bool -- ^ Instantiation of a BlackBox expression+  | BlackBoxE !S.Text [S.Text] [S.Text] (Maybe (S.Text,BlackBoxTemplate)) !BlackBoxTemplate !BlackBoxContext !Bool -- ^ Instantiation of a BlackBox expression   deriving Show  -- | Literals used in an expression@@ -179,11 +181,12 @@   -- ^ Function arguments (subset of inputs):   --   -- * (Blackbox Template,Partial Blackbox Concext)+  , bbQsysIncName :: Maybe Identifier   }   deriving Show  emptyBBContext :: BlackBoxContext-emptyBBContext = Context (Left $ Identifier (pack "__EMPTY__") Nothing, Void) [] empty+emptyBBContext = Context (Left $ Identifier (pack "__EMPTY__") Nothing, Void) [] empty Nothing  -- | Either the name of the identifier, or a tuple of the identifier and the -- corresponding clock
src/CLaSH/Netlist/Util.hs view
@@ -15,6 +15,7 @@ import           Control.Lens            ((.=),(%=)) import qualified Control.Lens            as Lens import qualified Control.Monad           as Monad+import           Control.Monad.Trans.Except (runExcept) import           Data.Either             (partitionEithers) import           Data.HashMap.Strict     (HashMap) import qualified Data.HashMap.Strict     as HashMap@@ -33,7 +34,7 @@ import           CLaSH.Core.TyCon        (TyCon (..), TyConName, tyConDataCons) import           CLaSH.Core.Type         (Type (..), TypeView (..), LitTy (..),                                           coreView, splitTyConAppM, tyView)-import           CLaSH.Core.Util         (collectBndrs, termType)+import           CLaSH.Core.Util         (collectBndrs, termType, tyNatSize) import           CLaSH.Core.Var          (Id, Var (..), modifyVarName) import           CLaSH.Netlist.Types     as HW import           CLaSH.Util@@ -49,7 +50,7 @@ -- | 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 is the term was not in a normalized form.-splitNormalized :: (Fresh m, Functor m)+splitNormalized :: Fresh m                 => HashMap TyConName TyCon                 -> Term                 -> m (Either String ([Id],[LetBinding],Id))@@ -97,11 +98,13 @@   = case name2String tyCon of       "CLaSH.Sized.Vector.Vec"        -> synchronizedClk tcm (args!!1)       "CLaSH.Signal.Internal.SClock" -> case splitTyConAppM (head args) of-                                          Just (_,[LitTy (SymTy s),LitTy (NumTy i)]) -> Just (pack s,i)-                                          _ -> error $ $(curLoc) ++ "Clock period not a simple literal: " ++ showDoc ty+        Just (_,[LitTy (SymTy s),litTy])+          | Right i <- runExcept (tyNatSize tcm litTy) -> Just (pack s,i)+        _ -> error $ $(curLoc) ++ "Clock period not a simple literal: " ++ showDoc ty       "CLaSH.Signal.Internal.Signal'" -> case splitTyConAppM (head args) of-                                           Just (_,[LitTy (SymTy s),LitTy (NumTy i)]) -> Just (pack s,i)-                                           _ -> error $ $(curLoc) ++ "Clock period not a simple literal: " ++ showDoc ty+        Just (_,[LitTy (SymTy s),litTy])+          | Right i <- runExcept (tyNatSize tcm litTy) -> Just (pack s,i)+        _ -> error $ $(curLoc) ++ "Clock period not a simple literal: " ++ showDoc ty       _                               -> case tyConDataCons (tcm HashMap.! tyCon) of                                            [dc] -> let argTys   = dcArgTys dc                                                        argTVs   = dcUnivTyVars dc@@ -168,10 +171,28 @@ -- | Determines if a Core type is translatable to a HWType given a function that -- translates certain builtin types. representableType :: (HashMap TyConName TyCon -> Type -> Maybe (Either String HWType))+                  -> Bool -- ^ Allow zero-bit things                   -> HashMap TyConName TyCon                   -> Type                   -> Bool-representableType builtInTranslation m = either (const False) ((> 0) . typeSize) . coreTypeToHWType builtInTranslation m+representableType builtInTranslation allowZero m = either (const False) isRepresentable . coreTypeToHWType builtInTranslation m+  where+    isRepresentable hty = case hty of+      String          -> True+      Bool            -> True+      BitVector n     -> (n > 0) || allowZero+      Index n         -> (n > 0) || allowZero+      Signed n        -> (n > 0) || allowZero+      Unsigned  n     -> (n > 0) || allowZero+      Vector n elTy+        | n > 0 || allowZero -> isRepresentable elTy+      RTree _n elTy   -> isRepresentable elTy+      Sum {}          -> True+      Product _ elTys -> all isRepresentable elTys+      SP _ elTyss     -> all (all isRepresentable . snd) elTyss+      Clock {}        -> True+      Reset {}        -> True+      _               -> False  -- | Determines the bitsize of a type typeSize :: HWType@@ -188,6 +209,7 @@ typeSize (Signed i) = i typeSize (Unsigned i) = i typeSize (Vector n el) = n * typeSize el+typeSize (RTree d el) = (2^d) * typeSize el typeSize t@(SP _ cons) = conSize t +   maximum (map (sum . map typeSize . snd) cons) typeSize (Sum _ dcs) = max 1 (fromMaybe 0 . clogBase 2 . toInteger $ length dcs)
src/CLaSH/Normalize.hs view
@@ -84,6 +84,7 @@                   tcm                   tupTcm                   eval+                  (opt_allowZero opts)      rwState   = RewriteState                   0
src/CLaSH/Normalize/PrimitiveReductions.hs view
@@ -19,6 +19,8 @@     * CLaSH.Sized.Vector.unconcatBitVector#     * CLaSH.Sized.Vector.replicate     * CLaSH.Sized.Vector.imap+    * CLaSH.Sized.Vector.dtfold+    * CLaSH.Sized.RTree.tfold    Partially handles: @@ -35,23 +37,23 @@ import qualified Control.Lens                     as Lens import qualified Data.HashMap.Lazy                as HashMap import qualified Data.Maybe                       as Maybe-import           Data.Text                        (pack) import           Unbound.Generics.LocallyNameless (bind, embed, rec, rebind,-                                                   string2Name, name2String)+                                                   string2Name) -import           CLaSH.Core.DataCon               (DataCon, dataConInstArgTys,-                                                   dcName, dcType)+import           CLaSH.Core.DataCon               (DataCon, dataConInstArgTys) import           CLaSH.Core.Literal               (Literal (..)) import           CLaSH.Core.Pretty                (showDoc) import           CLaSH.Core.Term                  (Term (..), Pat (..)) import           CLaSH.Core.Type                  (LitTy (..), Type (..),                                                    TypeView (..), coreView,                                                    mkFunTy, mkTyConApp,-                                                   splitFunForallTy, tyView)+                                                   splitFunForallTy, tyView,+                                                   undefinedTy) import           CLaSH.Core.TyCon                 (TyConName, tyConDataCons) import           CLaSH.Core.TysPrim               (integerPrimTy, typeNatKind) import           CLaSH.Core.Util                  (appendToVec, extractElems,-                                                   idToVar, mkApps, mkVec,+                                                   extractTElems, idToVar,+                                                   mkApps, mkRTree, mkVec,                                                    termType) import           CLaSH.Core.Var                   (Var (..)) @@ -357,24 +359,14 @@       , [_,consCon]  <- tyConDataCons vecTc       = do         let  (vars,elems)     = second concat . unzip-                             $ extractElems consCon aTy 'D' n arg+                         $ extractElems consCon aTy 'D' n arg         (_ltv:Right snTy:_,_) <- splitFunForallTy <$> termType tcm fun         let (TyConApp snatTcNm _) = tyView snTy             (Just snatTc)         = HashMap.lookup snatTcNm tcm             [snatDc]              = tyConDataCons snatTc--            ([_nTv,_kn,Right pTy],_) = splitFunForallTy (dcType snatDc)-            (TyConApp proxyTcNm _)   = tyView pTy-            (Just proxyTc)           = HashMap.lookup proxyTcNm tcm-            [proxyDc]                = tyConDataCons proxyTc--            buildSNat i = mkApps (Prim (pack (name2String (dcName snatDc)))-                                       (dcType snatDc))+            buildSNat i = mkApps (Data snatDc)                                  [Right (LitTy (NumTy i))                                  ,Left (Literal (IntegerLiteral (toInteger i)))-                                 ,Left (mkApps (Data proxyDc)-                                               [Right typeNatKind-                                               ,Right (LitTy (NumTy i))])                                  ]             lbody = doFold buildSNat (n-1) vars             lb    = Letrec (bind (rec (init elems)) lbody)@@ -434,6 +426,58 @@         in  changed lb     go _ ty = error $ $(curLoc) ++ "reduceTail: argument does not have a vector type: " ++ showDoc ty +-- | 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 :: Integer  -- ^ Length of the vector+           -> Type -- ^ Element type of the vector+           -> Term -- ^ The argument vector+           -> NormalizeSession Term+reduceLast n aTy vArg = do+    tcm <- Lens.view tcCache+    ty  <- termType tcm vArg+    go tcm ty+  where+    go tcm (coreView tcm -> Just ty') = go tcm ty'+    go tcm (tyView -> TyConApp vecTcNm _)+      | (Just vecTc) <- HashMap.lookup vecTcNm tcm+      , [_,consCon]  <- tyConDataCons vecTc+      = let (_,elems)    = unzip+                         $ extractElems consCon aTy 'L' n vArg+            (tB,_)       = head (last elems)+        in case n of+            0 -> changed (mkApps (Prim "CLaSH.Transformations.undefined" undefinedTy) [Right aTy])+            _ -> changed (Letrec (bind (rec (init (concat elems))) (idToVar tB)))+    go _ ty = error $ $(curLoc) ++ "reduceLast: argument does not have a vector type: " ++ showDoc ty++-- | 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 :: Integer  -- ^ Length of the vector+           -> Type -- ^ Element type of the vector+           -> Term -- ^ The argument vector+           -> NormalizeSession Term+reduceInit n aTy vArg = do+    tcm <- Lens.view tcCache+    ty  <- termType tcm vArg+    go tcm ty+  where+    go tcm (coreView tcm -> Just ty') = go tcm ty'+    go tcm (tyView -> TyConApp vecTcNm _)+      | (Just vecTc) <- HashMap.lookup vecTcNm tcm+      , [nilCon,consCon]  <- tyConDataCons vecTc+      = let (_,elems)    = unzip+                         $ extractElems consCon aTy 'L' n vArg+        in case n of+            0 -> changed (mkApps (Prim "CLaSH.Transformations.undefined" undefinedTy) [Right aTy])+            1 -> changed (mkVec nilCon consCon aTy 0 [])+            _ -> let el = init elems+                     iv = mkVec nilCon consCon aTy (n-1) (map (idToVar . fst . head) el)+                     lb = rec (init (concat el))+                 in  changed (Letrec (bind lb iv))++    go _ ty = error $ $(curLoc) ++ "reduceInit: argument does not have a vector type: " ++ showDoc ty+ -- | 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.(++)@@@ -525,3 +569,110 @@       = let retVec = mkVec nilCon consCon aTy n (replicate (fromInteger n) arg)         in  changed retVec     go _ ty = error $ $(curLoc) ++ "reduceReplicate: argument does not have a vector type: " ++ showDoc ty++-- | 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 :: Integer  -- ^ Length of the vector+             -> Type     -- ^ Element type of the argument vector+             -> Term     -- ^ Function to convert elements with+             -> Term     -- ^ Function to combine branches with+             -> Term     -- ^ The vector to fold+             -> NormalizeSession Term+reduceDTFold n aTy lrFun brFun arg = do+    tcm <- Lens.view tcCache+    ty  <- termType tcm arg+    go tcm ty+  where+    go tcm (coreView tcm -> Just ty') = go tcm ty'+    go tcm (tyView -> TyConApp vecTcNm _)+      | (Just vecTc) <- HashMap.lookup vecTcNm tcm+      , [_,consCon]  <- tyConDataCons vecTc+      = do let (vars,elems) = second concat . unzip+                            $ extractElems consCon aTy 'T' (2^n) arg+           (_ltv:Right snTy:_,_) <- splitFunForallTy <$> termType tcm brFun+           let (TyConApp snatTcNm _) = tyView snTy+               (Just snatTc)         = HashMap.lookup snatTcNm tcm+               [snatDc]              = tyConDataCons snatTc+               buildSNat i = mkApps (Data snatDc)+                                    [Right (LitTy (NumTy i))+                                    ,Left (Literal (IntegerLiteral i))+                                    ]+               lbody = doFold buildSNat (n-1) vars+               lb    = Letrec (bind (rec (init elems)) lbody)+           changed lb+    go _ ty = error $ $(curLoc) ++ "reduceDTFold: argument does not have a vector type: " ++ showDoc ty++    doFold :: (Integer -> Term) -> Integer -> [Term] -> Term+    doFold _    _ [x] = mkApps lrFun [Left x]+    doFold snDc k xs  =+      let (xsL,xsR) = splitAt (2^k) xs+          k'        = k-1+          eL        = doFold snDc k' xsL+          eR        = doFold snDc k' xsR+      in  mkApps brFun [Right (LitTy (NumTy k))+                       ,Left  (snDc k)+                       ,Left  eL+                       ,Left  eR+                       ]++-- | 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 :: Integer -- ^ Depth of the tree+            -> Type    -- ^ Element type of the argument tree+            -> Term    -- ^ Function to convert elements with+            -> Term    -- ^ Function to combine branches with+            -> Term    -- ^ The tree to fold+            -> NormalizeSession Term+reduceTFold n aTy lrFun brFun arg = do+    tcm <- Lens.view tcCache+    ty  <- termType tcm arg+    go tcm ty+  where+    go tcm (coreView tcm -> Just ty') = go tcm ty'+    go tcm (tyView -> TyConApp treeTcNm _)+      | (Just treeTc) <- HashMap.lookup treeTcNm tcm+      , [lrCon,brCon] <- tyConDataCons treeTc+      = do let (vars,elems)     = extractTElems lrCon brCon aTy 'T' n arg+           (_ltv:Right snTy:_,_) <- splitFunForallTy <$> termType tcm brFun+           let (TyConApp snatTcNm _) = tyView snTy+               (Just snatTc)         = HashMap.lookup snatTcNm tcm+               [snatDc]              = tyConDataCons snatTc+               buildSNat i = mkApps (Data snatDc)+                                    [Right (LitTy (NumTy i))+                                    ,Left (Literal (IntegerLiteral i))+                                    ]+               lbody = doFold buildSNat (n-1) vars+               lb    = Letrec (bind (rec elems) lbody)+           changed lb+    go _ ty = error $ $(curLoc) ++ "reduceTFold: argument does not have a tree type: " ++ showDoc ty++    doFold _    _ [x] = mkApps lrFun [Left x]+    doFold snDc k xs  =+      let (xsL,xsR) = splitAt (length xs `div` 2) xs+          k'        = k-1+          eL        = doFold snDc k' xsL+          eR        = doFold snDc k' xsR+      in  mkApps brFun [Right (LitTy (NumTy k))+                       ,Left (snDc k)+                       ,Left eL+                       ,Left eR+                       ]++reduceTReplicate :: Integer -- ^ Depth of the tree+                 -> Type    -- ^ Element type+                 -> Type    -- ^ Result type+                 -> Term    -- ^ Element+                 -> NormalizeSession Term+reduceTReplicate n aTy eTy arg = do+    tcm <- Lens.view tcCache+    go tcm eTy+  where+    go tcm (coreView tcm -> Just ty') = go tcm ty'+    go tcm (tyView -> TyConApp treeTcNm _)+      | (Just treeTc) <- HashMap.lookup treeTcNm tcm+      , [lrCon,brCon] <- tyConDataCons treeTc+      = let retVec = mkRTree lrCon brCon aTy n (replicate (2^n) arg)+        in  changed retVec+    go _ ty = error $ $(curLoc) ++ "reduceTReplicate: argument does not have a vector type: " ++ showDoc ty
src/CLaSH/Normalize/Strategy.hs view
@@ -16,7 +16,7 @@  -- | Normalisation transformation normalization :: NormRewrite-normalization = constantPropgation >-> etaTL >-> rmUnusedExpr >-!-> anf >-!-> rmDeadcode >->+normalization = rmDeadcode >-> constantPropgation >-> etaTL >-> rmUnusedExpr >-!-> anf >-!-> rmDeadcode >->                 bindConst >-> letTL >-> evalConst >-!-> cse >-!-> recLetRec   where     etaTL      = apply "etaTL" etaExpansionTL !-> innerMost (apply "applicationPropagation" appProp)@@ -24,7 +24,7 @@     letTL      = topdownSucR (apply "topLet" topLet)     recLetRec  = apply "recToLetRec" recToLetRec     rmUnusedExpr = bottomupR (apply "removeUnusedExpr" removeUnusedExpr)-    rmDeadcode = topdownR (apply "deadcode" deadCode)+    rmDeadcode = bottomupR (apply "deadcode" deadCode)     bindConst  = topdownR (apply "bindConstantVar" bindConstantVar)     evalConst  = topdownR (apply "evalConst" reduceConst)     cse        = topdownR (apply "CSE" simpleCSE)
src/CLaSH/Normalize/Transformations.hs view
@@ -93,17 +93,38 @@     nonRepTest :: (Var Term, Embed Term) -> RewriteMonad extra Bool     nonRepTest ((Id _ tyE), _)       = not <$> (representableType <$> Lens.view typeTranslator+                                   <*> Lens.view allowZero                                    <*> Lens.view tcCache                                    <*> pure (unembed tyE))     nonRepTest _ = return False      inlineTest :: Term -> (Var Term, Embed Term) -> RewriteMonad extra Bool     inlineTest e (id_@(Id idName _), exprE)-      = not <$> ((||) <$> (elem idName <$> (Lens.toListOf <$> localFreeIds <*> pure (unembed exprE)))-                      <*> pure (isJoinPointIn id_ e))+      = let e' = unembed exprE+        in  not <$> ((||) <$> (elem idName <$> (Lens.toListOf <$> localFreeIds <*> pure e'))+                          -- See: [Note] join points and void wrappers+                          <*> pure (isJoinPointIn id_ e && not (isVoidWrapper e')))      inlineTest _ _ = return True +{- [Note] join points and void wrappers+Join points are functions that only occur in tail-call positions within an+expression, and only when they occur in a tail-call position more than once.++Normally bindNonRep binds/inlines all non-recursive local functions. However,+doing so for join points would significantly increase compilation time, so we+avoid it. The only exception to this rule are so-called void wrappers. Void+wrappers are functions of the form:++> \(w :: Void) -> f a b c++i.e. a wrapper around the function 'f' where the argument 'w' is not used. We+do bind/line these join-points because these void-wrappers interfere with the+'disjoint expression consolidation' (DEC) and 'common sub-expression elimination'+(CSE) transformation, sometimes resulting in circuits that are twice as big+as they'd need to be.+-}+ -- | Specialize functions on their type typeSpec :: NormRewrite typeSpec ctx e@(TyApp e1 ty)@@ -123,7 +144,7 @@   = do tcm <- Lens.view tcCache        e2Ty <- termType tcm e2        localVar <- isLocalVar e2-       nonRepE2 <- not <$> (representableType <$> Lens.view typeTranslator <*> Lens.view tcCache <*> pure e2Ty)+       nonRepE2 <- not <$> (representableType <$> Lens.view typeTranslator <*> Lens.view allowZero <*> Lens.view tcCache <*> pure e2Ty)        if nonRepE2 && not localVar          then specializeNorm ctx e          else return e@@ -142,7 +163,7 @@ caseCase :: NormRewrite caseCase _ e@(Case (Case scrut alts1Ty alts1) alts2Ty alts2)   = do-    ty1Rep  <- representableType <$> Lens.view typeTranslator <*> Lens.view tcCache <*> pure alts1Ty+    ty1Rep  <- representableType <$> Lens.view typeTranslator <*> Lens.view allowZero <*> Lens.view tcCache <*> pure alts1Ty     if not ty1Rep       then do newAlts <- mapM ( return                                   . uncurry bind@@ -182,14 +203,14 @@                      (return e)       else do         bodyMaybe   <- fmap (HashMap.lookup f) $ Lens.use bindings-        nonRepScrut <- not <$> (representableType <$> Lens.view typeTranslator <*> Lens.view tcCache <*> pure scrutTy)+        nonRepScrut <- not <$> (representableType <$> Lens.view typeTranslator <*> Lens.view allowZero <*> Lens.view tcCache <*> pure scrutTy)         case (nonRepScrut, bodyMaybe) of           (True,Just (_,_,scrutBody)) -> do             Monad.when noException (zoomExtra (addNewInline f cf))             changed $ Case (mkApps scrutBody args) altsTy alts           _ -> return e   where-    exception tcm ((tyView . typeKind tcm) -> TyConApp (name2String -> "GHC.Prim.Constraint") _) = True+    exception tcm ((tyView . typeKind tcm) -> TyConApp (name2String -> "GHC.Types.Constraint") _) = True     exception _ _ = False  inlineNonRep _ e = return e@@ -216,7 +237,7 @@         in  changed (substTysinTm substTyMap e')       _ -> case alts' of              ((DefaultPat,e):_) -> changed e-             _ -> changed (mkApps (Prim "GHC.Err.undefined" undefinedTy) [Right ty])+             _ -> changed (mkApps (Prim "CLaSH.Transformations.undefined" undefinedTy) [Right ty])   where     equalCon dc (DataPat dc' _) = dcTag dc == dcTag (unembed dc')     equalCon _  _               = False@@ -242,17 +263,16 @@       Literal l -> caseCon ctx (Case (Literal l) ty alts)       subj' -> case collectArgs subj' of         (Data _,_) -> caseCon ctx (Case subj' ty alts)-        (Prim nm ty',[_,msg])-          | nm == "Control.Exception.Base.patError" ->-            let e' = mkApps (Prim nm ty') [Right ty,msg]-            in  changed e'-          | nm == "Control.Exception.Base.absentError" ->-            let e' = mkApps (Prim nm ty') [Right ty,msg]+        (Prim nm ty',repTy:_:msgOrCallStack:_)+          | nm `elem` ["Control.Exception.Base.patError"+                      ,"Control.Exception.Base.absentError"+                      ,"GHC.Err.undefined"] ->+            let e' = mkApps (Prim nm ty') [repTy,Right ty,msgOrCallStack]             in  changed e'         (Prim nm ty',[_])-          | nm == "GHC.Err.undefined" ->+          | nm `elem` ["CLaSH.Transformations.undefined"] ->             let e' = mkApps (Prim nm ty') [Right ty]-            in  changed e'+            in changed e'         _ -> traceIf (lvl > DebugNone)                      ("Irreducible constant as case subject: " ++ showDoc subj ++ "\nCan be reduced to: " ++ showDoc subj')                      (caseOneAlt e)@@ -335,7 +355,9 @@                                ) xes         xesUsed' = findUsedBndrs [] xesUsed xesOther     if length xesUsed' /= length xes-      then changed . Letrec $ bind (rec xesUsed') body+      then case xesUsed' of+              [] -> changed body+              _  -> changed . Letrec $ bind (rec xesUsed') body       else return e   where     findUsedBndrs :: [(Var Term, Embed Term)] -> [(Var Term, Embed Term)]@@ -356,14 +378,15 @@ removeUnusedExpr _ e@(collectArgs -> (p@(Prim nm _),args)) = do   bbM <- HashMap.lookup nm <$> Lens.use (extra.primitives)   case bbM of-    Just (BlackBox pNm templ) -> do+    Just (BlackBox pNm _ _ inc templ) -> do       let usedArgs = if pNm `elem` ["CLaSH.Sized.Internal.Signed.fromInteger#"                                    ,"CLaSH.Sized.Internal.Unsigned.fromInteger#"                                    ,"CLaSH.Sized.Internal.BitVector.fromInteger#"                                    ,"CLaSH.Sized.Internal.Index.fromInteger#"                                    ]                         then [0,1]-                        else either usedArguments usedArguments templ+                        else either usedArguments usedArguments templ +++                             maybe [] (usedArguments . snd) inc       tcm <- Lens.view tcCache       args' <- go tcm 0 usedArgs args       if args == args'@@ -906,8 +929,8 @@     tcm <- Lens.view tcCache     reduceConstant <- Lens.view evaluator     case reduceConstant tcm False e of-      e'@(Data _)    -> changed e'       e'@(Literal _) -> changed e'+      e'@(collectArgs -> (Data _,_)) -> changed e'       _              -> return e  reduceConst _ e = return e@@ -946,6 +969,7 @@ -- * CLaSH.Sized.Vector.unconcat -- * CLaSH.Sized.Vector.transpose -- * CLaSH.Sized.Vector.replicate+-- * CLaSH.Sized.Vector.dtfold reduceNonRepPrim :: NormRewrite reduceNonRepPrim _ e@(App _ _) | (Prim f _, args) <- collectArgs e = do   tcm <- Lens.view tcCache@@ -957,7 +981,7 @@           [nilCon,consCon] = tyConDataCons vecTc           nilE = mkVec nilCon consCon aTy 0 []       changed nilE-    _ -> case f of+    tv -> case f of       "CLaSH.Sized.Vector.zipWith" | length args == 7 -> do         let [lhsElTy,rhsElty,resElTy,nTy] = Either.rights args         case runExcept (tyNatSize tcm nTy) of@@ -1042,6 +1066,26 @@                then reduceTail n aTy vArg                else return e           _ -> return e+      "CLaSH.Sized.Vector.last" | length args == 3 -> do+        let [nTy,aTy] = Either.rights args+            [vArg]    = Either.lefts args+        case runExcept (tyNatSize tcm nTy) of+          Right n -> do+            untranslatableTy <- isUntranslatableType_not_poly aTy+            if untranslatableTy+               then reduceLast n aTy vArg+               else return e+          _ -> return e+      "CLaSH.Sized.Vector.init" | length args == 3 -> do+        let [nTy,aTy] = Either.rights args+            [vArg]    = Either.lefts args+        case runExcept (tyNatSize tcm nTy) of+          Right n -> do+            untranslatableTy <- isUntranslatableType_not_poly aTy+            if untranslatableTy+               then reduceInit n aTy vArg+               else return e+          _ -> return e       "CLaSH.Sized.Vector.unconcat" | length args == 6 -> do         let ([_knN,_sm,arg],[mTy,nTy,aTy]) = Either.partitionEithers args         case (runExcept (tyNatSize tcm nTy), runExcept (tyNatSize tcm mTy)) of@@ -1071,7 +1115,59 @@                     in  reduceImap n argElTy resElTy fun arg                else return e           _ -> return e+      "CLaSH.Sized.Vector.dtfold" | length args == 8 ->+        let ([_kn,_motive,lrFun,brFun,arg],[_mTy,nTy,aTy]) = Either.partitionEithers args+        in  case runExcept (tyNatSize tcm nTy) of+          Right n -> reduceDTFold n aTy lrFun brFun arg+          _ -> return e+      "CLaSH.Sized.RTree.tdfold" | length args == 8 ->+        let ([_kn,_motive,lrFun,brFun,arg],[_mTy,nTy,aTy]) = Either.partitionEithers args+        in  case runExcept (tyNatSize tcm nTy) of+          Right n -> reduceTFold n aTy lrFun brFun arg+          _ -> return e+      "CLaSH.Sized.RTree.treplicate" | length args == 4 -> do+        let ([_sArg,vArg],[nTy,aTy]) = Either.partitionEithers args+        case runExcept (tyNatSize tcm nTy) of+          Right n -> do+            untranslatableTy <- isUntranslatableType aTy+            if untranslatableTy+               then reduceReplicate n aTy eTy vArg+               else return e+          _ -> return e+      "CLaSH.Sized.Internal.BitVector.split#" | length args == 4 -> do+        let ([_knArg,bvArg],[nTy,mTy]) = Either.partitionEithers args+        case (runExcept (tyNatSize tcm nTy), runExcept (tyNatSize tcm mTy), tv) of+          (Right n, Right m, TyConApp tupTcNm [lTy,rTy])+            | n == 0 -> do+              let (Just tupTc) = HashMap.lookup tupTcNm tcm+                  [tupDc]      = tyConDataCons tupTc+                  tup          = mkApps (Data tupDc)+                                    [Right lTy+                                    ,Right rTy+                                    ,Left  bvArg+                                    ,Left  (Prim "CLaSH.Transformations.removedArg" lTy)+                                    ] +              changed tup+            | m == 0 -> do+              let (Just tupTc) = HashMap.lookup tupTcNm tcm+                  [tupDc]      = tyConDataCons tupTc+                  tup          = mkApps (Data tupDc)+                                    [Right lTy+                                    ,Right rTy+                                    ,Left  (Prim "CLaSH.Transformations.removedArg" lTy)+                                    ,Left  bvArg+                                    ]++              changed tup+          _ -> return e+      "CLaSH.Sized.Internal.BitVector.eq#"+        | ([_,_],[nTy]) <- Either.partitionEithers args+        , Right 0 <- runExcept (tyNatSize tcm nTy)+        , TyConApp boolTcNm [] <- tv+        -> let (Just boolTc) = HashMap.lookup boolTcNm tcm+               [_falseDc,trueDc] = tyConDataCons boolTc+           in  changed (Data trueDc)       _ -> return e   where     isUntranslatableType_not_poly t = do
src/CLaSH/Normalize/Util.hs view
@@ -61,7 +61,7 @@ specializeNorm = specialise specialisationCache specialisationHistory specialisationLimit  -- | Determine if a term is closed-isClosed :: (Functor m, Fresh m)+isClosed :: Fresh m          => HashMap TyConName TyCon          -> Term          -> m Bool
src/CLaSH/Primitives/Types.hs view
@@ -13,7 +13,7 @@ module CLaSH.Primitives.Types where  import           Control.Applicative  ((<|>))-import           Data.Aeson           (FromJSON (..), Value (..), (.:))+import           Data.Aeson           (FromJSON (..), Value (..), (.:), (.:?), (.!=)) import           Data.HashMap.Lazy    (HashMap) import qualified Data.HashMap.Strict  as H import qualified Data.Text            as S@@ -27,6 +27,9 @@   -- | A primitive that has a template that can be filled out by the backend render   = BlackBox   { name     :: !S.Text -- ^ Name of the primitive+  , library  :: [S.Text]+  , imports  :: [S.Text]+  , qsysInclude :: Maybe (S.Text,a)   , template :: !(Either a a) -- ^ Either a /declaration/ or an /expression/ template.   }   -- | A primitive that carries additional information@@ -39,8 +42,16 @@ instance FromJSON (Primitive Text) where   parseJSON (Object v) = case H.toList v of     [(conKey,Object conVal)] -> case conKey of-      "BlackBox"  -> BlackBox <$> conVal .: "name" <*> ((Left <$> conVal .: "templateD") <|> (Right <$> conVal .: "templateE"))+      "BlackBox"  -> BlackBox <$> conVal .: "name"+                              <*> conVal .:? "libraries" .!= []+                              <*> conVal .:? "imports" .!= []+                              <*> (conVal .:? "qsysInclude" >>= parseInclude)+                              <*> ((Left <$> conVal .: "templateD") <|> (Right <$> conVal .: "templateE"))       "Primitive" -> Primitive <$> conVal .: "name" <*> conVal .: "primType"       _ -> error "Expected: BlackBox or Primitive object"     _ -> error "Expected: BlackBox or Primitive object"+    where+      parseInclude Nothing  = pure Nothing+      parseInclude (Just c) =+        Just <$> ((,) <$> c .: "name" <*> c .: "content")   parseJSON _ = error "Expected: BlackBox or Primitive object"
src/CLaSH/Rewrite/Combinators.hs view
@@ -24,7 +24,7 @@ import           CLaSH.Rewrite.Types  -- | Apply a transformation on the subtrees of an term-allR :: forall m . (Functor m, Monad m, Fresh m)+allR :: forall m . (Monad m, Fresh m)      => Bool -- ^ Freshen variable references in abstracted terms      -> Transform m -- ^ The transformation to apply to the subtrees      -> Transform m@@ -78,32 +78,32 @@  infixr 6 >-> -- | Apply two transformations in succession-(>->) :: (Monad m) => Transform m -> Transform m -> Transform m+(>->) :: Monad m => Transform m -> Transform m -> Transform m (>->) r1 r2 c = r1 c >=> r2 c  infixr 6 >-!-> -- | Apply two transformations in succession, and perform a deepseq in between.-(>-!->) :: (Monad m) => Transform m -> Transform m -> Transform m+(>-!->) :: Monad m => Transform m -> Transform m -> Transform m (>-!->) r1 r2 c e = do   e' <- r1 c e   deepseq e' (r2 c e')  -- | Apply a transformation in a topdown traversal-topdownR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m+topdownR :: Fresh m => Transform m -> Transform m topdownR r = r >-> allR True (topdownR r)  -- | Apply a transformation in a topdown traversal. Doesn't freshen bound -- variables-unsafeTopdownR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m+unsafeTopdownR :: Fresh m => Transform m -> Transform m unsafeTopdownR r = r >-> allR False (unsafeTopdownR r)  -- | Apply a transformation in a bottomup traversal-bottomupR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m+bottomupR :: Fresh m => Transform m -> Transform m bottomupR r = allR True (bottomupR r) >-> r  -- | Apply a transformation in a bottomup traversal. Doesn't freshen bound -- variables-unsafeBottomupR :: (Fresh m, Functor m, Monad m) => Transform m -> Transform m+unsafeBottomupR :: Fresh m => Transform m -> Transform m unsafeBottomupR r = allR False (unsafeBottomupR r) >-> r  infixr 5 !->@@ -139,7 +139,7 @@     else return expr  -- | Only traverse downwards when the assertion evaluates to true-bottomupWhenR :: (Monad m, Fresh m, Functor m)+bottomupWhenR :: Fresh m               => ([CoreContext] -> Term -> m Bool)               -> Transform m               -> Transform m
src/CLaSH/Rewrite/Types.hs view
@@ -92,6 +92,8 @@   -- ^ Tuple TyCon cache   , _evaluator      :: HashMap TyConName TyCon -> Bool -> Term -> Term   -- ^ Hardcoded evaluator (delta-reduction)}+  , _allowZero      :: Bool+  -- ^ Zero bit wide things are representable   }  makeLenses ''RewriteEnv
src/CLaSH/Rewrite/Util.hs view
@@ -198,7 +198,7 @@   return (gamma',delta)  -- | Make a new binder and variable reference for a term-mkTmBinderFor :: (Functor m, Fresh m, MonadUnique m)+mkTmBinderFor :: (Fresh m, MonadUnique m)               => HashMap TyConName TyCon -- ^ TyCon cache               -> String -- ^ Name of the new binder               -> Term -- ^ Term to bind@@ -208,7 +208,7 @@   return r  -- | Make a new binder and variable reference for either a term or a type-mkBinderFor :: (Functor m, Monad m, MonadUnique m, Fresh m)+mkBinderFor :: (Monad m, MonadUnique m, Fresh m)             => HashMap TyConName TyCon -- ^ TyCon cache             -> String -- ^ Name of the new binder             -> Either Term Type -- ^ Type or Term to bind@@ -222,7 +222,7 @@   return $ Right (TyVar name' (embed kind), VarTy kind name')  -- | Make a new, unique, identifier and corresponding variable reference-mkInternalVar :: (Functor m, Monad m, MonadUnique m)+mkInternalVar :: (Monad m, MonadUnique m)               => String -- ^ Name of the identifier               -> KindOrType               -> m (Id,Term)@@ -299,6 +299,18 @@           _ -> Nothing   _ -> Just 0 +-- | 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+isVoidWrapper (Lam b) = case unsafeUnbind b of+  (bndr,e@(collectArgs -> (Var _ _,_))) -> varName bndr `notElem` Lens.toListOf termFreeIds e+  _ -> False+isVoidWrapper _ = False+ -- | Substitute the RHS of the first set of Let-binders for references to the -- first set of Let-binders in: the second set of Let-binders and the additional -- term@@ -459,6 +471,7 @@ isUntranslatable tm = do   tcm <- Lens.view tcCache   not <$> (representableType <$> Lens.view typeTranslator+                             <*> Lens.view allowZero                              <*> pure tcm                              <*> termType tcm tm) @@ -468,6 +481,7 @@                      -> RewriteMonad extra Bool isUntranslatableType ty =   not <$> (representableType <$> Lens.view typeTranslator+                             <*> Lens.view allowZero                              <*> Lens.view tcCache                              <*> pure ty) @@ -478,7 +492,7 @@ isLambdaBodyCtx _           = False  -- | Make a binder that should not be referenced-mkWildValBinder :: (Functor m, Monad m, MonadUnique m)+mkWildValBinder :: (Monad m, MonadUnique m)                 => Type                 -> m Id mkWildValBinder = fmap fst . mkInternalVar "wild"
src/CLaSH/Util.hs view
@@ -225,12 +225,19 @@ clashLibVersion = error "development version" #endif +-- | \x y -> floor (logBase x y), x > 1 && y > 0+flogBase :: Integer -> Integer -> Maybe Int+flogBase x y | x > 1 && y > 0 = Just (I# (integerLogBase# x y))+flogBase _ _ = Nothing+ -- | \x y -> ceiling (logBase x y), x > 1 && y > 0 clogBase :: Integer -> Integer -> Maybe Int clogBase x y | x > 1 && y > 0 =-  let z1 = integerLogBase# x y-      z2 = integerLogBase# x (y-1)-  in  if (isTrue# (z1 ==# z2))-         then Just (I# (z1 +# 1#))-         else Just (I# z1)+  case y of+    1 -> Just 0+    _ -> let z1 = integerLogBase# x y+             z2 = integerLogBase# x (y-1)+         in  if isTrue# (z1 ==# z2)+                then Just (I# (z1 +# 1#))+                else Just (I# z1) clogBase _ _ = Nothing
src/GHC/Extra.hs view
@@ -4,12 +4,15 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} +{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-orphans #-}  module GHC.Extra where +#if !(MIN_VERSION_GLASGOW_HASKELL(8,0,1,20161117)) import Control.DeepSeq import SrcLoc (SrcSpan)  instance NFData SrcSpan where   rnf x = x `seq` ()+#endif