module CLaSH.Netlist.Types where
import Control.DeepSeq
import Control.Monad.State.Strict (MonadIO, MonadState, StateT)
import Control.Monad.Writer.Strict (MonadWriter, WriterT)
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)
import Unbound.Generics.LocallyNameless (Fresh, FreshMT)
import SrcLoc (SrcSpan)
import CLaSH.Core.Term (Term, TmName)
import CLaSH.Core.Type (Type)
import CLaSH.Core.TyCon (TyCon, TyConName)
import CLaSH.Core.Util (Gamma)
import CLaSH.Netlist.BlackBox.Types
import CLaSH.Primitives.Types (PrimMap)
import CLaSH.Util
newtype NetlistMonad a =
NetlistMonad { runNetlist :: WriterT
(Set (Identifier,HWType))
(StateT NetlistState (FreshMT IO))
a
}
deriving (Functor, Monad, Applicative, MonadWriter (Set (Identifier,HWType)),
MonadState NetlistState, Fresh, MonadIO)
data NetlistState
= NetlistState
{ _bindings :: HashMap TmName (Type,SrcSpan,Term)
, _varEnv :: Gamma
, _varCount :: !Int
, _components :: HashMap TmName (SrcSpan,Component)
, _primitives :: PrimMap BlackBoxTemplate
, _typeTranslator :: HashMap TyConName TyCon -> Type -> Maybe (Either String HWType)
, _tcCache :: HashMap TyConName TyCon
, _curCompNm :: !(Identifier,SrcSpan)
, _dataFiles :: [(String,FilePath)]
, _intWidth :: Int
, _mkBasicIdFn :: Identifier -> Identifier
, _seenIds :: [Identifier]
, _seenComps :: [Identifier]
, _componentNames :: HashMap TmName Identifier
}
type Identifier = Text
data Component
= Component
{ componentName :: !Identifier
, hiddenPorts :: [(Identifier,HWType)]
, inputs :: [(Identifier,HWType)]
, outputs :: [(Identifier,HWType)]
, declarations :: [Declaration]
}
deriving Show
instance NFData Component where
rnf c = case c of
Component nm hi inps outps decls -> rnf nm `seq` rnf hi `seq` rnf inps `seq`
rnf outps `seq` rnf decls
type Size = Int
data HWType
= Void
| String
| Bool
| BitVector !Size
| Index !Integer
| Signed !Size
| Unsigned !Size
| Vector !Size !HWType
| Sum !Identifier [Identifier]
| Product !Identifier [HWType]
| SP !Identifier [(Identifier,[HWType])]
| Clock !Identifier !Integer
| Reset !Identifier !Integer
deriving (Eq,Ord,Show,Generic)
instance Hashable HWType
instance NFData HWType
data Declaration
= Assignment !Identifier !Expr
| CondAssignment !Identifier !HWType !Expr !HWType [(Maybe Literal,Expr)]
| InstDecl !Identifier !Identifier [(Identifier,PortDirection,HWType,Expr)]
| BlackBoxD !S.Text !BlackBoxTemplate BlackBoxContext
| NetDecl !Identifier !HWType
deriving Show
data PortDirection = In | Out
deriving Show
instance NFData Declaration where
rnf a = a `seq` ()
data Modifier
= Indexed (HWType,Int,Int)
| DC (HWType,Int)
| VecAppend
deriving Show
data Expr
= Literal !(Maybe (HWType,Size)) !Literal
| DataCon !HWType !Modifier [Expr]
| Identifier !Identifier !(Maybe Modifier)
| DataTag !HWType !(Either Identifier Identifier)
| BlackBoxE !S.Text !BlackBoxTemplate !BlackBoxContext !Bool
deriving Show
data Literal
= NumLit !Integer
| BitLit !Bit
| BoolLit !Bool
| VecLit [Literal]
| StringLit !String
deriving (Eq,Show)
data Bit
= H
| L
| U
| Z
deriving (Eq,Show)
data BlackBoxContext
= Context
{ bbResult :: (SyncExpr,HWType)
, bbInputs :: [(SyncExpr,HWType,Bool)]
, bbFunctions :: IntMap (Either BlackBoxTemplate Declaration,BlackBoxContext)
}
deriving Show
emptyBBContext :: BlackBoxContext
emptyBBContext = Context (Left $ Identifier (pack "__EMPTY__") Nothing, Void) [] empty
type SyncIdentifier = Either Identifier (Identifier,(Identifier,Int))
type SyncExpr = Either Expr (Expr,(Identifier,Integer))
makeLenses ''NetlistState