    {-|
      Copyright  :  (C) 2013-2016, University of Twente,
                        2016-2017, Myrtle Software Ltd,
                        2017     , QBayLogic, Google Inc.,
                        2020-2022, QBayLogic,
                        2022     , Google Inc.,
      License    :  BSD2 (see the file LICENSE)
      Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>

      Type definitions used by the Driver module
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveAnyClass #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RecordWildCards #-}

    module Clash.Driver.Types where

    -- For Int/Word size
    #include "MachDeps.h"

    import           Control.DeepSeq                (NFData(rnf), deepseq)
    import           Data.Binary                    (Binary)
    import           Data.Fixed
    import           Data.Hashable
    import           Data.HashMap.Strict            (HashMap)
    import           Data.IntMap.Strict             (IntMap)
    import           Data.Maybe                     (isJust)
    import           Data.Set                       (Set)
    import qualified Data.Set                       as Set
    import           Data.Text                      (Text)
    import qualified Data.Text as Text              (dropAround)

    #if MIN_VERSION_prettyprinter(1,7,0)
    import           Prettyprinter
    #else
    import           Data.Text.Prettyprint.Doc
    #endif

    import           GHC.Generics                   (Generic)

    #if MIN_VERSION_ghc(9,4,0)
    import           GHC.Types.Basic                (InlineSpec)
    import           GHC.Types.SrcLoc               (SrcSpan)
    import           GHC.Data.Bool                  (OverridingBool(..))
    #elif MIN_VERSION_ghc(9,0,0)
    import           GHC.Types.Basic                (InlineSpec)
    import           GHC.Types.SrcLoc               (SrcSpan)
    import           GHC.Utils.Misc                 (OverridingBool(..))
    #else
    import           BasicTypes                     (InlineSpec)
    import           SrcLoc                         (SrcSpan)
    import           Util                           (OverridingBool(..))
    #endif

    import           Clash.Annotations.BitRepresentation.Internal (CustomReprs)
    import           Clash.Signal.Internal

    import           Clash.Backend.Verilog.Time     (Period(..), Unit(Fs))
    import           Clash.Core.Term                (Term)
    import           Clash.Core.TyCon               (TyConMap, TyConName)
    import           Clash.Core.Var                 (Id)
    import           Clash.Core.VarEnv              (VarEnv)
    import           Clash.Netlist.BlackBox.Types   (HdlSyn (..))
    import {-# SOURCE #-} Clash.Netlist.Types       (PreserveCase(..), TopEntityT)
    import           Clash.Primitives.Types         (CompiledPrimMap)

    data ClashEnv = ClashEnv
      { ClashEnv -> ClashOpts
    envOpts        :: ClashOpts
      , ClashEnv -> TyConMap
    envTyConMap    :: TyConMap
      , ClashEnv -> IntMap TyConName
    envTupleTyCons :: IntMap TyConName
      , ClashEnv -> CompiledPrimMap
    envPrimitives  :: CompiledPrimMap
      , ClashEnv -> CustomReprs
    envCustomReprs :: CustomReprs
      , ClashEnv -> DomainMap
    envDomains     :: DomainMap
      } deriving ((forall x. ClashEnv -> Rep ClashEnv x)
    -> (forall x. Rep ClashEnv x -> ClashEnv) -> Generic ClashEnv
    forall x. Rep ClashEnv x -> ClashEnv
    forall x. ClashEnv -> Rep ClashEnv x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ClashEnv -> Rep ClashEnv x
    from :: forall x. ClashEnv -> Rep ClashEnv x
    $cto :: forall x. Rep ClashEnv x -> ClashEnv
    to :: forall x. Rep ClashEnv x -> ClashEnv
    Generic, ClashEnv -> ()
    (ClashEnv -> ()) -> NFData ClashEnv
    forall a. (a -> ()) -> NFData a
    $crnf :: ClashEnv -> ()
    rnf :: ClashEnv -> ()
    NFData)

    data ClashDesign = ClashDesign
      { ClashDesign -> [TopEntityT]
    designEntities :: [TopEntityT]
      , ClashDesign -> BindingMap
    designBindings :: BindingMap
      }

    instance NFData ClashDesign where
      rnf :: ClashDesign -> ()
    rnf ClashDesign
    design =
        ClashDesign -> [TopEntityT]
    designEntities ClashDesign
    design [TopEntityT] -> () -> ()
    forall a b. a -> b -> b
    `seq`
        ClashDesign -> BindingMap
    designBindings ClashDesign
    design BindingMap -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ()

    data IsPrim
      = IsPrim
        -- ^ The binding is the unfolding for a primitive.
      | IsFun
        -- ^ The binding is an ordinary function.
      deriving (Get IsPrim
    [IsPrim] -> Put
    IsPrim -> Put
    (IsPrim -> Put) -> Get IsPrim -> ([IsPrim] -> Put) -> Binary IsPrim
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: IsPrim -> Put
    put :: IsPrim -> Put
    $cget :: Get IsPrim
    get :: Get IsPrim
    $cputList :: [IsPrim] -> Put
    putList :: [IsPrim] -> Put
    Binary, IsPrim -> IsPrim -> Bool
    (IsPrim -> IsPrim -> Bool)
    -> (IsPrim -> IsPrim -> Bool) -> Eq IsPrim
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: IsPrim -> IsPrim -> Bool
    == :: IsPrim -> IsPrim -> Bool
    $c/= :: IsPrim -> IsPrim -> Bool
    /= :: IsPrim -> IsPrim -> Bool
    Eq, (forall x. IsPrim -> Rep IsPrim x)
    -> (forall x. Rep IsPrim x -> IsPrim) -> Generic IsPrim
    forall x. Rep IsPrim x -> IsPrim
    forall x. IsPrim -> Rep IsPrim x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. IsPrim -> Rep IsPrim x
    from :: forall x. IsPrim -> Rep IsPrim x
    $cto :: forall x. Rep IsPrim x -> IsPrim
    to :: forall x. Rep IsPrim x -> IsPrim
    Generic, IsPrim -> ()
    (IsPrim -> ()) -> NFData IsPrim
    forall a. (a -> ()) -> NFData a
    $crnf :: IsPrim -> ()
    rnf :: IsPrim -> ()
    NFData, Int -> IsPrim -> ShowS
    [IsPrim] -> ShowS
    IsPrim -> String
    (Int -> IsPrim -> ShowS)
    -> (IsPrim -> String) -> ([IsPrim] -> ShowS) -> Show IsPrim
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> IsPrim -> ShowS
    showsPrec :: Int -> IsPrim -> ShowS
    $cshow :: IsPrim -> String
    show :: IsPrim -> String
    $cshowList :: [IsPrim] -> ShowS
    showList :: [IsPrim] -> ShowS
    Show)

    -- A function binder in the global environment.
    --
    data Binding a = Binding
      { forall a. Binding a -> Id
    bindingId :: Id
        -- ^ The core identifier for this binding.
      , forall a. Binding a -> SrcSpan
    bindingLoc :: SrcSpan
        -- ^ The source location of this binding in the original source code.
      , forall a. Binding a -> InlineSpec
    bindingSpec :: InlineSpec
        -- ^ the inline specification for this binding, in the original source code.
      , forall a. Binding a -> IsPrim
    bindingIsPrim :: IsPrim
        -- ^ Is the binding a core term corresponding to a primitive with a known
        -- implementation? If so, it can potentially be inlined despite being
        -- marked as NOINLINE in source.
      , forall a. Binding a -> a
    bindingTerm :: a
        -- ^ The term representation for this binding. This is polymorphic so
        -- alternate representations can be used if more appropriate (i.e. in the
        -- evaluator this can be Value for evaluated bindings).
      , forall a. Binding a -> Bool
    bindingRecursive :: Bool
        -- ^ Whether the binding is recursive.
        --
        -- TODO Ideally the BindingMap would store recursive and non-recursive
        -- bindings in a way similar to Let / Letrec. GHC also does this.
      } deriving (Get (Binding a)
    [Binding a] -> Put
    Binding a -> Put
    (Binding a -> Put)
    -> Get (Binding a) -> ([Binding a] -> Put) -> Binary (Binding a)
    forall a. Binary a => Get (Binding a)
    forall a. Binary a => [Binding a] -> Put
    forall a. Binary a => Binding a -> Put
    forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
    $cput :: forall a. Binary a => Binding a -> Put
    put :: Binding a -> Put
    $cget :: forall a. Binary a => Get (Binding a)
    get :: Get (Binding a)
    $cputList :: forall a. Binary a => [Binding a] -> Put
    putList :: [Binding a] -> Put
    Binary, (forall a b. (a -> b) -> Binding a -> Binding b)
    -> (forall a b. a -> Binding b -> Binding a) -> Functor Binding
    forall a b. a -> Binding b -> Binding a
    forall a b. (a -> b) -> Binding a -> Binding b
    forall (f :: Type -> Type).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> Binding a -> Binding b
    fmap :: forall a b. (a -> b) -> Binding a -> Binding b
    $c<$ :: forall a b. a -> Binding b -> Binding a
    <$ :: forall a b. a -> Binding b -> Binding a
    Functor, (forall x. Binding a -> Rep (Binding a) x)
    -> (forall x. Rep (Binding a) x -> Binding a)
    -> Generic (Binding a)
    forall x. Rep (Binding a) x -> Binding a
    forall x. Binding a -> Rep (Binding a) x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    forall a x. Rep (Binding a) x -> Binding a
    forall a x. Binding a -> Rep (Binding a) x
    $cfrom :: forall a x. Binding a -> Rep (Binding a) x
    from :: forall x. Binding a -> Rep (Binding a) x
    $cto :: forall a x. Rep (Binding a) x -> Binding a
    to :: forall x. Rep (Binding a) x -> Binding a
    Generic, Binding a -> ()
    (Binding a -> ()) -> NFData (Binding a)
    forall a. NFData a => Binding a -> ()
    forall a. (a -> ()) -> NFData a
    $crnf :: forall a. NFData a => Binding a -> ()
    rnf :: Binding a -> ()
    NFData, Int -> Binding a -> ShowS
    [Binding a] -> ShowS
    Binding a -> String
    (Int -> Binding a -> ShowS)
    -> (Binding a -> String)
    -> ([Binding a] -> ShowS)
    -> Show (Binding a)
    forall a. Show a => Int -> Binding a -> ShowS
    forall a. Show a => [Binding a] -> ShowS
    forall a. Show a => Binding a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Binding a -> ShowS
    showsPrec :: Int -> Binding a -> ShowS
    $cshow :: forall a. Show a => Binding a -> String
    show :: Binding a -> String
    $cshowList :: forall a. Show a => [Binding a] -> ShowS
    showList :: [Binding a] -> ShowS
    Show)

    -- | Global function binders
    --
    -- Global functions cannot be mutually recursive, only self-recursive.
    type BindingMap = VarEnv (Binding Term)
    type DomainMap = HashMap Text VDomainConfiguration

    -- | Information to show about transformations during compilation.
    --
    -- __NB__: The @Ord@ instance compares by amount of information.
    data TransformationInfo
      = None
      -- ^ Show no information about transformations.
      | FinalTerm
      -- ^ Show the final term after all applied transformations.
      | AppliedName
      -- ^ Show the name of every transformation that is applied.
      | AppliedTerm
      -- ^ Show the name and result of every transformation that is applied.
      | TryName
      -- ^ Show the name of every transformation that is attempted, and the result
      -- of every transformation that is applied.
      | TryTerm
      -- ^ Show the name and input to every transformation that is applied, and
      -- the result of every transformation that is applied.
      deriving (TransformationInfo -> TransformationInfo -> Bool
    (TransformationInfo -> TransformationInfo -> Bool)
    -> (TransformationInfo -> TransformationInfo -> Bool)
    -> Eq TransformationInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: TransformationInfo -> TransformationInfo -> Bool
    == :: TransformationInfo -> TransformationInfo -> Bool
    $c/= :: TransformationInfo -> TransformationInfo -> Bool
    /= :: TransformationInfo -> TransformationInfo -> Bool
    Eq, (forall x. TransformationInfo -> Rep TransformationInfo x)
    -> (forall x. Rep TransformationInfo x -> TransformationInfo)
    -> Generic TransformationInfo
    forall x. Rep TransformationInfo x -> TransformationInfo
    forall x. TransformationInfo -> Rep TransformationInfo x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. TransformationInfo -> Rep TransformationInfo x
    from :: forall x. TransformationInfo -> Rep TransformationInfo x
    $cto :: forall x. Rep TransformationInfo x -> TransformationInfo
    to :: forall x. Rep TransformationInfo x -> TransformationInfo
    Generic, Eq TransformationInfo
    Eq TransformationInfo
    -> (Int -> TransformationInfo -> Int)
    -> (TransformationInfo -> Int)
    -> Hashable TransformationInfo
    Int -> TransformationInfo -> Int
    TransformationInfo -> Int
    forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
    $chashWithSalt :: Int -> TransformationInfo -> Int
    hashWithSalt :: Int -> TransformationInfo -> Int
    $chash :: TransformationInfo -> Int
    hash :: TransformationInfo -> Int
    Hashable, Eq TransformationInfo
    Eq TransformationInfo
    -> (TransformationInfo -> TransformationInfo -> Ordering)
    -> (TransformationInfo -> TransformationInfo -> Bool)
    -> (TransformationInfo -> TransformationInfo -> Bool)
    -> (TransformationInfo -> TransformationInfo -> Bool)
    -> (TransformationInfo -> TransformationInfo -> Bool)
    -> (TransformationInfo -> TransformationInfo -> TransformationInfo)
    -> (TransformationInfo -> TransformationInfo -> TransformationInfo)
    -> Ord TransformationInfo
    TransformationInfo -> TransformationInfo -> Bool
    TransformationInfo -> TransformationInfo -> Ordering
    TransformationInfo -> TransformationInfo -> TransformationInfo
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: TransformationInfo -> TransformationInfo -> Ordering
    compare :: TransformationInfo -> TransformationInfo -> Ordering
    $c< :: TransformationInfo -> TransformationInfo -> Bool
    < :: TransformationInfo -> TransformationInfo -> Bool
    $c<= :: TransformationInfo -> TransformationInfo -> Bool
    <= :: TransformationInfo -> TransformationInfo -> Bool
    $c> :: TransformationInfo -> TransformationInfo -> Bool
    > :: TransformationInfo -> TransformationInfo -> Bool
    $c>= :: TransformationInfo -> TransformationInfo -> Bool
    >= :: TransformationInfo -> TransformationInfo -> Bool
    $cmax :: TransformationInfo -> TransformationInfo -> TransformationInfo
    max :: TransformationInfo -> TransformationInfo -> TransformationInfo
    $cmin :: TransformationInfo -> TransformationInfo -> TransformationInfo
    min :: TransformationInfo -> TransformationInfo -> TransformationInfo
    Ord, ReadPrec [TransformationInfo]
    ReadPrec TransformationInfo
    Int -> ReadS TransformationInfo
    ReadS [TransformationInfo]
    (Int -> ReadS TransformationInfo)
    -> ReadS [TransformationInfo]
    -> ReadPrec TransformationInfo
    -> ReadPrec [TransformationInfo]
    -> Read TransformationInfo
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS TransformationInfo
    readsPrec :: Int -> ReadS TransformationInfo
    $creadList :: ReadS [TransformationInfo]
    readList :: ReadS [TransformationInfo]
    $creadPrec :: ReadPrec TransformationInfo
    readPrec :: ReadPrec TransformationInfo
    $creadListPrec :: ReadPrec [TransformationInfo]
    readListPrec :: ReadPrec [TransformationInfo]
    Read, Int -> TransformationInfo -> ShowS
    [TransformationInfo] -> ShowS
    TransformationInfo -> String
    (Int -> TransformationInfo -> ShowS)
    -> (TransformationInfo -> String)
    -> ([TransformationInfo] -> ShowS)
    -> Show TransformationInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> TransformationInfo -> ShowS
    showsPrec :: Int -> TransformationInfo -> ShowS
    $cshow :: TransformationInfo -> String
    show :: TransformationInfo -> String
    $cshowList :: [TransformationInfo] -> ShowS
    showList :: [TransformationInfo] -> ShowS
    Show, TransformationInfo -> ()
    (TransformationInfo -> ()) -> NFData TransformationInfo
    forall a. (a -> ()) -> NFData a
    $crnf :: TransformationInfo -> ()
    rnf :: TransformationInfo -> ()
    NFData)

    -- | Options related to debugging. See 'ClashOpts'
    data DebugOpts = DebugOpts
      { DebugOpts -> Bool
    dbg_invariants :: Bool
      -- ^ Check that the results of applied transformations do not violate the
      -- invariants for rewriting (e.g. no accidental shadowing, or type changes).
      --
      -- Command line flag: -fclash-debug-invariants
      , DebugOpts -> TransformationInfo
    dbg_transformationInfo :: TransformationInfo
      -- ^ The information to show when debugging a transformation. See the
      -- 'TransformationInfo' type for different configurations.
      --
      -- Command line flag: -fclash-debug-info (None|FinalTerm|AppliedName|AppliedTerm|TryName|TryTerm)
      , DebugOpts -> Set String
    dbg_transformations :: Set String
      -- ^ List the transformations that are being debugged. When the set is empty,
      -- all transformations are debugged.
      --
      -- Command line flag: -fclash-debug-transformations t1[,t2...]
      , DebugOpts -> Bool
    dbg_countTransformations :: Bool
      -- ^ Count how many times transformations are applied and provide a summary
      -- at the end of normalization. This includes all transformations, not just
      -- those in 'dbg_transformations'.
      --
      -- Command line flag: -fclash-debug-count-transformations
      , DebugOpts -> Maybe Word
    dbg_transformationsFrom :: Maybe Word
      -- ^ Debug transformations applied after the nth transformation applied. This
      -- includes all transformations, not just those in 'dbg_transformations'.
      --
      -- Command line flag: -fclash-debug-transformations-from=N
      , DebugOpts -> Maybe Word
    dbg_transformationsLimit :: Maybe Word
      -- ^ Debug up to the nth applied transformation. If this limit is exceeded
      -- then Clash will error. This includes all transformations, not just those
      -- in 'dbg_transformations'.
      --
      -- Command line flag: -fclash-debug-transformations-limit=N
      , DebugOpts -> Maybe String
    dbg_historyFile :: Maybe FilePath
      -- ^ Save information about all applied transformations to a history file
      -- for use with @clash-term@.
      --
      -- Command line flag: -fclash-debug-history[=FILE]
      } deriving ((forall x. DebugOpts -> Rep DebugOpts x)
    -> (forall x. Rep DebugOpts x -> DebugOpts) -> Generic DebugOpts
    forall x. Rep DebugOpts x -> DebugOpts
    forall x. DebugOpts -> Rep DebugOpts x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DebugOpts -> Rep DebugOpts x
    from :: forall x. DebugOpts -> Rep DebugOpts x
    $cto :: forall x. Rep DebugOpts x -> DebugOpts
    to :: forall x. Rep DebugOpts x -> DebugOpts
    Generic, DebugOpts -> ()
    (DebugOpts -> ()) -> NFData DebugOpts
    forall a. (a -> ()) -> NFData a
    $crnf :: DebugOpts -> ()
    rnf :: DebugOpts -> ()
    NFData, Int -> DebugOpts -> ShowS
    [DebugOpts] -> ShowS
    DebugOpts -> String
    (Int -> DebugOpts -> ShowS)
    -> (DebugOpts -> String)
    -> ([DebugOpts] -> ShowS)
    -> Show DebugOpts
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DebugOpts -> ShowS
    showsPrec :: Int -> DebugOpts -> ShowS
    $cshow :: DebugOpts -> String
    show :: DebugOpts -> String
    $cshowList :: [DebugOpts] -> ShowS
    showList :: [DebugOpts] -> ShowS
    Show, DebugOpts -> DebugOpts -> Bool
    (DebugOpts -> DebugOpts -> Bool)
    -> (DebugOpts -> DebugOpts -> Bool) -> Eq DebugOpts
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DebugOpts -> DebugOpts -> Bool
    == :: DebugOpts -> DebugOpts -> Bool
    $c/= :: DebugOpts -> DebugOpts -> Bool
    /= :: DebugOpts -> DebugOpts -> Bool
    Eq)

    instance Hashable DebugOpts where
      hashWithSalt :: Int -> DebugOpts -> Int
    hashWithSalt Int
    s DebugOpts{Bool
    Maybe String
    Maybe Word
    Set String
    TransformationInfo
    dbg_invariants :: DebugOpts -> Bool
    dbg_transformationInfo :: DebugOpts -> TransformationInfo
    dbg_transformations :: DebugOpts -> Set String
    dbg_countTransformations :: DebugOpts -> Bool
    dbg_transformationsFrom :: DebugOpts -> Maybe Word
    dbg_transformationsLimit :: DebugOpts -> Maybe Word
    dbg_historyFile :: DebugOpts -> Maybe String
    dbg_invariants :: Bool
    dbg_transformationInfo :: TransformationInfo
    dbg_transformations :: Set String
    dbg_countTransformations :: Bool
    dbg_transformationsFrom :: Maybe Word
    dbg_transformationsLimit :: Maybe Word
    dbg_historyFile :: Maybe String
    ..} =
        Int
    s Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    dbg_invariants Int -> TransformationInfo -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        TransformationInfo
    dbg_transformationInfo Int -> Set String -> Int
    `hashSet`
        Set String
    dbg_transformations Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    dbg_countTransformations Int -> Maybe Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe Word
    dbg_transformationsFrom Int -> Maybe Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe Word
    dbg_transformationsLimit Int -> Maybe String -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe String
    dbg_historyFile
       where
        hashSet :: Int -> Set String -> Int
    hashSet = (Int -> String -> Int) -> Int -> Set String -> Int
    forall a b. (a -> b -> a) -> a -> Set b -> a
    Set.foldl' Int -> String -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt
        infixl 0 `hashSet`

    -- | Check whether the debugging options mean the compiler is debugging. This
    -- is true only if at least one debugging feature is enabled, namely one of
    --
    --   * checking for invariants
    --   * showing info for transformations
    --   * counting applied transformations
    --   * limiting the number of transformations
    --
    -- Other flags, such as writing to a history file or offsetting which applied
    -- transformation to show information from do not affect the result, as it is
    -- possible to enable these but still not perform any debugging checks in
    -- functions like 'applyDebug'. If this is no longer the case, this function
    -- will need to be changed.
    isDebugging :: DebugOpts -> Bool
    isDebugging :: DebugOpts -> Bool
    isDebugging DebugOpts
    opts = [Bool] -> Bool
    forall (t :: Type -> Type). Foldable t => t Bool -> Bool
    or
      [ DebugOpts -> Bool
    dbg_invariants DebugOpts
    opts
      , DebugOpts -> TransformationInfo
    dbg_transformationInfo DebugOpts
    opts TransformationInfo -> TransformationInfo -> Bool
    forall a. Ord a => a -> a -> Bool
    > TransformationInfo
    None
      , DebugOpts -> Bool
    dbg_countTransformations DebugOpts
    opts
      , Maybe Word -> Bool
    forall a. Maybe a -> Bool
    isJust (DebugOpts -> Maybe Word
    dbg_transformationsLimit DebugOpts
    opts)
      ]

    -- | Check whether the requested information is available to the specified
    -- transformation according to the options. e.g.
    --
    -- @
    -- traceIf (hasDebugInfo AppliedName name opts) ("Trace something using: " <> show name)
    -- @
    --
    -- This accounts for the set of transformations which are being debugged. For a
    -- check which is agnostic to the a transformation, see 'hasTransformationInfo'.
    hasDebugInfo :: TransformationInfo -> String -> DebugOpts -> Bool
    hasDebugInfo :: TransformationInfo -> String -> DebugOpts -> Bool
    hasDebugInfo TransformationInfo
    info String
    name DebugOpts
    opts =
      String -> Bool
    isDebugged String
    name Bool -> Bool -> Bool
    && TransformationInfo -> DebugOpts -> Bool
    hasTransformationInfo TransformationInfo
    info DebugOpts
    opts
     where
      isDebugged :: String -> Bool
    isDebugged String
    n =
        let set :: Set String
    set = DebugOpts -> Set String
    dbg_transformations DebugOpts
    opts
         in Set String -> Bool
    forall a. Set a -> Bool
    Set.null Set String
    set Bool -> Bool -> Bool
    || String -> Set String -> Bool
    forall a. Ord a => a -> Set a -> Bool
    Set.member String
    n Set String
    set

    -- | Check that the transformation info shown supports the requested info.
    -- If the call-site is in the context of a particular transformation,
    -- 'hasDebugInfo' should be used instead.
    hasTransformationInfo :: TransformationInfo -> DebugOpts -> Bool
    hasTransformationInfo :: TransformationInfo -> DebugOpts -> Bool
    hasTransformationInfo TransformationInfo
    info DebugOpts
    opts =
      TransformationInfo
    info TransformationInfo -> TransformationInfo -> Bool
    forall a. Ord a => a -> a -> Bool
    <= DebugOpts -> TransformationInfo
    dbg_transformationInfo DebugOpts
    opts

    -- NOTE [debugging options]
    --
    -- The preset debugging options here provide backwards compatibility with the
    -- old style DebugLevel enum. However it is also possible to have finer-grained
    -- control over debugging by using individual flags which did not previously
    -- exist, e.g. -fclash-debug-invariants.

    -- | -fclash-debug DebugNone
    debugNone :: DebugOpts
    debugNone :: DebugOpts
    debugNone = DebugOpts
      { dbg_invariants :: Bool
    dbg_invariants = Bool
    False
      , dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    None
      , dbg_transformations :: Set String
    dbg_transformations = Set String
    forall a. Set a
    Set.empty
      , dbg_countTransformations :: Bool
    dbg_countTransformations = Bool
    False
      , dbg_transformationsFrom :: Maybe Word
    dbg_transformationsFrom = Maybe Word
    forall a. Maybe a
    Nothing
      , dbg_transformationsLimit :: Maybe Word
    dbg_transformationsLimit = Maybe Word
    forall a. Maybe a
    Nothing
      , dbg_historyFile :: Maybe String
    dbg_historyFile = Maybe String
    forall a. Maybe a
    Nothing
      }

    -- | -fclash-debug DebugSilent
    debugSilent :: DebugOpts
    debugSilent :: DebugOpts
    debugSilent = DebugOpts
    debugNone { dbg_invariants :: Bool
    dbg_invariants = Bool
    True }

    -- | -fclash-debug DebugFinal
    debugFinal :: DebugOpts
    debugFinal :: DebugOpts
    debugFinal = DebugOpts
    debugSilent { dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    FinalTerm }

    -- | -fclash-debug DebugCount
    debugCount :: DebugOpts
    debugCount :: DebugOpts
    debugCount = DebugOpts
    debugFinal { dbg_countTransformations :: Bool
    dbg_countTransformations = Bool
    True }

    -- | -fclash-debug DebugName
    debugName :: DebugOpts
    debugName :: DebugOpts
    debugName = DebugOpts
    debugCount { dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    AppliedName }

    -- | -fclash-debug DebugTry
    debugTry :: DebugOpts
    debugTry :: DebugOpts
    debugTry = DebugOpts
    debugName { dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    TryName }

    -- | -fclash-debug DebugApplied
    debugApplied :: DebugOpts
    debugApplied :: DebugOpts
    debugApplied = DebugOpts
    debugTry { dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    AppliedTerm }

    -- | -fclash-debug DebugAll
    debugAll :: DebugOpts
    debugAll :: DebugOpts
    debugAll = DebugOpts
    debugApplied { dbg_transformationInfo :: TransformationInfo
    dbg_transformationInfo = TransformationInfo
    TryTerm }

    -- | Options passed to Clash compiler
    data ClashOpts = ClashOpts
      { ClashOpts -> Bool
    opt_werror :: Bool
      -- ^ Are warnings treated as errors.
      --
      -- Command line flag: -Werror
      , ClashOpts -> Int
    opt_inlineLimit :: Int
      -- ^ Change the number of times a function f can undergo inlining inside
      -- some other function g. This prevents the size of g growing dramatically.
      --
      -- Command line flag: -fclash-inline-limit
      , ClashOpts -> Int
    opt_specLimit :: Int
      -- ^ Change the number of times a function can undergo specialization.
      --
      -- Command line flag: -fclash-spec-limit
      , ClashOpts -> Word
    opt_inlineFunctionLimit :: Word
      -- ^ Set the threshold for function size. Below this threshold functions are
      -- always inlined (if it is not recursive).
      --
      -- Command line flag: -fclash-inline-function-limit
      , ClashOpts -> Word
    opt_inlineConstantLimit :: Word
      -- ^ Set the threshold for constant size. Below this threshold constants are
      -- always inlined. A value of 0 inlines all constants.
      --
      -- Command line flag: -fclash-inline-constant-limit
      , ClashOpts -> Word
    opt_evaluatorFuelLimit :: Word
      -- ^ Set the threshold for maximum unfolding depth in the evaluator. A value
      -- of zero means no potentially non-terminating binding is unfolded.
      --
      -- Command line flag: -fclash-evaluator-fuel-limit
      , ClashOpts -> DebugOpts
    opt_debug :: DebugOpts
      -- ^ Options which control debugging. See 'DebugOpts'.
      , ClashOpts -> Bool
    opt_cachehdl :: Bool
      -- ^ Reuse previously generated output from Clash. Only caches topentities.
      --
      -- Command line flag: -fclash-no-cache
      , ClashOpts -> Bool
    opt_clear :: Bool
      -- ^ Remove HDL directories before writing to them. By default, Clash will
      -- only write to non-empty directories if it can prove all files in it are
      -- generated by a previous run. This option applies to directories of the
      -- various top entities, i.e., the subdirectories made in the directory passed
      -- in with @-fclash-hdldir@. Note that Clash will still use a cache if it can.
      --
      -- Command line flag: @-fclash-clear@
      , ClashOpts -> Bool
    opt_primWarn :: Bool
      -- ^ Disable warnings for primitives
      --
      -- Command line flag: -fclash-no-prim-warn
      , ClashOpts -> OverridingBool
    opt_color :: OverridingBool
      -- ^ Show colors in debug output
      --
      -- Command line flag: -fdiagnostics-color
      , ClashOpts -> Int
    opt_intWidth :: Int
      -- ^ Set the bit width for the Int\/Word\/Integer types. The only allowed values
      -- are 32 or 64.
      , ClashOpts -> Maybe String
    opt_hdlDir :: Maybe String
      -- ^ Directory to save HDL files to
      , ClashOpts -> HdlSyn
    opt_hdlSyn :: HdlSyn
      -- ^ Synthesis target. See "HdlSyn" for available options.
      , ClashOpts -> Bool
    opt_errorExtra :: Bool
      -- ^ Show additional information in error messages
      , ClashOpts -> [String]
    opt_importPaths :: [FilePath]
      -- ^ Paths where Clash should look for modules
      , ClashOpts -> Maybe Text
    opt_componentPrefix :: Maybe Text
      -- ^ Prefix components with given string
      , ClashOpts -> Bool
    opt_newInlineStrat :: Bool
      -- ^ Use new inline strategy. Functions marked NOINLINE will get their own
      -- HDL module.
      , ClashOpts -> Bool
    opt_escapedIds :: Bool
      -- ^ Use escaped identifiers in HDL. See:
      --
      --  * https://peterfab.com/ref/vhdl/vhdl_renerta/source/vhd00037.htm
      --  * https://peterfab.com/ref/verilog/verilog_renerta/source/vrg00018.htm
      , ClashOpts -> PreserveCase
    opt_lowerCaseBasicIds :: PreserveCase
      -- ^ Force all generated basic identifiers to lowercase. Among others, this
      -- affects module and file names.
      , ClashOpts -> Bool
    opt_ultra :: Bool
      -- ^ Perform a high-effort compile, trading improved performance for
      -- potentially much longer compile times.
      --
      -- Name inspired by Design Compiler's /compile_ultra/ flag.
      , ClashOpts -> Maybe (Maybe Int)
    opt_forceUndefined :: Maybe (Maybe Int)
      -- ^
      -- * /Nothing/: generate undefined's in the HDL
      --
      -- * /Just Nothing/: replace undefined's by a constant in the HDL; the
      -- compiler decides what's best
      --
      -- * /Just (Just x)/: replace undefined's by /x/ in the HDL
      , ClashOpts -> Bool
    opt_checkIDir :: Bool
      -- ^ Check whether paths specified in 'opt_importPaths' exists on the
      -- filesystem.
      , ClashOpts -> Bool
    opt_aggressiveXOpt :: Bool
      -- ^ Enable aggressive X optimization, which may remove undefineds from
      -- generated HDL by replaced with defined alternatives.
      , ClashOpts -> Bool
    opt_aggressiveXOptBB :: Bool
      -- ^ Enable aggressive X optimization, which may remove undefineds from
      -- HDL generated by blackboxes. This enables the ~ISUNDEFINED template tag.
      , ClashOpts -> Word
    opt_inlineWFCacheLimit :: Word
      -- ^ At what size do we cache normalized work-free top-level binders.
      , ClashOpts -> Bool
    opt_edalize :: Bool
      -- ^ Generate an EDAM file for use with Edalize.
      , ClashOpts -> Bool
    opt_renderEnums :: Bool
      -- ^ Render sum types with all zero-width fields as enums where supported, as
      -- opposed to rendering them as bitvectors.
      , ClashOpts -> Period
    opt_timescalePrecision :: Period
      -- ^ Timescale precision set in Verilog files. E.g., setting this would sets
      -- the second part of @`timescale 100fs/100fs@.
      }
      deriving (Int -> ClashOpts -> ShowS
    [ClashOpts] -> ShowS
    ClashOpts -> String
    (Int -> ClashOpts -> ShowS)
    -> (ClashOpts -> String)
    -> ([ClashOpts] -> ShowS)
    -> Show ClashOpts
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ClashOpts -> ShowS
    showsPrec :: Int -> ClashOpts -> ShowS
    $cshow :: ClashOpts -> String
    show :: ClashOpts -> String
    $cshowList :: [ClashOpts] -> ShowS
    showList :: [ClashOpts] -> ShowS
    Show)

    instance NFData ClashOpts where
      rnf :: ClashOpts -> ()
    rnf ClashOpts
    o =
        ClashOpts -> Bool
    opt_werror ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Int
    opt_inlineLimit ClashOpts
    o Int -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Int
    opt_specLimit ClashOpts
    o Int -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Word
    opt_inlineFunctionLimit ClashOpts
    o Word -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Word
    opt_inlineConstantLimit ClashOpts
    o Word -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Word
    opt_evaluatorFuelLimit ClashOpts
    o Word -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_cachehdl ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_clear ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_primWarn ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> OverridingBool
    opt_color ClashOpts
    o OverridingBool -> () -> ()
    forall a b. a -> b -> b
    `seq`
        ClashOpts -> Int
    opt_intWidth ClashOpts
    o Int -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Maybe String
    opt_hdlDir ClashOpts
    o Maybe String -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> HdlSyn
    opt_hdlSyn ClashOpts
    o HdlSyn -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_errorExtra ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> [String]
    opt_importPaths ClashOpts
    o [String] -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Maybe Text
    opt_componentPrefix ClashOpts
    o Maybe Text -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_newInlineStrat ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_escapedIds ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> PreserveCase
    opt_lowerCaseBasicIds ClashOpts
    o PreserveCase -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_ultra ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Maybe (Maybe Int)
    opt_forceUndefined ClashOpts
    o Maybe (Maybe Int) -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_checkIDir ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_aggressiveXOpt ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_aggressiveXOptBB ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Word
    opt_inlineWFCacheLimit ClashOpts
    o Word -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_edalize ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Bool
    opt_renderEnums ClashOpts
    o Bool -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ClashOpts -> Period
    opt_timescalePrecision ClashOpts
    o Period -> () -> ()
    forall a b. NFData a => a -> b -> b
    `deepseq`
        ()

    instance Eq ClashOpts where
      ClashOpts
    s0 == :: ClashOpts -> ClashOpts -> Bool
    == ClashOpts
    s1 =
        ClashOpts -> Bool
    opt_werror ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_werror ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Int
    opt_inlineLimit ClashOpts
    s0 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Int
    opt_inlineLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Int
    opt_specLimit ClashOpts
    s0 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Int
    opt_specLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Word
    opt_inlineFunctionLimit ClashOpts
    s0 Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Word
    opt_inlineFunctionLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Word
    opt_inlineConstantLimit ClashOpts
    s0 Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Word
    opt_inlineConstantLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Word
    opt_evaluatorFuelLimit ClashOpts
    s0 Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Word
    opt_evaluatorFuelLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_cachehdl ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_cachehdl ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_clear ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_clear ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_primWarn ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_primWarn ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        (ClashOpts -> OverridingBool
    opt_color ClashOpts
    s0 OverridingBool -> OverridingBool -> Bool
    `eqOverridingBool` ClashOpts -> OverridingBool
    opt_color ClashOpts
    s1) Bool -> Bool -> Bool
    &&
        ClashOpts -> Int
    opt_intWidth ClashOpts
    s0 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Int
    opt_intWidth ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Maybe String
    opt_hdlDir ClashOpts
    s0 Maybe String -> Maybe String -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Maybe String
    opt_hdlDir ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> HdlSyn
    opt_hdlSyn ClashOpts
    s0 HdlSyn -> HdlSyn -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> HdlSyn
    opt_hdlSyn ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_errorExtra ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_errorExtra ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> [String]
    opt_importPaths ClashOpts
    s0 [String] -> [String] -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> [String]
    opt_importPaths ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Maybe Text
    opt_componentPrefix ClashOpts
    s0 Maybe Text -> Maybe Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Maybe Text
    opt_componentPrefix ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_newInlineStrat ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_newInlineStrat ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_escapedIds ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_escapedIds ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> PreserveCase
    opt_lowerCaseBasicIds ClashOpts
    s0 PreserveCase -> PreserveCase -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> PreserveCase
    opt_lowerCaseBasicIds ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_ultra ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_ultra ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Maybe (Maybe Int)
    opt_forceUndefined ClashOpts
    s0 Maybe (Maybe Int) -> Maybe (Maybe Int) -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Maybe (Maybe Int)
    opt_forceUndefined ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_checkIDir ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_checkIDir ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_aggressiveXOpt ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_aggressiveXOpt ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_aggressiveXOptBB ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_aggressiveXOptBB ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Word
    opt_inlineWFCacheLimit ClashOpts
    s0 Word -> Word -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Word
    opt_inlineWFCacheLimit ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_edalize ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_edalize ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Bool
    opt_renderEnums ClashOpts
    s0 Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Bool
    opt_renderEnums ClashOpts
    s1 Bool -> Bool -> Bool
    &&
        ClashOpts -> Period
    opt_timescalePrecision ClashOpts
    s0 Period -> Period -> Bool
    forall a. Eq a => a -> a -> Bool
    == ClashOpts -> Period
    opt_timescalePrecision ClashOpts
    s1

       where
        eqOverridingBool :: OverridingBool -> OverridingBool -> Bool
        eqOverridingBool :: OverridingBool -> OverridingBool -> Bool
    eqOverridingBool OverridingBool
    Auto OverridingBool
    Auto = Bool
    True
        eqOverridingBool OverridingBool
    Always OverridingBool
    Always = Bool
    True
        eqOverridingBool OverridingBool
    Never OverridingBool
    Never = Bool
    True
        eqOverridingBool OverridingBool
    _ OverridingBool
    _ = Bool
    False

    instance Hashable ClashOpts where
      hashWithSalt :: Int -> ClashOpts -> Int
    hashWithSalt Int
    s ClashOpts {Bool
    Int
    [String]
    Maybe String
    Maybe (Maybe Int)
    Maybe Text
    Word
    OverridingBool
    Period
    PreserveCase
    HdlSyn
    DebugOpts
    opt_werror :: ClashOpts -> Bool
    opt_inlineLimit :: ClashOpts -> Int
    opt_specLimit :: ClashOpts -> Int
    opt_inlineFunctionLimit :: ClashOpts -> Word
    opt_inlineConstantLimit :: ClashOpts -> Word
    opt_evaluatorFuelLimit :: ClashOpts -> Word
    opt_debug :: ClashOpts -> DebugOpts
    opt_cachehdl :: ClashOpts -> Bool
    opt_clear :: ClashOpts -> Bool
    opt_primWarn :: ClashOpts -> Bool
    opt_color :: ClashOpts -> OverridingBool
    opt_intWidth :: ClashOpts -> Int
    opt_hdlDir :: ClashOpts -> Maybe String
    opt_hdlSyn :: ClashOpts -> HdlSyn
    opt_errorExtra :: ClashOpts -> Bool
    opt_importPaths :: ClashOpts -> [String]
    opt_componentPrefix :: ClashOpts -> Maybe Text
    opt_newInlineStrat :: ClashOpts -> Bool
    opt_escapedIds :: ClashOpts -> Bool
    opt_lowerCaseBasicIds :: ClashOpts -> PreserveCase
    opt_ultra :: ClashOpts -> Bool
    opt_forceUndefined :: ClashOpts -> Maybe (Maybe Int)
    opt_checkIDir :: ClashOpts -> Bool
    opt_aggressiveXOpt :: ClashOpts -> Bool
    opt_aggressiveXOptBB :: ClashOpts -> Bool
    opt_inlineWFCacheLimit :: ClashOpts -> Word
    opt_edalize :: ClashOpts -> Bool
    opt_renderEnums :: ClashOpts -> Bool
    opt_timescalePrecision :: ClashOpts -> Period
    opt_werror :: Bool
    opt_inlineLimit :: Int
    opt_specLimit :: Int
    opt_inlineFunctionLimit :: Word
    opt_inlineConstantLimit :: Word
    opt_evaluatorFuelLimit :: Word
    opt_debug :: DebugOpts
    opt_cachehdl :: Bool
    opt_clear :: Bool
    opt_primWarn :: Bool
    opt_color :: OverridingBool
    opt_intWidth :: Int
    opt_hdlDir :: Maybe String
    opt_hdlSyn :: HdlSyn
    opt_errorExtra :: Bool
    opt_importPaths :: [String]
    opt_componentPrefix :: Maybe Text
    opt_newInlineStrat :: Bool
    opt_escapedIds :: Bool
    opt_lowerCaseBasicIds :: PreserveCase
    opt_ultra :: Bool
    opt_forceUndefined :: Maybe (Maybe Int)
    opt_checkIDir :: Bool
    opt_aggressiveXOpt :: Bool
    opt_aggressiveXOptBB :: Bool
    opt_inlineWFCacheLimit :: Word
    opt_edalize :: Bool
    opt_renderEnums :: Bool
    opt_timescalePrecision :: Period
    ..} =
        Int
    s Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_werror Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Int
    opt_inlineLimit Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Int
    opt_specLimit Int -> Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Word
    opt_inlineFunctionLimit Int -> Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Word
    opt_inlineConstantLimit Int -> Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Word
    opt_evaluatorFuelLimit Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_cachehdl Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_clear Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_primWarn Int -> OverridingBool -> Int
    `hashOverridingBool`
        OverridingBool
    opt_color Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Int
    opt_intWidth Int -> Maybe String -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe String
    opt_hdlDir Int -> HdlSyn -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        HdlSyn
    opt_hdlSyn Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_errorExtra Int -> [String] -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        [String]
    opt_importPaths Int -> Maybe Text -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe Text
    opt_componentPrefix Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_newInlineStrat Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_escapedIds Int -> PreserveCase -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        PreserveCase
    opt_lowerCaseBasicIds Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_ultra Int -> Maybe (Maybe Int) -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Maybe (Maybe Int)
    opt_forceUndefined Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_checkIDir Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_aggressiveXOpt Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_aggressiveXOptBB Int -> Word -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Word
    opt_inlineWFCacheLimit Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_edalize Int -> Bool -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Bool
    opt_renderEnums Int -> Period -> Int
    forall a. Hashable a => Int -> a -> Int
    `hashWithSalt`
        Period
    opt_timescalePrecision
       where
        hashOverridingBool :: Int -> OverridingBool -> Int
        hashOverridingBool :: Int -> OverridingBool -> Int
    hashOverridingBool Int
    s1 OverridingBool
    Auto = Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    s1 (Int
    0 :: Int)
        hashOverridingBool Int
    s1 OverridingBool
    Always = Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    s1 (Int
    1 :: Int)
        hashOverridingBool Int
    s1 OverridingBool
    Never = Int -> Int -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    s1 (Int
    2 :: Int)
        infixl 0 `hashOverridingBool`

    defClashOpts :: ClashOpts
    defClashOpts :: ClashOpts
    defClashOpts
      = ClashOpts
      { opt_werror :: Bool
    opt_werror              = Bool
    False
      , opt_inlineLimit :: Int
    opt_inlineLimit         = Int
    20
      , opt_specLimit :: Int
    opt_specLimit           = Int
    20
      , opt_inlineFunctionLimit :: Word
    opt_inlineFunctionLimit = Word
    15
      , opt_inlineConstantLimit :: Word
    opt_inlineConstantLimit = Word
    0
      , opt_evaluatorFuelLimit :: Word
    opt_evaluatorFuelLimit  = Word
    20
      , opt_debug :: DebugOpts
    opt_debug               = DebugOpts
    debugNone
      , opt_cachehdl :: Bool
    opt_cachehdl            = Bool
    True
      , opt_clear :: Bool
    opt_clear               = Bool
    False
      , opt_primWarn :: Bool
    opt_primWarn            = Bool
    True
      , opt_color :: OverridingBool
    opt_color               = OverridingBool
    Auto
      , opt_intWidth :: Int
    opt_intWidth            = WORD_SIZE_IN_BITS
      , opt_hdlDir :: Maybe String
    opt_hdlDir              = Maybe String
    forall a. Maybe a
    Nothing
      , opt_hdlSyn :: HdlSyn
    opt_hdlSyn              = HdlSyn
    Other
      , opt_errorExtra :: Bool
    opt_errorExtra          = Bool
    False
      , opt_importPaths :: [String]
    opt_importPaths         = []
      , opt_componentPrefix :: Maybe Text
    opt_componentPrefix     = Maybe Text
    forall a. Maybe a
    Nothing
      , opt_newInlineStrat :: Bool
    opt_newInlineStrat      = Bool
    True
      , opt_escapedIds :: Bool
    opt_escapedIds          = Bool
    True
      , opt_lowerCaseBasicIds :: PreserveCase
    opt_lowerCaseBasicIds   = PreserveCase
    PreserveCase
      , opt_ultra :: Bool
    opt_ultra               = Bool
    False
      , opt_forceUndefined :: Maybe (Maybe Int)
    opt_forceUndefined      = Maybe (Maybe Int)
    forall a. Maybe a
    Nothing
      , opt_checkIDir :: Bool
    opt_checkIDir           = Bool
    True
      , opt_aggressiveXOpt :: Bool
    opt_aggressiveXOpt      = Bool
    False
      , opt_aggressiveXOptBB :: Bool
    opt_aggressiveXOptBB    = Bool
    False
      , opt_inlineWFCacheLimit :: Word
    opt_inlineWFCacheLimit  = Word
    10 -- TODO: find "optimal" value
      , opt_edalize :: Bool
    opt_edalize             = Bool
    False
      , opt_renderEnums :: Bool
    opt_renderEnums         = Bool
    True
      , opt_timescalePrecision :: Period
    opt_timescalePrecision  = Word64 -> Unit -> Period
    Period Word64
    100 Unit
    Fs
      }

    -- | Synopsys Design Constraint (SDC) information for a component.
    -- Currently this limited to the names and periods of clocks for create_clock.
    --
    newtype SdcInfo = SdcInfo
      { SdcInfo -> [(Text, VDomainConfiguration)]
    sdcClock :: [(Text, VDomainConfiguration)]
      }

    -- | Render an SDC file from an SdcInfo.
    -- The clock periods, waveforms, and targets are all hardcoded.
    --
    pprSDC :: SdcInfo -> Doc ()
    pprSDC :: SdcInfo -> Doc ()
    pprSDC = [Doc ()] -> Doc ()
    forall ann. [Doc ann] -> Doc ann
    vcat ([Doc ()] -> Doc ()) -> (SdcInfo -> [Doc ()]) -> SdcInfo -> Doc ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((Text, VDomainConfiguration) -> Doc ())
    -> [(Text, VDomainConfiguration)] -> [Doc ()]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Text, VDomainConfiguration) -> Doc ()
    forall {ann}. (Text, VDomainConfiguration) -> Doc ann
    go ([(Text, VDomainConfiguration)] -> [Doc ()])
    -> (SdcInfo -> [(Text, VDomainConfiguration)])
    -> SdcInfo
    -> [Doc ()]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SdcInfo -> [(Text, VDomainConfiguration)]
    sdcClock
     where
      go :: (Text, VDomainConfiguration) -> Doc ann
    go (Text
    i, VDomainConfiguration
    dom) =
            -- VDomainConfiguration stores period in ps, SDC expects it in ns.
        let p :: Fixed E3
    p        = Integer -> Fixed E3
    forall k (a :: k). Integer -> Fixed a
    MkFixed (Natural -> Integer
    forall a. Integral a => a -> Integer
    toInteger (Natural -> Integer) -> Natural -> Integer
    forall a b. (a -> b) -> a -> b
    $ VDomainConfiguration -> Natural
    vPeriod VDomainConfiguration
    dom) :: Fixed E3
            name :: Doc ann
    name     = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    braces (Text -> Doc ann
    forall ann. Text -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty ((Char -> Bool) -> Text -> Text
    Text.dropAround (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\\') Text
    i))
            period :: Doc ann
    period   = Fixed E3 -> Doc ann
    forall a ann. Show a => a -> Doc ann
    viaShow Fixed E3
    p
            waveform :: Doc ann
    waveform = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    braces (Doc ann
    "0.000" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Fixed E3 -> Doc ann
    forall a ann. Show a => a -> Doc ann
    viaShow (Fixed E3
    p Fixed E3 -> Fixed E3 -> Fixed E3
    forall a. Fractional a => a -> a -> a
    / Fixed E3
    2))
            targets :: Doc ann
    targets  = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    brackets (Doc ann
    "get_ports" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    forall {ann}. Doc ann
    name)
         in [Doc ann] -> Doc ann
    forall ann. [Doc ann] -> Doc ann
    hsep
              [ Doc ann
    "create_clock"
              , Doc ann
    "-name" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    forall {ann}. Doc ann
    name
              , Doc ann
    "-period" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    forall {ann}. Doc ann
    period
              , Doc ann
    "-waveform" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    forall {ann}. Doc ann
    waveform
              , Doc ann
    forall {ann}. Doc ann
    targets
              ]