packages feed

atom 0.0.3 → 0.0.4

raw patch · 10 files changed

+270/−414 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Language.Atom.Elaboration: gAsserts :: Global -> [(String, UE)]
- Language.Atom.Elaboration: gUVs :: Global -> [UV]
- Language.Atom.Expressions: Local :: Const -> UVLocality
- Language.Atom.Expressions: constType :: Const -> Type
- Language.Atom.Expressions: ueType :: UE -> Type
- Language.Atom.Expressions: uvSet :: UE -> [UV]
- Language.Atom.Expressions: uvType :: UV -> Type
- Language.Atom.Language: assert :: Name -> E Bool -> Atom ()
- Language.Atom.Verify: instance Show Group
- Language.Atom.Verify: verify :: Int -> [[[Rule]]] -> [UV] -> (String, UE) -> IO Bool
+ Language.Atom.Elaboration: array :: (Expr a) => Name -> [a] -> Atom (A a)
+ Language.Atom.Elaboration: gInit16 :: Global -> [Const]
+ Language.Atom.Elaboration: gInit32 :: Global -> [Const]
+ Language.Atom.Elaboration: gInit64 :: Global -> [Const]
+ Language.Atom.Elaboration: gInit8 :: Global -> [Const]
+ Language.Atom.Expressions: (!) :: (Expr a, IntegralE b) => A a -> E b -> V a
+ Language.Atom.Expressions: (!.) :: (Expr a, IntegralE b) => A a -> E b -> E a
+ Language.Atom.Expressions: A :: UA -> A a
+ Language.Atom.Expressions: Array :: UA -> UE -> UVLocality
+ Language.Atom.Expressions: UA :: Int -> String -> [Const] -> UA
+ Language.Atom.Expressions: bytes :: (Width a) => a -> Int
+ Language.Atom.Expressions: class (NumE a, Integral a) => IntegralE a
+ Language.Atom.Expressions: class TypeOf a
+ Language.Atom.Expressions: data A a
+ Language.Atom.Expressions: data UA
+ Language.Atom.Expressions: instance (Expr a) => TypeOf (E a)
+ Language.Atom.Expressions: instance Eq (A a)
+ Language.Atom.Expressions: instance Eq UA
+ Language.Atom.Expressions: instance Eq UVLocality
+ Language.Atom.Expressions: instance Ord UA
+ Language.Atom.Expressions: instance Ord UVLocality
+ Language.Atom.Expressions: instance Show UA
+ Language.Atom.Expressions: instance TypeOf (A a)
+ Language.Atom.Expressions: instance TypeOf (V a)
+ Language.Atom.Expressions: instance TypeOf Const
+ Language.Atom.Expressions: instance TypeOf UA
+ Language.Atom.Expressions: instance TypeOf UE
+ Language.Atom.Expressions: instance TypeOf UV
+ Language.Atom.Expressions: typeOf :: (TypeOf a) => a -> Type
+ Language.Atom.Language: array :: (Expr a) => Name -> [a] -> Atom (A a)
+ Language.Atom.Scheduling: instance Eq Usage
+ Language.Atom.Scheduling: instance Ord Usage
- Language.Atom.Code: writeC :: Name -> Config -> [[[Rule]]] -> [UV] -> IO ()
+ Language.Atom.Code: writeC :: Name -> Config -> [[[Rule]]] -> ([Const], [Const], [Const], [Const]) -> IO ()
- Language.Atom.Elaboration: Global :: Int -> [(String, Type, E Word64)] -> [UV] -> Int -> [(String, UE)] -> Global
+ Language.Atom.Elaboration: Global :: Int -> [(String, Type, E Word64)] -> [Const] -> [Const] -> [Const] -> [Const] -> Int -> Global
- Language.Atom.Elaboration: elaborate :: Name -> Atom () -> IO (Maybe ([Rule], [UV], [(String, UE)]))
+ Language.Atom.Elaboration: elaborate :: Name -> Atom () -> IO (Maybe ([Rule], ([Const], [Const], [Const], [Const])))
- Language.Atom.Elaboration: var :: Name -> Const -> Atom (V a)
+ Language.Atom.Elaboration: var :: (Expr a) => Name -> a -> Atom (V a)
- Language.Atom.Expressions: External :: Type -> UVLocality
+ Language.Atom.Expressions: External :: String -> Type -> UVLocality
- Language.Atom.Expressions: UV :: Int -> String -> UVLocality -> UV
+ Language.Atom.Expressions: UV :: UVLocality -> UV
- Language.Atom.Language: var :: Name -> Const -> Atom (V a)
+ Language.Atom.Language: var :: (Expr a) => Name -> a -> Atom (V a)

Files

