clash-prelude 1.4.4 → 1.4.5
raw patch · 12 files changed
+1992/−1886 lines, 12 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +14/−0
- clash-prelude.cabal +1/−1
- src/Clash/Explicit/Prelude.hs +9/−0
- src/Clash/Explicit/Prelude/Safe.hs +8/−0
- src/Clash/Explicit/Signal.hs +8/−3
- src/Clash/Explicit/Testbench.hs +3/−3
- src/Clash/HaskellPrelude.hs +6/−4
- src/Clash/Prelude.hs +5/−8
- src/Clash/Prelude/Safe.hs +6/−7
- src/Clash/Signal.hs +1913/−1846
- src/Clash/Signal/Internal.hs +8/−6
- src/Clash/Tutorial.hs +11/−8
CHANGELOG.md view
@@ -1,6 +1,20 @@ # Changelog for the Clash project +## 1.4.5 *Oct 13th 2021*++Changed:++ * `clash-lib` now supports prettyprinter 1.7++Documentation:++ * The documentation on hidden clocks, resets, and enables has been corrected and extended in `Clash.Signal`.+ ## 1.4.4 *Oct 11th 2021*+Changed:++ * `clash-lib` now supports aeson >= 2.0+ Fixed: * Dont' loop on recursive data types hiding behind type families [#1921](https://github.com/clash-lang/clash-compiler/issues/1921)
clash-prelude.cabal view
@@ -1,6 +1,6 @@ Cabal-version: 2.2 Name: clash-prelude-Version: 1.4.4+Version: 1.4.5 Synopsis: Clash: a functional hardware description language - Prelude library Description: Clash is a functional hardware description language that borrows both its
src/Clash/Explicit/Prelude.hs view
@@ -181,6 +181,15 @@ >>> let windowD3 = windowD @2 -} +{- $hiding+"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' -- -- @
src/Clash/Explicit/Prelude/Safe.hs view
@@ -143,6 +143,14 @@ >>> let rP clk rst en = registerB clk rst en (8::Int,8::Int) -} +{- $hiding+"Clash.Explicit.Prelude.Safe" 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".+-} -- | Create a 'register' function for product-type like signals (e.g. -- @('Signal' a, 'Signal' b)@)
src/Clash/Explicit/Signal.hs view
@@ -2,9 +2,10 @@ Copyright : (C) 2013-2016, University of Twente, 2016-2019, Myrtle Software, 2017 , Google Inc.- 2020 , Ben Gamari+ 2020 , Ben Gamari,+ 2021 , QBayLogic B.V. License : BSD2 (see the file LICENSE)-Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer : QBayLogic B.V. <devops@qbaylogic.com> Clash has synchronous 'Signal's in the form of: @@ -455,16 +456,20 @@ -- -- Note: this unsafeSynchronizer is defined to be consistent with the vhdl and verilog -- implementations however as only synchronous signals are represented in Clash this--- cannot be done precisely and can lead to odd behaviour. For example,+-- cannot be done precisely and can lead to odd behavior. For example,+-- -- @ -- sample $ unsafeSynchronizer @Dom2 @Dom7 . unsafeSynchronizer @Dom7 @Dom2 $ fromList [0..10] -- > [0,4,4,4,7,7,7,7,11,11,11.. -- @+-- -- is quite different from the identity,+-- -- @ -- sample $ fromList [0..10] -- > [0,1,2,3,4,5,6,7,8,9,10.. -- @+-- -- with values appearing from the "future". veryUnsafeSynchronizer :: Int
src/Clash/Explicit/Testbench.hs view
@@ -430,9 +430,9 @@ -- testInput = 'Clash.Explicit.Testbench.stimuliGenerator' clkA1 rstA1 $('Clash.Sized.Vector.listToVecTH' [1::Unsigned 8,2,3,4,5,6,7,8]) -- expectedOutput = 'Clash.Explicit.Testbench.outputVerifier' clkB2 rstB2 $('Clash.Sized.Vector.listToVecTH' [(0,0) :: (Unsigned 8, Unsigned 8),(1,2),(3,4),(5,6),(7,8)]) -- done = expectedOutput (topEntity clkA1 rstA1 enableGen clkB2 testInput)--- done' = not \<$\> done--- clkA1 = 'tbClockGen' \@\"Fast\" (unsafeSynchronizer clkB2 clkA1 done')--- clkB2 = 'tbClockGen' \@\"Slow\" done'+-- notDone = not \<$\> done+-- clkA1 = 'tbClockGen' \@\"Fast\" (unsafeSynchronizer clkB2 clkA1 notDone)+-- clkB2 = 'tbClockGen' \@\"Slow\" notDone -- rstA1 = 'Clash.Signal.resetGen' \@\"Fast\" -- rstB2 = 'Clash.Signal.resetGen' \@\"Slow\" -- @
src/Clash/HaskellPrelude.hs view
@@ -3,10 +3,12 @@ License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V <devops@qbaylogic.com> -"Clash.HaskellPrelude" re-exports most of the Haskell "Prelude" with the exception of-the following: (++), (!!), concat, drop, even, foldl, foldl1, foldr, foldr1, head,-init, iterate, last, length, map, odd, repeat, replicate, reverse, scanl, scanr,-splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3.+"Clash.HaskellPrelude" re-exports most of the Haskell "Prelude" with the+exception of those functions that the Clash API defines to work on+'Clash.Sized.Vector.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". -} {-# LANGUAGE Safe #-}
src/Clash/Prelude.hs view
@@ -210,15 +210,12 @@ {- $hiding "Clash.Prelude" re-exports most of the Haskell "Prelude" with the exception of-the following: (++), (!!), concat, drop, even, foldl, foldl1, foldr, foldr1, head,-init, iterate, last, length, map, odd, repeat, replicate, reverse, scanl, scanr,-splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3.--It instead exports the identically named functions defined in terms of-'Clash.Sized.Vector.Vec' at "Clash.Sized.Vector". For the 'odd' end 'even'-function a type class called Parity is available at 'Clash.Class.Parity'.+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' --
src/Clash/Prelude/Safe.hs view
@@ -159,13 +159,12 @@ -} {- $hiding-"Clash.Prelude" re-exports most of the Haskell "Prelude" with the exception of-the following: (++), (!!), concat, drop, foldl, foldl1, foldr, foldr1, head,-init, iterate, last, length, map, repeat, replicate, reverse, scanl, scanr,-splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3.--It instead exports the identically named functions defined in terms of-'Clash.Sized.Vector.Vec' at "Clash.Sized.Vector".+"Clash.Prelude.Safe" 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". -} -- | Create a 'register' function for product-type like signals (e.g. '(Signal a, Signal b)')
src/Clash/Signal.hs view
@@ -1,1852 +1,1919 @@ {-| Copyright : (C) 2013-2016, University of Twente, 2016-2019, Myrtle Software Ltd,- 2017 , Google Inc.-License : BSD2 (see the file LICENSE)-Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com>--Clash has synchronous 'Signal's in the form of:--@-'Signal' (dom :: 'Domain') a-@--Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,-and /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements-manipulating these 'Signal's belong.--The type-parameter, /dom/, is of the kind 'Domain' - a simple string. That-string refers to a single /synthesis domain/. A synthesis domain describes the-behavior of certain aspects of memory elements in it. More specifically, a-domain looks like:--@-'DomainConfiguration'- { _name :: 'Domain'- -- ^ Domain name- , _period :: 'Clash.Promoted.Nat.Nat'- -- ^ Clock period in /ps/- , _activeEdge :: 'ActiveEdge'- -- ^ Active edge of the clock- , _resetKind :: 'ResetKind'- -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)- , _initBehavior :: 'InitBehavior'- -- ^ Whether the initial (or "power up") value of memory elements is- -- unknown/undefined, or configurable to a specific value- , _resetPolarity :: ResetPolarity- -- ^ Whether resets are active high or active low- }-@--Check the documentation of each of the types to see the various options Clash-provides. In order to specify a domain, an instance of 'KnownDomain' should be-made. Clash provides an implementation 'System' with some common options-chosen:--@-instance KnownDomain "System" where- type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh- knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh-@--In words, \"System\" is a synthesis domain with a clock running with a period-of 10000 /ps/. Memory elements respond to the rising edge of the clock,-asynchronously to changes in their resets, and have defined power up values-if applicable.--In order to create a new domain, you don't have to instantiate it explicitly.-Instead, you can have 'createDomain' create a domain for you. You can also use-the same function to subclass existing domains.--* __NB__: \"Bad things\"™ happen when you actually use a clock period of @0@,-so do __not__ do that!-* __NB__: You should be judicious using a clock with period of @1@ as you can-never create a clock that goes any faster!-* __NB__: Whether 'System' has good defaults depends on your target platform.-Check out 'IntelSystem' and 'XilinxSystem' too!--}--{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RankNTypes #-}--{-# LANGUAGE Trustworthy #-}--#if __GLASGOW_HASKELL__ < 806-{-# LANGUAGE TypeInType #-}-#endif--{-# OPTIONS_HADDOCK show-extensions #-}--module Clash.Signal- ( -- * Synchronous signals- Signal- , BiSignalIn- , BiSignalOut- , BiSignalDefault(..)- -- * Domain- , Domain- , sameDomain- , KnownDomain(..)- , KnownConfiguration- , ActiveEdge(..)- , SActiveEdge(..)- , InitBehavior(..)- , SInitBehavior(..)- , ResetKind(..)- , SResetKind(..)- , ResetPolarity(..)- , SResetPolarity(..)- , DomainConfiguration(..)- , SDomainConfiguration(..)- -- ** Configuration type families- , DomainPeriod- , DomainActiveEdge- , DomainResetKind- , DomainInitBehavior- , DomainResetPolarity- -- ** Default domains- , System- , XilinxSystem- , IntelSystem- , vSystem- , vIntelSystem- , vXilinxSystem- -- ** Domain utilities- , VDomainConfiguration(..)- , vDomain- , createDomain- , knownVDomain- , clockPeriod- , activeEdge- , resetKind- , initBehavior- , resetPolarity- -- * Clock- , Clock- , periodToHz- , hzToPeriod-#ifdef CLASH_MULTIPLE_HIDDEN- -- ** Synchronization primitive- , unsafeSynchronizer-#endif- -- * Reset- , Reset- , unsafeToReset- , unsafeFromReset- , unsafeToHighPolarity- , unsafeToLowPolarity- , unsafeFromHighPolarity- , unsafeFromLowPolarity-#ifdef CLASH_MULTIPLE_HIDDEN- , convertReset-#endif- , resetSynchronizer- , resetGlitchFilter- , holdReset- -- ** Enabling- , Enable- , toEnable- , fromEnable- , S.enableGen- -- * Hidden clocks and resets- -- $hiddenclockandreset-- -- ** Hidden clock- , HiddenClock- , hideClock- , exposeClock- , withClock-#ifdef CLASH_MULTIPLE_HIDDEN- , exposeSpecificClock- , withSpecificClock-#endif- , hasClock- -- ** Hidden reset- , HiddenReset- , hideReset- , exposeReset- , withReset-#ifdef CLASH_MULTIPLE_HIDDEN- , exposeSpecificReset- , withSpecificReset-#endif- , hasReset- -- ** Hidden enable- , HiddenEnable- , hideEnable- , exposeEnable- , withEnable-#ifdef CLASH_MULTIPLE_HIDDEN- , exposeSpecificEnable- , withSpecificEnable-#endif- , hasEnable- -- ** Hidden clock, reset, and enable- , HiddenClockResetEnable- , hideClockResetEnable- , exposeClockResetEnable- , withClockResetEnable-#ifdef CLASH_MULTIPLE_HIDDEN- , exposeSpecificClockResetEnable- , withSpecificClockResetEnable-#endif- , SystemClockResetEnable- -- * Basic circuit functions- , dflipflop- , delay- , delayMaybe- , delayEn- , register- , regMaybe- , regEn- , mux- -- * Simulation and testbench functions- , clockGen- , resetGen- , resetGenN- , systemClockGen- , systemResetGen- -- * Boolean connectives- , (.&&.), (.||.)- -- * Product/Signal isomorphism- , Bundle(..)- , EmptyTuple(..)- , TaggedEmptyTuple(..)- -- * Simulation functions (not synthesizable)- , simulate- , simulateB- , simulateN- , simulateWithReset- , simulateWithResetN- -- ** lazy versions- , simulate_lazy- , simulateB_lazy- -- ** Automaton- , signalAutomaton- -- * List \<-\> Signal conversion (not synthesizable)- , sample- , sampleN- , sampleWithReset- , sampleWithResetN- , fromList- , fromListWithReset- -- ** lazy versions- , sample_lazy- , sampleN_lazy- , fromList_lazy- -- * QuickCheck combinators- , testFor- -- * Type classes- -- ** 'Eq'-like- , (.==.), (./=.)- -- ** 'Ord'-like- , (.<.), (.<=.), (.>=.), (.>.)- -- * Bisignal functions- , veryUnsafeToBiSignalIn- , readFromBiSignal- , writeToBiSignal- , mergeBiSignalOuts-- -- * Internals- , HiddenClockName- , HiddenResetName- , HiddenEnableName- )-where--import Control.Arrow.Transformer.Automaton (Automaton)-import GHC.TypeLits (type (<=))-import Data.Proxy (Proxy(..))-import Prelude-import Test.QuickCheck (Property, property)---#ifdef CLASH_MULTIPLE_HIDDEN-import GHC.TypeLits (AppendSymbol)-import Clash.Class.HasDomain (WithSingleDomain)-#endif--import Clash.Class.HasDomain (WithSpecificDomain)-import qualified Clash.Explicit.Signal as E-import qualified Clash.Explicit.Reset as E-import Clash.Explicit.Reset (resetSynchronizer, resetGlitchFilter)-import Clash.Explicit.Signal (systemClockGen, systemResetGen)-import qualified Clash.Explicit.Signal as S-import Clash.Hidden-import Clash.Promoted.Nat (SNat (..), snatToNum)-import Clash.Signal.Bundle- (Bundle (..), EmptyTuple(..), TaggedEmptyTuple(..))-import Clash.Signal.BiSignal --(BisignalIn, BisignalOut, )-import Clash.Signal.Internal hiding- (sample, sample_lazy, sampleN, sampleN_lazy, simulate, simulate_lazy, testFor,- signalAutomaton)-import Clash.Signal.Internal.Ambiguous- (knownVDomain, clockPeriod, activeEdge, resetKind, initBehavior, resetPolarity)-import Clash.XException (NFDataX)--{- $setup->>> :set -XFlexibleContexts -XTypeApplications->>> :m -Clash.Explicit.Prelude->>> :m -Clash.Explicit.Prelude.Safe->>> import Clash.Prelude->>> import Clash.Promoted.Nat (SNat(..))->>> import Clash.XException (printX)->>> import Control.Applicative (liftA2)->>> let oscillate = register False (not <$> oscillate)->>> let count = regEn 0 oscillate (count + 1)->>> :{-let sometimes1 = s where- s = register Nothing (switch <$> s)- switch Nothing = Just 1- switch _ = Nothing-:}-->>> :{-let countSometimes = s where- s = regMaybe 0 (plusM (pure <$> s) sometimes1)- plusM = liftA2 (liftA2 (+))-:}---}---- * Hidden clock, reset, and enable arguments--{- $hiddenclockandreset #hiddenclockandreset#-Clocks and resets are by default implicitly routed to their components. You can-see from the type of a component whether it has hidden clock or reset-arguments:--It has a hidden clock when it has a:--@-f :: 'HiddenClock' dom => ...-@--Constraint.--Or it has a hidden reset when it has a:--@-g :: 'HiddenReset' dom => ...-@--Constraint.--Or it has both a hidden clock argument and a hidden reset argument when it-has a:--@-h :: 'HiddenClockResetEnable' dom => ..-@--Constraint.--Given a component with an explicit clock and reset arguments, you can turn them-into hidden arguments using 'hideClock', 'hideReset', and 'hideEnable'. So given a:--@-f :: Clock dom -> Reset dom -> Enable dom -> Signal dom a -> ...-@--You hide the clock and reset arguments by:--@--- g :: 'HiddenClockResetEnable' dom => Signal dom a -> ...-g = 'hideClockResetEnable' f-@--Or, alternatively, by:--@--- h :: 'HiddenClockResetEnable' dom => Signal dom a -> ...-h = f 'hasClock' 'hasReset' 'hasEnable'-@--=== Assigning explicit clock and reset arguments to hidden clocks and resets--Given a component:--@-f :: 'HiddenClockResetEnable' dom- => Signal dom Int- -> Signal dom Int-@--which has hidden clock and routed reset arguments, we expose those hidden-arguments so that we can explicitly apply them:--@--- g :: Clock dom -> Reset dom -> Signal dom Int -> Signal dom Int-g = 'exposeClockResetEnable' f-@--or, alternatively, by:--@--- h :: Clock dom -> Reset dom -> Signal dom Int -> Signal dom Int-h clk rst = withClock clk rst f-@--Similarly, there are 'exposeClock' and 'exposeReset' to connect just expose-the hidden clock or the hidden reset argument.--You will need to explicitly apply clocks and resets when you want to use-components such as PPLs and 'resetSynchronizer':--@-topEntity- :: Clock System- -> Reset System- -> Signal System Bit- -> Signal System (BitVector 8)-topEntity clk rst ena key1 =- let (pllOut,pllStable) = altpll (SSymbol \@\"altpll50\") clk rst- rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable) ena- in exposeClockResetEnable leds pllOut rstSync enableGen- where- key1R = isRising 1 key1- leds = mealy blinkerT (1, False, 0) key1R-@--or, using the alternative method:--@-topEntity- :: Clock System- -> Reset System- -> Signal System Bit- -> Signal System (BitVector 8)-topEntity clk rst ena key1 =- let (pllOut,pllStable) = altpll (SSymbol \@\"altpll50\") clk rst- rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable) ena- in 'withClockResetEnable' pllOut rstSync enableGen leds- where- key1R = isRising 1 key1- leds = mealy blinkerT (1, False, 0) key1R-@---}--#ifdef CLASH_MULTIPLE_HIDDEN-type HiddenClockName dom = AppendSymbol dom "_clk"-type HiddenResetName dom = AppendSymbol dom "_rst"-type HiddenEnableName dom = AppendSymbol dom "_en"-#else-type HiddenClockName (dom :: Domain) = "clock"-type HiddenResetName (dom :: Domain) = "reset"-type HiddenEnableName (dom :: Domain) = "enable"-#endif---- | A /constraint/ that indicates the component has a hidden 'Clock'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-type HiddenClock dom =- ( Hidden (HiddenClockName dom) (Clock dom)- , KnownDomain dom )---- | A /constraint/ that indicates the component needs a 'Reset'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-type HiddenReset dom =- ( Hidden (HiddenResetName dom) (Reset dom)- , KnownDomain dom )---- | A /constraint/ that indicates the component needs a 'Enable'------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-type HiddenEnable dom =- ( Hidden (HiddenEnableName dom) (Enable dom)- , KnownDomain dom )---- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',--- and an 'Enable' belonging to the same dom.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-type HiddenClockResetEnable dom =- ( HiddenClock dom- , HiddenReset dom- , HiddenEnable dom- )---- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',--- and an 'Enable' belonging to the 'System' dom.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-type SystemClockResetEnable =- ( Hidden (HiddenClockName System) (Clock System)- , Hidden (HiddenResetName System) (Reset System)- , Hidden (HiddenEnableName System) (Enable System)- )---- | Expose a hidden 'Clock' argument of a component, so it can be applied--- explicitly.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single--- domain. For example, this function will refuse when:------ @--- r ~ HiddenClock dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenClock dom => Signal dom a -> Signal dom a--- @------ If you want to expose a clock of a component working on multiple domains--- (such as the first example), use 'exposeSpecificClock'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a /polymorphic/ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeClock reg clockGen--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force exposeClock to work on System (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeClock @System reg clockGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----exposeClock- :: forall dom r- .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- (HiddenClock dom => r)- -- ^ The component with a hidden clock- -> (KnownDomain dom => Clock dom -> r)- -- ^ The component with its clock argument exposed-exposeClock = \f clk -> exposeSpecificClock (const f) clk (Proxy @dom)-{-# INLINE exposeClock #-}---- | Expose a hidden 'Clock' argument of a component, so it can be applied--- explicitly. This function can be used on components with multiple domains.--- As opposed to 'exposeClock', callers should explicitly state what the clock--- domain is. See the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>----#ifdef CLASH_MULTIPLE_HIDDEN--- === __Example__--- 'exposeSpecificClock' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = exposeSpecificClock @System reg clockGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = exposeSpecificClock @@dom reg 'clockGen'--- @-#endif----exposeSpecificClock- :: forall dom r- . WithSpecificDomain dom r- => (HiddenClock dom => r)- -- ^ The component with a hidden clock- -> (KnownDomain dom => Clock dom -> r)- -- ^ The component with its clock argument exposed-exposeSpecificClock = \f clk -> expose @(HiddenClockName dom) f clk-{-# INLINE exposeSpecificClock #-}---- | Hide the 'Clock' argument of a component, so it can be routed implicitly.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hideClock- :: forall dom r- . HiddenClock dom- => (Clock dom -> r)- -- ^ Function whose clock argument you want to hide- -> r-hideClock = \f -> f (fromLabel @(HiddenClockName dom))-{-# INLINE hideClock #-}---- | Connect an explicit 'Clock' to a function with a hidden 'Clock'.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenClock dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenClock dom => Signal dom a -> Signal dom a--- @------ If you want to connect a clock to a component working on multiple domains--- (such as the first example), use 'withSpecificClock'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a _polymorphic_ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = withClock clockGen reg--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force withClock to work on signal (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = withClock @System clockGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----withClock- :: forall dom r- .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- KnownDomain dom- => Clock dom- -- ^ The 'Clock' we want to connect- -> (HiddenClock dom => r)- -- ^ The function with a hidden 'Clock' argument- -> r-withClock clk f = withSpecificClock clk (const f) (Proxy @dom)-{-# INLINE withClock #-}---- | Connect an explicit 'Clock' to a function with a hidden 'Clock'. This--- function can be used on components with multiple domains. As opposed to--- 'exposeClock', callers should explicitly state what the clock domain is. See--- the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- 'withSpecificClock' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = withClock @System clockGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = withClock @@dom 'clockGen' reg--- @----withSpecificClock- :: forall dom r- . (KnownDomain dom, WithSpecificDomain dom r)- => Clock dom- -- ^ The 'Clock' we want to connect- -> (HiddenClock dom => r)- -- ^ The function with a hidden 'Clock' argument- -> r-withSpecificClock = \clk f -> expose @(HiddenClockName dom) f clk-{-# INLINE withSpecificClock #-}---- | Connect a hidden 'Clock' to an argument where a normal 'Clock' argument--- was expected.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hasClock- :: forall dom- . HiddenClock dom- => Clock dom-hasClock = fromLabel @(HiddenClockName dom)-{-# INLINE hasClock #-}---- | Expose a hidden 'Reset' argument of a component, so it can be applied--- explicitly.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenReset dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenReset dom => Signal dom a -> Signal dom a--- @------ If you want to expose a reset of a component working on multiple domains--- (such as the first example), use 'exposeSpecificReset'.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>----#endif--- === __Example__--- Usage with a /polymorphic/ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeReset reg resetGen--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force exposeReset to work on System (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeReset @System reg resetGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----exposeReset- :: forall dom r- .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- (HiddenReset dom => r)- -- ^ The component with a hidden reset- -> (KnownDomain dom => Reset dom -> r)- -- ^ The component with its reset argument exposed-exposeReset = \f rst -> exposeSpecificReset (const f) rst (Proxy @dom)-{-# INLINE exposeReset #-}---- | Expose a hidden 'Reset' argument of a component, so it can be applied--- explicitly. This function can be used on components with multiple domains.--- As opposed to 'exposeReset', callers should explicitly state what the reset--- domain is. See the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>----#ifdef CLASH_MULTIPLE_HIDDEN--- === __Example__--- 'exposeSpecificReset' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = exposeSpecificReset @System reg resetGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = exposeSpecificReset @@dom reg 'resetGen'--- @-#endif----exposeSpecificReset- :: forall dom r- . WithSpecificDomain dom r- => (HiddenReset dom => r)- -- ^ The component with a hidden reset- -> (KnownDomain dom => Reset dom -> r)- -- ^ The component with its reset argument exposed-exposeSpecificReset = \f rst -> expose @(HiddenResetName dom) f rst-{-# INLINE exposeSpecificReset #-}---- | Hide the 'Reset' argument of a component, so it can be routed implicitly.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hideReset- :: forall dom r- . HiddenReset dom- => (Reset dom -> r)- -- ^ Component whose reset argument you want to hide- -> r-hideReset = \f -> f (fromLabel @(HiddenResetName dom))-{-# INLINE hideReset #-}---- | Connect an explicit 'Reset' to a function with a hidden 'Reset'.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenReset dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenReset dom => Signal dom a -> Signal dom a--- @------ If you want to connect a reset to a component working on multiple domains--- (such as the first example), use 'withSpecificReset'.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>----#endif--- === __Example__--- Usage with a _polymorphic_ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = withReset resetGen reg--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force withReset to work on signal (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = withReset @System resetGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----withReset- :: forall dom r- .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- KnownDomain dom- => Reset dom- -- ^ The 'Reset' we want to connect- -> (HiddenReset dom => r)- -- ^ The function with a hidden 'Reset' argument- -> r-withReset = \rst f -> expose @(HiddenResetName dom) f rst-{-# INLINE withReset #-}---- | Connect an explicit 'Reset' to a function with a hidden 'Reset'. This--- function can be used on components with multiple domains. As opposed to--- 'exposeReset', callers should explicitly state what the reset domain is. See--- the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- 'withSpecificReset' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = withReset @System resetGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = withReset @@dom 'resetGen' reg--- @----withSpecificReset- :: forall dom r- . (KnownDomain dom, WithSpecificDomain dom r)- => Reset dom- -- ^ The 'Reset' we want to connect- -> (HiddenReset dom => r)- -- ^ The function with a hidden 'Reset' argument- -> r-withSpecificReset = \rst f -> expose @(HiddenResetName dom) f rst-{-# INLINE withSpecificReset #-}---- | Connect a hidden 'Reset' to an argument where a normal 'Reset' argument--- was expected.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hasReset- :: forall dom- . HiddenReset dom- => Reset dom-hasReset = fromLabel @(HiddenResetName dom)-{-# INLINE hasReset #-}---- | Expose a hidden 'Enable' argument of a component, so it can be applied--- explicitly.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenEnable dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenEnable dom => Signal dom a -> Signal dom a--- @------ If you want to expose a enable of a component working on multiple domains--- (such as the first example), use 'exposeSpecificEnable'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a /polymorphic/ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeEnable reg enableGen--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force exposeEnable to work on System (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeEnable @System reg enableGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----exposeEnable- :: forall dom r .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- (HiddenEnable dom => r)- -- ^ The component with a hidden reset- -> (KnownDomain dom => Enable dom -> r)- -- ^ The component with its reset argument exposed-exposeEnable = \f gen -> exposeSpecificEnable (const f) gen (Proxy @dom)-{-# INLINE exposeEnable #-}---- | Expose a hidden 'Enable' argument of a component, so it can be applied--- explicitly. This function can be used on components with multiple domains.--- As opposed to 'exposeEnable', callers should explicitly state what the enable--- domain is. See the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>----#ifdef CLASH_MULTIPLE_HIDDEN--- === __Example__--- 'exposeSpecificEnable' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = exposeSpecificEnable @System reg enableGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = exposeSpecificEnable @@dom reg 'enableGen'--- @-#endif----exposeSpecificEnable- :: forall dom r- . WithSpecificDomain dom r- => (HiddenEnable dom => r)- -- ^ The component with a hidden reset- -> (KnownDomain dom => Enable dom -> r)- -- ^ The component with its reset argument exposed-exposeSpecificEnable = \f gen -> expose @(HiddenEnableName dom) f gen-{-# INLINE exposeSpecificEnable #-}---- | Hide the 'Enable' argument of a component, so it can be routed implicitly.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hideEnable- :: forall dom r- . HiddenEnable dom- => (Enable dom -> r)- -- ^ Component whose reset argument you want to hide- -> r-hideEnable = \f -> f (fromLabel @(HiddenEnableName dom))-{-# INLINE hideEnable #-}---- | Connect an explicit 'Enable' to a function with a hidden 'Enable'.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenEnable dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenEnable dom => Signal dom a -> Signal dom a--- @------ If you want to connect a enable to a component working on multiple domains--- (such as the first example), use 'withSpecificEnable'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a _polymorphic_ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = withEnable enableGen reg--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force withEnable to work on signal (hence 'sampleN' not needing an explicit--- domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = withEnable @System enableGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----withEnable- :: forall dom r- . KnownDomain dom-#ifdef CLASH_MULTIPLE_HIDDEN- => WithSingleDomain dom r-#endif- => Enable dom- -- ^ The 'Enable' we want to connect- -> (HiddenEnable dom => r)- -- ^ The function with a hidden 'Enable' argument- -> r-withEnable = \gen f -> expose @(HiddenEnableName dom) f gen-{-# INLINE withEnable #-}---- | Connect an explicit 'Reset' to a function with a hidden 'Enable'. This--- function can be used on components with multiple domains. As opposed to--- 'exposeEnable', callers should explicitly state what the enable domain is. See--- the examples for more information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- 'withSpecificEnable' can only be used when it can find the specified domain--- in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = withEnable @System enableGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = withEnable @@dom 'enableGen' reg--- @----withSpecificEnable- :: forall dom r- . (KnownDomain dom, WithSpecificDomain dom r)- => Enable dom- -- ^ The 'Enable' we want to connect- -> (HiddenEnable dom => r)- -- ^ The function with a hidden 'Enable' argument- -> r-withSpecificEnable = \gen f -> expose @(HiddenEnableName dom) f gen-{-# INLINE withSpecificEnable #-}---- | Connect a hidden 'Enable' to an argument where a normal 'Enable' argument--- was expected.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hasEnable- :: forall dom- . HiddenEnable dom- => Enable dom-hasEnable = fromLabel @(HiddenEnableName dom)-{-# INLINE hasEnable #-}----- | Expose a hidden 'Clock', 'Reset', and 'Enable' argument of a component, so--- it can be applied explicitly.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenClockResetEnable dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a--- @------ If you want to expose a clock, reset, and enable of a component working on--- multiple domains (such as the first example), use 'exposeSpecificClockResetEnable'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a /polymorphic/ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeClockResetEnable reg clockGen resetGen enableGen--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force exposeClockResetEnable to work on System (hence 'sampleN' not needing an--- explicit domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = exposeClockResetEnable @System reg clockGen resetGen enableGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Usage in a testbench context:------ @--- topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)--- topEntity = concat------ testBench :: Signal System Bool--- testBench = done--- where--- testInput = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)--- expectedOutput = outputVerifier' ((1:>2:>3:>4:>5:>6:>Nil):>Nil)--- done = exposeClockResetEnable (expectedOutput (topEntity <$> testInput)) clk rst--- clk = tbSystemClockGen (not <\$\> done)--- rst = systemResetGen--- @-exposeClockResetEnable- :: forall dom r .-#ifdef CLASH_MULTIPLE_HIDDEN- WithSingleDomain dom r =>-#endif- (HiddenClockResetEnable dom => r)- -- ^ The component with hidden clock, reset, and enable arguments- -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)- -- ^ The component with its clock, reset, and enable arguments exposed-exposeClockResetEnable =- \f clk rst en ->- exposeSpecificClock (exposeSpecificReset (exposeEnable f)) clk rst en-{-# INLINE exposeClockResetEnable #-}--#ifdef CLASH_MULTIPLE_HIDDEN--- | Expose a hidden 'Clock', 'Reset', and 'Enable' argument of a component, so--- it can be applied explicitly. This function can be used on components with--- multiple domains. As opposed to 'exposeClockResetEnable', callers should--- explicitly state what the enable domain is. See the examples for more--- information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- 'exposeSpecificClockResetEnable' can only be used when it can find the--- specified domain in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = exposeSpecificClockResetEnable @System reg clockGen resetGen enableGen--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = exposeSpecificClockResetEnable @@dom reg 'clockGen' 'resetGen' 'enableGen'--- @----exposeSpecificClockResetEnable- :: forall dom r- . WithSpecificDomain dom r- => (HiddenClockResetEnable dom => r)- -- ^ The component with hidden clock, reset, and enable arguments- -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)- -- ^ The component with its clock, reset, and enable arguments exposed-exposeSpecificClockResetEnable =- \f clk rst en ->- exposeSpecificClock (exposeSpecificReset (exposeSpecificEnable f)) clk rst en-{-# INLINE exposeSpecificClockResetEnable #-}-#endif---- -- | Hide the 'Clock' and 'Reset' arguments of a component, so they can be--- -- routed implicitly------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>-hideClockResetEnable- :: forall dom r- . HiddenClockResetEnable dom- => (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)- -- ^ Component whose clock, reset, and enable argument you want to hide- -> r-hideClockResetEnable =- \f ->- f- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenResetName dom))- (fromLabel @(HiddenEnableName dom))-{-# INLINE hideClockResetEnable #-}---- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with a--- hidden 'Clock', 'Reset', and 'Enable'.----#ifdef CLASH_MULTIPLE_HIDDEN--- This function can only be used on components with a single domain. For--- example, this function will refuse when:------ @--- r ~ HiddenClockResetEnable dom => Signal dom1 a -> Signal dom2 a--- @------ But will work when:------ @--- r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a--- @------ If you want to connect a enable to a component working on multiple domains--- (such as the first example), use 'withSpecificClockResetEnable'.----#endif--- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- Usage with a _polymorphic_ domain:------ >>> reg = register 5 (reg + 1)--- >>> sig = withClockResetEnable clockGen resetGen enableGen reg--- >>> sampleN @System 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Force withClockResetEnable to work on signal (hence 'sampleN' not needing--- an explicit domain later):------ >>> reg = register 5 (reg + 1)--- >>> sig = withClockResetEnable @System clockGen resetGen enableGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]----withClockResetEnable- :: forall dom r- . KnownDomain dom-#ifdef CLASH_MULTIPLE_HIDDEN- => WithSingleDomain dom r-#endif- => Clock dom- -- ^ The 'Clock' we want to connect- -> Reset dom- -- ^ The 'Reset' we want to connect- -> Enable dom- -- ^ The 'Enable' we want to connect- -> (HiddenClockResetEnable dom => r)- -- ^ The function with a hidden 'Clock', hidden 'Reset', and hidden- -- 'Enable' argument- -> r-withClockResetEnable =- \clk rst en f -> withSpecificClockResetEnable clk rst en (const f) (Proxy @dom)-{-# INLINE withClockResetEnable #-}---- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with a--- hidden 'Clock', 'Reset', and 'Enable'. This function can be used on components--- with multiple domains. As opposed to 'exposeClockResetEnable', callers should--- explicitly state what the enable domain is. See the examples for more--- information.------ <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>------ === __Example__--- 'withSpecificClockResetEnable' can only be used when it can find the--- specified domain in /r/:------ >>> reg = register @System 5 (reg + 1)--- >>> sig = withClockResetEnable @System clockGen resetGen enableGen reg--- >>> sampleN 10 sig--- [5,5,6,7,8,9,10,11,12,13]------ Type variables work too, if they are in scope. For example:------ @--- reg = 'register' @@dom 5 (reg + 1)--- sig = withClockResetEnable @@dom 'clockGen' 'resetGen' 'enableGen' reg--- @----withSpecificClockResetEnable- :: forall dom r- . (KnownDomain dom, WithSpecificDomain dom r)- => Clock dom- -- ^ The 'Clock' we want to connect- -> Reset dom- -- ^ The 'Reset' we want to connect- -> Enable dom- -- ^ The 'Enable' we want to connect- -> (HiddenClockResetEnable dom => r)- -- ^ The function with a hidden 'Clock', hidden 'Reset', and hidden- -- 'Enable' argument- -> r-withSpecificClockResetEnable =- \clk rst en f -> withSpecificClock clk (withSpecificReset rst (withSpecificEnable en f))-{-# INLINE withSpecificClockResetEnable #-}---- * Basic circuit functions---- | Special version of 'delay' that doesn't take enable signals of any kind.--- Initial value will be undefined.-dflipflop- :: forall dom a- . ( HiddenClock dom- , NFDataX a )- => Signal dom a- -> Signal dom a-dflipflop =- E.dflipflop (fromLabel @(HiddenClockName dom))-{-# INLINE dflipflop #-}---- | 'delay' @dflt@ @s@ delays the values in 'Signal' @s@ for once cycle, the--- value at time 0 is /dflt/.------ >>> sampleN @System 3 (delay 0 (fromList [1,2,3,4]))--- [0,1,2]-delay- :: forall dom a- . ( NFDataX a- , HiddenClock dom- , HiddenEnable dom )- => a- -- ^ Initial value- -> Signal dom a- -- ^ Signal to delay- -> Signal dom a-delay = \dflt i ->- delay#- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenEnableName dom))- dflt- i-{-# INLINE delay #-}---- | Version of 'delay' that only updates when its second argument is a 'Just'--- value.------ >>> let input = fromList [Just 1, Just 2, Nothing, Nothing, Just 5, Just 6, Just (7::Int)]--- >>> sampleN @System 7 (delayMaybe 0 input)--- [0,1,2,2,2,5,6]-delayMaybe- :: forall dom a- . ( NFDataX a- , HiddenClock dom- , HiddenEnable dom )- => a- -- ^ Initial value- -> Signal dom (Maybe a)- -> Signal dom a-delayMaybe = \dflt i ->- E.delayMaybe- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenEnableName dom))- dflt- i-{-# INLINE delayMaybe #-}---- | Version of 'delay' that only updates when its second argument is asserted.------ >>> let input = fromList [1,2,3,4,5,6,7::Int]--- >>> let enable = fromList [True,True,False,False,True,True,True]--- >>> sampleN @System 7 (delayEn 0 enable input)--- [0,1,2,2,2,5,6]-delayEn- :: forall dom a- . ( NFDataX a- , HiddenClock dom- , HiddenEnable dom )- => a- -- ^ Initial value- -> Signal dom Bool- -- ^ Enable- -> Signal dom a- -> Signal dom a-delayEn = \dflt en i ->- E.delayEn- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenEnableName dom))- dflt- en- i-{-# INLINE delayEn #-}---- | 'register' @i s@ delays the values in 'Signal' @s@ for one cycle, and sets--- the value at time 0 to @i@------ >>> sampleN @System 5 (register 8 (fromList [1,1,2,3,4]))--- [8,8,1,2,3]-register- :: forall dom a- . ( HiddenClockResetEnable dom- , NFDataX a )- => a- -- ^ Reset value. 'register' outputs the reset value when the reset is active.- -- If the domain has initial values enabled, the reset value will also be the- -- initial value.- -> Signal dom a- -> Signal dom a-register = \i s ->- E.register- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenResetName dom))- (fromLabel @(HiddenEnableName dom))- i- s-{-# INLINE register #-}-infixr 3 `register`---- | Version of 'register' that only updates its content when its second--- argument is a 'Just' value. So given:------ @--- sometimes1 = s where--- s = 'register' Nothing (switch '<$>' s)------ switch Nothing = Just 1--- switch _ = Nothing------ countSometimes = s where--- s = 'regMaybe' 0 (plusM ('pure' '<$>' s) sometimes1)--- plusM = 'Control.Applicative.liftA2' (liftA2 (+))--- @------ We get:------ >>> sampleN @System 9 sometimes1--- [Nothing,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]--- >>> sampleN @System 9 countSometimes--- [0,0,0,1,1,2,2,3,3]-regMaybe- :: forall dom a- . ( HiddenClockResetEnable dom- , NFDataX a )- => a- -- ^ Reset value. 'regMaybe' outputs the reset value when the reset is active.- -- If the domain has initial values enabled, the reset value will also be the- -- initial value.- -> Signal dom (Maybe a)- -> Signal dom a-regMaybe = \initial iM ->- E.regMaybe- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenResetName dom))- (fromLabel @(HiddenEnableName dom))- initial- iM-{-# INLINE regMaybe #-}-infixr 3 `regMaybe`---- | Version of 'register' that only updates its content when its second argument--- is asserted. So given:------ @--- oscillate = 'register' False ('not' '<$>' oscillate)--- count = 'regEn' 0 oscillate (count + 1)--- @------ We get:------ >>> sampleN @System 9 oscillate--- [False,False,True,False,True,False,True,False,True]--- >>> sampleN @System 9 count--- [0,0,0,1,1,2,2,3,3]-regEn- :: forall dom a- . ( HiddenClockResetEnable dom- , NFDataX a )- => a- -- ^ Reset value. 'regEn' outputs the reset value when the reset is active.- -- If the domain has initial values enabled, the reset value will also be the- -- initial value.- -> Signal dom Bool- -> Signal dom a- -> Signal dom a-regEn = \initial en i ->- E.regEn- (fromLabel @(HiddenClockName dom))- (fromLabel @(HiddenResetName dom))- (fromLabel @(HiddenEnableName dom))- initial- en- i-{-# INLINE regEn #-}---- * Signal -> List conversion---- | Get an infinite list of samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ If the given component has not yet been given a clock, reset, or enable--- line, 'sample' will supply them. The reset will be asserted for a single--- cycle. 'sample' will not drop the value produced by the circuit while--- the reset was asserted. If you want this, or if you want more than a--- single cycle reset, consider using 'sampleWithReset'.------ __NB__: This function is not synthesizable-sample- :: forall dom a- . ( KnownDomain dom- , NFDataX a )- => (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sample s =- S.sample (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sample #-}---- | Get a list of /n/ samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sampleN @System 3 s == [s0, s1, s2]------ If the given component has not yet been given a clock, reset, or enable--- line, 'sampleN' will supply them. The reset will be asserted for a single--- cycle. 'sampleN' will not drop the value produced by the circuit while--- the reset was asserted. If you want this, or if you want more than a--- single cycle reset, consider using 'sampleWithResetN'.------ __NB__: This function is not synthesizable-sampleN- :: forall dom a- . ( KnownDomain dom- , NFDataX a )- => Int- -- ^ Number of samples to produce- -> (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sampleN n s0 =- let s1 = exposeClockResetEnable @dom s0 clockGen resetGen enableGen in- S.sampleN n s1-{-# NOINLINE sampleN #-}---- | Get an infinite list of samples from a 'Signal', while asserting the reset--- line for /m/ clock cycles. 'sampleWithReset' does not return the first /m/--- cycles, i.e., when the reset is asserted.------ __NB__: This function is not synthesizable-sampleWithReset- :: forall dom a m- . ( KnownDomain dom- , NFDataX a- , 1 <= m )- => SNat m- -- ^ Number of cycles to assert the reset- -> (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sampleWithReset nReset f0 =- let f1 = exposeClockResetEnable f0 clockGen (resetGenN @dom nReset) enableGen in- drop (snatToNum nReset) (S.sample f1)-{-# NOINLINE sampleWithReset #-}---- | Get a list of /n/ samples from a 'Signal', while asserting the reset line--- for /m/ clock cycles. 'sampleWithReset' does not return the first /m/ cycles,--- i.e., while the reset is asserted.------ __NB__: This function is not synthesizable-sampleWithResetN- :: forall dom a m- . ( KnownDomain dom- , NFDataX a- , 1 <= m )- => SNat m- -- ^ Number of cycles to assert the reset- -> Int- -- ^ Number of samples to produce- -> (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sampleWithResetN nReset nSamples f =- take nSamples (sampleWithReset nReset f)---- | /Lazily/ get an infinite list of samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sample s == [s0, s1, s2, s3, ...------ If the given component has not yet been given a clock, reset, or enable--- line, 'sample_lazy' will supply them. The reset will be asserted for a--- single cycle. 'sample_lazy' will not drop the value produced by the--- circuit while the reset was asserted.------ __NB__: This function is not synthesizable-sample_lazy- :: forall dom a- . KnownDomain dom- => (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sample_lazy s =- S.sample_lazy (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sample_lazy #-}---- | Lazily get a list of /n/ samples from a 'Signal'------ The elements in the list correspond to the values of the 'Signal'--- at consecutive clock cycles------ > sampleN @System 3 s == [s0, s1, s2]------ If the given component has not yet been given a clock, reset, or enable--- line, 'sampleN_lazy' will supply them. The reset will be asserted for a--- single cycle. 'sampleN_lazy' will not drop the value produced by the--- circuit while the reset was asserted.------ __NB__: This function is not synthesizable-sampleN_lazy- :: forall dom a- . KnownDomain dom- => Int- -> (HiddenClockResetEnable dom => Signal dom a)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]-sampleN_lazy n s =- S.sampleN_lazy n (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sampleN_lazy #-}---- * Simulation functions---- | Simulate a (@'Signal' a -> 'Signal' b@) function given a list of samples--- of type /a/------ >>> simulate @System (register 8) [1, 2, 3]--- [8,1,2,3...--- ...------ Where 'System' denotes the /domain/ to simulate on. The reset line is--- asserted for a single cycle. The first value is therefore supplied twice to--- the circuit: once while reset is high, and once directly after. The first--- /output/ value (the value produced while the reset is asserted) is dropped.------ If you only want to simulate a finite number of samples, see 'simulateN'. If--- you need the reset line to be asserted for more than one cycle or if you--- need a custom reset value, see 'simulateWithReset' and 'simulateWithResetN'.------ __NB__: This function is not synthesizable-simulate- :: forall dom a b- . ( KnownDomain dom- , NFDataX a- , NFDataX b )- => (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)- -- ^ Circuit to simulate, whose source potentially has a hidden clock, reset,- -- and/or enable.- -> [a]- -> [b]-simulate f as = simulateWithReset (SNat @1) (head as) f as-{-# INLINE simulate #-}---- | Same as 'simulate', but only sample the first /Int/ output values.------ __NB__: This function is not synthesizable-simulateN- :: forall dom a b- . ( KnownDomain dom- , NFDataX a- , NFDataX b )- => Int- -- ^ Number of cycles to simulate (excluding cycle spent in reset)- -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]- -> [b]-simulateN n f as = simulateWithResetN (SNat @1) (head as) n f as-{-# INLINE simulateN #-}---- | Same as 'simulate', but with the reset line asserted for /n/ cycles. Similar--- to 'simulate', 'simulateWithReset' will drop the output values produced while--- the reset is asserted. While the reset is asserted, the reset value /a/ is--- supplied to the circuit.-simulateWithReset- :: forall dom a b m- . ( KnownDomain dom- , NFDataX a- , NFDataX b- , 1 <= m )- => SNat m- -- ^ Number of cycles to assert the reset- -> a- -- ^ Reset value- -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]- -> [b]-simulateWithReset n resetVal f as =- S.simulateWithReset n resetVal (exposeClockResetEnable f) as-{-# INLINE simulateWithReset #-}---- | Same as 'simulateWithReset', but only sample the first /Int/ output values.-simulateWithResetN- :: forall dom a b m- . ( KnownDomain dom- , NFDataX a- , NFDataX b- , 1 <= m )- => SNat m- -- ^ Number of cycles to assert the reset- -> a- -- ^ Reset value- -> Int- -- ^ Number of cycles to simulate (excluding cycles spent in reset)- -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)- -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock- -- (and reset)- -> [a]- -> [b]-simulateWithResetN nReset resetVal nSamples f as =- S.simulateWithResetN nReset resetVal nSamples (exposeClockResetEnable f) as-{-# INLINE simulateWithResetN #-}----- | /Lazily/ simulate a (@'Signal' a -> 'Signal' b@) function given a list of--- samples of type /a/------ >>> simulate @System (register 8) [1, 2, 3]--- [8,1,2,3...--- ...------ __NB__: This function is not synthesizable-simulate_lazy- :: forall dom a b- . KnownDomain dom- => (HiddenClockResetEnable dom =>- Signal dom a -> Signal dom b)- -- ^ Function we want to simulate, whose components potentially have a hidden- -- clock (and reset)- -> [a]- -> [b]-simulate_lazy f0 =- let f1 = exposeClockResetEnable @dom f0 clockGen resetGen enableGen in- tail . S.simulate_lazy f1 . dup1-{-# NOINLINE simulate_lazy #-}---- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of--- samples of type @a@------ >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...--- ...------ __NB__: This function is not synthesizable-simulateB- :: forall dom a b- . ( KnownDomain dom- , Bundle a- , Bundle b- , NFDataX a- , NFDataX b- )- => (HiddenClockResetEnable dom =>- Unbundled dom a -> Unbundled dom b)- -- ^ Function we want to simulate, whose components potentially have a hidden- -- clock (and reset)- -> [a]- -> [b]-simulateB f0 =- tail . S.simulateB f1 . dup1- where- f1 =- withSpecificClockResetEnable- @dom- clockGen- resetGen- enableGen- (const f0)- (Proxy @dom)-{-# NOINLINE simulateB #-}---- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a--- list of samples of type @a@------ >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]--- [(8,8),(1,1),(2,2),(3,3)...--- ...------ __NB__: This function is not synthesizable-simulateB_lazy- :: forall dom a b- . ( KnownDomain dom- , Bundle a- , Bundle b )- => (HiddenClockResetEnable dom =>- Unbundled dom a -> Unbundled dom b)- -- ^ Function we want to simulate, whose components potentially have a hidden- -- clock (and reset)- -> [a]- -> [b]-simulateB_lazy f0 =- tail . S.simulateB_lazy f1 . dup1- where- f1 =- withSpecificClockResetEnable- @dom- clockGen- resetGen- enableGen- (const f0)- (Proxy @dom)-{-# NOINLINE simulateB_lazy #-}--dup1 :: [a] -> [a]-dup1 (x:xs) = x:x:xs-dup1 _ = error "empty list"---- * QuickCheck combinators---- | @testFor n s@ tests the signal /s/ for /n/ cycles.------ __NB__: This function is not synthesizable-testFor- :: KnownDomain dom- => Int- -- ^ The number of cycles we want to test for- -> (HiddenClockResetEnable dom => Signal dom Bool)- -- ^ 'Signal' we want to evaluate, whose source potentially has a hidden clock- -- (and reset)- -> Property-testFor n s = property (and (Clash.Signal.sampleN n s))--#ifdef CLASH_MULTIPLE_HIDDEN--- ** Synchronization primitive--- | Implicit version of 'Clash.Explicit.Signal.unsafeSynchronizer'.-unsafeSynchronizer- :: forall dom1 dom2 a- . ( HiddenClock dom1- , HiddenClock dom2 )- => Signal dom1 a- -> Signal dom2 a-unsafeSynchronizer =- hideClock (hideClock S.unsafeSynchronizer)+ 2017 , Google Inc.,+ 2021 , QBayLogic B.V.+License : BSD2 (see the file LICENSE)+Maintainer : QBayLogic B.V. <devops@qbaylogic.com>++Clash has synchronous 'Signal's in the form of:++@+'Signal' (dom :: 'Domain') a+@++Where /a/ is the type of the value of the 'Signal', for example /Int/ or /Bool/,+and /dom/ is the /clock-/ (and /reset-/) domain to which the memory elements+manipulating these 'Signal's belong.++The type-parameter, /dom/, is of the kind 'Domain' - a simple string. That+string refers to a single /synthesis domain/. A synthesis domain describes the+behavior of certain aspects of memory elements in it. More specifically, a+domain looks like:++@+'DomainConfiguration'+ { _name :: 'Domain'+ -- ^ Domain name+ , _period :: 'Clash.Promoted.Nat.Nat'+ -- ^ Clock period in /ps/+ , _activeEdge :: 'ActiveEdge'+ -- ^ Active edge of the clock+ , _resetKind :: 'ResetKind'+ -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)+ , _initBehavior :: 'InitBehavior'+ -- ^ Whether the initial (or "power up") value of memory elements is+ -- unknown/undefined, or configurable to a specific value+ , _resetPolarity :: ResetPolarity+ -- ^ Whether resets are active high or active low+ }+@++Check the documentation of each of the types to see the various options Clash+provides. In order to specify a domain, an instance of 'KnownDomain' should be+made. Clash provides an implementation 'System' with some common options+chosen:++@+instance KnownDomain "System" where+ type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+ knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh+@++In words, \"System\" is a synthesis domain with a clock running with a period+of 10000 /ps/. Memory elements respond to the rising edge of the clock,+asynchronously to changes in their resets, and have defined power up values+if applicable.++In order to create a new domain, you don't have to instantiate it explicitly.+Instead, you can have 'createDomain' create a domain for you. You can also use+the same function to subclass existing domains.++* __NB__: \"Bad things\"™ happen when you actually use a clock period of @0@,+so do __not__ do that!+* __NB__: You should be judicious using a clock with period of @1@ as you can+never create a clock that goes any faster!+* __NB__: Whether 'System' has good defaults depends on your target platform.+Check out 'IntelSystem' and 'XilinxSystem' too!+-}++{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}++{-# LANGUAGE Trustworthy #-}++#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++{-# OPTIONS_HADDOCK show-extensions #-}++module Clash.Signal+ ( -- * Synchronous signals+ Signal+ , BiSignalIn+ , BiSignalOut+ , BiSignalDefault(..)+ -- * Domain+ , Domain+ , sameDomain+ , KnownDomain(..)+ , KnownConfiguration+ , ActiveEdge(..)+ , SActiveEdge(..)+ , InitBehavior(..)+ , SInitBehavior(..)+ , ResetKind(..)+ , SResetKind(..)+ , ResetPolarity(..)+ , SResetPolarity(..)+ , DomainConfiguration(..)+ , SDomainConfiguration(..)+ -- ** Configuration type families+ , DomainPeriod+ , DomainActiveEdge+ , DomainResetKind+ , DomainInitBehavior+ , DomainResetPolarity+ -- ** Default domains+ , System+ , XilinxSystem+ , IntelSystem+ , vSystem+ , vIntelSystem+ , vXilinxSystem+ -- ** Domain utilities+ , VDomainConfiguration(..)+ , vDomain+ , createDomain+ , knownVDomain+ , clockPeriod+ , activeEdge+ , resetKind+ , initBehavior+ , resetPolarity+ -- * Clock+ , Clock+ , periodToHz+ , hzToPeriod+#ifdef CLASH_MULTIPLE_HIDDEN+ -- ** Synchronization primitive+ , unsafeSynchronizer+#endif+ -- * Reset+ , Reset+ , unsafeToReset+ , unsafeFromReset+ , unsafeToHighPolarity+ , unsafeToLowPolarity+ , unsafeFromHighPolarity+ , unsafeFromLowPolarity+#ifdef CLASH_MULTIPLE_HIDDEN+ , convertReset+#endif+ , resetSynchronizer+ , resetGlitchFilter+ , holdReset+ -- * Enabling+ , Enable+ , toEnable+ , fromEnable+ , E.enableGen+ -- * Hidden clock, reset, and enable arguments+ -- $hiddenclockandreset++ -- ** Hidden clock+ , HiddenClock+ , hideClock+ , exposeClock+ , withClock+#ifdef CLASH_MULTIPLE_HIDDEN+ , exposeSpecificClock+ , withSpecificClock+#endif+ , hasClock+ -- ** Hidden reset+ , HiddenReset+ , hideReset+ , exposeReset+ , withReset+#ifdef CLASH_MULTIPLE_HIDDEN+ , exposeSpecificReset+ , withSpecificReset+#endif+ , hasReset+ -- ** Hidden enable+ , HiddenEnable+ , hideEnable+ , exposeEnable+ , withEnable+#ifdef CLASH_MULTIPLE_HIDDEN+ , exposeSpecificEnable+ , withSpecificEnable+#endif+ , hasEnable+ -- ** Hidden clock, reset, and enable+ , HiddenClockResetEnable+ , hideClockResetEnable+ , exposeClockResetEnable+ , withClockResetEnable+#ifdef CLASH_MULTIPLE_HIDDEN+ , exposeSpecificClockResetEnable+ , withSpecificClockResetEnable+#endif+ , SystemClockResetEnable+ -- * Basic circuit functions+ , dflipflop+ , delay+ , delayMaybe+ , delayEn+ , register+ , regMaybe+ , regEn+ , mux+ -- * Simulation and testbench functions+ , clockGen+ , resetGen+ , resetGenN+ , systemClockGen+ , systemResetGen+ -- * Boolean connectives+ , (.&&.), (.||.)+ -- * Product/Signal isomorphism+ , Bundle(..)+ , EmptyTuple(..)+ , TaggedEmptyTuple(..)+ -- * Simulation functions (not synthesizable)+ , simulate+ , simulateB+ , simulateN+ , simulateWithReset+ , simulateWithResetN+ -- ** lazy versions+ , simulate_lazy+ , simulateB_lazy+ -- ** Automaton+ , signalAutomaton+ -- * List \<-\> Signal conversion (not synthesizable)+ , sample+ , sampleN+ , sampleWithReset+ , sampleWithResetN+ , fromList+ , fromListWithReset+ -- ** lazy versions+ , sample_lazy+ , sampleN_lazy+ , fromList_lazy+ -- * QuickCheck combinators+ , testFor+ -- * Type classes+ -- ** 'Eq'-like+ , (.==.), (./=.)+ -- ** 'Ord'-like+ , (.<.), (.<=.), (.>=.), (.>.)+ -- * Bisignal functions+ , veryUnsafeToBiSignalIn+ , readFromBiSignal+ , writeToBiSignal+ , mergeBiSignalOuts++ -- * Internals+ , HiddenClockName+ , HiddenResetName+ , HiddenEnableName+ )+where++import Control.Arrow.Transformer.Automaton (Automaton)+import GHC.TypeLits (type (<=))+import Data.Proxy (Proxy(..))+import Prelude+import Test.QuickCheck (Property, property)+++#ifdef CLASH_MULTIPLE_HIDDEN+import GHC.TypeLits (AppendSymbol)+import Clash.Class.HasDomain (WithSingleDomain)+#endif++import Clash.Class.HasDomain (WithSpecificDomain)+import qualified Clash.Explicit.Signal as E+import qualified Clash.Explicit.Reset as E+import Clash.Explicit.Reset (resetSynchronizer, resetGlitchFilter)+import Clash.Explicit.Signal (systemClockGen, systemResetGen)+import Clash.Hidden+import Clash.Promoted.Nat (SNat (..), snatToNum)+import Clash.Signal.Bundle+ (Bundle (..), EmptyTuple(..), TaggedEmptyTuple(..))+import Clash.Signal.BiSignal --(BisignalIn, BisignalOut, )+import Clash.Signal.Internal hiding+ (sample, sample_lazy, sampleN, sampleN_lazy, simulate, simulate_lazy, testFor,+ signalAutomaton)+import Clash.Signal.Internal.Ambiguous+ (knownVDomain, clockPeriod, activeEdge, resetKind, initBehavior, resetPolarity)+import Clash.XException (NFDataX)++{- $setup+>>> :set -XFlexibleContexts -XTypeApplications+>>> :m -Clash.Explicit.Prelude+>>> :m -Clash.Explicit.Prelude.Safe+>>> import Clash.Prelude+>>> import Clash.Promoted.Nat (SNat(..))+>>> import Clash.XException (printX)+>>> import Control.Applicative (liftA2)+>>> let oscillate = register False (not <$> oscillate)+>>> let count = regEn 0 oscillate (count + 1)+>>> :{+let sometimes1 = s where+ s = register Nothing (switch <$> s)+ switch Nothing = Just 1+ switch _ = Nothing+:}++>>> :{+let countSometimes = s where+ s = regMaybe 0 (plusM (pure <$> s) sometimes1)+ plusM = liftA2 (liftA2 (+))+:}++-}++{- $hiddenclockandreset #hiddenclockandreset#+Clocks, resets and enables are by default implicitly routed to their components.+You can see from the type of a component whether it has hidden clock, reset or+enable arguments:++It has a hidden clock when it has a:++@+f :: 'HiddenClock' dom => ...+@++Constraint.++Or it has a hidden reset when it has a:++@+g :: 'HiddenReset' dom => ...+@++Constraint.++Or it has a hidden enable when it has a:++@+g :: 'HiddenEnable' dom => ...+@++Constraint.++Or it has a hidden clock argument, a hidden reset argument and a hidden enable+argument when it has a:++@+h :: 'HiddenClockResetEnable' dom => ..+@++Constraint.++Given a component with explicit clock, reset and enable arguments, you can turn+them into hidden arguments using 'hideClock', 'hideReset', and 'hideEnable'. So+given a:++@+f :: Clock dom -> Reset dom -> Enable dom -> Signal dom a -> ...+@++You hide the clock and reset arguments by:++@+-- g :: 'HiddenClockResetEnable' dom => Signal dom a -> ...+g = 'hideClockResetEnable' f+@++Or, alternatively, by:++@+-- h :: 'HiddenClockResetEnable' dom => Signal dom a -> ...+h = f 'hasClock' 'hasReset' 'hasEnable'+@++== Assigning explicit clock, reset and enable arguments to hidden clocks, resets and enables++Given a component:++@+f :: 'HiddenClockResetEnable' dom+ => Signal dom Int+ -> Signal dom Int+@++which has hidden clock, reset and enable arguments, we expose those hidden+arguments so that we can explicitly apply them:++@+-- g :: Clock dom -> Reset dom -> Enable dom -> Signal dom Int -> Signal dom Int+g = 'exposeClockResetEnable' f+@++or, alternatively, by:++@+-- h :: Clock dom -> Reset dom -> Enable dom -> Signal dom Int -> Signal dom Int+h clk rst en = 'withClockResetEnable' clk rst en f+@++Similarly, there are 'exposeClock', 'exposeReset' and 'exposeEnable' to just+expose the hidden clock, the hidden reset or the hidden enable argument.++You will need to explicitly apply clocks and resets when you want to use+components such as PLLs and 'resetSynchronizer':++@+topEntity+ :: Clock System+ -> Reset System+ -> Signal System Bit+ -> Signal System (BitVector 8)+topEntity clk rst key1 =+ let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst+ rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable) enableGen+ in 'exposeClockResetEnable' leds pllOut rstSync enableGen+ where+ key1R = isRising 1 key1+ leds = mealy blinkerT (1, False, 0) key1R+@++or, using the alternative method:++@+topEntity+ :: Clock System+ -> Reset System+ -> Signal System Bit+ -> Signal System (BitVector 8)+topEntity clk rst key1 =+ let (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' (SSymbol \@\"altpll50\") clk rst+ rstSync = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable) enableGen+ in 'withClockResetEnable' pllOut rstSync enableGen leds+ where+ key1R = isRising 1 key1+ leds = mealy blinkerT (1, False, 0) key1R+@++-}++#ifdef CLASH_MULTIPLE_HIDDEN+type HiddenClockName dom = AppendSymbol dom "_clk"+type HiddenResetName dom = AppendSymbol dom "_rst"+type HiddenEnableName dom = AppendSymbol dom "_en"+#else+type HiddenClockName (dom :: Domain) = "clock"+type HiddenResetName (dom :: Domain) = "reset"+type HiddenEnableName (dom :: Domain) = "enable"+#endif++-- | A /constraint/ that indicates the component has a hidden 'Clock'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenClock dom =+ ( Hidden (HiddenClockName dom) (Clock dom)+ , KnownDomain dom )++-- | A /constraint/ that indicates the component needs a 'Reset'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenReset dom =+ ( Hidden (HiddenResetName dom) (Reset dom)+ , KnownDomain dom )++-- | A /constraint/ that indicates the component needs an 'Enable'+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenEnable dom =+ ( Hidden (HiddenEnableName dom) (Enable dom)+ , KnownDomain dom )++-- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',+-- and an 'Enable' belonging to the same @dom@.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type HiddenClockResetEnable dom =+ ( HiddenClock dom+ , HiddenReset dom+ , HiddenEnable dom+ )++-- | A /constraint/ that indicates the component needs a 'Clock', a 'Reset',+-- and an 'Enable' belonging to the 'System' domain.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+type SystemClockResetEnable =+ ( Hidden (HiddenClockName System) (Clock System)+ , Hidden (HiddenResetName System) (Reset System)+ , Hidden (HiddenEnableName System) (Enable System)+ )++{- | Expose a hidden 'Clock' argument of a component, so it can be applied+explicitly.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single+domain. For example, this function will refuse when:++@+r ~ HiddenClock dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenClock dom => Signal dom a -> Signal dom a+@++If you want to expose a clock of a component working on multiple domains+(such as the first example), use 'exposeSpecificClock'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = exposeClock reg clockGen+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'exposeClock' to work on 'System' (hence 'sampleN' not needing an explicit+domain later):++>>> reg = register 5 (reg + 1)+>>> sig = exposeClock @System reg clockGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+exposeClock+ :: forall dom r+ .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ (HiddenClock dom => r)+ -- ^ The component with a hidden clock+ -> (KnownDomain dom => Clock dom -> r)+ -- ^ The component with its clock argument exposed+exposeClock = \f clk -> exposeSpecificClock (const f) clk (Proxy @dom)+-- See Note [Going from WithSingleDomain to WithSpecificDomain]+{-# INLINE exposeClock #-}++-- Note [Going from WithSingleDomain to WithSpecificDomain]+--+-- Functions like 'exposeSpecificClock' have a 'WithSpecificDomain dom r'+-- constraint on the component with type 'r' that's passed to them. This+-- requires 'dom' to be present in 'r' at the time the function is used,+-- otherwise it will not type-check.+--+-- Functions like 'exposeClock' have a 'WithSingleDomain dom r' constraint, so+-- it is known that the domain 'dom' is indeed in 'r'. So we can safely+-- introduce 'dom' into the type passed to 'exposeSpecificClock'. By introducing+-- 'dom' into the type, the type checker can find the 'dom' when it type-checks+-- that the use of 'exposeSpecificClock' in 'exposeClock' satisies the+-- 'WithSpecificDomain dom r' constraint.+--+-- So given:+--+-- exposeClock+-- :: forall dom r+-- . WithSingleDomain dom r+-- => (HiddenClock dom => r)+-- -> (KnownDomain dom => Clock dom -> r)+-- exposeClock = \f clk -> exposeSpecificClock (const f) clk (Proxy @dom)+--+-- The type of 'exposeSpecificClock' as called from 'exposeClock' could be+-- written something like:+--+-- exposeSpecificClock+-- :: ( WithSpecificDomain dom s+-- , s ~ (Proxy dom -> r)+-- )+-- => (HiddenClock dom => Proxy dom -> r)+-- -> (KnownDomain dom => Clock dom -> Proxy dom -> r)+--+-- The type-checker can now find 'dom' in the 'Proxy', so it type-checks.+--+-- The argument+--+-- (HiddenClock dom => Proxy dom -> r)+--+-- is filled in as 'const f', consuming the 'Proxy' before passing on to 'f'.+--+-- In the resulting+--+-- (KnownDomain dom => Clock dom -> Proxy dom -> r)+--+-- the filled in values are 'clk' and 'Proxy @dom', leaving 'r'.++{- | Expose a hidden 'Clock' argument of a component, so it can be applied+explicitly. This function can be used on components with multiple domains.+As opposed to 'exposeClock', callers should explicitly state what the clock+domain is. See the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'exposeSpecificClock' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = exposeSpecificClock @System reg clockGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'exposeSpecificClock' @@dom reg 'clockGen'+@+#endif+-}+exposeSpecificClock+ :: forall dom r+ . WithSpecificDomain dom r+ => (HiddenClock dom => r)+ -- ^ The component with a hidden clock+ -> (KnownDomain dom => Clock dom -> r)+ -- ^ The component with its clock argument exposed+exposeSpecificClock = \f clk -> expose @(HiddenClockName dom) f clk+{-# INLINE exposeSpecificClock #-}++-- | Hide the 'Clock' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideClock+ :: forall dom r+ . HiddenClock dom+ => (Clock dom -> r)+ -- ^ Function whose clock argument you want to hide+ -> r+hideClock = \f -> f (fromLabel @(HiddenClockName dom))+{-# INLINE hideClock #-}++{- | Connect an explicit 'Clock' to a function with a hidden 'Clock'.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenClock dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenClock dom => Signal dom a -> Signal dom a+@++If you want to connect a clock to a component working on multiple domains+(such as the first example), use 'withSpecificClock'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = withClock clockGen reg+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'withClock' to work on 'System' (hence 'sampleN' not needing an explicit+domain later):++>>> reg = register 5 (reg + 1)+>>> sig = withClock @System clockGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+withClock+ :: forall dom r+ .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ KnownDomain dom+ => Clock dom+ -- ^ The 'Clock' we want to connect+ -> (HiddenClock dom => r)+ -- ^ The function with a hidden 'Clock' argument+ -> r+withClock clk f = withSpecificClock clk (const f) (Proxy @dom)+-- See Note [Going from WithSingleDomain to WithSpecificDomain]+{-# INLINE withClock #-}++{- | Connect an explicit 'Clock' to a function with a hidden 'Clock'. This+function can be used on components with multiple domains. As opposed to+'withClock', callers should explicitly state what the clock domain is. See+the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'withSpecificClock' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = withSpecificClock @System clockGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'withSpecificClock' @@dom 'clockGen' reg+@+#endif+-}+withSpecificClock+ :: forall dom r+ . (KnownDomain dom, WithSpecificDomain dom r)+ => Clock dom+ -- ^ The 'Clock' we want to connect+ -> (HiddenClock dom => r)+ -- ^ The function with a hidden 'Clock' argument+ -> r+withSpecificClock = \clk f -> expose @(HiddenClockName dom) f clk+{-# INLINE withSpecificClock #-}++-- | Connect a hidden 'Clock' to an argument where a normal 'Clock' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasClock+ :: forall dom+ . HiddenClock dom+ => Clock dom+hasClock = fromLabel @(HiddenClockName dom)+{-# INLINE hasClock #-}++{- | Expose a hidden 'Reset' argument of a component, so it can be applied+explicitly.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenReset dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenReset dom => Signal dom a -> Signal dom a+@++If you want to expose a reset of a component working on multiple domains+(such as the first example), use 'exposeSpecificReset'.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#endif+=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = exposeReset reg resetGen+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'exposeReset' to work on 'System' (hence 'sampleN' not needing an explicit+domain later):++>>> reg = register 5 (reg + 1)+>>> sig = exposeReset @System reg resetGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+exposeReset+ :: forall dom r+ .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ (HiddenReset dom => r)+ -- ^ The component with a hidden reset+ -> (KnownDomain dom => Reset dom -> r)+ -- ^ The component with its reset argument exposed+exposeReset = \f rst -> exposeSpecificReset (const f) rst (Proxy @dom)+-- See Note [Going from WithSingleDomain to WithSpecificDomain]+{-# INLINE exposeReset #-}++{- | Expose a hidden 'Reset' argument of a component, so it can be applied+explicitly. This function can be used on components with multiple domains.+As opposed to 'exposeReset', callers should explicitly state what the reset+domain is. See the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'exposeSpecificReset' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = exposeSpecificReset @System reg resetGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'exposeSpecificReset' @@dom reg 'resetGen'+@+#endif+-}+exposeSpecificReset+ :: forall dom r+ . WithSpecificDomain dom r+ => (HiddenReset dom => r)+ -- ^ The component with a hidden reset+ -> (KnownDomain dom => Reset dom -> r)+ -- ^ The component with its reset argument exposed+exposeSpecificReset = \f rst -> expose @(HiddenResetName dom) f rst+{-# INLINE exposeSpecificReset #-}++-- | Hide the 'Reset' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideReset+ :: forall dom r+ . HiddenReset dom+ => (Reset dom -> r)+ -- ^ Component whose reset argument you want to hide+ -> r+hideReset = \f -> f (fromLabel @(HiddenResetName dom))+{-# INLINE hideReset #-}++{- | Connect an explicit 'Reset' to a function with a hidden 'Reset'.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenReset dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenReset dom => Signal dom a -> Signal dom a+@++If you want to connect a reset to a component working on multiple domains+(such as the first example), use 'withSpecificReset'.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#endif+=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = withReset resetGen reg+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'withReset' to work on 'System' (hence 'sampleN' not needing an explicit+domain later):++>>> reg = register 5 (reg + 1)+>>> sig = withReset @System resetGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+withReset+ :: forall dom r+ .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ KnownDomain dom+ => Reset dom+ -- ^ The 'Reset' we want to connect+ -> (HiddenReset dom => r)+ -- ^ The function with a hidden 'Reset' argument+ -> r+withReset = \rst f -> expose @(HiddenResetName dom) f rst+{-# INLINE withReset #-}++{- | Connect an explicit 'Reset' to a function with a hidden 'Reset'. This+function can be used on components with multiple domains. As opposed to+'withReset', callers should explicitly state what the reset domain is. See+the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'withSpecificReset' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = withSpecificReset @System resetGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'withSpecificReset' @@dom 'resetGen' reg+@+#endif+-}+withSpecificReset+ :: forall dom r+ . (KnownDomain dom, WithSpecificDomain dom r)+ => Reset dom+ -- ^ The 'Reset' we want to connect+ -> (HiddenReset dom => r)+ -- ^ The function with a hidden 'Reset' argument+ -> r+withSpecificReset = \rst f -> expose @(HiddenResetName dom) f rst+{-# INLINE withSpecificReset #-}++-- | Connect a hidden 'Reset' to an argument where a normal 'Reset' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasReset+ :: forall dom+ . HiddenReset dom+ => Reset dom+hasReset = fromLabel @(HiddenResetName dom)+{-# INLINE hasReset #-}++{- | Expose a hidden 'Enable' argument of a component, so it can be applied+explicitly.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenEnable dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenEnable dom => Signal dom a -> Signal dom a+@++If you want to expose a enable of a component working on multiple domains+(such as the first example), use 'exposeSpecificEnable'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = exposeEnable reg enableGen+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'exposeEnable' to work on 'System' (hence 'sampleN' not needing an+explicit domain later):++>>> reg = register 5 (reg + 1)+>>> sig = exposeEnable @System reg enableGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+exposeEnable+ :: forall dom r .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ (HiddenEnable dom => r)+ -- ^ The component with a hidden enable+ -> (KnownDomain dom => Enable dom -> r)+ -- ^ The component with its enable argument exposed+exposeEnable = \f gen -> exposeSpecificEnable (const f) gen (Proxy @dom)+-- See Note [Going from WithSingleDomain to WithSpecificDomain]+{-# INLINE exposeEnable #-}++{- | Expose a hidden 'Enable' argument of a component, so it can be applied+explicitly. This function can be used on components with multiple domains.+As opposed to 'exposeEnable', callers should explicitly state what the enable+domain is. See the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'exposeSpecificEnable' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = exposeSpecificEnable @System reg enableGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'exposeSpecificEnable' @@dom reg 'enableGen'+@+#endif+-}+exposeSpecificEnable+ :: forall dom r+ . WithSpecificDomain dom r+ => (HiddenEnable dom => r)+ -- ^ The component with a hidden enable+ -> (KnownDomain dom => Enable dom -> r)+ -- ^ The component with its enable argument exposed+exposeSpecificEnable = \f gen -> expose @(HiddenEnableName dom) f gen+{-# INLINE exposeSpecificEnable #-}++-- | Hide the 'Enable' argument of a component, so it can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideEnable+ :: forall dom r+ . HiddenEnable dom+ => (Enable dom -> r)+ -- ^ Component whose enable argument you want to hide+ -> r+hideEnable = \f -> f (fromLabel @(HiddenEnableName dom))+{-# INLINE hideEnable #-}++{- | Connect an explicit 'Enable' to a function with a hidden 'Enable'.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenEnable dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenEnable dom => Signal dom a -> Signal dom a+@++If you want to connect a enable to a component working on multiple domains+(such as the first example), use 'withSpecificEnable'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = withEnable enableGen reg+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'withEnable' to work on 'System' (hence 'sampleN' not needing an explicit+domain later):++>>> reg = register 5 (reg + 1)+>>> sig = withEnable @System enableGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+withEnable+ :: forall dom r+ . KnownDomain dom+#ifdef CLASH_MULTIPLE_HIDDEN+ => WithSingleDomain dom r+#endif+ => Enable dom+ -- ^ The 'Enable' we want to connect+ -> (HiddenEnable dom => r)+ -- ^ The function with a hidden 'Enable' argument+ -> r+withEnable = \gen f -> expose @(HiddenEnableName dom) f gen+{-# INLINE withEnable #-}++{- | Connect an explicit 'Enable' to a function with a hidden 'Enable'. This+function can be used on components with multiple domains. As opposed to+'withEnable', callers should explicitly state what the enable domain is. See+the examples for more information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'withSpecificEnable' can only be used when it can find the specified domain+in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = withSpecificEnable @System enableGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'withSpecificEnable' @@dom 'enableGen' reg+@+#endif+-}+withSpecificEnable+ :: forall dom r+ . (KnownDomain dom, WithSpecificDomain dom r)+ => Enable dom+ -- ^ The 'Enable' we want to connect+ -> (HiddenEnable dom => r)+ -- ^ The function with a hidden 'Enable' argument+ -> r+withSpecificEnable = \gen f -> expose @(HiddenEnableName dom) f gen+{-# INLINE withSpecificEnable #-}++-- | Connect a hidden 'Enable' to an argument where a normal 'Enable' argument+-- was expected.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hasEnable+ :: forall dom+ . HiddenEnable dom+ => Enable dom+hasEnable = fromLabel @(HiddenEnableName dom)+{-# INLINE hasEnable #-}++{- | Expose hidden 'Clock', 'Reset', and 'Enable' arguments of a component, so+they can be applied explicitly.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenClockResetEnable dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a+@++If you want to expose a clock, reset, and enable of a component working on+multiple domains (such as the first example), use 'exposeSpecificClockResetEnable'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = exposeClockResetEnable reg clockGen resetGen enableGen+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'exposeClockResetEnable' to work on 'System' (hence 'sampleN' not needing+an explicit domain later):++>>> reg = register 5 (reg + 1)+>>> sig = exposeClockResetEnable @System reg clockGen resetGen enableGen+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Usage in a testbench context:++@+topEntity :: Vec 2 (Vec 3 (Unsigned 8)) -> Vec 6 (Unsigned 8)+topEntity = concat++testBench :: Signal System Bool+testBench = done+ where+ testInput = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)+ expectedOutput = outputVerifier' ((1:>2:>3:>4:>5:>6:>Nil):>Nil)+ done = exposeClockResetEnable (expectedOutput (topEntity \<\$> testInput)) clk rst en+ clk = tbSystemClockGen (not <\$\> done)+ rst = systemResetGen+ en = enableGen+@+-}+exposeClockResetEnable+ :: forall dom r .+#ifdef CLASH_MULTIPLE_HIDDEN+ WithSingleDomain dom r =>+#endif+ (HiddenClockResetEnable dom => r)+ -- ^ The component with hidden clock, reset, and enable arguments+ -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+ -- ^ The component with its clock, reset, and enable arguments exposed+exposeClockResetEnable =+ \f clk rst en ->+ exposeSpecificClock (exposeSpecificReset (exposeEnable f)) clk rst en+{-# INLINE exposeClockResetEnable #-}++#ifdef CLASH_MULTIPLE_HIDDEN+-- | Expose hidden 'Clock', 'Reset', and 'Enable' arguments of a component, so+-- they can be applied explicitly. This function can be used on components with+-- multiple domains. As opposed to 'exposeClockResetEnable', callers should+-- explicitly state what the domain is. See the examples for more information.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+--+-- === __Example__+-- 'exposeSpecificClockResetEnable' can only be used when it can find the+-- specified domain in /r/:+--+-- >>> reg = register @System 5 (reg + 1)+-- >>> sig = exposeSpecificClockResetEnable @System reg clockGen resetGen enableGen+-- >>> sampleN 10 sig+-- [5,5,6,7,8,9,10,11,12,13]+--+-- Type variables work too, if they are in scope. For example:+--+-- @+-- reg = 'register' @@dom 5 (reg + 1)+-- sig = exposeSpecificClockResetEnable @@dom reg 'clockGen' 'resetGen' 'enableGen'+-- @+--+exposeSpecificClockResetEnable+ :: forall dom r+ . WithSpecificDomain dom r+ => (HiddenClockResetEnable dom => r)+ -- ^ The function with hidden 'Clock', 'Reset', and 'Enable' arguments+ -> (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+ -- ^ The component with its 'Clock', 'Reset', and 'Enable' arguments exposed+exposeSpecificClockResetEnable =+ \f clk rst en ->+ exposeSpecificClock (exposeSpecificReset (exposeSpecificEnable f)) clk rst en+{-# INLINE exposeSpecificClockResetEnable #-}+#endif++-- | Hide the 'Clock', 'Reset', and 'Enable' arguments of a component, so they+-- can be routed implicitly.+--+-- <Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>+hideClockResetEnable+ :: forall dom r+ . HiddenClockResetEnable dom+ => (KnownDomain dom => Clock dom -> Reset dom -> Enable dom -> r)+ -- ^ Component whose clock, reset, and enable argument you want to hide+ -> r+hideClockResetEnable =+ \f ->+ f+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenResetName dom))+ (fromLabel @(HiddenEnableName dom))+{-# INLINE hideClockResetEnable #-}++{- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with a+hidden 'Clock', 'Reset', and 'Enable'.++#ifdef CLASH_MULTIPLE_HIDDEN+This function can only be used on components with a single domain. For+example, this function will refuse when:++@+r ~ HiddenClockResetEnable dom1 => Signal dom1 a -> Signal dom2 a+@++But will work when:++@+r ~ HiddenClockResetEnable dom => Signal dom a -> Signal dom a+@++If you want to connect a clock, reset, and enable to a component working on+multiple domains (such as the first example), use+'withSpecificClockResetEnable'.++#endif+<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++=== __Example__+Usage with a /polymorphic/ domain:++>>> reg = register 5 (reg + 1)+>>> sig = withClockResetEnable clockGen resetGen enableGen reg+>>> sampleN @System 10 sig+[5,5,6,7,8,9,10,11,12,13]++Force 'withClockResetEnable' to work on 'System' (hence 'sampleN' not needing+an explicit domain later):++>>> reg = register 5 (reg + 1)+>>> sig = withClockResetEnable @System clockGen resetGen enableGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]+-}+withClockResetEnable+ :: forall dom r+ . KnownDomain dom+#ifdef CLASH_MULTIPLE_HIDDEN+ => WithSingleDomain dom r+#endif+ => Clock dom+ -- ^ The 'Clock' we want to connect+ -> Reset dom+ -- ^ The 'Reset' we want to connect+ -> Enable dom+ -- ^ The 'Enable' we want to connect+ -> (HiddenClockResetEnable dom => r)+ -- ^ The function with a hidden 'Clock', hidden 'Reset', and hidden+ -- 'Enable' argument+ -> r+withClockResetEnable =+ \clk rst en f -> withSpecificClockResetEnable clk rst en (const f) (Proxy @dom)+-- See Note [Going from WithSingleDomain to WithSpecificDomain]+{-# INLINE withClockResetEnable #-}++{- | Connect an explicit 'Clock', 'Reset', and 'Enable' to a function with+hidden 'Clock', 'Reset', and 'Enable' arguments. This function can be used on+components with multiple domains. As opposed to 'withClockResetEnable',+callers should explicitly state what the domain is. See the examples for more+information.++<Clash-Signal.html#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables>++#ifdef CLASH_MULTIPLE_HIDDEN+=== __Example__+'withSpecificClockResetEnable' can only be used when it can find the+specified domain in /r/:++>>> reg = register @System 5 (reg + 1)+>>> sig = withSpecificClockResetEnable @System clockGen resetGen enableGen reg+>>> sampleN 10 sig+[5,5,6,7,8,9,10,11,12,13]++Type variables work too, if they are in scope. For example:++@+reg = 'register' @@dom 5 (reg + 1)+sig = 'withSpecificClockResetEnable' @@dom 'clockGen' 'resetGen' 'enableGen' reg+@+#endif+-}+withSpecificClockResetEnable+ :: forall dom r+ . (KnownDomain dom, WithSpecificDomain dom r)+ => Clock dom+ -- ^ The 'Clock' we want to connect+ -> Reset dom+ -- ^ The 'Reset' we want to connect+ -> Enable dom+ -- ^ The 'Enable' we want to connect+ -> (HiddenClockResetEnable dom => r)+ -- ^ The function with hidden 'Clock', 'Reset', and 'Enable' arguments+ -> r+withSpecificClockResetEnable =+ \clk rst en f -> withSpecificClock clk (withSpecificReset rst (withSpecificEnable en f))+{-# INLINE withSpecificClockResetEnable #-}++-- * Basic circuit functions++-- | Special version of 'delay' that doesn't take enable signals of any kind.+-- Initial value will be undefined.+dflipflop+ :: forall dom a+ . ( HiddenClock dom+ , NFDataX a )+ => Signal dom a+ -> Signal dom a+dflipflop =+ E.dflipflop (fromLabel @(HiddenClockName dom))+{-# INLINE dflipflop #-}++-- | 'delay' @dflt@ @s@ delays the values in 'Signal' @s@ for once cycle, the+-- value at time 0 is /dflt/.+--+-- >>> sampleN @System 3 (delay 0 (fromList [1,2,3,4]))+-- [0,1,2]+delay+ :: forall dom a+ . ( NFDataX a+ , HiddenClock dom+ , HiddenEnable dom )+ => a+ -- ^ Initial value+ -> Signal dom a+ -- ^ Signal to delay+ -> Signal dom a+delay = \dflt i ->+ delay#+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenEnableName dom))+ dflt+ i+{-# INLINE delay #-}++-- | Version of 'delay' that only updates when its second argument is a 'Just'+-- value.+--+-- >>> let input = fromList [Just 1, Just 2, Nothing, Nothing, Just 5, Just 6, Just (7::Int)]+-- >>> sampleN @System 7 (delayMaybe 0 input)+-- [0,1,2,2,2,5,6]+delayMaybe+ :: forall dom a+ . ( NFDataX a+ , HiddenClock dom+ , HiddenEnable dom )+ => a+ -- ^ Initial value+ -> Signal dom (Maybe a)+ -> Signal dom a+delayMaybe = \dflt i ->+ E.delayMaybe+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenEnableName dom))+ dflt+ i+{-# INLINE delayMaybe #-}++-- | Version of 'delay' that only updates when its second argument is asserted.+--+-- >>> let input = fromList [1,2,3,4,5,6,7::Int]+-- >>> let enable = fromList [True,True,False,False,True,True,True]+-- >>> sampleN @System 7 (delayEn 0 enable input)+-- [0,1,2,2,2,5,6]+delayEn+ :: forall dom a+ . ( NFDataX a+ , HiddenClock dom+ , HiddenEnable dom )+ => a+ -- ^ Initial value+ -> Signal dom Bool+ -- ^ Enable+ -> Signal dom a+ -> Signal dom a+delayEn = \dflt en i ->+ E.delayEn+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenEnableName dom))+ dflt+ en+ i+{-# INLINE delayEn #-}++-- | 'register' @i s@ delays the values in 'Signal' @s@ for one cycle, and sets+-- the value at time 0 to @i@+--+-- >>> sampleN @System 5 (register 8 (fromList [1,1,2,3,4]))+-- [8,8,1,2,3]+register+ :: forall dom a+ . ( HiddenClockResetEnable dom+ , NFDataX a )+ => a+ -- ^ Reset value. 'register' outputs the reset value when the reset is active.+ -- If the domain has initial values enabled, the reset value will also be the+ -- initial value.+ -> Signal dom a+ -> Signal dom a+register = \i s ->+ E.register+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenResetName dom))+ (fromLabel @(HiddenEnableName dom))+ i+ s+{-# INLINE register #-}+infixr 3 `register`++-- | Version of 'register' that only updates its content when its second+-- argument is a 'Just' value. So given:+--+-- @+-- sometimes1 = s where+-- s = 'register' Nothing (switch '<$>' s)+--+-- switch Nothing = Just 1+-- switch _ = Nothing+--+-- countSometimes = s where+-- s = 'regMaybe' 0 (plusM ('pure' '<$>' s) sometimes1)+-- plusM = 'Control.Applicative.liftA2' (liftA2 (+))+-- @+--+-- We get:+--+-- >>> sampleN @System 9 sometimes1+-- [Nothing,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1,Nothing,Just 1]+-- >>> sampleN @System 9 countSometimes+-- [0,0,0,1,1,2,2,3,3]+regMaybe+ :: forall dom a+ . ( HiddenClockResetEnable dom+ , NFDataX a )+ => a+ -- ^ Reset value. 'regMaybe' outputs the reset value when the reset is active.+ -- If the domain has initial values enabled, the reset value will also be the+ -- initial value.+ -> Signal dom (Maybe a)+ -> Signal dom a+regMaybe = \initial iM ->+ E.regMaybe+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenResetName dom))+ (fromLabel @(HiddenEnableName dom))+ initial+ iM+{-# INLINE regMaybe #-}+infixr 3 `regMaybe`++-- | Version of 'register' that only updates its content when its second argument+-- is asserted. So given:+--+-- @+-- oscillate = 'register' False ('not' '<$>' oscillate)+-- count = 'regEn' 0 oscillate (count + 1)+-- @+--+-- We get:+--+-- >>> sampleN @System 9 oscillate+-- [False,False,True,False,True,False,True,False,True]+-- >>> sampleN @System 9 count+-- [0,0,0,1,1,2,2,3,3]+regEn+ :: forall dom a+ . ( HiddenClockResetEnable dom+ , NFDataX a )+ => a+ -- ^ Reset value. 'regEn' outputs the reset value when the reset is active.+ -- If the domain has initial values enabled, the reset value will also be the+ -- initial value.+ -> Signal dom Bool+ -> Signal dom a+ -> Signal dom a+regEn = \initial en i ->+ E.regEn+ (fromLabel @(HiddenClockName dom))+ (fromLabel @(HiddenResetName dom))+ (fromLabel @(HiddenEnableName dom))+ initial+ en+ i+{-# INLINE regEn #-}++-- * Signal -> List conversion++-- | Get an infinite list of samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sample' will supply them. The reset will be asserted for a single+-- cycle. 'sample' will not drop the value produced by the circuit while+-- the reset was asserted. If you want this, or if you want more than a+-- single cycle reset, consider using 'sampleWithReset'.+--+-- __NB__: This function is not synthesizable+sample+ :: forall dom a+ . ( KnownDomain dom+ , NFDataX a )+ => (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sample s =+ E.sample (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sample #-}++-- | Get a list of /n/ samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sampleN @System 3 s == [s0, s1, s2]+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sampleN' will supply them. The reset will be asserted for a single+-- cycle. 'sampleN' will not drop the value produced by the circuit while+-- the reset was asserted. If you want this, or if you want more than a+-- single cycle reset, consider using 'sampleWithResetN'.+--+-- __NB__: This function is not synthesizable+sampleN+ :: forall dom a+ . ( KnownDomain dom+ , NFDataX a )+ => Int+ -- ^ Number of samples to produce+ -> (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sampleN n s0 =+ let s1 = exposeClockResetEnable @dom s0 clockGen resetGen enableGen in+ E.sampleN n s1+{-# NOINLINE sampleN #-}++-- | Get an infinite list of samples from a 'Signal', while asserting the reset+-- line for /m/ clock cycles. 'sampleWithReset' does not return the first /m/+-- cycles, i.e., when the reset is asserted.+--+-- __NB__: This function is not synthesizable+sampleWithReset+ :: forall dom a m+ . ( KnownDomain dom+ , NFDataX a+ , 1 <= m )+ => SNat m+ -- ^ Number of cycles to assert the reset+ -> (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sampleWithReset nReset f0 =+ let f1 = exposeClockResetEnable f0 clockGen (resetGenN @dom nReset) enableGen in+ drop (snatToNum nReset) (E.sample f1)+{-# NOINLINE sampleWithReset #-}++-- | Get a list of /n/ samples from a 'Signal', while asserting the reset line+-- for /m/ clock cycles. 'sampleWithReset' does not return the first /m/ cycles,+-- i.e., while the reset is asserted.+--+-- __NB__: This function is not synthesizable+sampleWithResetN+ :: forall dom a m+ . ( KnownDomain dom+ , NFDataX a+ , 1 <= m )+ => SNat m+ -- ^ Number of cycles to assert the reset+ -> Int+ -- ^ Number of samples to produce+ -> (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sampleWithResetN nReset nSamples f =+ take nSamples (sampleWithReset nReset f)++-- | /Lazily/ get an infinite list of samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sample s == [s0, s1, s2, s3, ...+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sample_lazy' will supply them. The reset will be asserted for a+-- single cycle. 'sample_lazy' will not drop the value produced by the+-- circuit while the reset was asserted.+--+-- __NB__: This function is not synthesizable+sample_lazy+ :: forall dom a+ . KnownDomain dom+ => (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sample_lazy s =+ E.sample_lazy (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sample_lazy #-}++-- | Lazily get a list of /n/ samples from a 'Signal'+--+-- The elements in the list correspond to the values of the 'Signal'+-- at consecutive clock cycles+--+-- > sampleN @System 3 s == [s0, s1, s2]+--+-- If the given component has not yet been given a clock, reset, or enable+-- line, 'sampleN_lazy' will supply them. The reset will be asserted for a+-- single cycle. 'sampleN_lazy' will not drop the value produced by the+-- circuit while the reset was asserted.+--+-- __NB__: This function is not synthesizable+sampleN_lazy+ :: forall dom a+ . KnownDomain dom+ => Int+ -> (HiddenClockResetEnable dom => Signal dom a)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+sampleN_lazy n s =+ E.sampleN_lazy n (exposeClockResetEnable @dom s clockGen resetGen enableGen)+{-# NOINLINE sampleN_lazy #-}++-- * Simulation functions++-- | Simulate a (@'Signal' a -> 'Signal' b@) function given a list of samples+-- of type /a/+--+-- >>> simulate @System (register 8) [1, 2, 3]+-- [8,1,2,3...+-- ...+--+-- Where 'System' denotes the /domain/ to simulate on. The reset line is+-- asserted for a single cycle. The first value is therefore supplied twice to+-- the circuit: once while reset is high, and once directly after. The first+-- /output/ value (the value produced while the reset is asserted) is dropped.+--+-- If you only want to simulate a finite number of samples, see 'simulateN'. If+-- you need the reset line to be asserted for more than one cycle or if you+-- need a custom reset value, see 'simulateWithReset' and 'simulateWithResetN'.+--+-- __NB__: This function is not synthesizable+simulate+ :: forall dom a b+ . ( KnownDomain dom+ , NFDataX a+ , NFDataX b )+ => (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+ -- ^ Circuit to simulate, whose source potentially has a hidden clock, reset,+ -- and/or enable.+ -> [a]+ -> [b]+simulate f as = simulateWithReset (SNat @1) (head as) f as+{-# INLINE simulate #-}++-- | Same as 'simulate', but only sample the first /Int/ output values.+--+-- __NB__: This function is not synthesizable+simulateN+ :: forall dom a b+ . ( KnownDomain dom+ , NFDataX a+ , NFDataX b )+ => Int+ -- ^ Number of cycles to simulate (excluding cycle spent in reset)+ -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+ -> [b]+simulateN n f as = simulateWithResetN (SNat @1) (head as) n f as+{-# INLINE simulateN #-}++-- | Same as 'simulate', but with the reset line asserted for /n/ cycles. Similar+-- to 'simulate', 'simulateWithReset' will drop the output values produced while+-- the reset is asserted. While the reset is asserted, the reset value /a/ is+-- supplied to the circuit.+simulateWithReset+ :: forall dom a b m+ . ( KnownDomain dom+ , NFDataX a+ , NFDataX b+ , 1 <= m )+ => SNat m+ -- ^ Number of cycles to assert the reset+ -> a+ -- ^ Reset value+ -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+ -> [b]+simulateWithReset n resetVal f as =+ E.simulateWithReset n resetVal (exposeClockResetEnable f) as+{-# INLINE simulateWithReset #-}++-- | Same as 'simulateWithReset', but only sample the first /Int/ output values.+simulateWithResetN+ :: forall dom a b m+ . ( KnownDomain dom+ , NFDataX a+ , NFDataX b+ , 1 <= m )+ => SNat m+ -- ^ Number of cycles to assert the reset+ -> a+ -- ^ Reset value+ -> Int+ -- ^ Number of cycles to simulate (excluding cycles spent in reset)+ -> (HiddenClockResetEnable dom => Signal dom a -> Signal dom b)+ -- ^ 'Signal' we want to sample, whose source potentially has a hidden clock+ -- (and reset)+ -> [a]+ -> [b]+simulateWithResetN nReset resetVal nSamples f as =+ E.simulateWithResetN nReset resetVal nSamples (exposeClockResetEnable f) as+{-# INLINE simulateWithResetN #-}+++-- | /Lazily/ simulate a (@'Signal' a -> 'Signal' b@) function given a list of+-- samples of type /a/+--+-- >>> simulate @System (register 8) [1, 2, 3]+-- [8,1,2,3...+-- ...+--+-- __NB__: This function is not synthesizable+simulate_lazy+ :: forall dom a b+ . KnownDomain dom+ => (HiddenClockResetEnable dom =>+ Signal dom a -> Signal dom b)+ -- ^ Function we want to simulate, whose components potentially have a hidden+ -- clock (and reset)+ -> [a]+ -> [b]+simulate_lazy f0 =+ let f1 = exposeClockResetEnable @dom f0 clockGen resetGen enableGen in+ tail . E.simulate_lazy f1 . dup1+{-# NOINLINE simulate_lazy #-}++-- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of+-- samples of type @a@+--+-- >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(1,1),(2,2),(3,3)...+-- ...+--+-- __NB__: This function is not synthesizable+simulateB+ :: forall dom a b+ . ( KnownDomain dom+ , Bundle a+ , Bundle b+ , NFDataX a+ , NFDataX b+ )+ => (HiddenClockResetEnable dom =>+ Unbundled dom a -> Unbundled dom b)+ -- ^ Function we want to simulate, whose components potentially have a hidden+ -- clock (and reset)+ -> [a]+ -> [b]+simulateB f0 =+ tail . E.simulateB f1 . dup1+ where+ f1 =+ withSpecificClockResetEnable+ @dom+ clockGen+ resetGen+ enableGen+ (const f0)+ (Proxy @dom)+{-# NOINLINE simulateB #-}++-- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a+-- list of samples of type @a@+--+-- >>> simulateB @System (unbundle . register (8,8) . bundle) [(1,1), (2,2), (3,3)] :: [(Int,Int)]+-- [(8,8),(1,1),(2,2),(3,3)...+-- ...+--+-- __NB__: This function is not synthesizable+simulateB_lazy+ :: forall dom a b+ . ( KnownDomain dom+ , Bundle a+ , Bundle b )+ => (HiddenClockResetEnable dom =>+ Unbundled dom a -> Unbundled dom b)+ -- ^ Function we want to simulate, whose components potentially have a hidden+ -- clock (and reset)+ -> [a]+ -> [b]+simulateB_lazy f0 =+ tail . E.simulateB_lazy f1 . dup1+ where+ f1 =+ withSpecificClockResetEnable+ @dom+ clockGen+ resetGen+ enableGen+ (const f0)+ (Proxy @dom)+{-# NOINLINE simulateB_lazy #-}++dup1 :: [a] -> [a]+dup1 (x:xs) = x:x:xs+dup1 _ = error "empty list"++-- * QuickCheck combinators++-- | @testFor n s@ tests the signal /s/ for /n/ cycles.+--+-- __NB__: This function is not synthesizable+testFor+ :: KnownDomain dom+ => Int+ -- ^ The number of cycles we want to test for+ -> (HiddenClockResetEnable dom => Signal dom Bool)+ -- ^ 'Signal' we want to evaluate, whose source potentially has a hidden clock+ -- (and reset)+ -> Property+testFor n s = property (and (Clash.Signal.sampleN n s))++#ifdef CLASH_MULTIPLE_HIDDEN+-- ** Synchronization primitive+-- | Implicit version of 'Clash.Explicit.Signal.unsafeSynchronizer'.+unsafeSynchronizer+ :: forall dom1 dom2 a+ . ( HiddenClock dom1+ , HiddenClock dom2 )+ => Signal dom1 a+ -> Signal dom2 a+unsafeSynchronizer =+ hideClock (hideClock E.unsafeSynchronizer) #endif -- | Hold reset for a number of cycles relative to an implicit reset signal.
src/Clash/Signal/Internal.hs view
@@ -1,9 +1,10 @@ {-| Copyright : (C) 2013-2016, University of Twente, 2017-2019, Myrtle Software Ltd- 2017, Google Inc.+ 2017 , Google Inc.,+ 2021 , QBayLogic B.V. License : BSD2 (see the file LICENSE)-Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer : QBayLogic B.V. <devops@qbaylogic.com> -} {-# LANGUAGE ConstraintKinds #-}@@ -395,8 +396,9 @@ -- | Returns 'SDomainConfiguration' corresponding to an instance's 'DomainConfiguration'. -- -- Example usage:- -- > knownDomain @System --+ -- >>> knownDomain @System+ -- SDomainConfiguration (SSymbol @"System") (SNat @10000) SRising SAsynchronous SDefined SActiveHigh knownDomain :: SDomainConfiguration dom (KnownConf dom) -- | Version of 'knownDomain' that takes a 'SSymbol'. For example:@@ -429,7 +431,7 @@ -- | Convenience value to allow easy "subclassing" of System domain. Should -- be used in combination with 'createDomain'. For example, if you just want to--- change the period but leave all other settings in tact use:+-- change the period but leave all other settings intact use: -- -- > createDomain vSystem{vName="System10", vPeriod=10} --@@ -447,7 +449,7 @@ -- | Convenience value to allow easy "subclassing" of IntelSystem domain. Should -- be used in combination with 'createDomain'. For example, if you just want to--- change the period but leave all other settings in tact use:+-- change the period but leave all other settings intact use: -- -- > createDomain vIntelSystem{vName="Intel10", vPeriod=10} --@@ -464,7 +466,7 @@ -- | Convenience value to allow easy "subclassing" of XilinxSystem domain. Should -- be used in combination with 'createDomain'. For example, if you just want to--- change the period but leave all other settings in tact use:+-- change the period but leave all other settings intact use: -- -- > createDomain vXilinxSystem{vName="Xilinx10", vPeriod=10} --
src/Clash/Tutorial.hs view
@@ -1,8 +1,11 @@ {-| Copyright : © 2014-2016, Christiaan Baaij, 2017-2019, Myrtle Software Ltd- 2017 , QBayLogic, Google Inc.+ 2017 , QBayLogic, Google Inc.,+ 2021 , QBayLogic B.V.+ Licence : Creative Commons 4.0 (CC BY 4.0) (https://creativecommons.org/licenses/by/4.0/)+Maintainer: QBayLogic B.V. <devops@qbaylogic.com> -} {-# LANGUAGE NoImplicitPrelude #-}@@ -1088,14 +1091,13 @@ module BlockRam where import Clash.Explicit.Prelude-import qualified Data.Vector as V-import GHC.Stack (HasCallStack, withFrozenCallStack)--import Clash.Signal.Internal- (Clock, Signal (..), (.&&.))-import Clash.Sized.Vector (Vec, toList)-import Clash.XException (defaultSeqX)+import Clash.Annotations.Primitive (hasBlackBox)+import Clash.Signal.Internal (Clock, Signal (..), (.&&.))+import Clash.Sized.Vector (Vec, toList)+import Clash.XException (defaultSeqX) +import qualified Data.Vector as V+import GHC.Stack (HasCallStack, withFrozenCallStack) blockRam# :: ( KnownDomain dom@@ -1135,6 +1137,7 @@ Just wa -> ram V.// [(wa,d)] _ -> ram {\-\# NOINLINE blockRam# \#\-\}+{\-\# ANN blockRam# hasBlackBox \#\-\} @ And for which the /declaration/ primitive is: