hardware-edsl-0.1.0.0: src/Language/Embedded/Hardware/Command/Frontend.hs
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
module Language.Embedded.Hardware.Command.Frontend where
import Language.Embedded.VHDL (Mode(..))
import Language.Embedded.Hardware.Interface (PredicateExp)
import Language.Embedded.Hardware.Command.CMD
import Control.Monad.Operational.Higher
import Data.Ix (Ix)
--------------------------------------------------------------------------------
-- ** Signals.
-- | Declare a signal.
newSignal :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => IExp i a -> ProgramT i m (Signal a)
newSignal = singleE . NewSignal Port SArchitecture InOut . Just
-- | Declare an uninitialized signal.
newSignal_ :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => ProgramT i m (Signal a)
newSignal_ = singleE $ NewSignal Port SArchitecture InOut Nothing
-- | Fetches the current value of a signal.
getSignal :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Signal a -> ProgramT i m (IExp i a)
getSignal = singleE . GetSignal
-- | Update the value of a signal.
setSignal :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Signal a -> IExp i a -> ProgramT i m ()
setSignal s = singleE . SetSignal s
-- | Unsafe version of fetching the contents of a signal.
unsafeFreezeSignal :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Signal a -> ProgramT i m (IExp i a)
unsafeFreezeSignal = singleE . UnsafeFreezeSignal
-- | Declare port signals of the given mode and assign it initial value.
newPort :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Mode -> IExp i a -> ProgramT i m (Signal a)
newPort m = singleE . NewSignal Port SEntity m . Just
-- | Declare port signals of the given mode.
newPort_ :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Mode -> ProgramT i m (Signal a)
newPort_ m = singleE $ NewSignal Port SEntity m Nothing
-- | Declare generic signals of the given mode and assign it initial value.
newGeneric :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Mode -> IExp i a -> ProgramT i m (Signal a)
newGeneric m = singleE . NewSignal Generic SEntity m . Just
-- | Declare generic signals of the given mode.
newGeneric_ :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Mode -> ProgramT i m (Signal a)
newGeneric_ m = singleE $ NewSignal Generic SEntity m Nothing
-- | Short-hand for 'setSignal'.
(<==) :: (SignalCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Signal a -> IExp i a -> ProgramT i m ()
(<==) = setSignal
--------------------------------------------------------------------------------
-- ** Variables.
-- | Declare a variable.
newVariable :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => IExp i a -> ProgramT i m (Variable a)
newVariable = singleE . NewVariable . Just
-- | Declare an uninitialized variable.
newVariable_ :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => ProgramT i m (Variable a)
newVariable_ = singleE $ NewVariable Nothing
-- | Fetches the current value of a variable.
getVariable :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Variable a -> ProgramT i m (IExp i a)
getVariable = singleE . GetVariable
-- | Updates the value of a variable.
setVariable :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Variable a -> IExp i a -> ProgramT i m ()
setVariable v = singleE . SetVariable v
-- | Unsafe version of fetching the contents of a variable.
unsafeFreezeVariable :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Variable a -> ProgramT i m (IExp i a)
unsafeFreezeVariable = singleE . UnsafeFreezeVariable
-- | Short-hand for 'setVariable'.
(==:) :: (VariableCMD (IExp i) :<: i, PredicateExp (IExp i) a) => Variable a -> IExp i a -> ProgramT i m ()
(==:) = setVariable
--------------------------------------------------------------------------------
-- ** Arrays.
-- | Create an uninitialized array.
newArray
:: ( PredicateExp (IExp instr) a
, PredicateExp (IExp instr) i
, Integral i, Ix i
, ArrayCMD (IExp instr) :<: instr )
=> IExp instr i -> ProgramT instr m (Array i a)
newArray = singleE . NewArray
-- | Create an initialized array.
initArray
:: ( PredicateExp (IExp instr) a
, PredicateExp (IExp instr) i
, Integral i, Ix i
, ArrayCMD (IExp instr) :<: instr )
=> [a] -> ProgramT instr m (Array i a)
initArray = singleE . InitArray
-- | Get an element of an array.
getArray
:: ( PredicateExp (IExp instr) a
, PredicateExp (IExp instr) i
, Integral i, Ix i
, ArrayCMD (IExp instr) :<: instr )
=> IExp instr i -> Array i a -> ProgramT instr m (IExp instr a)
getArray i = singleE . GetArray i
-- | Set an element of an array.
setArray
:: ( PredicateExp (IExp instr) a
, PredicateExp (IExp instr) i
, Integral i, Ix i
, ArrayCMD (IExp instr) :<: instr )
=> IExp instr i -> IExp instr a -> Array i a -> ProgramT instr m ()
setArray i a = singleE . SetArray i a
-- | Unsafe version of fetching the contents of an array's index.
unsafeGetArray
:: ( PredicateExp (IExp instr) a
, PredicateExp (IExp instr) i
, Integral i, Ix i
, ArrayCMD (IExp instr) :<: instr )
=> IExp instr i -> Array i a -> ProgramT instr m (IExp instr a)
unsafeGetArray i = singleE . UnsafeGetArray i
--------------------------------------------------------------------------------
-- ** Looping.
-- | For loop.
for
:: (LoopCMD (IExp instr) :<: instr, PredicateExp (IExp instr) n, Integral n)
=> IExp instr n
-> (IExp instr n -> ProgramT instr m ())
-> ProgramT instr m ()
for range = singleE . For range
-- | While loop.
while
:: (LoopCMD (IExp instr) :<: instr, PredicateExp (IExp instr) Bool)
=> ProgramT instr m (IExp instr Bool)
-> ProgramT instr m ()
-> ProgramT instr m ()
while cond = singleE . While cond
--------------------------------------------------------------------------------
-- ** Conditional statements.
-- | Conditional statements guarded by if and then clauses with an optional else.
conditional
:: (ConditionalCMD (IExp i) :<: i, PredicateExp (IExp i) Bool)
=> (IExp i Bool, ProgramT i m ())
-> [(IExp i Bool, ProgramT i m ())]
-> Maybe (ProgramT i m ())
-> ProgramT i m ()
conditional a bs = singleE . If a bs
-- | Guarded statement.
when
:: (ConditionalCMD (IExp i) :<: i, PredicateExp (IExp i) Bool)
=> IExp i Bool
-> ProgramT i m ()
-> ProgramT i m ()
when e p = conditional (e, p) [] Nothing
-- | Standard if-then-else statement.
iff
:: (ConditionalCMD (IExp i) :<: i, PredicateExp (IExp i) Bool)
=> IExp i Bool
-> ProgramT i m ()
-> ProgramT i m ()
-> ProgramT i m ()
iff b t e = conditional (b, t) [] (Just e)
--------------------------------------------------------------------------------
-- ** Structural entities.
-- | Declare a new entity by wrapping the program to declare ports & generics.
entity :: (StructuralCMD (IExp i) :<: i) => String -> ProgramT i m a -> ProgramT i m a
entity e = singleE . Entity e
-- | Declare a new architecture for some entity by wrapping the given program.
architecture :: (StructuralCMD (IExp i) :<: i) => String -> String -> ProgramT i m a -> ProgramT i m a
architecture e a = singleE . Architecture e a
-- | Declare a new process listening to some signals by wrapping the given program.
process :: (StructuralCMD (IExp i) :<: i) => [SignalX] -> ProgramT i m () -> ProgramT i m ()
process is = singleE . Process is
-- | ...
hideSig :: Signal a -> SignalX
hideSig = SignalX
--------------------------------------------------------------------------------