hardware-edsl 0.1.2 → 0.1.5
raw patch · 13 files changed
+1115/−418 lines, 13 files
Files
- hardware-edsl.cabal +2/−2
- src/Language/Embedded/Hardware/Command.hs +35/−20
- src/Language/Embedded/Hardware/Command/Backend/VHDL.hs +48/−69
- src/Language/Embedded/Hardware/Command/CMD.hs +5/−5
- src/Language/Embedded/Hardware/Command/Frontend.hs +34/−13
- src/Language/Embedded/Hardware/Expression.hs +1/−4
- src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs +16/−10
- src/Language/Embedded/Hardware/Expression/Frontend.hs +49/−47
- src/Language/Embedded/Hardware/Expression/Represent.hs +165/−134
- src/Language/Embedded/Hardware/Expression/Represent/Bit.hs +26/−80
- src/Language/Embedded/Hardware/Expression/Syntax.hs +86/−33
- src/Language/Embedded/Hardware/Interface/AXI.hs +644/−0
- src/Language/Embedded/VHDL/Monad/Type.hs +4/−1
hardware-edsl.cabal view
@@ -1,5 +1,5 @@ name: hardware-edsl-version: 0.1.2+version: 0.1.5 synopsis: Deep embedding of hardware descriptions with code generation. description: Deep embedding of hardware descriptions with code generation. license: BSD3@@ -28,6 +28,7 @@ Language.Embedded.Hardware.Expression.Represent.Bit, Language.Embedded.Hardware.Expression.Syntax, Language.Embedded.Hardware.Interface,+ Language.Embedded.Hardware.Interface.AXI Language.Embedded.Hardware.Command, Language.Embedded.Hardware.Command.Backend.VHDL, Language.Embedded.Hardware.Command.CMD,@@ -37,7 +38,6 @@ Language.Embedded.VHDL.Monad.Type, Language.Embedded.VHDL.Monad.Expression Language.Embedded.VHDL.Monad.Util--- Language.Embedded.Hardware.Common.AXI --other-modules:
src/Language/Embedded/Hardware/Command.hs view
@@ -4,17 +4,22 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE GADTs #-}+ module Language.Embedded.Hardware.Command- ( compile+ (+ -- Regular hardware compilers.+ compile , icompile , runIO-+ -- AXI compilers.+ , compileAXILite+ , icompileAXILite+ -- compilers that wraps a program in a dummy entity. , compileWrap , icompileWrap- , runIOWrap-+ , VHDL.Mode(..)- , module CMD , module Language.Embedded.Hardware.Command.CMD , module Language.Embedded.Hardware.Command.Frontend@@ -26,6 +31,7 @@ import Language.Embedded.Hardware.Command.Frontend import Language.Embedded.Hardware.Command.Backend.VHDL import Language.Embedded.Hardware.Interface+import Language.Embedded.Hardware.Interface.AXI import Language.Embedded.VHDL (VHDL, prettyVHDL) @@ -34,6 +40,8 @@ import Control.Monad.Operational.Higher +import Control.Monad.Identity+ import qualified GHC.Exts as GHC (Constraint) --------------------------------------------------------------------------------@@ -69,7 +77,29 @@ runIO = interpretBi (return . evalE) --------------------------------------------------------------------------------+-- Some extra compilers that might be handy to have. +compileAXILite :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .+ ( Interp instr VHDL (Param2 exp pred)+ , HFunctor instr+ , AXIPred instr exp pred+ )+ => Comp instr exp pred Identity a+ -> String+compileAXILite = compile . void . component . axi_light ++icompileAXILite :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .+ ( Interp instr VHDL (Param2 exp pred)+ , HFunctor instr+ , AXIPred instr exp pred+ )+ => Comp instr exp pred Identity a+ -> IO ()+icompileAXILite = putStrLn . compileAXILite++--------------------------------------------------------------------------------+-- todo: Not sure we need these any more.+ compileWrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a . ( Interp instr VHDL (Param2 exp pred) , HFunctor instr@@ -93,21 +123,6 @@ => (Signal Bool -> Signal Bool -> Program instr (Param2 exp pred) ()) -> IO () icompileWrap = icompile . wrap--runIOWrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a- . ( InterpBi instr IO (Param1 pred)- , HBifunctor instr- , EvaluateExp exp- , ComponentCMD :<: instr- , StructuralCMD :<: instr- , SignalCMD :<: instr- , pred Bool- )- => (Signal Bool -> Signal Bool -> Program instr (Param2 exp pred) ())- -> IO ()-runIOWrap = runIO . wrap---------------------------------------------------------------------------------- -- | Wrap a hardware program in a architecture/entity pair. wrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .
src/Language/Embedded/Hardware/Command/Backend/VHDL.hs view
@@ -37,42 +37,33 @@ -- * Translation of hardware commands into VHDL. -------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ ** ...--evalEM :: forall exp a . EvaluateExp exp => Maybe (exp a) -> a-evalEM e = maybe (error "empty value") id $ fmap evalE e--compEM :: forall exp a . CompileExp exp => Maybe (exp a) -> VHDL (Maybe V.Expression)-compEM e = maybe (return Nothing) (>>= return . Just) $ fmap compE e------------------------------------------------------------------------------------- ** ...- class CompileType ct where compileType :: ct a => proxy1 ct -> proxy2 a -> VHDL V.Type compileLit :: ct a => proxy1 ct -> a -> VHDL V.Expression compileBits :: ct a => proxy1 ct -> a -> VHDL V.Expression -instance CompileType HType+instance CompileType PrimType where compileType _ = compT- compileLit _ = return . literal . printVal- compileBits _ = return . literal . printBits+ compileLit _ = return . literal . primTypeVal+ compileBits _ = return . literal . primTypeBits -------------------------------------------------------------------------------- -compT :: HType a => proxy a -> VHDL V.Type-compT = declare+compT :: forall proxy a . PrimType a => proxy a -> VHDL V.Type+compT _ = declareType (Proxy :: Proxy a) -compTM :: forall proxy ct exp a . (CompileType ct, ct a) => proxy ct -> Maybe (exp a) -> VHDL V.Type+compTM :: forall proxy ct exp a . (CompileType ct, ct a)+ => proxy ct -> Maybe (exp a) -> VHDL V.Type compTM _ _ = compileType (Proxy::Proxy ct) (Proxy::Proxy a) -compTF :: forall proxy ct exp a b . (CompileType ct, ct a) => proxy ct -> (exp a -> b) -> VHDL V.Type+compTF :: forall proxy ct exp a b . (CompileType ct, ct a)+ => proxy ct -> (exp a -> b) -> VHDL V.Type compTF _ _ = compileType (Proxy::Proxy ct) (Proxy::Proxy a) -compTA :: forall proxy ct array i a . (CompileType ct, ct a) => proxy ct -> V.Range -> array a -> VHDL V.Type+compTA :: forall proxy ct array i a . (CompileType ct, ct a)+ => proxy ct -> V.Range -> array a -> VHDL V.Type compTA _ range _ = do i <- newSym (Base "array") t <- compileType (Proxy::Proxy ct) (Proxy::Proxy a)@@ -92,6 +83,16 @@ -------------------------------------------------------------------------------- +evalEM :: forall exp a . EvaluateExp exp+ => Maybe (exp a) -> a+evalEM e = maybe (error "empty value") id $ fmap evalE e++compEM :: forall exp a . CompileExp exp+ => Maybe (exp a) -> VHDL (Maybe V.Expression)+compEM e = maybe (return Nothing) (>>= return . Just) $ fmap compE e++--------------------------------------------------------------------------------+ proxyE :: exp a -> Proxy a proxyE _ = Proxy @@ -102,12 +103,7 @@ proxyF _ = Proxy ----------------------------------------------------------------------------------- ** ... -newSym :: Name -> VHDL String-newSym (Base n) = V.newSym n-newSym (Exact n) = return n- freshVar :: forall proxy ct exp a . (CompileType ct, ct a) => proxy ct -> Name -> VHDL (Val a) freshVar _ prefix =@@ -116,8 +112,26 @@ V.variable (ident' i) t Nothing return (ValC i) +newSym :: Name -> VHDL String+newSym (Base n) = V.newSym n+newSym (Exact n) = return n++ident :: ToIdent a => a -> String+ident a = let (Ident s) = toIdent a in s++ident' :: ToIdent a => a -> V.Identifier+ident' a = V.Ident $ ident a++-- todo: this... why does this work?+instance ToIdent String where toIdent = Ident+instance ToIdent Ident where toIdent = id+instance ToIdent Name where+ toIdent (Base s) = Ident s+ toIdent (Exact s) = Ident s+ -------------------------------------------------------------------------------- -- ** Signals.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp SignalCMD VHDL (Param2 exp ct) where@@ -160,6 +174,7 @@ -------------------------------------------------------------------------------- -- ** Variables.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp VariableCMD VHDL (Param2 exp ct) where@@ -200,6 +215,7 @@ -------------------------------------------------------------------------------- -- ** Constants.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp ConstantCMD VHDL (Param2 exp ct) where@@ -225,6 +241,7 @@ -------------------------------------------------------------------------------- -- ** Arrays.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp ArrayCMD VHDL (Param2 exp ct) where@@ -278,6 +295,7 @@ -------------------------------------------------------------------------------- -- ** Virtual Arrays.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp VArrayCMD VHDL (Param2 exp ct) where@@ -361,6 +379,7 @@ -------------------------------------------------------------------------------- -- ** Loops.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp LoopCMD VHDL (Param2 exp ct) where@@ -402,6 +421,7 @@ -------------------------------------------------------------------------------- -- ** Conditional.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp ConditionalCMD VHDL (Param2 exp ct) where@@ -456,6 +476,7 @@ -------------------------------------------------------------------------------- -- ** Components.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp ComponentCMD VHDL (Param2 exp ct) where@@ -524,6 +545,7 @@ -------------------------------------------------------------------------------- -- ** Structural.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp StructuralCMD VHDL (Param2 exp ct) where@@ -552,6 +574,7 @@ -------------------------------------------------------------------------------- -- ** VHDL.+-------------------------------------------------------------------------------- instance (CompileExp exp, CompileType ct) => Interp VHDLCMD VHDL (Param2 exp ct) where@@ -616,26 +639,7 @@ runVHDL = error "hardware-edsl.runVHDL: todo." ----------------------------------------------------------------------------------- Helpers.------ todo : make a lift that first tries to go backwards. If that's not possible,--- perform a regular lift. This should get rid of most extra parenthesis. -ident :: ToIdent a => a -> String-ident a = let (Ident s) = toIdent a in s--ident' :: ToIdent a => a -> V.Identifier-ident' a = V.Ident $ ident a---- todo: this... why does this work?-instance ToIdent String where toIdent = Ident-instance ToIdent Ident where toIdent = id-instance ToIdent Name where- toIdent (Base s) = Ident s- toIdent (Exact s) = Ident s----------------------------------------------------------------------------------- simple :: String -> V.Name simple s = V.simple s @@ -654,13 +658,9 @@ slice' :: String -> V.Range -> V.Expression slice' s = lift . V.name . slice s ---------------------------------------------------------------------------------- literal :: String -> V.Expression literal s = lift $ V.literal $ V.number s ---------------------------------------------------------------------------------- range :: V.Expression -> V.Direction -> V.Expression -> V.Range range l dir r = V.range (unpackSimple l) dir (unpackSimple r) @@ -671,7 +671,6 @@ rangePoint a = V.range (V.point $ toInteger a) V.downto (V.point 0) ----------------------------------------------------------------------------------- ... unpackShift :: V.Expression -> V.ShiftExpression unpackShift (V.ENand (V.Relation s Nothing) Nothing) = s@@ -685,24 +684,4 @@ unpackTerm (V.ENand (V.Relation (V.ShiftExpression (V.SimpleExpression Nothing t []) Nothing) Nothing) Nothing) = t unpackTerm e = lift e ---------------------------------------------------------------------------------------------------------------------------------------------------------------------{--ident :: String -> V.Identifier-ident s = V.Ident s--ident' :: Name -> V.Identifier-ident' (Base n) = ident n-ident' (Exact n) = ident n--name :: String -> V.Primary-name = V.PrimName . V.NSimple . ident--}----------------------------------------------------------------------------------{--fromIdent :: ToIdent a => a -> V.Identifier-fromIdent a = let (Ident i) = toIdent a in ident i--} --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Command/CMD.hs view
@@ -15,7 +15,7 @@ import Language.Embedded.VHDL (Mode) import Language.Embedded.Hardware.Interface-import Language.Embedded.Hardware.Expression.Represent (Inhabited, Sized)+import Language.Embedded.Hardware.Expression.Represent (PrimType, Inhabited, Sized) import Language.Embedded.Hardware.Expression.Represent.Bit (Bit, Bits) import Control.Monad.Reader (ReaderT(..), runReaderT, lift)@@ -411,11 +411,11 @@ data Signature fs a where Ret :: prog () -> Signature (Param3 prog exp pred) ()- SSig :: (pred a, Inhabited a, Sized a)+ SSig :: (pred a, Integral a, PrimType a) => Name -> Mode -> (Signal a -> Signature (Param3 prog exp pred) b) -> Signature (Param3 prog exp pred) (Signal a -> b)- SArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i)+ SArr :: (pred a, Integral a, PrimType a, pred i, Integral i, Ix i) => Name -> Mode -> i -> (Array i a -> Signature (Param3 prog exp pred) b) -> Signature (Param3 prog exp pred) (Array i a -> b)@@ -443,11 +443,11 @@ data Argument pred a where Nil :: Argument pred ()- ASig :: (pred a, Inhabited a, Sized a)+ ASig :: (pred a, Integral a, PrimType a) => Signal a -> Argument pred b -> Argument pred (Signal a -> b)- AArr :: (pred a, Inhabited a, Sized a, Integral i, Ix i)+ AArr :: (pred a, Integral a, PrimType a, pred i, Integral i, Ix i) => Array i a -> Argument pred b -> Argument pred (Array i a -> b)
src/Language/Embedded/Hardware/Command/Frontend.hs view
@@ -20,6 +20,7 @@ import Data.IORef (readIORef) import Data.Int import Data.Word+import Data.Typeable import System.IO.Unsafe -- used for `veryUnsafeFreezeVariable`. @@ -401,43 +402,63 @@ -------------------------------------------------------------------------------- -exactInput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+exactInput :: (pred a, Integral a, PrimType a)+ => String+ -> (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) exactInput n = SSig (Exact n) In -namedInput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+namedInput :: (pred a, Integral a, PrimType a)+ => String+ -> (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) namedInput n = SSig (Base n) In -input :: (pred a, Inhabited a, Sized a) => (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+input :: (pred a, Integral a, PrimType a)+ => (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) input = namedInput "in" -exactInputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+{-+exactInputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) exactInputArr n l = SArr (Exact n) In l -namedInputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+namedInputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) namedInputArr n l = SArr (Base n) In l -inputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+inputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) inputArr = namedInputArr "in"+-} -exactOutput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+exactOutput :: (pred a, Integral a, PrimType a)+ => String+ -> (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) exactOutput n = SSig (Exact n) Out -namedOutput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+namedOutput :: (pred a, Integral a, PrimType a)+ => String+ -> (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) namedOutput n = SSig (Base n) Out -output :: (pred a, Inhabited a, Sized a) => (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)+output :: (pred a, Integral a, PrimType a)+ => (Signal a -> Sig instr exp pred m b)+ -> Sig instr exp pred m (Signal a -> b) output = namedOutput "out" -exactOutputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+{-+exactOutputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) exactOutputArr n l = SArr (Exact n) Out l -namedOutputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+namedOutputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) namedOutputArr n l = SArr (Base n) Out l -outputArr :: (pred a, Inhabited a, pred i, Sized a, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)+outputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b) outputArr = namedOutputArr "out"+-} -ret :: (ProgramT instr (Param2 exp pred) m) () -> Signature (Param3 (ProgramT instr (Param2 exp pred) m) exp pred) ()+ret :: ProgramT instr (Param2 exp pred) m () -> Sig instr exp pred m () ret = Ret --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Expression.hs view
@@ -2,11 +2,8 @@ ( HExp , HType , module Language.Embedded.Hardware.Expression.Frontend- , module Language.Embedded.Hardware.Expression.Represent.Bit ) where -import Language.Embedded.Hardware.Expression.Syntax (HExp)+import Language.Embedded.Hardware.Expression.Syntax (HExp, HType) import Language.Embedded.Hardware.Expression.Frontend-import Language.Embedded.Hardware.Expression.Represent (HType)-import Language.Embedded.Hardware.Expression.Represent.Bit import Language.Embedded.Hardware.Expression.Backend.VHDL ()
src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs view
@@ -29,7 +29,7 @@ instance FreeExp HExp where- type PredicateExp HExp = HType+ type PredicateExp HExp = PrimType litE = value varE = var @@ -52,11 +52,13 @@ where compE = compHExp -compHType :: forall a . HType a => HExp a -> VHDL VHDL.Type-compHType _ = declare (undefined :: proxy a)+compHType :: forall a . PrimType a+ => HExp a -> VHDL VHDL.Type+compHType _ = declareType (Proxy :: Proxy a) -compHTypeFun :: forall a b . (HType a, HType b) => (a -> b) -> VHDL VHDL.Type-compHTypeFun _ = declare (undefined :: proxy a)+compHTypeFun :: forall a b . (PrimType a, PrimType b)+ => (a -> b) -> VHDL VHDL.Type+compHTypeFun _ = declareType (Proxy :: Proxy a) compHExp :: forall a . HExp a -> VHDL VHDL.Expression compHExp e = Hoist.lift <$> compSimple e@@ -69,7 +71,7 @@ compDomain :: forall sig- . HType (DenResult sig)+ . PrimType (DenResult sig) => Dom sig -> Args (AST T) sig -> VHDL Kind@@ -172,12 +174,16 @@ x' <- Hoist.lift <$> compLoop x return $ Hoist.E $ VHDL.uCast x' tf tt compDomain primary args- | Just (Name n) <- prj primary = return $ Hoist.P $ VHDL.name n- | Just (Literal i) <- prj primary = return $ Hoist.P $ VHDL.literal $ VHDL.number $ printVal i- | Just (Aggregate a) <- prj primary = return $ Hoist.P $ VHDL.aggregate a+ | Just (Name n) <- prj primary =+ return $ Hoist.P $ VHDL.name n+ | Just (Literal i) <- prj primary =+ return $ Hoist.P $ VHDL.literal $ VHDL.number $ primTypeVal i+ | Just (Aggregate a) <- prj primary =+ return $ Hoist.P $ VHDL.aggregate a | Just (Function f _) <- prj primary = do as <- sequence $ listArgs compLoop args return $ Hoist.P $ VHDL.function (VHDL.simple f) (fmap Hoist.lift as)- | Just (Allocator) <- prj primary = error "expression-backend: todo"+ | Just (Allocator) <- prj primary =+ error "expression-backend-todo: allocators." --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Expression/Frontend.hs view
@@ -7,11 +7,9 @@ import qualified Language.VHDL as V -import Language.Embedded.Hardware.Interface-import Language.Embedded.Hardware.Expression.Syntax hiding (Term, Factor, Primary)-import Language.Embedded.Hardware.Expression.Hoist-import Language.Embedded.Hardware.Expression.Represent-import Language.Embedded.Hardware.Expression.Represent.Bit+import Language.Embedded.Hardware.Expression.Syntax (HExp, HType, sugarT)+import Language.Embedded.Hardware.Expression.Represent.Bit (Bits, bitFromInteger, bitToInteger)+import qualified Language.Embedded.Hardware.Expression.Syntax as H import qualified Language.Embedded.VHDL.Monad.Expression as V import Data.Typeable (Typeable)@@ -51,31 +49,31 @@ instance Expr HExp where true = value True false = value False- and = sugarT And- or = sugarT Or- xor = sugarT Xor- xnor = sugarT Xnor- nand = sugarT Nand- nor = sugarT Nor+ and = sugarT H.And+ or = sugarT H.Or+ xor = sugarT H.Xor+ xnor = sugarT H.Xnor+ nand = sugarT H.Nand+ nor = sugarT H.Nor -------------------------------------------------------------------------------- -- | Relational operators. class Rel exp where- eq :: (HType a, Eq a) => exp a -> exp a -> exp Bool- neq :: (HType a, Eq a) => exp a -> exp a -> exp Bool+ eq :: (HType a, Eq a) => exp a -> exp a -> exp Bool+ neq :: (HType a, Eq a) => exp a -> exp a -> exp Bool lt :: (HType a, Ord a) => exp a -> exp a -> exp Bool lte :: (HType a, Ord a) => exp a -> exp a -> exp Bool gt :: (HType a, Ord a) => exp a -> exp a -> exp Bool gte :: (HType a, Ord a) => exp a -> exp a -> exp Bool instance Rel HExp where- eq = sugarT Eq- neq = sugarT Neq- lt = sugarT Lt- lte = sugarT Lte- gt = sugarT Gt- gte = sugarT Gte+ eq = sugarT H.Eq+ neq = sugarT H.Neq+ lt = sugarT H.Lt+ lte = sugarT H.Lte+ gt = sugarT H.Gt+ gte = sugarT H.Gte -------------------------------------------------------------------------------- @@ -89,12 +87,12 @@ ror :: (HType a, B.Bits a) => exp a -> exp Integer -> exp a instance Shift HExp where- sll = sugarT Sll- srl = sugarT Srl- sla = sugarT Sla- sra = sugarT Sra- rol = sugarT Rol- ror = sugarT Ror+ sll = sugarT H.Sll+ srl = sugarT H.Srl+ sla = sugarT H.Sla+ sra = sugarT H.Sra+ rol = sugarT H.Rol+ ror = sugarT H.Ror -------------------------------------------------------------------------------- @@ -103,14 +101,14 @@ neg :: (HType a, Num a) => exp a -> exp a add :: (HType a, Num a) => exp a -> exp a -> exp a sub :: (HType a, Num a) => exp a -> exp a -> exp a- cat :: ( KnownNat n, KnownNat m, KnownNat (n + m), Typeable (n + m))+ cat :: (KnownNat n, KnownNat m, KnownNat (n + m), Typeable (n + m)) => exp (Bits n) -> exp (Bits m) -> exp (Bits (n + m)) instance Simple HExp where- neg = sugarT Neg- add = sugarT Add- sub = sugarT Sub- cat = sugarT Cat+ neg = sugarT H.Neg+ add = sugarT H.Add+ sub = sugarT H.Sub+ cat = sugarT H.Cat -------------------------------------------------------------------------------- @@ -122,10 +120,10 @@ rem :: (HType a, Integral a) => exp a -> exp a -> exp a instance Term HExp where- mul = sugarT Mul- div = sugarT Div- mod = sugarT Mod- rem = sugarT Rem+ mul = sugarT H.Mul+ div = sugarT H.Div+ mod = sugarT H.Mod+ rem = sugarT H.Rem -------------------------------------------------------------------------------- @@ -136,9 +134,9 @@ not :: exp Bool -> exp Bool instance Factor HExp where- exp = sugarT Exp- abs = sugarT Abs- not = sugarT Not+ exp = sugarT H.Exp+ abs = sugarT H.Abs+ not = sugarT H.Not -------------------------------------------------------------------------------- @@ -149,33 +147,37 @@ cast :: (HType a, HType b) => (a -> b) -> exp a -> exp b instance Primary HExp where- value = sugarT . Literal- name n = sugarT (Name (V.NSimple (V.Ident n)))- cast f = sugarT (Conversion f)+ value = sugarT . H.Literal+ name n = sugarT (H.Name (V.NSimple (V.Ident n)))+ cast f = sugarT (H.Conversion f) -- | Creates a variable from a string. var :: (Primary exp, HType a) => String -> exp a var = name -- | Converts an integral (signed/unsigned/integer) to an integer.-toInteger :: (Primary exp, HType a, Integral a) => exp a -> exp Integer+toInteger :: (Primary exp, HType a, Integral a)+ => exp a -> exp Integer toInteger = cast (fromIntegral) -- | Converts an integral to a signed value.-toSigned :: (Primary exp, HType a, HType b, Integral a, Num b) => exp a -> exp b+toSigned :: (Primary exp, HType a, HType b, Integral a, Num b)+ => exp a -> exp b toSigned = cast (fromIntegral) -- | Converts an integral to a unsigned value.-toUnsigned :: (Primary exp, HType a, HType b, Integral a, Num b) => exp a -> exp b+toUnsigned :: (Primary exp, HType a, HType b, Integral a, Num b)+ => exp a -> exp b toUnsigned = cast (fromIntegral) -- | Converts an integral to its bit representation.-toBits :: (Primary exp, HType a, HType (Bits b), Integral a, KnownNat b) => exp a -> exp (Bits b)+toBits :: (Primary exp, HType a, Integral a, KnownNat b)+ => exp a -> exp (Bits b) toBits = cast (bitFromInteger . fromIntegral) -----------------------------------------------------------------------------------fromBits :: (Primary exp, HType (Bits a), HType b, Num b, KnownNat a) => exp (Bits a) -> exp b+-- | Converts a bit representation of integral into its original form.+fromBits :: (Primary exp, HType b, Num b, KnownNat a)+ => exp (Bits a) -> exp b fromBits = cast (fromIntegral . bitToInteger) --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Expression/Represent.hs view
@@ -1,143 +1,29 @@+{-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ScopedTypeVariables #-}--module Language.Embedded.Hardware.Expression.Represent- ( Rep(..)- , Inhabited(..)- , Sized(..)- , HType(..)- - , declareBoolean- , declareNumeric- , declareFloating- - , module Data.Int- , module Data.Word- ) where+{-# LANGUAGE StandaloneDeriving #-} -import qualified Language.VHDL as V+module Language.Embedded.Hardware.Expression.Represent where -import Language.VHDL (Expression)+import Language.Embedded.Hardware.Expression.Represent.Bit import Language.Embedded.VHDL (VHDL) import Language.Embedded.VHDL.Monad (newSym, newLibrary, newImport) import Language.Embedded.VHDL.Monad.Type-import qualified Language.Embedded.VHDL.Monad.Util as Util (printBits)--import Language.Embedded.Hardware.Expression.Hoist (lift)+import Language.Embedded.VHDL.Monad.Util (printBits) import Data.Char (isDigit) import Data.Int import Data.Word-import Data.Typeable-import Text.Printf------------------------------------------------------------------------------------- * Representation of types.---------------------------------------------------------------------------------+import Data.Proxy (Proxy(..))+import Data.Typeable (Typeable) --- | Collection of required classes for hardware expressions.-class (Typeable a, Rep a, Eq a) => HType a-instance (Typeable a, Rep a, Eq a) => HType a+import GHC.TypeLits ----------------------------------------------------------------------------------- ** Representable types.---- | 'Rep'resentable types.-class Rep a- where- declare :: proxy a -> VHDL Type- printVal :: a -> String- printBits :: a -> String--instance Rep Bool where- declare _ = declareBoolean >> return std_logic- printVal True = "\'1\'"- printVal False = "\'0\'"- printBits = printVal--instance Rep Int8 where- declare _ = declareNumeric >> return signed8- printVal = show- printBits = Util.printBits 8--instance Rep Int16 where- declare _ = declareNumeric >> return signed16- printVal = show- printBits = Util.printBits 16--instance Rep Int32 where- declare _ = declareNumeric >> return signed32- printVal = show- printBits = Util.printBits 32--instance Rep Int64 where- declare _ = declareNumeric >> return signed64- printVal = show- printBits = Util.printBits 64--instance Rep Word8 where- declare _ = declareNumeric >> return usigned8- printVal = show- printBits = Util.printBits 8--instance Rep Word16 where- declare _ = declareNumeric >> return usigned16- printVal = show- printBits = Util.printBits 16--instance Rep Word32 where- declare _ = declareNumeric >> return usigned32- printVal = show- printBits = Util.printBits 32--instance Rep Word64 where- declare _ = declareNumeric >> return usigned64- printVal = show- printBits = Util.printBits 64--instance Rep Int where- declare _ = return (integer Nothing)- printVal = show- printBits = error "hardware-edsl.printBits: int."--instance Rep Integer where- declare _ = return (integer Nothing)- printVal = show- printBits = error "hardware-edsl.printBits: integer."--instance Rep Float where- declare _ = declareFloating >> return float- printVal = show- printBits = error "hardware-edsl.printBits: float."--instance Rep Double where- declare _ = declareFloating >> return double- printVal = show- printBits = error "hardware-edsl.printBits: double."---- | Declare the necessary libraries to support boolean operations.-declareBoolean :: VHDL ()-declareBoolean =- do newLibrary "IEEE"- newImport "IEEE.std_logic_1164"---- | Declare the necessary libraries to support numerical operations.-declareNumeric :: VHDL ()-declareNumeric =- do newLibrary "IEEE"- newImport "IEEE.std_logic_1164"- newImport "IEEE.numeric_std"---- | Declare the necessary libraries to support floating point operations.-declareFloating :: VHDL ()-declareFloating =- do newLibrary "IEEE"- newImport "IEEE.float_pkg"-+-- * Inhabited types. ----------------------------------------------------------------------------------- ** Inhabited types. -- | Inhabited types, that is, types with a base element. class Inhabited a@@ -159,8 +45,13 @@ instance Inhabited Float where reset = 0 instance Inhabited Double where reset = 0 +instance forall n . KnownNat n => Inhabited (Bits n)+ where+ reset = bitFromInteger 0+ ----------------------------------------------------------------------------------- ** Sized types.+-- * Sized types.+-------------------------------------------------------------------------------- -- | Types with a known size. class Sized a@@ -177,18 +68,158 @@ instance Sized Word16 where bits _ = 16 instance Sized Word32 where bits _ = 32 instance Sized Word64 where bits _ = 64+instance Sized Int where bits _ = 32+instance Sized Integer where bits _ = 64+instance Sized Float where bits _ = 32+instance Sized Double where bits _ = 64 +instance forall n . KnownNat n => Sized (Bits n)+ where+ bits _ = ni (Proxy :: Proxy n)+ ----------------------------------------------------------------------------------- ** Hmm...+-- * Representable types.+-------------------------------------------------------------------------------- -instance Num Bool where- (+) = error "(+) not implemented for Bool"- (-) = error "(-) not implemented for Bool"- (*) = error "(*) not implemented for Bool"- abs = id- signum = id- fromInteger 0 = False- fromInteger 1 = True- fromInteger _ = error "bool-num: >1" +-- | Representation of primitive hardware types.+data TypeRep a+ where+ -- booleans.+ BoolT :: TypeRep Bool+ -- signed numbers.+ Int8T :: TypeRep Int8+ Int16T :: TypeRep Int16+ Int32T :: TypeRep Int32+ Int64T :: TypeRep Int64+ -- unsigned numbers.+ Word8T :: TypeRep Word8+ Word16T :: TypeRep Word16+ Word32T :: TypeRep Word32+ Word64T :: TypeRep Word64+ -- integers.+ IntT :: TypeRep Int+ IntegerT :: TypeRep Integer+ -- floating point numbers.+ FloatT :: TypeRep Float+ DoubleT :: TypeRep Double+ -- variable sized bit values (todo).+ BitsT :: KnownNat n => TypeRep (Bits n)++deriving instance Eq (TypeRep a)+deriving instance Show (TypeRep a)+deriving instance Typeable (TypeRep a)++--------------------------------------------------------------------------------++-- | Primitive hardware types.+class (Eq a, Show a, Typeable a, Inhabited a, Sized a) => PrimType a+ where+ typeRep :: TypeRep a++instance PrimType Bool where typeRep = BoolT+instance PrimType Int8 where typeRep = Int8T+instance PrimType Int16 where typeRep = Int16T+instance PrimType Int32 where typeRep = Int32T+instance PrimType Int64 where typeRep = Int64T+instance PrimType Word8 where typeRep = Word8T+instance PrimType Word16 where typeRep = Word16T+instance PrimType Word32 where typeRep = Word32T+instance PrimType Word64 where typeRep = Word64T+instance PrimType Int where typeRep = IntT+instance PrimType Integer where typeRep = IntegerT+instance PrimType Float where typeRep = FloatT+instance PrimType Double where typeRep = DoubleT++instance forall n . KnownNat n => PrimType (Bits n)+ where+ typeRep = BitsT++--------------------------------------------------------------------------------++-- | Print a value.+primTypeVal :: forall a . PrimType a => a -> String+primTypeVal a = case typeRep :: TypeRep a of+ BoolT -> if a then "\'1\'" else "\'0\'"+ _ -> show a++-- | Print a value as its bit representation.+primTypeBits :: forall a . PrimType a => a -> String+primTypeBits a = case typeRep :: TypeRep a of+ BoolT -> primTypeVal a+ Int8T -> printBits 8 a+ Int16T -> printBits 16 a+ Int32T -> printBits 32 a+ Int64T -> printBits 64 a+ Word8T -> printBits 8 a+ Word16T -> printBits 16 a+ Word32T -> printBits 32 a+ Word64T -> printBits 64 a+ IntT -> error "todo: print ints as bits."+ IntegerT -> error "todo: print integers as bits."+ FloatT -> error "todo: print floats as bits."+ DoubleT -> error "todo: print doubles as bits."++-- | Hardware type representation of a primitive type.+primTypeRep :: forall a . PrimType a => Proxy a -> Type+primTypeRep _ = case typeRep :: TypeRep a of+ BoolT -> std_logic+ Int8T -> signed8+ Int16T -> signed16+ Int32T -> signed32+ Int64T -> signed64+ Word8T -> usigned8+ Word16T -> usigned16+ Word32T -> usigned32+ Word64T -> usigned64+ IntT -> integer Nothing -- todo: might be wrong.+ IntegerT -> integer Nothing -- todo: migth be wrong.+ FloatT -> float+ DoubleT -> double+ BitsT -> primTypeRepBits (Proxy :: Proxy a)++primTypeRepBits :: forall n . KnownNat n => Proxy (Bits n) -> Type+primTypeRepBits _ = std_logic_vector size+ where size = fromInteger (ni (undefined :: Bits n))++-- | Declare the necessary imports/packages to support a primitive type.+primTypeDeclare :: forall a . PrimType a => Proxy a -> VHDL ()+primTypeDeclare p = case typeRep :: TypeRep a of+ BoolT -> declareBoolean+ Int8T -> declareNumeric+ Int16T -> declareNumeric+ Int32T -> declareNumeric+ Int64T -> declareNumeric+ Word8T -> declareNumeric+ Word16T -> declareNumeric+ Word32T -> declareNumeric+ Word64T -> declareNumeric+ IntT -> declareNumeric+ IntegerT -> declareNumeric+ FloatT -> declareFloating+ DoubleT -> declareFloating+ BitsT -> declareBoolean++-- | Declare a primitive hardware type and get back its representation.+declareType :: PrimType a => Proxy a -> VHDL Type+declareType proxy = primTypeDeclare proxy >> return (primTypeRep proxy)++-- | Declare the necessary libraries to support boolean operations.+declareBoolean :: VHDL ()+declareBoolean =+ do newLibrary "IEEE"+ newImport "IEEE.std_logic_1164"++-- | Declare the necessary libraries to support numerical operations.+declareNumeric :: VHDL ()+declareNumeric =+ do newLibrary "IEEE"+ newImport "IEEE.std_logic_1164"+ newImport "IEEE.numeric_std"++-- | Declare the necessary libraries to support floating point operations.+declareFloating :: VHDL ()+declareFloating =+ do newLibrary "IEEE"+ newImport "IEEE.float_pkg" --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Expression/Represent/Bit.hs view
@@ -38,25 +38,15 @@ , bitToList , bitShowBin , bitShowHex-- , UBits- , forgetBits- , recallBits ) where -import Language.Embedded.Hardware.Expression.Represent--import Language.Embedded.VHDL (VHDL)-import Language.Embedded.VHDL.Monad (newSym, newLibrary, newImport)-import Language.Embedded.VHDL.Monad.Type- import Data.Ix import Data.Typeable import Data.Bits hiding (Bits) import qualified Data.Bits as Bit (Bits) -import Control.Monad (guard)+import Control.Monad (guard) import Control.DeepSeq (NFData(..)) import Data.Char (intToDigit)@@ -65,54 +55,14 @@ import GHC.TypeLits ----------------------------------------------------------------------------------- * ...+-- * Bit vectors of known lenght. -------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ ** Single bit.--type Bit = Bool------------------------------------------------------------------------------------- These aren't great to have..--instance Real Bool- where- toRational = error "toRational not implemented for bit."--instance Integral Bool- where- toInteger True = 1- toInteger False = 0- quotRem = error "quotRem not implemented for bit."------------------------------------------------------------------------------------- ** Bit vectors of known lenght.- newtype Bits (n :: Nat) = B Integer -instance forall n. KnownNat n => Inhabited (Bits n)- where- reset = bitFromInteger 0--instance forall n. KnownNat n => Rep (Bits n)- where- declare = declareBits- printVal = show . bitToInteger- printBits b = '\"' : (tail $ bitShowBin b) ++ ['\"'] -- *** why tail?--instance forall n. KnownNat n => Sized (Bits n)- where- bits _ = ni (Proxy::Proxy n)- deriving instance Typeable (Bits n)--declareBits :: forall proxy n. KnownNat n => proxy (Bits n) -> VHDL Type-declareBits _ = declareBoolean >> return (std_logic_vector size)- where size = fromInteger (ni (undefined :: Bits n)) ----------------------------------------------------------------------------------- *** ... ni :: KnownNat n => proxy n -> Integer ni = fromIntegral . natVal@@ -127,7 +77,6 @@ bitToInteger (B i) = i ----------------------------------------------------------------------------------- *** ... lift1 :: KnownNat n => (Integer -> Integer) -> Bits n -> Bits n lift1 f (B i) = norm (B (f i))@@ -136,7 +85,6 @@ lift2 f (B i) (B j) = norm (B (f i j)) ----------------------------------------------------------------------------------- *** ... bitAdd :: KnownNat n => Bits n -> Bits n -> Bits n bitAdd = lift2 (+)@@ -207,7 +155,9 @@ bitRotate :: KnownNat n => Bits n -> Int -> Bits n bitRotate b@(B i) n | si < 2 = b- | otherwise = bitOr (bitFromInteger (shiftL i n)) (bitFromInteger (shiftR i (si - n)))+ | otherwise =+ bitOr (bitFromInteger (shiftL i n))+ (bitFromInteger (shiftR i (si - n))) where n' = mod n si si = fromInteger (ni b) @@ -303,36 +253,32 @@ inRange = undefined ----------------------------------------------------------------------------------- ** Bit vectors of unknown lenght.--newtype UBits = UB Integer- deriving (Eq, Enum, Ord, Num, Real, Integral)--instance Rep UBits- where- declare = declareUBits- printVal = show- -- *** This is bad and produces a warning in vhdl as there's no guarantee- -- that the lenght of the printed binary will be the expected one.- -- Give UB an extra 'Maybe Integer' for storing the length whenever its- -- available.- printBits (UB i) = '\"' : (N.showIntAtBase 2 intToDigit i "") ++ ['\"']- +-- * Bit.+-------------------------------------------------------------------------------- -declareUBits :: proxy UBits -> VHDL Type-declareUBits _ = declareBoolean >> return std_logic+type Bit = Bool ----------------------------------------------------------------------------------forgetBits :: Bits n -> UBits-forgetBits b = UB (bitToInteger b)+-- These aren't too great to have.. -recallBits :: KnownNat n => UBits -> Bits n-recallBits (UB i) = (B i)+instance Num Bool where+ (+) = error "(+) not implemented for Bool"+ (-) = error "(-) not implemented for Bool"+ (*) = error "(*) not implemented for Bool"+ abs = id+ signum = id+ fromInteger 0 = False+ fromInteger 1 = True+ fromInteger _ = error "bool-num: >1" ---------------------------------------------------------------------------------+instance Real Bool+ where+ toRational = error "toRational not implemented for bit." -instance Show UBits where- showsPrec p (UB x) = showsPrec p x+instance Integral Bool+ where+ toInteger True = 1+ toInteger False = 0+ quotRem = error "quotRem not implemented for bit." --------------------------------------------------------------------------------
src/Language/Embedded/Hardware/Expression/Syntax.hs view
@@ -6,6 +6,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE DataKinds #-}+{-# LANGUAGE ConstraintKinds #-} module Language.Embedded.Hardware.Expression.Syntax where @@ -14,7 +15,9 @@ import qualified Language.VHDL as V (Name, Aggregate) -import Language.Embedded.Hardware.Command (CompArrayIx)+--import Language.Embedded.Hardware.Command (CompArrayIx)+--instance CompArrayIx HExp+ import Language.Embedded.Hardware.Interface import Language.Embedded.Hardware.Expression.Represent import Language.Embedded.Hardware.Expression.Represent.Bit@@ -41,7 +44,7 @@ -- | Typed expressions. data T sig where- T :: HType (DenResult sig) => { unT :: Dom sig } -> T sig+ T :: PrimType (DenResult sig) => { unT :: Dom sig } -> T sig -- | Specialized sugarSym for T. sugarT@@ -49,11 +52,14 @@ , T :<: SmartSym fi , SyntacticN f fi , SmartFun (SmartSym fi) (SmartSig fi) ~ fi- , HType (DenResult (SmartSig fi)))+ , PrimType (DenResult (SmartSig fi))) => sub (SmartSig fi) -> f sugarT sym = sugarSym (T $ inj sym) +-- | Hardware primitive types.+type HType = PrimType+ -- | Hardware expressions. newtype HExp a = HExp { unHExp :: ASTF T a } @@ -81,66 +87,65 @@ -- | Relational expressions. data Relational sig where- Eq :: (HType a) => Relational (a :-> a :-> Full Bool)- Neq :: (HType a) => Relational (a :-> a :-> Full Bool)- Lt :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)- Lte :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)- Gt :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)- Gte :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)+ Eq :: (PrimType a) => Relational (a :-> a :-> Full Bool)+ Neq :: (PrimType a) => Relational (a :-> a :-> Full Bool)+ Lt :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)+ Lte :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)+ Gt :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)+ Gte :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool) -- | Bit vector expressions. data ShiftExpression sig where- Sll :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)- Srl :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)- Sla :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)- Sra :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)- Rol :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)- Ror :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Sll :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Srl :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Sla :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Sra :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Rol :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)+ Ror :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a) -- | Numerical expressions. data SimpleExpression sig where- Neg :: (HType a, Num a) => SimpleExpression (a :-> Full a)- Pos :: (HType a, Num a) => SimpleExpression (a :-> Full a)- Add :: (HType a, Num a) => SimpleExpression (a :-> a :-> Full a)- Sub :: (HType a, Num a) => SimpleExpression (a :-> a :-> Full a)+ Neg :: (PrimType a, Num a) => SimpleExpression (a :-> Full a)+ Pos :: (PrimType a, Num a) => SimpleExpression (a :-> Full a)+ Add :: (PrimType a, Num a) => SimpleExpression (a :-> a :-> Full a)+ Sub :: (PrimType a, Num a) => SimpleExpression (a :-> a :-> Full a) Cat :: (KnownNat n, KnownNat m) => SimpleExpression (Bits n :-> Bits m :-> Full (Bits (n + m))) -- | Integral expressions. data Term sig where- Mul :: (HType a, Num a) => Term (a :-> a :-> Full a)- Div :: (HType a, Integral a) => Term (a :-> a :-> Full a)- Mod :: (HType a, Integral a) => Term (a :-> a :-> Full a)- Rem :: (HType a, Integral a) => Term (a :-> a :-> Full a)+ Mul :: (PrimType a, Num a) => Term (a :-> a :-> Full a)+ Div :: (PrimType a, Integral a) => Term (a :-> a :-> Full a)+ Mod :: (PrimType a, Integral a) => Term (a :-> a :-> Full a)+ Rem :: (PrimType a, Integral a) => Term (a :-> a :-> Full a) -- | ... data Factor sig where- Exp :: (HType a, Num a, HType b, Integral b) => Factor (a :-> b :-> Full a)- Abs :: (HType a, Num a) => Factor (a :-> Full a)+ Exp :: (PrimType a, Num a, PrimType b, Integral b)+ => Factor (a :-> b :-> Full a)+ Abs :: (PrimType a, Num a) => Factor (a :-> Full a) Not :: Factor (Bool :-> Full Bool) -- | ... data Primary sig where- Name :: (HType a) => V.Name -> Primary (Full a)- Literal :: (HType a) => a -> Primary (Full a)- Aggregate :: (HType a) => V.Aggregate -> Primary (Full a)+ Name :: (PrimType a) => V.Name -> Primary (Full a)+ Literal :: (PrimType a) => a -> Primary (Full a)+ Aggregate :: (PrimType a) => V.Aggregate -> Primary (Full a) Function :: (Signature sig) => String -> Denotation sig -> Primary sig- Qualified :: (HType a, HType b) => b -> Primary (a :-> Full a)- Conversion :: (HType a, HType b) => (a -> b) -> Primary (a :-> Full b)- Allocator :: (HType a) => Primary (Full a)+ Qualified :: (PrimType a, PrimType b) => b -> Primary (a :-> Full a)+ Conversion :: (PrimType a, PrimType b) => (a -> b) -> Primary (a :-> Full b)+ Allocator :: (PrimType a) => Primary (Full a) -- *** todo: expanded aggregate Others :: Primary (Bit :-> Full (Bits n)) -------------------------------------------------------------------------------- -- ** Syntactic instances. -instance CompArrayIx HExp- instance Equality T where equal (T s) (T t) = equal s t@@ -378,3 +383,51 @@ instance EvalEnv Primary env --------------------------------------------------------------------------------+-- *** Temporary fix until GHC fixes their class resolution for DTC ***+--------------------------------------------------------------------------------++instance {-# OVERLAPPING #-} Project sub Dom => Project sub (AST T)+ where+ prj (Sym s) = prj s++instance {-# OVERLAPPING #-} Project sub Dom => Project sub T+ where+ prj (T a) = prj a++instance {-# OVERLAPPING #-} Project Expression Dom+ where+ prj (InjL a) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project Relational Dom+ where+ prj (InjR (InjL a)) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project ShiftExpression Dom+ where+ prj (InjR (InjR (InjL a))) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project SimpleExpression Dom+ where+ prj (InjR (InjR (InjR (InjL a)))) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project Term Dom+ where+ prj (InjR (InjR (InjR (InjR (InjL a))))) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project Factor Dom+ where+ prj (InjR (InjR (InjR (InjR (InjR (InjL a)))))) = Just a+ prj _ = Nothing++instance {-# OVERLAPPING #-} Project Primary Dom+ where+ prj ((InjR (InjR (InjR (InjR (InjR (InjR a))))))) = Just a+ prj _ = Nothing++--------------------------------------------------------------------------------+
+ src/Language/Embedded/Hardware/Interface/AXI.hs view
@@ -0,0 +1,644 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}++module Language.Embedded.Hardware.Interface.AXI (axi_light, AXIPred) where++import Language.Embedded.VHDL (Mode(..))+import Language.Embedded.Hardware.Command.CMD+import Language.Embedded.Hardware.Command.Frontend+import Language.Embedded.Hardware.Interface+import Language.Embedded.Hardware.Expression.Frontend+import Language.Embedded.Hardware.Expression.Represent+import Language.Embedded.Hardware.Expression.Represent.Bit (Bits, Bit, bitFromInteger, ni)++import Control.Monad.Identity (Identity)+import Control.Monad.Operational.Higher hiding (when)+import Data.Constraint (Constraint)+import Data.Typeable+import Data.Int+import Data.Word+import Data.Bits ()+import Data.Ix (Ix)++import GHC.TypeLits+import qualified GHC.Exts as GHC (Constraint)++import Prelude hiding (not, and, or, div, null)+import qualified Prelude as P++--------------------------------------------------------------------------------+-- * AXI-light Controller.+--------------------------------------------------------------------------------+-- todo : we make a slight simplification and assume that components which we+-- connect to AXI-lite has a signature of+-- "input -> input -> .. -> input -> output -> ()"+-- this can easily be fixed by inspecting the modes given by the+-- signature.+--------------------------------------------------------------------------------++-- | Short-hand for programs.+type Prog instr exp pred = Program instr (Param2 exp pred)++-- | Short-hand for constraints.+type AXIPred instr exp pred = (+ SignalCMD :<: instr+ , ArrayCMD :<: instr+ , VariableCMD :<: instr+ , ConditionalCMD :<: instr+ , StructuralCMD :<: instr+ , LoopCMD :<: instr+ , ComponentCMD :<: instr+ , VHDLCMD :<: instr+--+ , Expr exp+ , Rel exp+ , Factor exp+ , Primary exp+--+ , FreeExp exp+ -- todo: this equality might be bad. It should be enough to+ -- say that 'PredicateExp' holds, and not that it has+ -- to be equal to 'pred'.+ , pred ~ PredicateExp exp+ , pred (Bit)+ , pred (Bits 2)+ , pred (Bits 3)+ , pred (Bits 4)+ , pred (Bits 32)+ , pred (Integer)+ , Num (exp Integer)+ )++--------------------------------------------------------------------------------+-- ** Signature.+--------------------------------------------------------------------------------++axi_light+ :: forall instr exp pred sig . AXIPred instr exp pred+ => Comp instr exp pred Identity sig+ -> Sig instr exp pred Identity (+ Signal Bit -- ^ Global clock signal.+ -> Signal Bit -- ^ Global reset signal.+ -> Signal (Bits 32) -- ^ Write address.+ -> Signal (Bits 3) -- ^ Write channel protection type.+ -> Signal Bit -- ^ Write address valid.+ -> Signal Bit -- ^ Write address ready.+ -> Signal (Bits 32) -- ^ Write data.+ -> Signal (Bits 4) -- ^ Write strobes.+ -> Signal Bit -- ^ Write valid.+ -> Signal Bit -- ^ Write ready.+ -> Signal (Bits 2) -- ^ Write response.+ -> Signal Bit -- ^ Write response valid.+ -> Signal Bit -- ^ Response ready.+ -> Signal (Bits 32) -- ^ Read address.+ -> Signal (Bits 3) -- ^ Protection type.+ -> Signal Bit -- ^ Read address valid.+ -> Signal Bit -- ^ Read address ready.+ -> Signal (Bits 32) -- ^ Read data.+ -> Signal (Bits 2) -- ^ Read response.+ -> Signal Bit -- ^ Read valid.+ -> Signal Bit -- ^ Read ready. + -> ()+ )+axi_light comp =+ exactInput "S_AXI_ACLK" $ \s_axi_aclk -> + exactInput "S_AXI_ARESETN" $ \s_axi_aresetn -> + exactInput "S_AXI_AWADDR" $ \s_axi_awaddr ->+ exactInput "S_AXI_AWPROT" $ \s_axi_awprot ->+ exactInput "S_AXI_AWVALID" $ \s_axi_awvalid -> + exactOutput "S_AXI_AWREADY" $ \s_axi_awready ->+ exactInput "S_AXI_WDATA" $ \s_axi_wdata ->+ exactInput "S_AXI_WSTRB" $ \s_axi_wstrb ->+ exactInput "S_AXI_WVALID" $ \s_axi_wvalid -> + exactOutput "S_AXI_WREADY" $ \s_axi_wready -> + exactOutput "S_AXI_BRESP" $ \s_axi_bresp -> + exactOutput "S_AXI_BVALID" $ \s_axi_bvalid -> + exactInput "S_AXI_BREADY" $ \s_axi_bready -> + exactInput "S_AXI_ARADDR" $ \s_axi_araddr ->+ exactInput "S_AXI_ARPROT" $ \s_axi_arprot ->+ exactInput "S_AXI_ARVALID" $ \s_axi_arvalid -> + exactOutput "S_AXI_ARREADY" $ \s_axi_arready ->+ exactOutput "S_AXI_RDATA" $ \s_axi_rdata -> + exactOutput "S_AXI_RRESP" $ \s_axi_rresp -> + exactOutput "S_AXI_RVALID" $ \s_axi_rvalid ->+ exactInput "S_AXI_RREADY" $ \s_axi_rready -> + ret $ axi_light_impl comp+ s_axi_aclk s_axi_aresetn+ s_axi_awaddr s_axi_awprot s_axi_awvalid s_axi_awready+ s_axi_wdata s_axi_wstrb s_axi_wvalid s_axi_wready+ s_axi_bresp s_axi_bvalid s_axi_bready+ s_axi_araddr s_axi_arprot s_axi_arvalid s_axi_arready s_axi_rdata+ s_axi_rresp s_axi_rvalid s_axi_rready ++--------------------------------------------------------------------------------+-- ** Implementation.+--------------------------------------------------------------------------------++axi_light_impl+ :: forall instr exp pred sig . AXIPred instr exp pred+ -- Component to connect:+ => Comp instr exp pred Identity sig+ -- AXI signals:+ -> Signal Bit -- ^ Global clock signal.+ -> Signal Bit -- ^ Global reset signal.+ -> Signal (Bits 32) -- ^ Write address.+ -> Signal (Bits 3) -- ^ Write channel protection type.+ -> Signal Bit -- ^ Write address valid.+ -> Signal Bit -- ^ Write address ready.+ -> Signal (Bits 32) -- ^ Write data.+ -> Signal (Bits 4) -- ^ Write strobes.+ -> Signal Bit -- ^ Write valid.+ -> Signal Bit -- ^ Write ready.+ -> Signal (Bits 2) -- ^ Write response.+ -> Signal Bit -- ^ Write response valid.+ -> Signal Bit -- ^ Response ready.+ -> Signal (Bits 32) -- ^ Read address.+ -> Signal (Bits 3) -- ^ Protection type.+ -> Signal Bit -- ^ Read address valid.+ -> Signal Bit -- ^ Read address ready.+ -> Signal (Bits 32) -- ^ Read data.+ -> Signal (Bits 2) -- ^ Read response.+ -> Signal Bit -- ^ Read valid.+ -> Signal Bit -- ^ Read ready. + -> Prog instr exp pred ()+axi_light_impl comp+ s_axi_aclk s_axi_aresetn+ s_axi_awaddr s_axi_awprot s_axi_awvalid s_axi_awready+ s_axi_wdata s_axi_wstrb s_axi_wvalid s_axi_wready+ s_axi_bresp s_axi_bvalid s_axi_bready+ s_axi_araddr s_axi_arprot s_axi_arvalid s_axi_arready s_axi_rdata+ s_axi_rresp s_axi_rvalid s_axi_rready+ = do+ ----------------------------------------+ -- AXI Light signals.+ --+ awaddr <- signal "axi_awaddr" :: Prog instr exp pred (Signal (Bits 32))+ awready <- signal "axi_awready" :: Prog instr exp pred (Signal (Bit))+ wready <- signal "axi_wready" :: Prog instr exp pred (Signal (Bit))+ bresp <- signal "axi_bresp" :: Prog instr exp pred (Signal (Bits 2))+ bvalid <- signal "axi_bvalid" :: Prog instr exp pred (Signal (Bit))+ araddr <- signal "axi_araddr" :: Prog instr exp pred (Signal (Bits 32))+ arready <- signal "axi_arready" :: Prog instr exp pred (Signal (Bit))+ rdata <- signal "axi_rdata" :: Prog instr exp pred (Signal (Bits 32))+ rresp <- signal "axi_rresp" :: Prog instr exp pred (Signal (Bits 2))+ rvalid <- signal "axi_rvalid" :: Prog instr exp pred (Signal (Bit))++ ----------------------------------------+ -- Signals for user logic registers.+ --+ reg_rden <- signal "slv_reg_rden" :: Prog instr exp pred (Signal (Bit))+ reg_wren <- signal "slv_reg_wren" :: Prog instr exp pred (Signal (Bit))+ reg_out <- signal "reg_data_out" :: Prog instr exp pred (Signal (Bits 32))+ reg_index <- signal "byte_index" :: Prog instr exp pred (Signal (Integer))+ registers <- declareRegisters (signatureOf comp)++ ----------------------------------------+ -- Short-hands for ...+ --+ -- > reset all input registers.+ let mReset = resetInputs (signatureOf comp) registers+ -- > reload all input registers.+ let mReload = reloadInputs (signatureOf comp) registers+ -- > fetch the names of all input registers.+ let mInputs = identInputs (signatureOf comp) registers+ -- > write to output.+ let mWrite :: Prog instr exp pred ()+ mWrite = loadOutputs araddr reg_out+ (signatureOf comp)+ (registers)+ -- > read from input.+ let mRead :: Prog instr exp pred ()+ mRead = loadInputs awaddr reg_wren s_axi_wdata s_axi_wstrb+ (signatureOf comp)+ (registers)+ + ----------------------------------------+ -- I/O Connections.+ --+ s_axi_awready <=- awready+ s_axi_wready <=- wready+ s_axi_bresp <=- bresp+ s_axi_bvalid <=- bvalid+ s_axi_arready <=- arready+ s_axi_rdata <=- rdata+ s_axi_rresp <=- rresp+ s_axi_rvalid <=- rvalid++ ----------------------------------------+ -- Mem. mapped register select and write+ -- logic generation.+ --+ u_wr <- unsafeFreezeSignal wready+ u_wv <- unsafeFreezeSignal s_axi_wvalid+ u_awr <- unsafeFreezeSignal awready+ u_awv <- unsafeFreezeSignal s_axi_awvalid+ concurrentSetSignal reg_wren+ (u_wr `and` u_wv `and` u_awr `and` u_awv)++ ----------------------------------------+ -- Mem. mapped register select and read+ -- logic generation.+ --+ u_arr <- unsafeFreezeSignal arready+ u_arv <- unsafeFreezeSignal s_axi_arvalid+ u_rv <- unsafeFreezeSignal rvalid+ concurrentSetSignal reg_rden+ (u_arr `and` u_arv `and` not u_rv)++ ----------------------------------------+ -- AXI_AWREADY generation.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do awready <== low)+ (do rdy <- getSignal awready+ awv <- getSignal s_axi_awvalid+ wv <- getSignal s_axi_wvalid+ iff (isLow rdy `and` isHigh awv `and` isHigh wv)+ (do awready <== high)+ (do awready <== low)))+ + ----------------------------------------+ -- AXI_AWADDR latching.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do awaddr <== zeroes)+ (do rdy <- getSignal awready+ awv <- getSignal s_axi_awvalid+ wv <- getSignal s_axi_wvalid+ when (isLow rdy `and` isHigh awv `and` isHigh wv)+ (awaddr <=- s_axi_awaddr)))++ ----------------------------------------+ -- AXI_WREADY generation.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do wready <== low)+ (do rdy <- getSignal awready+ awv <- getSignal s_axi_awvalid+ wv <- getSignal s_axi_wvalid+ iff (isLow rdy `and` isHigh awv `and` isHigh wv)+ (wready <== high)+ (wready <== low)))++ ----------------------------------------+ -- Slave register logic.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ mReset+ mRead)+ + ----------------------------------------+ -- Write response logic.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do bvalid <== low+ bresp <== zeroes)+ (do awr <- getSignal awready+ awv <- getSignal s_axi_awvalid+ wr <- getSignal wready+ wv <- getSignal s_axi_wvalid+ bv <- getSignal bvalid+ br <- getSignal s_axi_bready+ ifE ((isHigh awr `and` isHigh awv+ `and` isHigh wr+ `and` isHigh wv+ `and` isLow bv),+ do bvalid <== high+ bresp <== zeroes)+ ((isHigh br `and` isHigh bv),+ do bvalid <== low)))++ ----------------------------------------+ -- AXI_AWREADY generation.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do arready <== low+ araddr <== ones)+ (do arr <- getSignal arready+ arv <- getSignal s_axi_arvalid+ iff (isLow arr `and` isHigh arv)+ (do arready <== high+ araddr <=- s_axi_araddr)+ (do arready <== low)))++ ----------------------------------------+ -- AXI_ARVALID generation.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do rvalid <== low+ rresp <== zeroes)+ (do arr <- getSignal arready+ arv <- getSignal s_axi_arvalid+ rv <- getSignal rvalid+ rr <- getSignal s_axi_rready+ ifE ((isHigh arr `and` isHigh arv),+ do rvalid <== high+ rresp <== zeroes)+ ((isHigh rv `and` isHigh rr),+ do rvalid <== low)))++ ----------------------------------------+ -- Memory mapped rigister select and+ -- read logic generaiton.+ --+ process (araddr .: s_axi_aresetn .: reg_rden .: mInputs) (do+ mWrite)++ ----------------------------------------+ -- Output register of memory read data.+ --+ process (s_axi_aclk .: []) (do+ whenRising s_axi_aclk s_axi_aresetn+ (do rdata <== zeroes)+ (do rden <- getSignal reg_rden+ when (isHigh rden)+ (do rdata <=- reg_out)))++ ----------------------------------------+ -- User logic.+ --+ portmap comp registers+ --+ -- The end.+ ----------------------------------------+ where+ -- Application-specific design signals.+ addr_lsb, addr_bits :: Integer+ addr_lsb = 2+ addr_bits = 2 + 1+ --addr_lsb + (widthOf comp)++--------------------------------------------------------------------------------+-- ** Helpers.+--------------------------------------------------------------------------------++-- | Declare the registers which will be used by our AXI-lite slave to store+-- values received from the master and, once filled, as input for the comp.+declareRegisters :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred+ => Sig instr exp pred Identity a+ -> Prog instr exp pred (Argument pred a)+declareRegisters (Ret _) = return Nil+declareRegisters (SSig _ _ sf) =+ do s <- newSignal+ a <- declareRegisters (sf s)+ return (ASig s a)+declareRegisters (SArr _ _ l af) =+ do s <- newArray (litE l)+ a <- declareRegisters (af s)+ return (AArr s a)++--------------------------------------------------------------------------------++-- | Reset the input registers.+resetInputs :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred+ => Sig instr exp pred Identity a+ -> Argument pred a+ -> Prog instr exp pred ()+resetInputs (Ret _) (Nil) = return ()+resetInputs (SSig _ Out sf) (ASig s arg) = resetInputs (sf s) arg+resetInputs (SArr _ Out _ af) (AArr a arg) = resetInputs (af a) arg+resetInputs (SSig _ In sf) (ASig s arg) =+ do setSignal s (litE reset)+ resetInputs (sf s) arg+resetInputs (SArr _ In _ af) (AArr a arg) =+ do resetArray a (litE reset)+ resetInputs (af a) arg++--------------------------------------------------------------------------------++-- | Reset the input registers to their previous values.+reloadInputs :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred+ => Sig instr exp pred Identity a+ -> Argument pred a+ -> Prog instr exp pred ()+reloadInputs (Ret _) (Nil) = return ()+reloadInputs (SSig _ Out sf) (ASig s arg) = reloadInputs (sf s) arg+reloadInputs (SArr _ Out _ af) (AArr a arg) = reloadInputs (af a) arg+reloadInputs (SSig _ In sf) (ASig s arg) =+ do sv <- unsafeFreezeSignal s+ setSignal s sv+ reloadInputs (sf s) arg+reloadInputs (SArr _ In l af) (AArr a arg) =+ do copyArray (a, litE 0) (a, litE 0) (litE l)+ reloadInputs (af a) arg++--------------------------------------------------------------------------------++-- | ...+loadInputs :: forall instr (exp :: * -> *) pred a . AXIPred instr exp pred+ => Signal (Bits 32) -- ^ Address.+ -> Signal (Bit) -- ^ Ready.+ -> Signal (Bits 32) -- ^ Input.+ -> Signal (Bits 4) -- ^ Protected bits.+ -> Sig instr exp pred Identity a+ -> Argument pred a+ -> Prog instr exp pred ()+loadInputs waddr rwren wdata wren sig arg =+ do loc <- getBits waddr addr_lsb addr_msb+ ready <- getSignal rwren+ when (isHigh ready) $+ switched loc+ (cases 0 sig arg)+ (reloadInputs sig arg)+ where+ cases :: Integer+ -> Sig instr exp pred Identity b+ -> Argument pred b+ -> [When Integer (Prog instr exp pred)]+ cases ix (Ret _) (Nil) = []+ cases ix (SArr _ _ l af) (AArr a arg) = error "axi-todo: loading arrays."+ cases ix (SSig _ Out sf) (ASig s arg) = cases (ix+1) (sf s) arg+ cases ix (SSig _ In sf) (ASig s arg) =+ is (ix) (loadInputSignal wdata wren s) : cases (ix+1) (sf s) arg++ addr_lsb, addr_msb :: exp Integer+ addr_lsb = litE 2+ addr_msb = litE 3++loadInputSignal :: forall instr (exp :: * -> *) pred a .+ (AXIPred instr exp pred, pred a, Sized a)+ => Signal (Bits 32)+ -> Signal (Bits 4)+ -> Signal a+ -> Prog instr exp pred ()+loadInputSignal wdata wren reg = for 0 size $ \byte_index ->+ do bit <- getBit wren byte_index+ when (isHigh bit) $+ copyBits (reg, byte_index*8) (wdata, byte_index*8) (litE 7)+ where+ size :: exp Integer+ size = litE $ (P.div (bits reg) 8) - 1+-- todo: I assume that `a` has a type \width\ that is some multiple of eight,+-- hence the hard-coded seven when copying.++--------------------------------------------------------------------------------++-- | ...+loadOutputs :: forall instr (exp :: * -> *) pred a . AXIPred instr exp pred+ => Signal (Bits 32) -- ^ Address.+ -> Signal (Bits 32) -- ^ Output.+ -> Sig instr exp pred Identity a+ -> Argument pred a+ -> Prog instr exp pred ()+loadOutputs araddr rout sig arg =+ do loc <- getBits araddr addr_lsb addr_msb+ switched loc+ (cases 0 sig arg)+ (setSignal rout (litE reset))+ where+ cases :: Integer+ -> Sig instr exp pred Identity b+ -> Argument pred b+ -> [When Integer (Prog instr exp pred)]+ cases ix (Ret _) (Nil) = []+ cases ix (SArr _ _ l af) (AArr a arg) = error "axi-todo: loading arrays."+ cases ix (SSig _ Out sf) (ASig s arg) = cases (ix+1) (sf s) arg+ cases ix (SSig _ In sf) (ASig s arg) =+ is (ix) (loadOutputSignal rout s) : cases (ix+1) (sf s) arg++ addr_lsb, addr_msb :: exp Integer+ addr_lsb = litE 2+ addr_msb = litE 3++loadOutputSignal :: forall instr (exp :: * -> *) pred a .+ (AXIPred instr exp pred, pred a, PrimType a, Integral a)+ => Signal (Bits 32)+ -> Signal a+ -> Prog instr exp pred ()+loadOutputSignal rout reg =+ do r <- unsafeFreezeSignal reg+ setSignal rout (toBits r :: exp (Bits 32))++--------------------------------------------------------------------------------++identInputs :: forall instr (exp :: * -> *) pred m a .+ Sig instr exp pred m a+ -> Argument pred a+ -> [Ident]+identInputs (Ret _) (Nil) = []+identInputs (SSig _ In sf) (ASig s arg) = toIdent s : identInputs (sf s) arg+identInputs (SSig _ _ sf) (ASig s arg) = identInputs (sf s) arg+identInputs (SArr _ In _ af) (AArr a arg) = toIdent a : identInputs (af a) arg+identInputs (SArr _ _ _ af) (AArr a arg) = identInputs (af a) arg++--------------------------------------------------------------------------------++signatureOf :: Comp instr exp pred m a -> Sig instr exp pred m a+signatureOf (Component _ sig) = sig++widthOf :: Comp instr exp pred m a -> Integer+widthOf = go . signatureOf+ where+ go :: Sig instr exp pred m b -> Integer+ go (Ret _) = 0+ go (SSig _ _ f) = 1 + go (f dummy)+-- go (SArr _ _ l g) = l + go (g dummy)++dummy :: a+dummy = error "todo: evaluated dummy"++high, low :: Expr exp => exp Bit+high = true+low = false++isHigh, isLow :: (Expr exp, Rel exp) => exp Bit -> exp Bit+isHigh e = e `eq` high+isLow e = e `eq` low++zeroes :: (Primary exp, Typeable n, KnownNat n) => exp (Bits n)+zeroes = value 0++ones :: forall exp n. (Primary exp, Typeable n, KnownNat n) => exp (Bits n)+ones = value $ bitFromInteger (read (replicate size '1') :: Integer)+ where size = fromIntegral (ni (Proxy::Proxy n)) - 1++--------------------------------------------------------------------------------+-- Program stubs.+--------------------------------------------------------------------------------+{-+loadInputs wdata wren tmp i (SSig _ In sf) (ASig s arg) =+ When (Is i) cases : loadInputs wdata wren tmp (i+1) (sf s) arg+ where+ size :: Integer+ size = bits s++ loadBit :: Prog instr exp pred ()+ loadBit = do+ wb <- getBit wren (0 :: exp Integer)+ undefined+ when (isHigh wb) $+ do bit <- getBit wdata (0 :: exp Integer)+ setBit s (0 :: exp Integer) bit++ loadBits :: Integer -> Integer -> Prog instr exp pred ()+ loadBits ix len = do+ wb <- getBit wren (value ix)+ undefined+ when (isHigh wb) $+ copyBits (s, value $ ix*8) (wdata, value $ ix*8) (value $ len-1)++ cases :: Prog instr exp pred ()+ cases | size == 1 = loadBit+ | otherwise = sequence_ $ map (uncurry loadBits) $ zip [0..] $ chunk size+loadInputs wdata wren tmp i (SArr _ Out l af) (AArr a arg) =+ loadInputs wdata wren tmp (i+(Prelude.toInteger l)) (af a) arg+loadInputs wdata wren tmp i (SArr _ In l af) (AArr (a :: Array i b) arg)+ let cs = map (\ix -> When (Is $ i+ix) $ cases ix) [0..l'-1]+ in cs ++ loadInputs wdata wren tmp (i+l') (af a) arg+ where+ l', size :: Integer+ l' = Prelude.toInteger l + size = bits a++ loadBit :: Integer -> Prog instr exp pred ()+ loadBit ax = error "axi-todo: loadBit for array."++ loadBits :: Integer -> Integer -> Integer -> Prog instr exp pred ()+ loadBits ax ix len = do+ wb <- getBit wren (value ix)+ when (isHigh wb) $+ copyVBits (tmp, value $ ix*8) (wdata, value $ ix*8) (value $ len-1)++ cases :: Integer -> Prog instr exp pred ()+ cases ax | size == 1 = loadBit ax+ | otherwise = do+ sequence_ $ map (uncurry $ loadBits ax) $ zip [0..] $ chunk size+ val :: exp (Bits 32) <- unsafeFreezeVariable tmp+ let ix = litE (fromInteger ax) :: exp i+ let b = fromBits val :: exp b+ undefined --setArray a ix b+-}+{-+loadOutputs o i (Ret _) (Nil) = []+loadOutputs o i (SSig _ Out sf) (ASig s arg) =+ let p = setSignal o . toBits =<< unsafeFreezeSignal s+ in When (Is i) p : loadOutputs o (i+1) (sf s) arg+loadOutputs o i (SSig _ _ sf) (ASig s arg) =+ loadOutputs o (i+1) (sf s) arg+loadOutputs o i (SArr _ Out l af) (AArr a arg) =+ let f ix = When (Is ix) (setSignal o . toBits =<< getArray a (value ix))+ in map f [i..i+l-1] ++ loadOutputs o (i+l) (af a) arg+loadOutputs o i (SArr _ _ l af) (AArr a arg) =+ loadOutputs o (i+l) (af a) arg++chunk :: Integer -> [Integer]+chunk i | i > 8 = 8 : chunk (i - 8)+ | i <= 8 = [i]+-}+--------------------------------------------------------------------------------+
src/Language/Embedded/VHDL/Monad/Type.hs view
@@ -9,7 +9,7 @@ , unconstrainedArray, constrainedArray -- utility. , typeName, typeRange, typeWidth- , isBit, isBits, isSigned, isUnsigned, isInteger+ , isBit, isBits, isSigned, isUnsigned, isInteger, isFloating ) where import Language.VHDL@@ -159,5 +159,8 @@ isInteger :: Type -> Bool isInteger t = "integer" == typeName t++isFloating :: Type -> Bool+isFloating t = "float" == typeName t --------------------------------------------------------------------------------