clash-lib-1.10.0: src/Clash/Backend.hs
{-|
Copyright : (C) 2015-2016, University of Twente,
2017 , Myrtle Software Ltd, Google Inc.,
2021-2022, QBayLogic B.V.
2022 , Google Inc.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Clash.Backend where
import Data.HashMap.Strict (HashMap, empty)
import Data.HashSet (HashSet)
import Control.Lens (Lens')
import Data.Monoid (Ap)
import Data.Text (Text)
import qualified Data.Text.Lazy as LT
import Control.Monad.State (State)
import Data.Text.Prettyprint.Doc.Extra (Doc)
import GHC.Types.SrcLoc (SrcSpan)
import Clash.Driver.Types (ClashOpts)
import {-# SOURCE #-} Clash.Netlist.Types
(Component, Declaration, Expr, HWType, Identifier, IdentifierSet, HasIdentifierSet, UsageMap)
import Clash.Netlist.BlackBox.Types
import Clash.Signal.Internal (VDomainConfiguration)
import Clash.Annotations.Primitive (HDL)
#ifdef CABAL
import qualified Paths_clash_lib
import qualified Data.Version
#else
import qualified System.FilePath
#endif
primsRoot :: IO FilePath
#ifdef CABAL
primsRoot = Paths_clash_lib.getDataFileName "prims"
#else
primsRoot = return ("clash-lib" System.FilePath.</> "prims")
#endif
clashVer :: String
#ifdef CABAL
clashVer = Data.Version.showVersion Paths_clash_lib.version
#else
clashVer = "development"
#endif
type ModName = Text
-- | Is a type used for internal or external use
data Usage
= Internal
-- ^ Internal use
| External Text
-- ^ External use, field indicates the library name
-- | Is '-fclash-aggresive-x-optimization-blackbox' set?
newtype AggressiveXOptBB = AggressiveXOptBB Bool
-- | Is '-fclash-render-enums' set?
newtype RenderEnums = RenderEnums Bool
-- | Kind of a HDL type. Used to determine whether types need conversions in
-- order to cross top entity boundaries.
data HWKind
= PrimitiveType
-- ^ A type defined in an HDL spec. Usually types such as: bool, bit, ..
| SynonymType
-- ^ A user defined type that's simply a synonym for another type, very much
-- like a type synonym in Haskell. As long as two synonym types refer to the
-- same type, they can be used interchangeably. E.g., a subtype in VHDL.
| UserType
-- ^ User defined type that's not interchangeable with any others, even if
-- the underlying structures are the same. Similar to an ADT in Haskell.
type DomainMap = HashMap Text VDomainConfiguration
emptyDomainMap :: DomainMap
emptyDomainMap = empty
class HasUsageMap s where
usageMap :: Lens' s UsageMap
class (HasUsageMap state, HasIdentifierSet state) => Backend state where
-- | Initial state for state monad
initBackend :: ClashOpts -> state
-- | What HDL is the backend generating
hdlKind :: state -> HDL
-- | Location for the primitive definitions
primDirs :: state -> IO [FilePath]
-- | Name of backend, used for directory to put output files in. Should be
-- constant function / ignore argument.
name :: state -> String
-- | File extension for target langauge
extension :: state -> String
-- | Get the set of types out of state
extractTypes :: state -> HashSet HWType
-- | Generate HDL for a Netlist component
genHDL :: ClashOpts -> ModName -> SrcSpan -> IdentifierSet -> UsageMap -> Component -> Ap (State state) ((String, Doc),[(String,Doc)])
-- | Generate a HDL package containing type definitions for the given HWTypes
mkTyPackage :: ModName -> [HWType] -> Ap (State state) [(String, Doc)]
-- | Convert a Netlist HWType to a target HDL type
hdlType :: Usage -> HWType -> Ap (State state) Doc
-- | Query what kind of type a given HDL type is
hdlHWTypeKind :: HWType -> State state HWKind
-- | Convert a Netlist HWType to an HDL error value for that type
hdlTypeErrValue :: HWType -> Ap (State state) Doc
-- | Convert a Netlist HWType to the root of a target HDL type
hdlTypeMark :: HWType -> Ap (State state) Doc
-- | Create a record selector
hdlRecSel :: HWType -> Int -> Ap (State state) Doc
-- | Create a signal declaration from an identifier (Text) and Netlist HWType
hdlSig :: LT.Text -> HWType -> Ap (State state) Doc
-- | Create a generative block statement marker
genStmt :: Bool -> State state Doc
-- | Turn a Netlist Declaration to a HDL concurrent block
inst :: Declaration -> Ap (State state) (Maybe Doc)
-- | Turn a Netlist expression into a HDL expression
expr :: Bool -- ^ Enclose in parentheses?
-> Expr -- ^ Expr to convert
-> Ap (State state) Doc
-- | Bit-width of Int,Word,Integer
iwWidth :: State state Int
-- | Convert to a bit-vector
toBV :: HWType -> LT.Text -> Ap (State state) Doc
-- | Convert from a bit-vector
fromBV :: HWType -> LT.Text -> Ap (State state) Doc
-- | Synthesis tool we're generating HDL for
hdlSyn :: State state HdlSyn
-- | setModName
setModName :: ModName -> state -> state
-- | Set the name of the current top entity
setTopName :: Identifier -> state -> state
-- | Get the name of the current top entity
getTopName :: State state Identifier
-- | setSrcSpan
setSrcSpan :: SrcSpan -> State state ()
-- | getSrcSpan
getSrcSpan :: State state SrcSpan
-- | Block of declarations
blockDecl :: Identifier -> [Declaration] -> Ap (State state) Doc
addIncludes :: [(String, Doc)] -> State state ()
addLibraries :: [LT.Text] -> State state ()
addImports :: [LT.Text] -> State state ()
addAndSetData :: FilePath -> State state String
getDataFiles :: State state [(String,FilePath)]
addMemoryDataFile :: (String,String) -> State state ()
getMemoryDataFiles :: State state [(String,String)]
ifThenElseExpr :: state -> Bool
-- | Whether -fclash-aggressive-x-optimization-blackboxes was set
aggressiveXOptBB :: State state AggressiveXOptBB
-- | Whether -fclash-no-render-enums was set
renderEnums :: State state RenderEnums
-- | All the domain configurations of design
domainConfigurations :: State state DomainMap
-- | Set the domain configurations
setDomainConfigurations :: DomainMap -> state -> state