{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Clash.Netlist.Types
(Declaration (..,NetDecl), module Clash.Netlist.Types)
where
import Control.DeepSeq
import Control.Monad.State.Strict (MonadIO, MonadState, StateT)
import Data.Hashable
import Data.HashMap.Lazy (HashMap)
import Data.IntMap.Lazy (IntMap, empty)
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.Annotations.TopEntity (TopEntity)
import Clash.Core.Term (TmOccName)
import Clash.Core.Type (Type)
import Clash.Core.TyCon (TyCon, TyConOccName)
import Clash.Driver.Types (BindingMap)
import Clash.Netlist.BlackBox.Types
import Clash.Netlist.Id (IdType)
import Clash.Primitives.Types (PrimMap)
import Clash.Signal.Internal (ClockKind, ResetKind)
import Clash.Util
newtype NetlistMonad a =
NetlistMonad { runNetlist :: StateT NetlistState (FreshMT IO) a }
deriving (Functor, Monad, Applicative, MonadState NetlistState, Fresh, MonadIO)
data NetlistState
= NetlistState
{ _bindings :: BindingMap
, _varCount :: !Int
, _components :: HashMap TmOccName (SrcSpan,Component)
, _primitives :: PrimMap BlackBoxTemplate
, _typeTranslator :: HashMap TyConOccName TyCon -> Bool -> Type -> Maybe (Either String HWType)
, _tcCache :: HashMap TyConOccName TyCon
, _curCompNm :: !(Identifier,SrcSpan)
, _dataFiles :: [(String,FilePath)]
, _intWidth :: Int
, _mkIdentifierFn :: IdType -> Identifier -> Identifier
, _extendIdentifierFn :: IdType -> Identifier -> Identifier -> Identifier
, _seenIds :: [Identifier]
, _seenComps :: [Identifier]
, _componentNames :: HashMap TmOccName Identifier
, _topEntityAnns :: HashMap TmOccName (Type, Maybe TopEntity)
, _hdlDir :: FilePath
, _curBBlvl :: Int
}
type Identifier = Text
data Component
= Component
{ componentName :: !Identifier
, inputs :: [(Identifier,HWType)]
, outputs :: [(WireOrReg,(Identifier,HWType))]
, declarations :: [Declaration]
}
deriving Show
instance NFData Component where
rnf c = case c of
Component nm inps outps decls -> rnf nm `seq` rnf inps `seq`
rnf outps `seq` rnf decls
type Size = Int
data HWType
= Void (Maybe HWType)
| String
| Bool
| Bit
| BitVector !Size
| Index !Integer
| Signed !Size
| Unsigned !Size
| Vector !Size !HWType
| RTree !Size !HWType
| Sum !Identifier [Identifier]
| Product !Identifier [HWType]
| SP !Identifier [(Identifier,[HWType])]
| Clock !Identifier !Integer !ClockKind
| Reset !Identifier !Integer !ResetKind
deriving (Eq,Ord,Show,Generic)
instance Hashable ClockKind
instance Hashable ResetKind
instance Hashable HWType
instance NFData HWType
data Declaration
= Assignment !Identifier !Expr
| CondAssignment !Identifier !HWType !Expr !HWType [(Maybe Literal,Expr)]
| InstDecl (Maybe Identifier) !Identifier !Identifier [(Expr,PortDirection,HWType,Expr)]
| BlackBoxD !S.Text [BlackBoxTemplate] [BlackBoxTemplate] (Maybe ((S.Text,S.Text),BlackBoxTemplate)) !BlackBoxTemplate BlackBoxContext
| NetDecl' (Maybe Identifier) WireOrReg !Identifier (Either Identifier HWType)
deriving Show
data WireOrReg = Wire | Reg
deriving (Show,Generic)
instance NFData WireOrReg
pattern NetDecl :: Maybe Identifier -> Identifier -> HWType -> Declaration
pattern NetDecl note d ty <- NetDecl' note Wire d (Right ty)
where
NetDecl note d ty = NetDecl' note Wire d (Right ty)
data PortDirection = In | Out
deriving Show
instance NFData Declaration where
rnf a = a `seq` ()
data Modifier
= Indexed (HWType,Int,Int)
| DC (HWType,Int)
| VecAppend
| RTreeAppend
| Nested Modifier Modifier
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] [BlackBoxTemplate] (Maybe ((S.Text,S.Text),BlackBoxTemplate)) !BlackBoxTemplate !BlackBoxContext !Bool
| ConvBV (Maybe Identifier) HWType Bool Expr
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 :: (Expr,HWType)
, bbInputs :: [(Expr,HWType,Bool)]
, bbFunctions :: IntMap (Either BlackBoxTemplate (Identifier,[Declaration])
,WireOrReg
,[BlackBoxTemplate]
,[BlackBoxTemplate]
,Maybe ((S.Text,S.Text),BlackBoxTemplate),BlackBoxContext)
, bbQsysIncName :: Maybe Identifier
, bbLevel :: Int
}
deriving Show
emptyBBContext :: BlackBoxContext
emptyBBContext = Context (Identifier (pack "__EMPTY__") Nothing, Void Nothing) [] empty Nothing (-1)
makeLenses ''NetlistState