packages feed

clash-lib 0.5.2 → 0.5.3

raw patch · 8 files changed

+61/−134 lines, 8 filesdep +clash-preludePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: clash-prelude

API changes (from Hackage documentation)

- CLaSH.Driver.TopWrapper: [Clk] :: Text -> Int -> Clock
- CLaSH.Driver.TopWrapper: [ClockPath] :: Maybe (Text, Text) -> [(Text, Clock)] -> ClockPath
- CLaSH.Driver.TopWrapper: [ClockSource] :: Text -> [ClockPath] -> Maybe (Text, Text) -> Text -> Bool -> ClockSource
- CLaSH.Driver.TopWrapper: [TopEntity] :: Text -> [Text] -> [Text] -> [(Text, Int)] -> [(Text, Int)] -> [ClockSource] -> TopEntity
- CLaSH.Driver.TopWrapper: [c_lock] :: ClockSource -> Text
- CLaSH.Driver.TopWrapper: [c_name] :: ClockSource -> Text
- CLaSH.Driver.TopWrapper: [c_paths] :: ClockSource -> [ClockPath]
- CLaSH.Driver.TopWrapper: [c_reset] :: ClockSource -> Maybe (Text, Text)
- CLaSH.Driver.TopWrapper: [c_sync] :: ClockSource -> Bool
- CLaSH.Driver.TopWrapper: [clk_name] :: Clock -> Text
- CLaSH.Driver.TopWrapper: [clk_rate] :: Clock -> Int
- CLaSH.Driver.TopWrapper: [cp_inp] :: ClockPath -> Maybe (Text, Text)
- CLaSH.Driver.TopWrapper: [cp_outp] :: ClockPath -> [(Text, Clock)]
- CLaSH.Driver.TopWrapper: [t_clocks] :: TopEntity -> [ClockSource]
- CLaSH.Driver.TopWrapper: [t_extraIn] :: TopEntity -> [(Text, Int)]
- CLaSH.Driver.TopWrapper: [t_extraOut] :: TopEntity -> [(Text, Int)]
- CLaSH.Driver.TopWrapper: [t_inputs] :: TopEntity -> [Text]
- CLaSH.Driver.TopWrapper: [t_name] :: TopEntity -> Text
- CLaSH.Driver.TopWrapper: [t_outputs] :: TopEntity -> [Text]
- CLaSH.Driver.TopWrapper: data Clock
- CLaSH.Driver.TopWrapper: data ClockPath
- CLaSH.Driver.TopWrapper: data ClockSource
- CLaSH.Driver.TopWrapper: data TopEntity
- CLaSH.Driver.TopWrapper: generateTopEnt :: String -> IO (Maybe TopEntity)
- CLaSH.Driver.TopWrapper: instance Eq Clock
- CLaSH.Driver.TopWrapper: instance FromJSON Clock
- CLaSH.Driver.TopWrapper: instance FromJSON ClockPath
- CLaSH.Driver.TopWrapper: instance FromJSON ClockSource
- CLaSH.Driver.TopWrapper: instance FromJSON TopEntity
- CLaSH.Driver.TopWrapper: instance Show Clock
- CLaSH.Driver.TopWrapper: instance Show ClockPath
- CLaSH.Driver.TopWrapper: instance Show ClockSource
- CLaSH.Driver.TopWrapper: instance Show TopEntity
- CLaSH.Netlist.Types: instance MonadWriter [(Identifier, HWType)] NetlistMonad
+ CLaSH.Driver.TopWrapper: stringToVar :: String -> Expr
+ CLaSH.Netlist.Types: instance MonadWriter (Set (Identifier, HWType)) NetlistMonad
+ CLaSH.Netlist.Types: instance Ord HWType
- CLaSH.Driver.TopWrapper: clockPorts :: ClockPath -> ([(Identifier, Expr)], [Clock])
+ CLaSH.Driver.TopWrapper: clockPorts :: Maybe (String, String) -> [(String, String)] -> ([(Identifier, Expr)], [String])
- CLaSH.Driver.TopWrapper: genSyncReset :: PrimMap -> Identifier -> Identifier -> Clock -> NetlistMonad [Declaration]
+ CLaSH.Driver.TopWrapper: genSyncReset :: PrimMap -> Identifier -> Identifier -> Text -> Int -> NetlistMonad [Declaration]
- CLaSH.Driver.TopWrapper: mkClock :: ClockSource -> ([Declaration], (Identifier, [Clock], Bool))
+ CLaSH.Driver.TopWrapper: mkClock :: ClockSource -> ([Declaration], (Identifier, [String], Bool))
- CLaSH.Driver.TopWrapper: mkResets :: PrimMap -> [(Identifier, HWType)] -> [(Identifier, [Clock], Bool)] -> [Declaration]
+ CLaSH.Driver.TopWrapper: mkResets :: PrimMap -> [(Identifier, HWType)] -> [(Identifier, [String], Bool)] -> [Declaration]
- CLaSH.Netlist.BlackBox.Util: setClocks :: (MonadWriter [(Identifier, HWType)] m, Applicative m) => BlackBoxContext -> BlackBoxTemplate -> m BlackBoxTemplate
+ CLaSH.Netlist.BlackBox.Util: setClocks :: (MonadWriter (Set (Identifier, HWType)) m, Applicative m) => BlackBoxContext -> BlackBoxTemplate -> m BlackBoxTemplate
- CLaSH.Netlist.Types: [NetlistMonad] :: WriterT [(Identifier, HWType)] (StateT NetlistState (FreshMT IO)) a -> NetlistMonad a
+ CLaSH.Netlist.Types: [NetlistMonad] :: WriterT (Set (Identifier, HWType)) (StateT NetlistState (FreshMT IO)) a -> NetlistMonad a
- CLaSH.Netlist.Types: [runNetlist] :: NetlistMonad a -> WriterT [(Identifier, HWType)] (StateT NetlistState (FreshMT IO)) a
+ CLaSH.Netlist.Types: [runNetlist] :: NetlistMonad a -> WriterT (Set (Identifier, HWType)) (StateT NetlistState (FreshMT IO)) a