Language/Atom/Code.hs view
@@ -11,7 +11,9 @@ import Data.Char import Data.List import Data.Maybe+import Data.Word import System.IO+import Unsafe.Coerce  import Language.Atom.Elaboration import Language.Atom.Expressions@@ -34,30 +36,19 @@   , cPostCode = ""   } -declareMemory :: Config -> UV -> String-declareMemory config (UV id name (Local init)) = cType config (constType init) ++ " " ++ e id ++ " = " ++ c ++ ";  /* " ++ name ++ " */\n"-  where-  c = case init of-    CBool   c -> if c then "1" else "0" -    CInt8   c -> show c-    CInt16  c -> show c-    CInt32  c -> show c-    CInt64  c -> show c-    CWord8  c -> show c-    CWord16 c -> show c-    CWord32 c -> show c-    CWord64 c -> show c-    CFloat  c -> show c-    CDouble c -> show c-declareMemory _ (UV _ _ (External _)) = ""--declareUE :: Config -> String -> (UE, String) -> String-declareUE config d (ue, n) = case ue of-  UVRef _              -> ""-  UConst (CBool True ) -> d ++ "const " ++ cType config (ueType ue) ++ " " ++ n ++ " = 1;\n"-  UConst (CBool False) -> d ++ "const " ++ cType config (ueType ue) ++ " " ++ n ++ " = 0;\n"-  UConst c             -> d ++ "const " ++ cType config (ueType ue) ++ " " ++ n ++ " = " ++ show c ++ ";\n"-  _                    -> d ++             cType config (ueType ue) ++ " " ++ n ++ ";\n"+showConst :: Const -> String+showConst c = case c of+  CBool   c -> if c then "1" else "0" +  CInt8   c -> show c+  CInt16  c -> show c+  CInt32  c -> show c+  CInt64  c -> show c+  CWord8  c -> show c+  CWord16 c -> show c+  CWord32 c -> show c+  CWord64 c -> show c+  CFloat  c -> show c+  CDouble c -> show c  -- | ANSI C type naming rules. cTypes :: Type -> String@@ -90,17 +81,15 @@   Double -> "double"  codeUE :: Config -> [(UE, String)] -> String -> (UE, String) -> String-codeUE config ues d (ue, n) = case ue of-  UConst _       -> ""-  UVRef _        -> ""-  _              -> d ++ n ++ " = " ++ basic operands ++ ";\n"+codeUE config ues d (ue, n) = d ++ cType config (typeOf ue) ++ " " ++ n ++ " = " ++ basic operands ++ ";\n"   where   operands = map (fromJust . flip lookup ues) $ ueUpstream ue   basic :: [String] -> String   basic operands = case ue of-    UVRef _              -> error "Code.ueStmt: should not get here."-    UCast _ _            -> "(" ++ cType config (ueType ue) ++ ") (" ++ a ++ ")"-    UConst _             -> error "Code.ueStmt: should not get here."+    UVRef (UV (Array ua@(UA _ n _) _)) -> arrayIndex config ua a ++ " /* " ++ n ++ " */ "+    UVRef (UV (External n _)) -> n+    UCast _ _            -> "(" ++ cType config (typeOf ue) ++ ") " ++ a+    UConst c             -> showConst c     UAdd _ _             ->  a ++ " + " ++ b     USub _ _             ->  a ++ " - " ++ b     UMul _ _             ->  a ++ " * " ++ b@@ -124,8 +113,8 @@     b = operands !! 1     c = operands !! 2 -writeC :: Name -> Config -> [[[Rule]]] -> [UV] -> IO ()-writeC name config periods uvs = do+writeC :: Name -> Config -> [[[Rule]]] -> ([Const], [Const], [Const], [Const]) -> IO ()+writeC name config periods (init8, init16, init32, init64) = do   putStrLn $ "Writing C code (" ++ name ++ ".c)..."   writeFile (name ++ ".c") c   putStrLn $ "Writing coverage data description (" ++ name' ++ "CoverageData.hs)..."@@ -134,11 +123,11 @@   name' = toUpper (head name) : tail name   c = unlines     [ cPreCode config-    , cType config Word64 ++ " __clock = 0;"-    , "const " ++ cType config Word32 ++ " __coverage_len = " ++ show covLen ++ ";"-    , cType config Word32 ++ " __coverage[" ++ show covLen ++ "] = {" ++ drop 2 (concat $ replicate covLen ", 0") ++ "};"-    , cType config Word32 ++ " __coverage_index = 0;"-    , concatMap (declareMemory config) uvs+    , "static " ++ cType config Word64 ++ " __clock = 0;"+    , "static const " ++ cType config Word32 ++ " __coverage_len = " ++ show covLen ++ ";"+    , "static " ++ cType config Word32 ++ " __coverage[" ++ show covLen ++ "] = {" ++ drop 2 (concat $ replicate covLen ", 0") ++ "};"+    , "static " ++ cType config Word32 ++ " __coverage_index = 0;"+    , memoryInit config Word8  init8 ++ memoryInit config Word16 init16 ++ memoryInit config Word32 init32 ++ memoryInit config Word64 init64     , concatMap (codeRule config topo') $ concat $ concat periods     , "void " ++ (if null (cFuncName config) then name else cFuncName config) ++ "(void) {"     , concatMap codePeriod $ zip [1..] periods@@ -157,29 +146,65 @@     , "coverageData = " ++ show [ (ruleName r, (div (ruleId r) 32, mod (ruleId r) 32)) | r <- rules ]     ] -  topo' = topo $ maximum (map (\ (UV i _ _) -> i) uvs) + 1+  topo' = topo 0   covLen = 1 + div (maximum $ map ruleId rules) 32 +memoryInit :: Config -> Type -> [Const] -> String+memoryInit _ _ [] = ""+memoryInit config t init = "static " ++ cType config t ++ " " ++ memory t ++ "[" ++ show (length init) ++ "] = {" ++ drop 2 (concat [", " ++ format a | a <- init ]) ++ "};\n"+  where+  format :: Const -> String+  format c = case c of+    CBool True  -> "1"+    CBool False -> "0"+    CInt8   a   -> show a+    CInt16  a   -> show a+    CInt32  a   -> show a+    CInt64  a   -> show a+    CWord8  a   -> show a+    CWord16 a   -> show a+    CWord32 a   -> show a+    CWord64 a   -> show a+    CFloat  a   -> show $ floatBits  a+    CDouble a   -> show $ doubleBits a++floatBits :: Float -> Word32+floatBits = unsafeCoerce++doubleBits :: Double -> Word64+doubleBits = unsafeCoerce++memory :: Width a => a -> String+memory a = "__memory" ++ show (if width a == 1 then 8 else width a)+ codeRule :: Config -> ([UE] -> [(UE, String)]) -> Rule -> String codeRule config topo rule =    "/* " ++ show rule ++ " */\n" ++-  "void __r" ++ show (ruleId rule) ++ "(void) {\n" ++-  concatMap (declareUE config     "  ") ues +++  "static void __r" ++ show (ruleId rule) ++ "(void) {\n" ++   concatMap (codeUE    config ues "  ") ues ++   "  if (" ++ id (ruleEnable rule) ++ ") {\n" ++   concatMap codeAction (ruleActions rule) ++   "    __coverage[" ++ covWord ++ "] = __coverage[" ++ covWord ++ "] | (1 << " ++ covBit ++ ");\n" ++   "  }\n" ++-  concatMap (\ (uv, ue) -> "  " ++ v uv ++ " = " ++ id ue ++ ";\n") (ruleAssigns rule) +++  concatMap codeAssign (ruleAssigns rule) ++   "}\n\n"   where-  ues = topo $ ruleEnable rule : snd (unzip (ruleAssigns rule)) ++ concat (snd (unzip (ruleActions rule)))+  ues = topo $ allUEs rule   id ue = fromJust $ lookup ue ues+   codeAction :: (([String] -> String), [UE]) -> String   codeAction (f, args) = "    " ++ f (map id args) ++ ";\n"+   covWord = show $ div (ruleId rule) 32   covBit  = show $ mod (ruleId rule) 32 +  codeAssign :: (UV, UE) -> String+  codeAssign (UV (Array ua@(UA _ n _) i), ue) = "  " ++ arrayIndex config ua (id i) ++ " = " ++ id ue ++ ";  /* " ++ n ++ " */\n"+  codeAssign (UV (External n _), ue) = "  " ++ n ++ " = " ++ id ue ++ ";\n"++arrayIndex :: Config -> UA -> String -> String+arrayIndex config (UA addr _ c) i = "((" ++ cType config (typeOf (head c)) ++ " *) (" ++ memory (head c) ++ " + " ++ show addr ++ "))[" ++ i ++ "]"+ codePeriod :: (Int, [[Rule]]) -> String codePeriod (period, cycles) = concatMap (codeCycle period) $ zip [0..] cycles @@ -194,9 +219,12 @@ e :: Int -> String e i = "__" ++ show i -v :: UV -> String-v (UV i _ (Local _)) = e i-v (UV _ n (External _)) = n+allUEs :: Rule -> [UE]+allUEs rule = ruleEnable rule : concat [ ue : index uv | (uv, ue) <- ruleAssigns rule ] ++ concat (snd (unzip (ruleActions rule)))+  where+  index :: UV -> [UE]+  index (UV (Array _ ue)) = [ue]+  index _ = []  -- | Topologically sorts a list of expressions and subexpressions. topo :: Int -> [UE] -> [(UE, String)]@@ -205,14 +233,9 @@   (_, ues') = foldl collect (start, []) ues   collect :: (Int, [(UE, String)]) -> UE -> (Int, [(UE, String)])   collect (n, ues) ue | any ((== ue) . fst) ues = (n, ues)-  collect (n, ues) ue = case ue of-    UVRef (UV i _ (Local    _)) -> (n, (ue, e i) : ues)-    UVRef (UV _ a (External _)) -> (n, (ue, a)   : ues)-    _                -> (n' + 1, (ue, e n') : ues')-      where-      (n', ues') = foldl collect (n, ues) $ ueUpstream ue+  collect (n, ues) ue = (n' + 1, (ue, e n') : ues') where (n', ues') = foldl collect (n, ues) $ ueUpstream ue  -- | Number of UE's computed in rule. ruleComplexity :: Rule -> Int-ruleComplexity rule = length $ topo 0 $ ruleEnable rule : snd (unzip (ruleAssigns rule)) ++ concat (snd (unzip (ruleActions rule)))+ruleComplexity rule = length $ topo 0 $ allUEs rule 
Language/Atom/Compile.hs view
@@ -12,7 +12,6 @@ import Language.Atom.Scheduling import Language.Atom.Elaboration import Language.Atom.Language hiding (Atom)-import Language.Atom.Verify ()  -- | Compiles an atom description to C. compile :: Name -> Config -> Atom () -> IO ()@@ -20,18 +19,12 @@   r <- elaborate name atom   case r of     Nothing -> putStrLn "ERROR: Design rule checks failed." >> exitWith (ExitFailure 1)-    Just (rules, uvs, _) -> do+    Just (rules, init) -> do       r <- schedule name rules       case r of         Nothing -> putStrLn "ERROR: Rule scheduling failed." >> exitWith (ExitFailure 1)         Just schedule -> do-          {--          when (depth > 0) $ do-            putStrLn $ "Starting bounded model checking with depth " ++ show depth ++ "..."-            v <- mapM (verify depth schedule uvs) asserts -            when (not $ and v) $ putStrLn "ERROR: Verification failed." >> exitWith (ExitFailure 1)-          -}           putStrLn "Starting code generation..."           hFlush stdout-          writeC name config schedule uvs+          writeC name config schedule init 
Language/Atom/Elaboration.hs view
@@ -13,6 +13,7 @@   , elaborate   , var   , var'+  , array   , addName   , get   , put@@ -36,9 +37,11 @@ data Global = Global   { gId      :: Int   , gProbes  :: [(String, Type, E Word64)]-  , gUVs     :: [UV]+  , gInit8   :: [Const]+  , gInit16  :: [Const]+  , gInit32  :: [Const]+  , gInit64  :: [Const]   , gPeriod  :: Int-  , gAsserts :: [(String, UE)]   }  data AtomDB = AtomDB@@ -131,20 +134,17 @@ -- data Relation = Higher UID | Lower UID deriving (Show, Eq)  -- | Given a top level name and design, elabortes design and returns a design database.-elaborate :: Name -> Atom () -> IO (Maybe ([Rule], [UV], [(String, UE)]))+elaborate :: Name -> Atom () -> IO (Maybe ([Rule], ([Const], [Const], [Const], [Const]))) elaborate name atom = do   putStrLn "Starting atom elaboration..."   hFlush stdout-  (_, (g, atomDB)) <- buildAtom (Global { gId = 0, gProbes = [], gUVs = [], gPeriod = 1, gAsserts = [] }) name atom+  (_, (g, atomDB)) <- buildAtom (Global { gId = 0, gInit8 = [], gInit16 = [], gInit32 = [], gInit64 = [], gProbes = [], gPeriod = 1 }) name atom   let rules = reIdRules $ elaborateRules (ubool True) atomDB   mapM_ checkEnable rules   ok <- checkAssignConflicts atomDB   if not ok     then return Nothing-    else do-      let uvs = sort $ gUVs g-      ruleGraph name rules uvs-      return $ Just (rules, uvs, gAsserts g)+    else return $ Just (rules, (gInit8 g, gInit16 g, gInit32 g, gInit64 g))  checkEnable :: Rule -> IO () checkEnable rule | ruleEnable rule == ubool False = putStrLn $ "WARNING: Rule will never execute: " ++ show rule@@ -164,21 +164,32 @@   vars' = nub vars  -- | Generic local variable declaration.-var :: Name -> Const -> Atom (V a)-var name const = do-  name <- addName name-  (g, atom) <- get-  let uv = UV (gId g) name $ Local const-  put (g { gId = gId g  + 1, gUVs =  uv : gUVs g }, atom)-  return $ V uv+var :: Expr a => Name -> a -> Atom (V a)+var name init = do+  A a <- array name [init]+  return $ V $ UV $ Array a $ UConst $ CWord8 0  -- | Generic external variable declaration. var' :: Name -> Type -> Atom (V a)-var' name t = do+var' name t = return $ V $ UV $ External name t++-- | Generic array declaration.+array :: Expr a => Name -> [a] -> Atom (A a)+array name [] = error $ "ERROR: arrays can not be empty: " ++ name+array name init = do+  name <- addName name   (g, atom) <- get-  let uv = UV (gId g) name $ External t-  put (g { gId = gId g  + 1, gUVs =  uv : gUVs g }, atom)-  return $ V uv+  let constants = map constant init+      (addr, g') = case width $ head constants of+        1  -> (length $ gInit8  g, g { gInit8  = gInit8  g ++ constants })+        8  -> (length $ gInit8  g, g { gInit8  = gInit8  g ++ constants })+        16 -> (length $ gInit16 g, g { gInit16 = gInit16 g ++ constants })+        32 -> (length $ gInit32 g, g { gInit32 = gInit32 g ++ constants })+        64 -> (length $ gInit64 g, g { gInit64 = gInit64 g ++ constants })+        _  -> error "Elaboration.array: unknown width"+      ua = UA addr name constants+  put (g', atom)+  return $ A ua  addName :: Name -> Atom Name addName name = do@@ -189,6 +200,7 @@       put (g, atom { atomNames = name : atomNames atom })       return $ atomName atom ++ "." ++ name +{- ruleGraph :: Name -> [Rule] -> [UV] -> IO () ruleGraph name rules uvs = do   putStrLn $ "Writing rule graph (" ++ name ++ ".dot)..."@@ -214,4 +226,4 @@   ruleUVRefs r = nub $ concatMap uvSet ues     where     ues = ruleEnable r : snd (unzip (ruleAssigns r)) ++ concat (snd (unzip (ruleActions r)))-+-}
Language/Atom/Example.hs view
@@ -16,6 +16,7 @@   , "#include <stdio.h>"   , "unsigned long int a;"   , "unsigned long int b;"+  , "unsigned long int x;"   , "unsigned char running = 1;"   ] @@ -24,12 +25,12 @@   [ "int main(int argc, char* argv[]) {"   , "  a = atoi(argv[1]);"   , "  b = atoi(argv[2]);"-  , "  printf(\"Computing the GCD of %i and %i...\\n\", a, b);"+  , "  printf(\"Computing the GCD of %lu and %lu...\\n\", a, b);"   , "  while(running) {"   , "    example();"-  , "    printf(\"iteration:  a = %i  b = %i\\n\", a, b);"+  , "    printf(\"iteration:  a = %lu  b = %lu\\n\", a, b);"   , "  }"-  , "  printf(\"GCD result: %i\\n\", a);"+  , "  printf(\"GCD result: %lu\\n\", a);"   , "  return 0;"   , "}"   ]@@ -62,5 +63,4 @@   atom "stop" $ do     cond $ value a ==. value b     running <== false- 
Language/Atom/Expressions.hs view
@@ -6,20 +6,21 @@   , UE    (..)   , UV    (..)   , UVLocality (..)+  , A     (..)+  , UA    (..)   , Expr  (..)   , Expression (..)   , Variable   (..)   , Type  (..)   , Const (..)   , Width (..)-  , constType+  , TypeOf (..)+  , bytes   , ue   , uv-  , ueType-  , uvType   , ueUpstream-  , uvSet   , NumE+  , IntegralE   , FloatingE   , EqE   , OrdE@@ -53,6 +54,9 @@   , mod_   -- * Conditional Operator   , mux+  -- * Array Indexing+  , (!)+  , (!.)   -- * Smart constructors for untyped expressions.   , ubool   , unot@@ -71,6 +75,7 @@ --infixl 7 /., %. --infixl 6 +., -. --infixr 5 ++.+infixl 9 !, !. infix  4 ==., /=., <., <=., >., >=. infixl 3 &&. --, ^. -- , &&&, $&, $&& infixl 2 ||. -- , |||, $$, $:, $|@@ -120,20 +125,6 @@     CFloat  c -> show c     CDouble c -> show c -constType :: Const -> Type-constType c = case c of-  CBool   _ -> Bool-  CInt8   _ -> Int8-  CInt16  _ -> Int16-  CInt32  _ -> Int32-  CInt64  _ -> Int64-  CWord8  _ -> Word8-  CWord16 _ -> Word16-  CWord32 _ -> Word32-  CWord64 _ -> Word64-  CFloat  _ -> Float-  CDouble _ -> Double- data Expression   = EBool   (E Bool)   | EInt8   (E Int8)@@ -164,14 +155,18 @@ -- | Variables updated by state transition rules. data V a = V UV deriving Eq --- | Unsigned variables.-data UV = UV Int String UVLocality deriving Show-instance Eq   UV where UV a _ _  == UV b _ _ = a == b-instance Ord  UV where compare (UV a _ _) (UV b _ _) = compare a b+-- | Untyped variables.+data UV = UV UVLocality deriving (Show, Eq, Ord)  -- | UV locality.-data UVLocality = Local Const | External Type deriving Show+data UVLocality = Array UA UE | External String Type deriving (Show, Eq, Ord) +-- | A typed array.+data A a = A UA deriving Eq++-- | An untyped array.+data UA = UA Int String [Const] deriving (Show, Eq, Ord)+ -- | A typed expression. data E a where   VRef    :: V a -> E a@@ -230,6 +225,9 @@ class Width a where   width :: a -> Int +bytes :: Width a => a -> Int+bytes a = div (width a) 8 + if mod (width a) 8 == 0 then 0 else 1+ instance Width Type where   width t = case t of     Bool   -> 1@@ -244,11 +242,69 @@     Float  -> 32     Double -> 64 -instance Width Const           where width = width . constType-instance Expr a => Width (E a) where width = width . eType-instance Expr a => Width (V a) where width = width . eType . value-instance Width UE              where width = width . ueType+instance Width Const           where width = width . typeOf+instance Expr a => Width (E a) where width = width . typeOf+instance Expr a => Width (V a) where width = width . typeOf+instance Width UE              where width = width . typeOf +class TypeOf a where typeOf :: a -> Type++instance TypeOf Const where+  typeOf a = case a of+    CBool   _ -> Bool+    CInt8   _ -> Int8+    CInt16  _ -> Int16+    CInt32  _ -> Int32+    CInt64  _ -> Int64+    CWord8  _ -> Word8+    CWord16 _ -> Word16+    CWord32 _ -> Word32+    CWord64 _ -> Word64+    CFloat  _ -> Float+    CDouble _ -> Double++instance TypeOf UV where+  typeOf a = case a of+    UV (Array a _)  -> typeOf a+    UV (External _ t) -> t++instance TypeOf (V a) where+  typeOf (V uv) = typeOf uv++instance TypeOf UA where+  typeOf (UA _ _ c) = typeOf $ head c++instance TypeOf (A a) where+  typeOf (A ua) = typeOf ua++instance TypeOf UE where+  typeOf t = case t of+    UVRef uvar -> typeOf uvar+    UCast t _  -> t+    UConst c   -> typeOf c+    UAdd a _   -> typeOf a+    USub a _   -> typeOf a+    UMul a _   -> typeOf a+    UDiv a _   -> typeOf a+    UMod a _   -> typeOf a+    UNot _     -> Bool+    UAnd _     -> Bool+    UBWNot a   -> typeOf a+    UBWAnd a _ -> typeOf a+    UBWOr  a _ -> typeOf a+    UShift a _ -> typeOf a+    UEq  _ _   -> Bool+    ULt  _ _   -> Bool+    UMux _ a _ -> typeOf a+    UF2B _     -> Word32+    UD2B _     -> Word64+    UB2F _     -> Float+    UB2D _     -> Double++instance Expr a => TypeOf (E a) where+  typeOf = eType++ class Eq a => Expr a where   eType      :: E a -> Type   constant   :: a -> Const@@ -545,67 +601,21 @@ mux :: Expr a => E Bool -> E a -> E a -> E a mux = Mux --- | A set of all variables referenced in a term.-uvSet :: UE -> [UV]-uvSet = nub . uvList+-- | Array index to variable.+(!) :: (Expr a, IntegralE b) => A a -> E b -> V a+(A ua) ! e = V $ UV $ Array ua $ ue e -uvList :: UE -> [UV]-uvList t = case t of-  UVRef v      -> [v]-  UCast _ a    -> uvList a-  UConst _     -> []-  UAdd a b     -> uvList a ++ uvList b-  USub a b     -> uvList a ++ uvList b-  UMul a b     -> uvList a ++ uvList b-  UDiv a b     -> uvList a ++ uvList b-  UMod a b     -> uvList a ++ uvList b-  UNot a       -> uvList a-  UAnd a       -> concatMap uvList a-  UBWNot a     -> uvList a-  UBWAnd a b   -> uvList a ++ uvList b-  UBWOr  a b   -> uvList a ++ uvList b-  UShift a _   -> uvList a-  UEq  a b     -> uvList a ++ uvList b-  ULt  a b     -> uvList a ++ uvList b-  UMux a b c   -> uvList a ++ uvList b ++ uvList c-  UF2B a       -> uvList a-  UD2B a       -> uvList a-  UB2F a       -> uvList a-  UB2D a       -> uvList a+-- | Array index to expression.+(!.) :: (Expr a, IntegralE b) => A a -> E b -> E a+a !. i = value $ a ! i -uvType :: UV -> Type-uvType (UV _ _ (Local c))    = constType c-uvType (UV _ _ (External t)) = t --- | The type of an UE.-ueType :: UE -> Type-ueType t = case t of-  UVRef uvar -> uvType uvar-  UCast t _  -> t-  UConst c   -> constType c-  UAdd a _   -> ueType a-  USub a _   -> ueType a-  UMul a _   -> ueType a-  UDiv a _   -> ueType a-  UMod a _   -> ueType a-  UNot _     -> Bool-  UAnd _     -> Bool-  UBWNot a   -> ueType a-  UBWAnd a _ -> ueType a-  UBWOr  a _ -> ueType a-  UShift a _ -> ueType a-  UEq  _ _   -> Bool-  ULt  _ _   -> Bool-  UMux _ a _ -> ueType a-  UF2B _     -> Word32-  UD2B _     -> Word64-  UB2F _     -> Float-  UB2D _     -> Double  -- | The list of UEs adjacent upstream of a UE. ueUpstream :: UE -> [UE] ueUpstream t = case t of-  UVRef _   -> []+  UVRef (UV (Array _ ue))   -> [ue]+  UVRef (UV (External _ _)) -> []   UCast _ a   -> [a]   UConst _    -> []   UAdd a b    -> [a, b]@@ -741,7 +751,7 @@  umux :: UE -> UE -> UE -> UE umux _ t f | t == f = f-umux b t f | ueType t == Bool = uor (uand b t) (uand (unot b) f)+umux b t f | typeOf t == Bool = uor (uand b t) (uand (unot b) f) umux (UConst (CBool b)) t f = if b then t else f umux (UNot b) t f = umux b f t umux b1 (UMux b2 t _) f | b1 == b2 = umux b1 t f
Language/Atom/Language.hs view
@@ -13,12 +13,10 @@   , Assign (..)   , incr   , decr-  -- ** Performance Constraints-  --, required-  --, priority   -- * Variable Declarations   , var   , var'+  , array   , bool   , bool'   , int8@@ -43,8 +41,6 @@   , double'   -- * Custom Actions   , action-  -- * Assertions-  , assert   -- * Probing   , probe   , probes@@ -108,7 +104,7 @@  -- | Local boolean variable declaration. bool :: Name -> Bool -> Atom (V Bool)-bool name init = var name $ CBool init+bool = var  -- | External boolean variable declaration. bool' :: Name -> Atom (V Bool)@@ -116,7 +112,7 @@  -- | Local int8 variable declaration. int8 :: Name -> Int8 -> Atom (V Int8)-int8 name init = var name $ CInt8 init+int8 = var  -- | External int8 variable declaration. int8' :: Name -> Atom (V Int8)@@ -124,7 +120,7 @@  -- | Local int16 variable declaration. int16 :: Name -> Int16 -> Atom (V Int16)-int16 name init = var name $ CInt16 init+int16 = var  -- | External int16 variable declaration. int16' :: Name -> Atom (V Int16)@@ -132,7 +128,7 @@  -- | Local int32 variable declaration. int32 :: Name -> Int32 -> Atom (V Int32)-int32 name init = var name $ CInt32 init+int32 = var  -- | External int32 variable declaration. int32' :: Name -> Atom (V Int32)@@ -140,7 +136,7 @@  -- | Local int64 variable declaration. int64 :: Name -> Int64 -> Atom (V Int64)-int64 name init = var name $ CInt64 init+int64 = var  -- | External int64 variable declaration. int64' :: Name -> Atom (V Int64)@@ -148,7 +144,7 @@  -- | Local word8 variable declaration. word8 :: Name -> Word8 -> Atom (V Word8)-word8 name init = var name $ CWord8 init+word8 = var  -- | External word8 variable declaration. word8' :: Name -> Atom (V Word8)@@ -156,7 +152,7 @@  -- | Local word16 variable declaration. word16 :: Name -> Word16 -> Atom (V Word16)-word16 name init = var name $ CWord16 init+word16 = var  -- | External word16 variable declaration. word16' :: Name -> Atom (V Word16)@@ -164,7 +160,7 @@  -- | Local word32 variable declaration. word32 :: Name -> Word32 -> Atom (V Word32)-word32 name init = var name $ CWord32 init+word32 = var  -- | External word32 variable declaration. word32' :: Name -> Atom (V Word32)@@ -172,7 +168,7 @@  -- | Local word64 variable declaration. word64 :: Name -> Word64 -> Atom (V Word64)-word64 name init = var name $ CWord64 init+word64 = var  -- | External word64 variable declaration. word64' :: Name -> Atom (V Word64)@@ -180,7 +176,7 @@  -- | Local float variable declaration. float :: Name -> Float -> Atom (V Float)-float name init = var name $ CFloat init+float = var  -- | External float variable declaration. float' :: Name -> Atom (V Float)@@ -188,7 +184,7 @@  -- | Local double variable declaration. double :: Name -> Double -> Atom (V Double)-double name init = var name $ CDouble init+double = var  -- | External double variable declaration. double' :: Name -> Atom (V Double)@@ -200,18 +196,13 @@   (g, a) <- get   put (g, a { atomActions = atomActions a ++ [(f, ues)] }) --- | Asserts expression must always be true.-assert :: Name -> E Bool -> Atom ()-assert name a = do-  name <- addName name-  (g, atom) <- get-  put (g { gAsserts = gAsserts g ++ [(name, ue a)] }, atom)- -- | Declares a probe. probe :: Expr a => Name -> E a -> Atom () probe name a = do   (g, atom) <- get-  put (g { gProbes = (name, eType a, rawBits a) : gProbes g }, atom)+  if any (\ (n, _, _) -> name == n) $ gProbes g+    then error $ "ERROR: Duplicated probe name: " ++ name+    else put (g { gProbes = (name, eType a, rawBits a) : gProbes g }, atom)   -- | Fetches all declared probes to current design point.@@ -231,7 +222,7 @@   class Expr a => Assign a where-  -- | Assigns a 'E' to a 'V'.+  -- | Assign an 'E' to a 'V'.   (<==) :: V a -> E a -> Atom ()   v <== e = do     (g, atom) <- get@@ -259,11 +250,11 @@  -- | Reference to the 64-bit free running clock. clock :: E Word64-clock = value (V (UV (-1) "__clock" (External Word64)))+clock = value $ V $ UV $ External "__clock" Word64  -- | Rule coverage information.  (current coverage index, coverage data) nextCoverage :: Atom (E Word32, E Word32) nextCoverage = do   action (\_ -> "__coverage_index = (__coverage_index + 1) % __coverage_len") []-  return (value (V (UV (-2) "__coverage_index" (External Word32))), value (V (UV (-3) "__coverage[__coverage_index]" (External Word32))))+  return (value $ V $ UV $ External "__coverage_index" Word32, value $ V $ UV $ External "__coverage[__coverage_index]" Word32) 
Language/Atom/Scheduling.hs view
@@ -39,7 +39,12 @@ reportSchedule :: [[[Rule]]] -> String reportSchedule s = "Rule Scheduling Report\n\n  Period  Cycle  Exprs  Rule\n  ------  -----  -----  ----\n" ++ (concatMap reportPeriod) (zip [1..] s) ++                    "                 -----\n" ++-                   printf "                 %5i\n" (sum $ map ruleComplexity (concat (concat s)))+                   printf "                 %5i\n" (sum $ map ruleComplexity (concat (concat s))) ++ "\n" +++                   "Heirarchical Expression Count\n\n" +++                   "  Total   Local     Rule\n" +++                   "  ------  ------    ----\n" +++                   reportUsage "" (usage $ concat $ concat s) +++                   "\n"  reportPeriod (period, p) = concatMap (reportCycle period) (zip [0..] p) @@ -49,4 +54,33 @@ reportRule period cycle rule = printf "  %6i  %5i  %5i  %s\n" period cycle (ruleComplexity rule) (show rule)  +data Usage = Usage String Int [Usage] deriving Eq++instance Ord Usage where compare (Usage a _ _) (Usage b _ _) = compare a b++reportUsage :: String -> Usage -> String+reportUsage i node@(Usage name n subs) = printf "  %6i  %6i    %s\n" (totalComplexity node) n (i ++ name) ++ concatMap (reportUsage ("  " ++ i)) subs++totalComplexity :: Usage -> Int+totalComplexity (Usage _ n subs) = n + sum (map totalComplexity subs)++usage :: [Rule] -> Usage+usage rules = head $ foldl insertUsage [] $ map usage' rules++usage' :: Rule -> Usage+usage' rule = f $ split $ ruleName rule+  where+  f :: [String] -> Usage+  f [] = undefined+  f [name] = Usage name (ruleComplexity rule) []+  f (name:names) = Usage name 0 [f names]++split :: String -> [String]+split "" = []+split s = a : if null b then [] else split (tail b) where (a,b) = span (/= '.') s++insertUsage :: [Usage] -> Usage -> [Usage]+insertUsage [] u = [u]+insertUsage (a@(Usage n1 i1 s1) : rest) b@(Usage n2 i2 s2) | n1 == n2  = Usage n1 (max i1 i2) (sort $ foldl insertUsage s1 s2) : rest+                                                           | otherwise = a : insertUsage rest b 
− Language/Atom/Verify.hs
@@ -1,215 +0,0 @@-module Language.Atom.Verify (verify) where--import Data.Char-import Data.Int-import Data.List-import Data.Ratio-import Data.Word-import System.Process--import Language.Atom.Elaboration-import Language.Atom.Expressions--verify :: Int -> [[[Rule]]] -> [UV] -> (String, UE) -> IO Bool-verify depth rules uvs (name, assert) = do-  putStrLn $ "Checking assertion " ++ name ++ "..."-  verify-      -  where-  verify | assert == ubool True  = return True-         | assert == ubool False = putStrLn ("Assertion failed trivially.") >> return False-         | otherwise = do-             --putStrLn yices-             --putStrLn "***********************************************"-             out <- readProcess "yices" ["-e"] yices-             case parseYices out of-               S "unsat" : _ -> return True-               S "sat"   : vars' -> do-                 let vars = map (parseVar uvs) vars'-                 putStrLn ("Assertion failed.  See counter example: " ++ name ++ ".vcd")-                 writeFile (name ++ ".vcd") $ vcd uvs vars-                 return False-               _         -> error "Unexpected results from yices."-      -  assertUE :: Int -> String-  assertUE step = "(assert (not " ++ f ++ "))\n"-    where-    f = case assert of-      UVRef uv -> uvName step uv-      _        -> error "expressions not supported assertions yet"--  asserts = concatMap assertUE [0..depth]-  yices = initialize uvs ++ concatMap (transition rules uvs) [1..depth] ++ asserts ++ "(check)"--yicesType :: Type -> String-yicesType t = case t of-  Bool   -> "bool"-  Int8   -> "(bitvector  8)"-  Int16  -> "(bitvector 16)"-  Int32  -> "(bitvector 32)"-  Int64  -> "(bitvector 64)"-  Word8  -> "(bitvector  8)"-  Word16 -> "(bitvector 16)"-  Word32 -> "(bitvector 32)"-  Word64 -> "(bitvector 64)"-  Float  -> "real"-  Double -> "real"--vars :: [UV] -> Int -> String-vars uvs step = concatMap (var step) uvs-  where-  var :: Int -> UV -> String-  var step uv = "(define " ++ uvName step uv ++ "::" ++ yicesType (uvType uv) ++ ")\n"--uvName :: Int -> UV -> String-uvName step (UV i _ _) = "v" ++ show i ++ "_" ++ show step--initialize :: [UV] -> String-initialize uvs = vars uvs 0 ++ concatMap initialize uvs-  where-  initialize :: UV -> String-  initialize uv@(UV _ _ (Local c)) = "(assert (= " ++ uvName 0 uv ++ " " ++ const c ++ "))\n"-  initialize (UV _ _ (External _)) = ""-  const :: Const -> String-  const c = case c of-    CBool   c -> if c then "true" else "false" -    CInt8   c -> "0b" ++ bits  8 (fromIntegral c)-    CInt16  c -> "0b" ++ bits 16 (fromIntegral c)-    CInt32  c -> "0b" ++ bits 32 (fromIntegral c)-    CInt64  c -> "0b" ++ bits 64 (fromIntegral c)-    CWord8  c -> "0b" ++ bits  8 (fromIntegral c)-    CWord16 c -> "0b" ++ bits 16 (fromIntegral c)-    CWord32 c -> "0b" ++ bits 32 (fromIntegral c)-    CWord64 c -> "0b" ++ bits 64 (fromIntegral c)-    CFloat  c -> "(/ " ++ show (numerator $ toRational c) ++ " " ++ show (denominator $ toRational c) ++ ")"-    CDouble c -> "(/ " ++ show (numerator $ toRational c) ++ " " ++ show (denominator $ toRational c) ++ ")"--  bits :: Int -> Word64 -> String-  bits 0 _ = ""-  bits n a = bits (n - 1) (div a 2) ++ show (mod a 2)---- Time 0 to 1 is step 1.-transition :: [[[Rule]]] -> [UV] -> Int -> String-transition _ {-schedule-} uvs step = vars uvs step ++ transition-  where-  transition = "; transition " ++ show (step - 1) ++ " to " ++ show step ++ "\n"  --XXX--getUV :: [UV] -> Int -> UV-getUV [] _ = error "Verify.getUV"-getUV (uv@(UV i _ _):_) j | i == j = uv-getUV (_:a) i = getUV a i---parseVar :: [UV] -> Group -> (Int, UV, String)-parseVar uvs (G [S "=", S name, value]) = (t, getUV uvs i, parseValue value)-  where-  (i', t') = break (== '_') $ tail name-  i = read i'-  t = read $ tail t'-parseVar _ g = error $ "Verify.parseVar: " ++ show g--parseValue :: Group -> String-parseValue (S ('0':'b':a)) = "b" ++ a ++ " "-parseValue (S "true")      = "1"-parseValue (S "false")     = "0"-parseValue (S v)           = "r" ++ v ++ " "-parseValue (G [S "/", S n, S d]) = "r" ++ show (fromRational (read n % read d)) ++ " "-parseValue a               = error $ "Verify.parseValue: " ++ show a---data Group = G [Group] | S String deriving Show--parseYices :: String -> [Group]-parseYices = groups . tokens--groups :: [String] -> [Group]-groups [] = []-groups ("(":a) = G (groups x) : groups y where (x, y) = split 0 [] a-groups (a:b) = S a : groups b--split :: Int -> [String] -> [String] -> ([String], [String])-split 0 a (")":b) = (reverse a, b)-split n a ("(":b) = split (n + 1) ("(" : a) b-split n a (")":b) = split (n - 1) (")" : a) b-split n a (b:c)   = split n (b:a) c-split _ _ []      = error "Verify.split"--tokens :: String -> [String]-tokens [] = []-tokens (a:b) | isSpace a = tokens b-tokens ('(':b) = "(" : tokens b-tokens (')':b) = ")" : tokens b-tokens a = tokens' "" a--tokens' :: String -> String -> [String]-tokens' a [] = [reverse a]-tokens' a c@(b:_) | isSpace b || elem b "()" = reverse a : tokens c-tokens' a (b:c) = tokens' (b:a) c--data Heirarchy = Variable UV | Module String [Heirarchy]--vcd :: [UV] -> [(Int, UV, String)] -> String-vcd uvs signals' = header ++ samples ++ end-  where-  signals = sortBy (\ (a,_,_) (b,_,_) -> compare a b) signals' --  header = "$timescale\n  1 ms\n$end\n" ++ concatMap decl (heirarchy 0 uvs) ++ "$enddefinitions $end\n"-  (lastTime, _, _) = last signals-  end = "#" ++ show (lastTime + 1) ++ "\n"--  decl :: Heirarchy -> String-  decl (Module name subs) = "$scope module " ++ name ++ " $end\n" ++ concatMap decl subs ++ "$upscope $end\n"-  decl (Variable uv)      = declVar uv--  declVar :: UV -> String-  declVar uv@(UV i n _) = case uvType uv of-    Bool   -> "$var wire 1 "     ++ code ++ " " ++ name ++ " $end\n"-    Int8   -> "$var integer 8 "  ++ code ++ " " ++ name ++ " $end\n"-    Int16  -> "$var integer 16 " ++ code ++ " " ++ name ++ " $end\n"-    Int32  -> "$var integer 32 " ++ code ++ " " ++ name ++ " $end\n"-    Int64  -> "$var integer 64 " ++ code ++ " " ++ name ++ " $end\n"-    Word8  -> "$var wire 8 "     ++ code ++ " " ++ name ++ " $end\n"-    Word16 -> "$var wire 16 "    ++ code ++ " " ++ name ++ " $end\n"-    Word32 -> "$var wire 32 "    ++ code ++ " " ++ name ++ " $end\n"-    Word64 -> "$var wire 64 "    ++ code ++ " " ++ name ++ " $end\n"-    Float  -> "$var real 32 "    ++ code ++ " " ++ name ++ " $end\n"-    Double -> "$var real 64 "    ++ code ++ " " ++ name ++ " $end\n"-    where-    code = vcdCode i-    name = reverse $ takeWhile (/= '.') $ reverse n--  samples = concatMap sample signals--  sample (t, (UV i _ _), v) = "#" ++ show t ++ "\n" ++ v ++ vcdCode i ++ "\n"--heirarchy :: Int -> [UV] -> [Heirarchy]-heirarchy _ [] = []-heirarchy depth uvs = heirarchy' depth notvars ++ map Variable vars-  where-  isVar :: UV -> Bool-  isVar uv = length (path depth uv) == 1-  (vars, notvars) = partition isVar uvs--heirarchy' :: Int -> [UV] -> [Heirarchy]-heirarchy' _ [] = []-heirarchy' depth uvs@(a:_) = Module n (heirarchy (depth + 1) yes) : heirarchy' depth no-  where-  n = head $ path depth a-  isMod uv = n == head (path depth uv)-  (yes, no) = partition isMod uvs--path :: Int -> UV -> [String]-path depth (UV _ n _) = drop depth $ words $ map (\ c -> if c == '.' then ' ' else c) n- -vcdCode :: Int -> String-vcdCode i | i < 94 =              [chr (33 + mod i 94)] -vcdCode i = vcdCode (div i 94) ++ [chr (33 + mod i 94)] --{--bitString :: Int -> String-bitString n = if null bits then "0" else bits-  where-  bit :: Int -> Char-  bit i = if testBit n i then '1' else '0'-  bits = dropWhile (== '0') $ map bit $ reverse [0..31]--}
RELEASE-NOTES view
@@ -1,3 +1,12 @@+atom 0.0.4    05/19/2009++- Made local variables static in generated C.+- Added checking for duplicate probe names.+- Added hierarchical expression count report.+- Removed dot graph for rule-variable relationships.+- Added support for arrays.  See array, (!), and (!.).+  WARNING: No checks for index out of bounds or overlapping assignments.+ atom 0.0.3    05/05/2009  - Set build-depends: process >= 1.0.1.1 for readProcess
atom.cabal view
@@ -1,5 +1,5 @@ Name:           atom-Version:        0.0.3+Version:        0.0.4 Synopsis:       A DSL for embedded hard realtime applications. Description:    Atom is a Haskell DSL for designing hard realtime embedded programs.                 Based on conditional term rewriting, atom will compile@@ -26,8 +26,7 @@     Language.Atom.Example,     Language.Atom.Expressions,     Language.Atom.Language,-    Language.Atom.Scheduling,-    Language.Atom.Verify+    Language.Atom.Scheduling   extensions:      GADTs   ghc-options:     -W   Other-Modules: