| 
 Copyright   :   ( C ) 2013 - 2016 , University of Twente , 
                   2017      , Google Inc. 
                   2019      , Myrtle Software Ltd , 
                   2021 - 2023 , QBayLogic B.V. , 
                   2022      , Myrtle.ai , 
 License     :   BSD2 ( see the file LICENSE ) 
 Maintainer :   QBayLogic B.V. <  > 

 This module defines the explicitly clocked counterparts of the functions 
 defined in " Clash . Prelude " . 

Copyright  :  (C) 2013-2016, University of Twente,
                  2017     , Google Inc.
                  2019     , Myrtle Software Ltd,
                  2021-2023, QBayLogic B.V.,
                  2022     , Myrtle.ai,
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <>

This module defines the explicitly clocked counterparts of the functions
defined in "Clash.Prelude".
-}

# LANGUAGE NoImplicitPrelude #
# LANGUAGE QuasiQuotes #
{-# LANGUAGE TemplateHaskellQuotes #-}

# LANGUAGE Unsafe #

# OPTIONS_GHC -fplugin GHC.TypeLits . KnownNat . Solver #
{-# OPTIONS_HADDOCK show-extensions, not-home #-}

module Clash.Explicit.Prelude
  ( -- * Creating synchronous sequential circuits
    mealy
  , mealyB
  , moore
  , mooreB
  , registerB
    -- * Synchronizer circuits for safe clock domain crossings
  , dualFlipFlopSynchronizer
  , asyncFIFOSynchronizer
    -- * ROMs
  , asyncRom
  , asyncRomPow2
  , rom
  , romPow2
    -- ** ROMs defined by a 'MemBlob'
  , asyncRomBlob
  , asyncRomBlobPow2
  , romBlob
  , romBlobPow2
    -- ** ROMs defined by a data file
  , asyncRomFile
  , asyncRomFilePow2
  , romFile
  , romFilePow2
    -- * RAM primitives with a combinational read port
  , asyncRam
  , asyncRamPow2
    -- * Block RAM primitives
  , blockRam
  , blockRamPow2
  , blockRamU
  , blockRam1
  , ResetStrategy(..)
    -- ** Block RAM primitives initialized with a 'MemBlob'
  , blockRamBlob
  , blockRamBlobPow2
    -- *** Creating and inspecting 'MemBlob'
  , MemBlob
  , createMemBlob
  , memBlobTH
  , unpackMemBlob
    -- ** Block RAM primitives initialized with a data file
  , blockRamFile
  , blockRamFilePow2
  -- ** Block RAM read/write conflict resolution
  , readNew
  * * True dual - port block RAM
  , trueDualPortBlockRam
  , RamOp(..)
    -- * Utility functions
  , window
  , windowD
  , isRising
  , isFalling
  , riseEvery
  , oscillate
    -- * Static assertions
  , clashCompileError
  * Testbench functions
  , assert
  , stimuliGenerator
  , outputVerifier'
    -- * Tracing
    -- ** Simple
  , traceSignal1
  , traceVecSignal1
    -- ** Tracing in a multi-clock environment
  , traceSignal
  , traceVecSignal
    -- ** VCD dump functions
  , dumpVCD
    -- * Exported modules
    -- ** Synchronous signals
  , module Clash.Explicit.Reset
  , module Clash.Explicit.Signal
  , module Clash.Explicit.Signal.Delayed
  * * 
    -- *** Bit vectors
  , module Clash.Sized.BitVector
    -- *** Arbitrary-width numbers
  , module Clash.Sized.Signed
  , module Clash.Sized.Unsigned
  , module Clash.Sized.Index
    -- *** Fixed point numbers
  , module Clash.Sized.Fixed
    -- *** Fixed size vectors
  , module Clash.Sized.Vector
    -- *** Perfect depth trees
  , module Clash.Sized.RTree
    -- ** Annotations
  , module Clash.Annotations.TopEntity
    -- ** Generics type-classes
  , Generic
  , Generic1
    -- ** Type-level natural numbers
  , module GHC.TypeLits
  , module GHC.TypeLits.Extra
  , module Clash.Promoted.Nat
  , module Clash.Promoted.Nat.Literals
  , module Clash.Promoted.Nat.TH
    -- ** Type-level strings
  , module Clash.Promoted.Symbol
    -- ** Template Haskell
  , Lift (..)
    -- ** Type classes
    -- *** Clash
  , module Clash.Class.AutoReg
  , module Clash.Class.BitPack
  , module Clash.Class.Exp
  , module Clash.Class.Num
  , module Clash.Class.Resize
    -- *** Other
  , module Control.Applicative
  , module Data.Bits
  , module Data.Default.Class
    -- ** Exceptions
  , module Clash.XException
    -- ** Named types
  , module Clash.NamedTypes
    -- ** Magic
  , module Clash.Magic
    -- ** Haskell Prelude
    -- $hiding
  , module Clash.HaskellPrelude
  )
where

import Control.Applicative
import Data.Bits
import Data.Default.Class
import Data.String.Interpolate (__i)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeLits
import GHC.TypeLits.Extra
import Language.Haskell.TH.Syntax  (Lift(..))
import Clash.HaskellPrelude

import Clash.Annotations.Primitive (Primitive(..))
import Clash.Annotations.TopEntity
import Clash.Class.AutoReg
import Clash.Class.BitPack
import Clash.Class.Exp
import Clash.Class.Num
import Clash.Class.Resize
import Clash.Magic
import Clash.NamedTypes
import Clash.Explicit.BlockRam
import Clash.Explicit.BlockRam.Blob
import Clash.Explicit.BlockRam.File
import Clash.Explicit.Mealy
import Clash.Explicit.Moore
import Clash.Explicit.RAM
import Clash.Explicit.ROM
import Clash.Explicit.ROM.Blob
import Clash.Explicit.ROM.File
import Clash.Explicit.Prelude.Safe
import Clash.Explicit.Reset
import Clash.Explicit.Signal
import Clash.Explicit.Signal.Delayed
import Clash.Explicit.Testbench
import Clash.Prelude.ROM.File       (asyncRomFile, asyncRomFilePow2)
import Clash.Promoted.Nat
import Clash.Promoted.Nat.TH
import Clash.Promoted.Nat.Literals
import Clash.Promoted.Symbol
import Clash.Signal.Trace
import Clash.Sized.BitVector
import Clash.Sized.Fixed
import Clash.Sized.Index
import Clash.Sized.RTree
import Clash.Sized.Signed
import Clash.Sized.Unsigned
import Clash.Sized.Vector hiding (fromList, unsafeFromList)
import Clash.XException

  $ setup 
 > > > : set -XDataKinds -XTypeApplications 
 > > > import Clash . Explicit . Prelude 
 > > > let window4 = window @3 
 > > > let windowD3 = windowD @2 

>>> :set -XDataKinds -XTypeApplications
>>> import Clash.Explicit.Prelude
>>> let window4 = window @3
>>> let windowD3 = windowD @2
-}

  $ hiding 
 " Clash . Explicit . Prelude " re - exports most of the  " Prelude " with the 
 exception of those functions that the Clash API defines to work on '  ' from 
 " Clash . Sized . Vector " instead of on lists as the Haskell Prelude does . In 
 addition , for the ' Clash.Class.Parity.odd ' and ' Clash.Class.Parity.even ' 
 functions a type class called ' Clash . Class . Parity . Parity ' is available at 
 " Clash . Class . Parity " . 

"Clash.Explicit.Prelude" re-exports most of the Haskell "Prelude" with the
exception of those functions that the Clash API defines to work on 'Vec' from
"Clash.Sized.Vector" instead of on lists as the Haskell Prelude does. In
addition, for the 'Clash.Class.Parity.odd' and 'Clash.Class.Parity.even'
functions a type class called 'Clash.Class.Parity.Parity' is available at
"Clash.Class.Parity".
-}

  | Give a window over a ' Signal '
--
-- @
-- window4
---  :: Clock dom
--   -> Reset dom
--   -> Enable dom
--   -> 'Signal' dom Int
    - > '  ' 4 ( ' Signal ' dom Int )
-- window4 = 'window'
-- @
--
  > > > simulateB ( window4 systemClockGen systemResetGen enableGen ) [ 1::Int,2,3,4,5 ] : : [ Vec 4 Int ]
  [ 1 :> 0 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> 0 :> Nil,3 :> 2 :> 1 :> 0 :> Nil,4 :> 3 :> 2 :> 1 :> Nil,5 :> 4 :> 3 :> 2 :> Nil , ...
-- ...
window
  :: ( KnownNat n
     , KnownDomain dom
     , NFDataX a
     , Default a
     )
  => Clock dom
  -- ^ Clock to the incoming signal is synchronized
  -> Reset dom
  -> Enable dom
  -> Signal dom a
  -- ^ Signal to create a window over
  -> Vec (n + 1) (Signal dom a)
  ^ Window of at least size 1
window clk rst en x = res
  where
    res  = x :> prev
    prev = case natVal (asNatProxy prev) of
             0 -> repeat def
             _ -> let next = x +>> prev
                  in  registerB clk rst en (repeat def) next
# INLINABLE window #

  | Give a delayed window over a ' Signal '
--
-- @
-- windowD3
    : :  
--   -> Clock dom
--   -> Enable dom
--   -> Reset dom
--   -> 'Signal' dom Int
    - > '  ' 3 ( ' Signal ' dom Int )
-- windowD3 = 'windowD'
-- @
--
-- >>> simulateB (windowD3 systemClockGen resetGen enableGen) [1::Int,1,2,3,4] :: [Vec 3 Int]
  [ 0 :> 0 :> 0 :> Nil,0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil , ...
-- ...
windowD
  :: ( KnownNat n
     , NFDataX a
     , Default a
     , KnownDomain dom )
  => Clock dom
  -- ^ Clock to which the incoming signal is synchronized
  -> Reset dom
  -> Enable dom
  -> Signal dom a
  -- ^ Signal to create a window over
  -> Vec (n + 1) (Signal dom a)
  ^ Window of at least size 1
windowD clk rst en x =
  let prev = registerB clk rst en (repeat def) next
      next = x +>> prev
  in  prev
# INLINABLE windowD #

-- | Same as 'error' but will make HDL generation fail if included in the
-- final circuit.
--
-- This is useful for the error case of static assertions.
--
-- Note that the error message needs to be a literal, and during HDL generation
-- the error message does not include a stack trace, so it had better be
-- descriptive.
clashCompileError :: forall a . HasCallStack => String -> a
clashCompileError msg = withFrozenCallStack $ error msg
# NOINLINE clashCompileError #
# ANN clashCompileError ( 
   let primName = ' clashCompileError 
   in InlineYamlPrimitive [  .. ] [ _ _ i| 
     BlackBoxHaskell : 
       name : # { primName } 
       templateFunction : Clash . Primitives . Prelude.clashCompileErrorBBF 
     | ] ) #
  let primName = 'clashCompileError
  in InlineYamlPrimitive [minBound..] [__i|
    BlackBoxHaskell:
      name: #{primName}
      templateFunction: Clash.Primitives.Prelude.clashCompileErrorBBF
    |]) #-}