Files

CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog for the [`clash-lib`](http://hackage.haskell.org/package/clash-lib) package +## 0.5.3 *May 5th 2015*+* New features:+  * `TopEntity` wrappers are now specified as `ANN` annotation pragmas+* Fixes bugs:+  * Lost system1000 clock in VHDL generation... [#53](https://github.com/clash-lang/clash-compiler/issues/53)+  * `flattenCallTree` sometimes introduces free variables+ ## 0.5.2 *May 1st 2015* * New features:   * Generate wrappers around `topEntity` that have constant names and types
clash-lib.cabal view
@@ -1,5 +1,5 @@ Name:                 clash-lib-Version:              0.5.2+Version:              0.5.3 Synopsis:             CAES Language for Synchronous Hardware - As a Library Description:   CλaSH (pronounced ‘clash’) is a functional hardware description language that@@ -57,6 +57,7 @@                       attoparsec              >= 0.10.4.0,                       base                    >= 4.8 && < 5,                       bytestring              >= 0.10.0.2,+                      clash-prelude           >= 0.7.4,                       concurrent-supply       >= 0.1.7,                       containers              >= 0.5.0.0,                       deepseq                 >= 1.3.0.2,
src/CLaSH/Driver.hs view
@@ -20,6 +20,7 @@ import           Text.PrettyPrint.Leijen.Text     (Doc, hPutDoc) import           Unbound.Generics.LocallyNameless (name2String) +import           CLaSH.Annotations.TopEntity      (TopEntity) import           CLaSH.Backend import           CLaSH.Core.Term                  (Term) import           CLaSH.Core.Type                  (Type)
src/CLaSH/Driver/TopWrapper.hs view
@@ -12,17 +12,14 @@ -} module CLaSH.Driver.TopWrapper where -import           Data.Aeson           (FromJSON (..), Value (..), (.:), (.:?),-                                       (.!=))-import           Data.Aeson.Extra     (decodeAndReport)-import qualified Data.ByteString.Lazy as B-import qualified Data.HashMap.Strict  as H+ import qualified Data.HashMap.Lazy    as HashMap import           Data.List            (mapAccumL)-import           Data.Text.Lazy       (Text, append, pack)-import           System.Directory     (doesFileExist)+import           Data.Text.Lazy       (Text, append, pack, unpack) import           System.IO.Unsafe     (unsafePerformIO) +import CLaSH.Annotations.TopEntity    (TopEntity (..), ClockSource (..))+ import CLaSH.Netlist                  (runNetlistMonad) import CLaSH.Netlist.BlackBox         (prepareBlackBox) import CLaSH.Netlist.Types            (BlackBoxContext (..), Component (..),@@ -32,93 +29,6 @@ import CLaSH.Primitives.Types         (PrimMap, Primitive (..)) import CLaSH.Util --- | TopEntity specifications, fields are self-explanatory-data TopEntity-  = TopEntity-  { t_name     :: Text-  , t_inputs   :: [Text]        -- optional-  , t_outputs  :: [Text]        -- optional-  , t_extraIn  :: [(Text,Int)]  -- optional-  , t_extraOut :: [(Text,Int)]  -- optional-  , t_clocks   :: [ClockSource] -- optional-  }-  deriving Show---- | A clock source-data ClockSource-  = ClockSource-  { c_name  :: Text              -- ^ Component name-  , c_paths :: [ClockPath]       -- ^ Number of clock paths-  , c_reset :: Maybe (Text,Text) -- ^ optional: Asynchronous reset input-  , c_lock  :: Text              -- ^ Port name that indicates clock is stable-  , c_sync  :: Bool              -- ^ optional: devices connected this clock-                                 -- source should be pulled out of reset in-sync-  }-  deriving Show---- | A clock path-data ClockPath-  = ClockPath-  { cp_inp   :: Maybe (Text,Text) -- optional: (Input port, clock pin)-  , cp_outp  :: [(Text,Clock)]    -- [(output port,clock signal)]-  }-  deriving Show---- | A clock-data Clock-  = Clk { clk_name :: Text, clk_rate :: Int }-  deriving (Eq,Show)--instance FromJSON TopEntity where-  parseJSON (Object v) = case H.toList v of-    [(conKey,Object conVal)] -> case conKey of-      "TopEntity"  -> TopEntity <$> conVal .: "name"-                                <*> (conVal .:? "inputs" .!= [])-                                <*> (conVal .:? "outputs" .!= [])-                                <*> (conVal .:? "extra_in" .!= [])-                                <*> (conVal .:? "extra_out" .!= [])-                                <*> (conVal .:? "clocks" .!= [])-      _ -> error "Expected: TopEntity"-    _ -> error "Expected: TopEntity object"-  parseJSON _ = error "Expected: TopEntity object"--instance FromJSON ClockSource where-  parseJSON (Object v) = case H.toList v of-    [(conKey,Object conVal)] -> case conKey of-      "Source" -> ClockSource <$> conVal .: "name" <*> conVal .: "paths"-                              <*> conVal .:? "reset" <*> conVal .: "lock"-                              <*> (conVal .:? "sync" .!= False)-      _ -> error "Expected: Source"-    _ -> error "Expected: Source object"-  parseJSON _ = error "Expected: Source object"--instance FromJSON ClockPath where-  parseJSON (Object v) = case H.toList v of-    [(conKey,Object conVal)] -> case conKey of-      "Path" -> ClockPath <$> conVal .:? "inp" <*> conVal .: "outp"-      _ -> error "Expected: Path"-    _ -> error "Expected: Path object"-  parseJSON _ = error "Expected: Path object"--instance FromJSON Clock where-  parseJSON (Object v) = case H.toList v of-    [(conKey,Object conVal)] -> case conKey of-      "Clk" -> Clk <$> conVal .: "name" <*> conVal .: "rate"-      _ -> error "Expected: Clk"-    _ -> error "Expected: Clk object"-  parseJSON (String "System") = pure (Clk "system" 1000)-  parseJSON _ = error "Expected: System, or, Clk object"---- | Create a 'TopEntity' data type from the JSON encoded @.topentity@ file.-generateTopEnt :: String-               -> IO (Maybe TopEntity)-generateTopEnt modName = do-  let topEntityFile = modName ++ ".topentity"-  exists <- doesFileExist topEntityFile-  if exists-    then return . decodeAndReport <=< B.readFile $ topEntityFile-    else return Nothing- -- | Create a wrapper around a component, potentially initiating clock sources mkTopWrapper :: PrimMap              -> Maybe TopEntity -- ^ TopEntity specifications@@ -126,7 +36,7 @@              -> Component mkTopWrapper primMap teM topComponent   = Component-  { componentName = maybe "topEntity" t_name teM+  { componentName = maybe "topEntity" (pack . t_name) teM   , inputs        = inputs'' ++ extraIn teM   , outputs       = outputs'' ++ extraOut teM   , hiddenPorts   = case maybe [] t_clocks teM of@@ -138,7 +48,7 @@                            ]   }   where-    iNameSupply                = maybe [] t_inputs teM+    iNameSupply                = maybe [] (map pack . t_inputs) teM     originalHidden             = hiddenPorts topComponent      inputs'                    = map (first (const "input"))@@ -150,7 +60,7 @@                                             iNameSupply                                             (zip inputs' [0..]) -    oNameSupply                   = maybe [] t_outputs teM+    oNameSupply                   = maybe [] (map pack . t_outputs) teM     outputs'                      = map (first (const "output"))                                         (outputs topComponent)     (outputs'',(unwrappers,idsO)) = (concat *** (first concat . unzip))@@ -175,11 +85,11 @@  -- | Create extra input ports for the wrapper extraIn :: Maybe TopEntity -> [(Identifier,HWType)]-extraIn = maybe [] ((map (second BitVector)) . t_extraIn)+extraIn = maybe [] ((map (pack *** BitVector)) . t_extraIn)  -- | Create extra output ports for the wrapper extraOut :: Maybe TopEntity -> [(Identifier,HWType)]-extraOut = maybe [] ((map (second BitVector)) . t_extraOut)+extraOut = maybe [] ((map (pack *** BitVector)) . t_extraOut)  -- | Generate input port mappings mkInput :: [Identifier]@@ -292,52 +202,55 @@     , resets     ]   where-    hiddenSigDecs        = map (uncurry NetDecl) hidden+    hiddenSigDecs        = maybe [] (const (map (uncurry NetDecl) hidden)) teM     (clockGens,clkLocks) = maybe ([],[])                                  (first concat . unzip . map mkClock . t_clocks)                                  teM     resets               = mkResets primMap hidden clkLocks +stringToVar :: String -> Expr+stringToVar = (`Identifier` Nothing) . pack+ -- | Create a single clock generator-mkClock :: ClockSource -> ([Declaration],(Identifier,[Clock],Bool))+mkClock :: ClockSource -> ([Declaration],(Identifier,[String],Bool)) mkClock (ClockSource {..}) = ([lockedDecl,instDecl],(lockedName,clks,c_sync))   where-    lockedName   = append c_name "_locked"+    c_nameT      = pack c_name+    lockedName   = append c_nameT "_locked"     lockedDecl   = NetDecl lockedName (Reset lockedName 0)-    (ports,clks) = (concat *** concat) . unzip $ map clockPorts c_paths-    instDecl     = InstDecl c_name (append c_name "_inst")+    (ports,clks) = clockPorts c_inp c_outp+    instDecl     = InstDecl c_nameT (append c_nameT "_inst")                  $ concat [ ports-                          , maybe [] ((:[]) . second (`Identifier` Nothing))+                          , maybe [] ((:[]) . (pack *** stringToVar))                                   c_reset-                          , [(c_lock,Identifier lockedName Nothing)]+                          , [(pack c_lock,Identifier lockedName Nothing)]                           ]  -- | Create a single clock path-clockPorts :: ClockPath -> ([(Identifier,Expr)],[Clock])-clockPorts (ClockPath {..}) = (inp ++ outp,clks)+clockPorts :: Maybe (String,String) -> [(String,String)]+           -> ([(Identifier,Expr)],[String])+clockPorts inp outp = (inp' ++ outp',clks)   where-    inp  = maybe [] ((:[]) . second (`Identifier` Nothing)) cp_inp-    outp = map (second ((`Identifier` Nothing) . clkToId)) cp_outp-    clks = map snd cp_outp--    clkToId (Clk nm r) = append nm (pack (show r))+    inp'  = maybe [] ((:[]) . (pack *** stringToVar)) inp+    outp' = map (pack *** stringToVar) outp+    clks  = map snd outp  -- | Generate resets mkResets :: PrimMap          -> [(Identifier,HWType)]-         -> [(Identifier,[Clock],Bool)]+         -> [(Identifier,[String],Bool)]          -> [Declaration] mkResets primMap hidden = unsafeRunNetlist . fmap concat . mapM assingReset   where     assingReset (lock,clks,doSync) = concat <$> mapM connectReset matched       where         matched = filter match hidden-        match (_,(Reset nm r)) = elem (Clk nm r) clks+        match (_,(Reset nm r)) = elem (unpack nm ++ show r) clks         match _                = False          connectReset (rst,(Reset nm r)) = if doSync             then return [Assignment rst (Identifier lock Nothing)]-            else genSyncReset primMap lock rst (Clk nm r)+            else genSyncReset primMap lock rst nm r         connectReset _ = return []  -- | Generate a reset synchroniser that synchronously de-asserts an@@ -345,9 +258,10 @@ genSyncReset :: PrimMap              -> Identifier              -> Identifier-             -> Clock+             -> Text+             -> Int              -> NetlistMonad [Declaration]-genSyncReset primMap lock rst (Clk nm r) = do+genSyncReset primMap lock rst nm r = do   let resetType = Reset rst 0       ctx = emptyBBContext               { bbResult = (Right ((Identifier rst Nothing),(nm,r)), resetType)
src/CLaSH/Netlist.hs view
@@ -7,12 +7,13 @@ import           Control.Lens                     ((.=), (<<%=)) import qualified Control.Lens                     as Lens import           Control.Monad.State              (runStateT)-import           Control.Monad.Writer             (listen, runWriterT)+import           Control.Monad.Writer             (listen, runWriterT, tell) import           Data.Either                      (lefts,partitionEithers) import           Data.HashMap.Lazy                (HashMap) import qualified Data.HashMap.Lazy                as HashMap-import           Data.List                        (elemIndex, nub)+import           Data.List                        (elemIndex) import           Data.Maybe                       (fromMaybe)+import           Data.Set                         (toList,fromList) import qualified Data.Text.Lazy                   as Text import           Unbound.Generics.LocallyNameless (Embed (..), name2String,                                                   runFreshMT, unbind, unembed,@@ -137,7 +138,7 @@    let compInps       = zip (map (mkBasicId . Text.pack . name2String . varName) arguments) argTypes       compOutp       = (mkBasicId . Text.pack $ name2String result, resType)-      component      = Component componentName' (nub clks) compInps [compOutp] (netDecls ++ decls)+      component      = Component componentName' (toList clks) compInps [compOutp] (netDecls ++ decls)   return component  -- | Generate a list of Declarations for a let-binder@@ -245,6 +246,7 @@                     outpAssign    = (fst compOutp,Identifier dstId Nothing)                     instLabel     = Text.concat [compName, Text.pack "_", dstId]                     instDecl      = InstDecl compName instLabel (outpAssign:hiddenAssigns ++ inpAssigns)+                tell (fromList hidden)                 return (argDecls ++ [instDecl])         else error $ $(curLoc) ++ "under-applied normalized function"     Nothing -> case args of
src/CLaSH/Netlist/BlackBox/Util.hs view
@@ -13,6 +13,7 @@ import           Control.Monad.Writer                 (MonadWriter, tell) import           Data.Foldable                        (foldrM) import qualified Data.IntMap                          as IntMap+import           Data.Set                             (Set,singleton) import           Data.Text.Lazy                       (Text) import qualified Data.Text.Lazy                       as Text import           Text.PrettyPrint.Leijen.Text.Monadic (displayT, renderCompact,@@ -76,7 +77,7 @@                       _             -> pure e               ) -setClocks :: ( MonadWriter [(Identifier,HWType)] m+setClocks :: ( MonadWriter (Set (Identifier,HWType)) m              , Applicative m              )           => BlackBoxContext@@ -89,19 +90,19 @@      setClocks' (Clk Nothing)  = let (clk,rate) = clkSyncId $ fst $ bbResult bc                                     clkName    = Text.append clk (Text.pack (show rate))-                                in  tell [(clkName,Clock clk rate)] >> return (C clkName)+                                in  tell (singleton (clkName,Clock clk rate)) >> return (C clkName)     setClocks' (Clk (Just n)) = let (e,_,_)    = bbInputs bc !! n                                     (clk,rate) = clkSyncId e                                     clkName    = Text.append clk (Text.pack (show rate))-                                in  tell [(clkName,Clock clk rate)] >> return (C clkName)+                                in  tell (singleton (clkName,Clock clk rate)) >> return (C clkName)      setClocks' (Rst Nothing)  = let (rst,rate) = clkSyncId $ fst $ bbResult bc                                     rstName    = Text.concat [rst,Text.pack (show rate),"_rstn"]-                                in  tell [(rstName,Reset rst rate)] >> return (C rstName)+                                in  tell (singleton (rstName,Reset rst rate)) >> return (C rstName)     setClocks' (Rst (Just n)) = let (e,_,_)    = bbInputs bc !! n                                     (rst,rate) = clkSyncId e                                     rstName    = Text.concat [rst,Text.pack (show rate),"_rstn"]-                                in  tell [(rstName,Reset rst rate)] >> return (C rstName)+                                in  tell (singleton (rstName,Reset rst rate)) >> return (C rstName)      setClocks' e = return e 
src/CLaSH/Netlist/Types.hs view
@@ -11,6 +11,7 @@ import Data.Hashable import Data.HashMap.Lazy                    (HashMap) import Data.IntMap.Lazy                     (IntMap, empty)+import Data.Set                             (Set) import qualified Data.Text                  as S import Data.Text.Lazy                       (Text, pack) import GHC.Generics                         (Generic)@@ -28,11 +29,11 @@ -- of components that are being generated (WriterT) newtype NetlistMonad a =   NetlistMonad { runNetlist :: WriterT-                               [(Identifier,HWType)]+                               (Set (Identifier,HWType))                                (StateT NetlistState (FreshMT IO))                                a                }-  deriving (Functor, Monad, Applicative, MonadWriter [(Identifier,HWType)],+  deriving (Functor, Monad, Applicative, MonadWriter (Set (Identifier,HWType)),             MonadState NetlistState, Fresh, MonadIO)  -- | State of the NetlistMonad@@ -85,7 +86,7 @@   | SP       Identifier [(Identifier,[HWType])] -- ^ Sum-of-Product type: Name and Constructor names + field types   | Clock    Identifier Int -- ^ Clock type with specified name and period   | Reset    Identifier Int -- ^ Reset type corresponding to clock with a specified name and period-  deriving (Eq,Show,Generic)+  deriving (Eq,Ord,Show,Generic)  instance Hashable HWType instance NFData HWType
src/CLaSH/Normalize.hs view
@@ -10,7 +10,7 @@ import           Data.Either                      (partitionEithers) import           Data.HashMap.Strict              (HashMap) import qualified Data.HashMap.Strict              as HashMap-import           Data.List                        (mapAccumL)+import           Data.List                        (mapAccumL,intersect) import qualified Data.Map                         as Map import qualified Data.Maybe                       as Maybe import qualified Data.Set                         as Set@@ -165,9 +165,9 @@                                 then Nothing                                 else Just args   where-    mentionsId t = case t of-                     (Left (Var _ nm)) | nm `elem` allIds -> True-                     _ -> False+    mentionsId t = not $ null (either (Lens.toListOf termFreeIds) (const []) t+                              `intersect`+                              allIds)  stripArgs allIds (id_:ids) (Left (Var _ nm):args)       | varName id_ == nm = stripArgs allIds ids args