packages feed

hardware-edsl-0.1.2: src/Language/Embedded/VHDL/Monad/Expression.hs

module Language.Embedded.VHDL.Monad.Expression
  ( and, or, xor, xnor, nand, nor
  , eq, neq, lt, lte, gt, gte
  , sll, srl, sla, sra, rol, ror
  , add, sub, cat, neg
  , mul, div, mod, rem
  , exp, abs, not
  , name, simple, indexed, selected, slice, attribute
  , literal, number, string
  , aggregate, aggregated, associated, others
  , function
  , qualified
  , cast
  -- utility.
  , resize, asBits, asSigned, asUnsigned, toSigned, toUnsigned, toInteger
  , range, downto, to
  , point, upper, lower, zero
  , choices, is, between
  ) where

import Language.VHDL

import Prelude hiding (and, or, div, mod, rem, exp, abs, not, null, toInteger)

--------------------------------------------------------------------------------
-- * Expressions and their sub-layers.
--------------------------------------------------------------------------------

relation :: RelationalOperator -> ShiftExpression -> ShiftExpression -> Relation
relation r a b = Relation a (Just (r, b))

shiftexp :: ShiftOperator -> SimpleExpression -> SimpleExpression -> ShiftExpression
shiftexp s a b = ShiftExpression a (Just (s, b))

simplexp :: Maybe Sign -> AddingOperator -> [Term] -> SimpleExpression
simplexp s o (a:as) = SimpleExpression s a (fmap ((,) o) as)

term :: MultiplyingOperator -> [Factor] -> Term
term o (a:as) = Term a (fmap ((,) o) as)

--------------------------------------------------------------------------------
-- ** Expressions

and, or, xor, xnor :: [Relation] -> Expression
and  = EAnd  
or   = EOr   
xor  = EXor  
xnor = EXnor

nand, nor :: Relation -> Relation -> Expression
nand a b = ENand a (Just b)
nor  a b = ENor  a (Just b)

--------------------------------------------------------------------------------
-- ** Relations

eq, neq, lt, lte, gt, gte :: ShiftExpression -> ShiftExpression -> Relation
eq  = relation Eq
neq = relation Neq
lt  = relation Lt
lte = relation Lte
gt  = relation Gt
gte = relation Gte

--------------------------------------------------------------------------------
-- ** Shift Expressions

sll, srl, sla, sra, rol, ror :: SimpleExpression -> SimpleExpression -> ShiftExpression
sll = shiftexp Sll
srl = shiftexp Srl
sla = shiftexp Sla
sra = shiftexp Sra
rol = shiftexp Rol
ror = shiftexp Ror

--------------------------------------------------------------------------------
-- ** Simple Expressions

add, sub, cat :: [Term] -> SimpleExpression
add = simplexp Nothing Plus
sub = simplexp Nothing Minus
cat = simplexp Nothing Concat

neg :: Term -> SimpleExpression
neg = simplexp (Just Negation) Plus . (: [])

--------------------------------------------------------------------------------
-- ** Terms

mul, div, mod, rem :: [Factor] -> Term
mul = term Times
div = term Div
mod = term Mod
rem = term Rem

--------------------------------------------------------------------------------
-- ** Factors

exp :: Primary -> Primary -> Factor
exp a b = FacPrim a (Just b)

abs, not :: Primary -> Factor
abs = FacAbs
not = FacNot

--------------------------------------------------------------------------------
-- ** Primaries.

--------------------------------------------------------------------------------
-- *** Names.

name :: Name -> Primary
name = PrimName

simple :: String -> Name
simple = NSimple . Ident

selected :: Name -> Identifier -> Name
selected i s = NSelect $ SelectedName (PName i) (SSimple s)

indexed :: Name -> Expression -> Name
indexed i l = NIndex $ IndexedName (PName i) [l]

slice :: Name -> Range -> Name
slice i r = NSlice $ SliceName (PName i) (DRRange r)

attribute :: String -> Name -> Primary
attribute s n = PrimName $ NAttr $ AttributeName (PName n) Nothing (Ident s) Nothing

--------------------------------------------------------------------------------
-- *** Literals.

literal :: Literal -> Primary
literal = PrimLit

number :: String -> Literal
number = LitNum . NLitPhysical . PhysicalLiteral Nothing . NSimple . Ident

string :: String -> Literal
string = LitString . SLit

--------------------------------------------------------------------------------
-- *** Aggregates.

aggregate :: Aggregate -> Primary
aggregate = PrimAgg

aggregated :: [Expression] -> Aggregate
aggregated = Aggregate . fmap (ElementAssociation Nothing)

associated :: [(Maybe Choices, Expression)] -> Aggregate
associated es = Aggregate $ map (uncurry ElementAssociation) es

others :: Expression -> Aggregate
others = Aggregate . (:[]) . ElementAssociation (Just (Choices [ChoiceOthers]))

--------------------------------------------------------------------------------
-- *** Functions.

function :: Name -> [Expression] -> Primary
function i [] = PrimFun $ FunctionCall i Nothing
function i xs = PrimFun
  . FunctionCall i . Just . AssociationList
  $ fmap (AssociationElement Nothing . APDesignator . ADExpression) xs

--------------------------------------------------------------------------------
-- *** Qualified.

qualified :: SubtypeIndication -> Expression -> Primary
qualified (SubtypeIndication _ t _) = PrimQual . QualExp t

--------------------------------------------------------------------------------
-- *** Type conversion.

cast :: SubtypeIndication -> Expression -> Primary
cast (SubtypeIndication _ t _) = PrimTCon . TypeConversion (unrange t)
  where
    unrange :: TypeMark -> TypeMark
    unrange (TMType (NSlice (SliceName (PName (NSimple (Ident typ))) _))) = TMType (NSimple (Ident typ))
    unrange (TMType (NSimple (Ident typ))) = TMType (NSimple (Ident typ))

--------------------------------------------------------------------------------
-- ...

resize :: Expression -> Expression -> Primary
resize exp size = function (simple "resize") [exp, size]

asBits :: Expression -> Primary
asBits exp = function (simple "std_logic_vector") [exp]

asSigned :: Expression -> Primary
asSigned exp = function (simple "signed") [exp]

asUnsigned :: Expression -> Primary
asUnsigned exp = function (simple "unsigned") [exp]

toSigned :: Expression -> Expression -> Primary
toSigned exp size = function (simple "to_signed") [exp, size]

toUnsigned :: Expression -> Expression -> Primary
toUnsigned exp size = function (simple "to_unsigned") [exp, size]

toInteger :: Expression -> Primary
toInteger exp = function (simple "to_integer") [exp]

--------------------------------------------------------------------------------
-- ...

range :: SimpleExpression -> Direction -> SimpleExpression -> Range
range  = RSimple

downto, to :: Direction
downto = DownTo
to     = To

--------------------------------------------------------------------------------
-- ...

point :: Show i => i -> SimpleExpression
point i = SimpleExpression Nothing (Term (FacPrim (literal (number (show i))) (Nothing)) []) []

upper, lower :: Integer -> SimpleExpression
upper 0 = point 0
upper n = point (n-1)
lower n = point n

zero :: SimpleExpression
zero = point 0

--------------------------------------------------------------------------------
-- ...

choices :: [Choice] -> Choices
choices = Choices

is :: SimpleExpression -> Choice
is = ChoiceSimple

between :: Range -> Choice
between = ChoiceRange . DRRange

--------------------------------------------------------------------------------