# LANGUAGE TemplateHaskellQuotes #
# OPTIONS_HADDOCK show-extensions, not-home #
 * Creating synchronous sequential circuits
 * Synchronizer circuits for safe clock domain crossings
 * ROMs
 ** ROMs defined by a 'MemBlob'
 ** ROMs defined by a data file
 * RAM primitives with a combinational read port
 * Block RAM primitives
 ** Block RAM primitives initialized with a 'MemBlob'
 *** Creating and inspecting 'MemBlob'
 ** Block RAM primitives initialized with a data file
 ** Block RAM read/write conflict resolution
 * Utility functions
 * Static assertions
 * Tracing
 ** Simple
 ** Tracing in a multi-clock environment
 ** VCD dump functions
 * Exported modules
 ** Synchronous signals
 *** Bit vectors
 *** Arbitrary-width numbers
 *** Fixed point numbers
 *** Fixed size vectors
 *** Perfect depth trees
 ** Annotations
 ** Generics type-classes
 ** Type-level natural numbers
 ** Type-level strings
 ** Template Haskell
 ** Type classes
 *** Clash
 *** Other
 ** Exceptions
 ** Named types
 ** Magic
 ** Haskell Prelude
 $hiding

 @
 window4
-  :: Clock dom
   -> Reset dom
   -> Enable dom
   -> 'Signal' dom Int
 window4 = 'window'
 @

 ...
 ^ Clock to the incoming signal is synchronized
 ^ Signal to create a window over

 @
 windowD3
   -> Clock dom
   -> Enable dom
   -> Reset dom
   -> 'Signal' dom Int
 windowD3 = 'windowD'
 @

 >>> simulateB (windowD3 systemClockGen resetGen enableGen) [1::Int,1,2,3,4] :: [Vec 3 Int]
 ...
 ^ Clock to which the incoming signal is synchronized
 ^ Signal to create a window over
 | Same as 'error' but will make HDL generation fail if included in the
 final circuit.

 This is useful for the error case of static assertions.

 Note that the error message needs to be a literal, and during HDL generation
 the error message does not include a stack trace, so it had better be
 descriptive.
| 
 Copyright   :   ( C ) 2013 - 2016 , University of Twente , 
                   2017      , Google Inc. 
                   2019      , Myrtle Software Ltd , 
                   2021 - 2023 , QBayLogic B.V. , 
                   2022      , Myrtle.ai , 
 License     :   BSD2 ( see the file LICENSE ) 
 Maintainer :   QBayLogic B.V. <  > 

 This module defines the explicitly clocked counterparts of the functions 
 defined in " Clash . Prelude " . 

Copyright  :  (C) 2013-2016, University of Twente,
                  2017     , Google Inc.
                  2019     , Myrtle Software Ltd,
                  2021-2023, QBayLogic B.V.,
                  2022     , Myrtle.ai,
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <>

This module defines the explicitly clocked counterparts of the functions
defined in "Clash.Prelude".
-}

# LANGUAGE NoImplicitPrelude #
# LANGUAGE QuasiQuotes #

# LANGUAGE Unsafe #

# OPTIONS_GHC -fplugin GHC.TypeLits . KnownNat . Solver #

module Clash.Explicit.Prelude
    mealy
  , mealyB
  , moore
  , mooreB
  , registerB
  , dualFlipFlopSynchronizer
  , asyncFIFOSynchronizer
  , asyncRom
  , asyncRomPow2
  , rom
  , romPow2
  , asyncRomBlob
  , asyncRomBlobPow2
  , romBlob
  , romBlobPow2
  , asyncRomFile
  , asyncRomFilePow2
  , romFile
  , romFilePow2
  , asyncRam
  , asyncRamPow2
  , blockRam
  , blockRamPow2
  , blockRamU
  , blockRam1
  , ResetStrategy(..)
  , blockRamBlob
  , blockRamBlobPow2
  , MemBlob
  , createMemBlob
  , memBlobTH
  , unpackMemBlob
  , blockRamFile
  , blockRamFilePow2
  , readNew
  * * True dual - port block RAM
  , trueDualPortBlockRam
  , RamOp(..)
  , window
  , windowD
  , isRising
  , isFalling
  , riseEvery
  , oscillate
  , clashCompileError
  * Testbench functions
  , assert
  , stimuliGenerator
  , outputVerifier'
  , traceSignal1
  , traceVecSignal1
  , traceSignal
  , traceVecSignal
  , dumpVCD
  , module Clash.Explicit.Reset
  , module Clash.Explicit.Signal
  , module Clash.Explicit.Signal.Delayed
  * * 
  , module Clash.Sized.BitVector
  , module Clash.Sized.Signed
  , module Clash.Sized.Unsigned
  , module Clash.Sized.Index
  , module Clash.Sized.Fixed
  , module Clash.Sized.Vector
  , module Clash.Sized.RTree
  , module Clash.Annotations.TopEntity
  , Generic
  , Generic1
  , module GHC.TypeLits
  , module GHC.TypeLits.Extra
  , module Clash.Promoted.Nat
  , module Clash.Promoted.Nat.Literals
  , module Clash.Promoted.Nat.TH
  , module Clash.Promoted.Symbol
  , Lift (..)
  , module Clash.Class.AutoReg
  , module Clash.Class.BitPack
  , module Clash.Class.Exp
  , module Clash.Class.Num
  , module Clash.Class.Resize
  , module Control.Applicative
  , module Data.Bits
  , module Data.Default.Class
  , module Clash.XException
  , module Clash.NamedTypes
  , module Clash.Magic
  , module Clash.HaskellPrelude
  )
where

import Control.Applicative
import Data.Bits
import Data.Default.Class
import Data.String.Interpolate (__i)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeLits
import GHC.TypeLits.Extra
import Language.Haskell.TH.Syntax  (Lift(..))
import Clash.HaskellPrelude

import Clash.Annotations.Primitive (Primitive(..))
import Clash.Annotations.TopEntity
import Clash.Class.AutoReg
import Clash.Class.BitPack
import Clash.Class.Exp
import Clash.Class.Num
import Clash.Class.Resize
import Clash.Magic
import Clash.NamedTypes
import Clash.Explicit.BlockRam
import Clash.Explicit.BlockRam.Blob
import Clash.Explicit.BlockRam.File
import Clash.Explicit.Mealy
import Clash.Explicit.Moore
import Clash.Explicit.RAM
import Clash.Explicit.ROM
import Clash.Explicit.ROM.Blob
import Clash.Explicit.ROM.File
import Clash.Explicit.Prelude.Safe
import Clash.Explicit.Reset
import Clash.Explicit.Signal
import Clash.Explicit.Signal.Delayed
import Clash.Explicit.Testbench
import Clash.Prelude.ROM.File       (asyncRomFile, asyncRomFilePow2)
import Clash.Promoted.Nat
import Clash.Promoted.Nat.TH
import Clash.Promoted.Nat.Literals
import Clash.Promoted.Symbol
import Clash.Signal.Trace
import Clash.Sized.BitVector
import Clash.Sized.Fixed
import Clash.Sized.Index
import Clash.Sized.RTree
import Clash.Sized.Signed
import Clash.Sized.Unsigned
import Clash.Sized.Vector hiding (fromList, unsafeFromList)
import Clash.XException

  $ setup 
 > > > : set -XDataKinds -XTypeApplications 
 > > > import Clash . Explicit . Prelude 
 > > > let window4 = window @3 
 > > > let windowD3 = windowD @2 

>>> :set -XDataKinds -XTypeApplications
>>> import Clash.Explicit.Prelude
>>> let window4 = window @3
>>> let windowD3 = windowD @2
-}

  $ hiding 
 " Clash . Explicit . Prelude " re - exports most of the  " Prelude " with the 
 exception of those functions that the Clash API defines to work on '  ' from 
 " Clash . Sized . Vector " instead of on lists as the Haskell Prelude does . In 
 addition , for the ' Clash.Class.Parity.odd ' and ' Clash.Class.Parity.even ' 
 functions a type class called ' Clash . Class . Parity . Parity ' is available at 
 " Clash . Class . Parity " . 

"Clash.Explicit.Prelude" re-exports most of the Haskell "Prelude" with the
exception of those functions that the Clash API defines to work on 'Vec' from
"Clash.Sized.Vector" instead of on lists as the Haskell Prelude does. In
addition, for the 'Clash.Class.Parity.odd' and 'Clash.Class.Parity.even'
functions a type class called 'Clash.Class.Parity.Parity' is available at
"Clash.Class.Parity".
-}

  | Give a window over a ' Signal '
    - > '  ' 4 ( ' Signal ' dom Int )
  > > > simulateB ( window4 systemClockGen systemResetGen enableGen ) [ 1::Int,2,3,4,5 ] : : [ Vec 4 Int ]
  [ 1 :> 0 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> 0 :> Nil,3 :> 2 :> 1 :> 0 :> Nil,4 :> 3 :> 2 :> 1 :> Nil,5 :> 4 :> 3 :> 2 :> Nil , ...
window
  :: ( KnownNat n
     , KnownDomain dom
     , NFDataX a
     , Default a
     )
  => Clock dom
  -> Reset dom
  -> Enable dom
  -> Signal dom a
  -> Vec (n + 1) (Signal dom a)
  ^ Window of at least size 1
window clk rst en x = res
  where
    res  = x :> prev
    prev = case natVal (asNatProxy prev) of
             0 -> repeat def
             _ -> let next = x +>> prev
                  in  registerB clk rst en (repeat def) next
# INLINABLE window #

  | Give a delayed window over a ' Signal '
    : :  
    - > '  ' 3 ( ' Signal ' dom Int )
  [ 0 :> 0 :> 0 :> Nil,0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil , ...
windowD
  :: ( KnownNat n
     , NFDataX a
     , Default a
     , KnownDomain dom )
  => Clock dom
  -> Reset dom
  -> Enable dom
  -> Signal dom a
  -> Vec (n + 1) (Signal dom a)
  ^ Window of at least size 1
windowD clk rst en x =
  let prev = registerB clk rst en (repeat def) next
      next = x +>> prev
  in  prev
# INLINABLE windowD #

clashCompileError :: forall a . HasCallStack => String -> a
clashCompileError msg = withFrozenCallStack $ error msg
# NOINLINE clashCompileError #
# ANN clashCompileError ( 
   let primName = ' clashCompileError 
   in InlineYamlPrimitive [  .. ] [ _ _ i| 
     BlackBoxHaskell : 
       name : # { primName } 
       templateFunction : Clash . Primitives . Prelude.clashCompileErrorBBF 
     | ] ) #
  let primName = 'clashCompileError
  in InlineYamlPrimitive [minBound..] [__i|
    BlackBoxHaskell:
      name: #{primName}
      templateFunction: Clash.Primitives.Prelude.clashCompileErrorBBF
    |]) #-}
