⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 language.hs

📁 Cores are generated from Confluence a modern logic design language. Confluence is a simple, yet high
💻 HS
字号:
-- | The Atom language.module Language.Atom.Language  (    module Language.Atom.Terms  -- * Primary Language Containers  , System  , Action  -- * Namespace Control  , scope  , scopeEnabled  , scopePeriodic  -- * System Sample Period  , samplePeriod  -- * Compile-time and Runtime Assertions  , assert  -- * Rule Declarations and Operations  , rule  , rules  , sequenceActions  , loopActions  -- * Action Directives  , when  , (<==)  --, display  --, finish  , incrInt  , decrInt  -- ** Performance Constraints  , priority  , alwaysActiveWhenEnabled  -- * Variable Declarations  , bool  , int  , float  , double  -- * Variable Declarations  , input  , Name  , lift  , liftIO  ) whereimport Control.Monad.State hiding (when, join)import Control.Monad.Transimport Language.Atom.Elaboration hiding (System, Action)import qualified Language.Atom.Elaboration as Eimport Language.Atom.Termsimport Language.Atom.Utilsinfixr 1 <==-- | A System captures various declarations including inputs, variables, rules, and assertions.type System = E.System-- | An Action captures rule behavior including enabling conditions (eg. 'when') and variable updates (eg, '<==').type Action = E.Action-- | Creates a new namespace.scope :: Name -> System a -> System ascope name system = scopeEnabled name true system-- | Creates a new namespace with an enabling condition.scopeEnabled :: Name -> Term Bool -> System a -> System ascopeEnabled name enable system = do  sys <- get  put sys    { sysPath    = name : sysPath sys    , sysEnable  = sysEnable sys &&. enable    , sysContent = []    }  a <- system  sys' <- get  put sys'    { sysPath    = sysPath sys    , sysEnable  = sysEnable sys    , sysContent = SystemScope name (sysContent sys') : sysContent sys    }  return a-- | Creates a new namespace with a periodic enabling condition.scopePeriodic :: Name -> Int -> Int -> System a -> System ascopePeriodic name period offset system = if period < 0 || offset < 0 then error ("Invalid period of offset for periodic scope: " ++ name) else do  clock <- int (name ++ "_clock") offset  rule (name ++ "_clock_tick") $ do    alwaysActiveWhenEnabled    clock <== mux (value clock ==. 0) (intC $ period - 1) (value clock - 1)  sys <- get  put sys { sysPeriod = sysPeriod sys * fromIntegral period }  a <- scopeEnabled name (value clock ==. 0) system  sys' <- get  put sys' { sysPeriod = sysPeriod sys }  return a-- | Returns the sample period (sec) of the current 'System' scope.--   The sample period is altered with system scopes created with 'scopePeriodic'.samplePeriod :: System DoublesamplePeriod = do  sys <- get  return $ sysPeriod sysclass Assert a where  -- | Asserts a property is always true.  Supports compile-time assertions (ie. Bool)  --   and runtime assertsion (ie. Term Bool).  assert :: Name -> a -> System ()instance Assert Bool where  assert name a = do    sys <- get    if not a      then error $ "ASSERT ERROR: " ++ join (reverse (name : sysPath sys)) "."      else return ()instance Assert (Term Bool) where  assert name a = do    sys <- get    let t = (reverse (name : sysPath sys), a)    put sys      { sysAsserts = t : sysAsserts sys      , sysContent = SystemAssert name t : sysContent sys      }nextId :: System IntnextId = do  sys <- get  put $ sys { sysNextId = sysNextId sys + 1 }  return $ sysNextId sys{--- | Addition.(+.) :: Signal -> Signal -> Signal(+.) a b | width a /= width b = error "(+.): Signals do not have same width."(+.) a b = x where (x,_) = fullAdd (bits a) (bits b)fullAdd :: [Signal] -> [Signal] -> (Signal,Signal)fullAdd (a:as) (b:bs) = ((a ^. b ^. c) ++ x, ((a ^. b) &. c) |. (a &. b)) where (x,c) = fullAdd as bsfullAdd _ _ = ([],false)-- | Subtraction.(-.) :: Signal -> Signal -> Signal(-.) a b | width a /= width b = error "(-.): Signals do not have same width."(-.) a b = x where (x,_) = fullSub (bits a) (bits b)fullSub :: [Signal] -> [Signal] -> (Signal,Signal)fullSub (a:as) (b:bs) = ((a ^. b ^. c) ++ x, (inv (a ^. b) &. c) |. (inv a &. b)) where (x,c) = fullSub as bsfullSub _ _ = ([],false)-}{--- | Logical XOR.(^^.) :: Term Bool -> Term Bool -> Term Bool(^^.) a b = (a &&. inv b) ||. (inv a &&. b)-- | Implication.imply :: Term Bool -> Term Bool -> Term Boolimply a b = inv a ||. b-- | Equivalence.equiv :: Term Bool -> Term Bool -> Term Boolequiv a b = inv (a ^^. b)-}{--- | A 2-input mux.---- > mux ctrl onHigh onLow  -- Verilog equivalent:  ctrl ? onHigh : onLow--mux :: Signal -> Signal -> Signal -> Signal--mux c _ _ | width c /= 1 = error "mux: Control signal is not a single bit."--mux _ h l | width h /= width l = error "mux: Data do not have the same width."--mux c h l = concatMap mux' $ zip (bits h) (bits l)  --where  --mux' (h,l) | h == l = h  --mux' (h,l) = (c &. h) |. (inv c &. l)-- | A tree of muxs to select data from a list of signals.--muxs :: Signal -> [Signal] -> Signal--muxs _ []  = error "muxs: Can not mux an empty list."--muxs _ [s] = s--muxs c _ | null c = error "muxs: Not enough control bits to select data."--muxs c s = muxs (msbs c) (muxRow s)  --where  --muxRow :: [Signal] -> [Signal]  --muxRow [] = []  --muxRow [a] = [a]  --muxRow (a:b:r) = mux (lsb c) b a : muxRow r -}-- | Boolean variable declaration.bool :: Name -> Bool -> System (Var Bool)bool name init = do  sys <- get  let v = Var (reverse (name : sysPath sys)) init      uv = UVarBool v  put sys    { sysVars = uv : sysVars sys    , sysContent = SystemVar name uv : sysContent sys    }  return v-- | Int variable declaration.int :: Name -> Int -> System (Var Int)int name init = do  sys <- get  let v = Var (reverse (name : sysPath sys)) init      uv = UVarInt v  put sys    { sysVars = uv : sysVars sys    , sysContent = SystemVar name uv : sysContent sys    }  return v-- | Float variable declaration.float :: Name -> Float -> System (Var Float)float name init = do  sys <- get  let v = Var (reverse (name : sysPath sys)) init      uv = UVarFloat v  put sys    { sysVars = uv : sysVars sys    , sysContent = SystemVar name uv : sysContent sys    }  return v-- | Double variable declaration.double :: Name -> Double -> System (Var Double)double name init = do  sys <- get  let v = Var (reverse (name : sysPath sys)) init      uv = UVarDouble v  put sys    { sysVars = uv : sysVars sys    , sysContent = SystemVar name uv : sysContent sys    }  return v-- | Declare a primary input.  Use variable declarions without initial values.----   > a <- input bool   "a"--   > b <- input int    "b"--   > c <- input float  "c"--   > d <- input double "d"--input :: TermT a => (Name -> a -> System (Var a)) -> Name -> System (Term a)input f name = do  Var n _ <- f name zeroConst  let input = Input n  sys <- get  put sys    { sysVars = tail (sysVars sys)    , sysIns  = uterm input : sysIns sys    , sysContent = SystemInput name (uterm input) : tail (sysContent sys)    }  return input-- | Increments a 'Var Int'.incrInt :: Var Int -> Action ()incrInt a = a <== value a + 1-- | Decrements a 'Var Int'.decrInt :: Var Int -> Action ()decrInt a = a <== value a - 1-- | Given a name and an 'Action', adds a transition rule to the 'System'.---- > rule "ruleName" actionrule :: Name -> Action () -> System ()rule name action = do  i <- nextId  act <- buildAction action  sys <- get  let rule = Rule { ruleUID = i                  , ruleName = reverse (name : sysPath sys)                  , ruleEnable = sysEnable sys &&. actEnable act                  , ruleAssigns           = actAssigns           act                  , ruleActiveWhenEnabled = actActiveWhenEnabled act                  , ruleRelations         = actRelations         act                  }  put sys { sysRules = rule : sysRules sys }-- | Defines a rule for each action.rules :: Name -> [Action ()] -> System ()rules name actions = mapM_ (\ (a,n) -> rule (name ++ show n) a) $ zip actions [0..]class Assign a where  -- | Assigns a 'Term' to a 'Var'.  (<==) :: Var a -> Term a -> Action ()instance Assign Bool where  v <== t = do    act <- get    put $ act { actAssigns = (UVarBool v, UTermBool t) : actAssigns act }instance Assign Int where  v <== t = do    act <- get    put $ act { actAssigns = (UVarInt v, UTermInt t) : actAssigns act }instance Assign Float where  v <== t = do    act <- get    put $ act { actAssigns = (UVarFloat v, UTermFloat t) : actAssigns act }instance Assign Double where  v <== t = do    act <- get    put $ act { actAssigns = (UVarDouble v, UTermDouble t) : actAssigns act }-- | Adds an enabling condition to an action.when :: Term Bool -> Action ()when c = do  act <- get  put $ act { actEnable = actEnable act &&. c }-- | Sequences 'Action's in consecutive cycles.sequenceActions :: Name -> [Action ()] -> System ()sequenceActions name actions = do  count <- int (name ++ "SequenceCount") 0  mapM_ (sequenceRule count) $ zip [0..] actions  where  sequenceRule :: Var Int -> (Int, Action ()) -> System ()  sequenceRule count (n,a) = rule (name ++ show n) $ do      when (value count ==. intC n)      a      incrInt count  -- | Loops through a list of 'Action's in consecutive cycles.  Goes back to first once last is finished.loopActions :: Name -> [Action ()] -> System ()loopActions name actions = do  count <- int (name ++ "LoopCount") 0  mapM_ (loopRule count) $ zip [0..] actions  where  loopRule :: Var Int -> (Int, Action ()) -> System ()  loopRule count (n,a) = rule (name ++ show n) $ do      when (value count ==. intC n)      a      if n == length actions - 1        then count <== 0        else incrInt count-- | Used to define priority between rules.  Returns two 'Action's.  The first should be called in the higher priority rule.--   The second should be called in the lower priority rule.---- > (higherPriority, lowerPriority) <- prioritypriority :: System (Action (), Action ())priority = do  i <- nextId  let higher = do        act <- get        put $ act { actRelations = Higher i : actRelations act }      lower  = do        act <- get        put $ act { actRelations = Lower  i : actRelations act }  return (higher,lower)-- | Asserts the current 'Action' must always be active when enabled.alwaysActiveWhenEnabled :: Action ()alwaysActiveWhenEnabled = do  act <- get  put $ act { actActiveWhenEnabled = True }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -