packages feed

clash-prelude 1.6.6 → 1.8.0

raw patch · 102 files changed

+5215/−1867 lines, 102 filesdep +infinite-listdep +mtldep +string-interpolatedep −interpolatedep ~deepseqdep ~ghc-bignumdep ~ghc-primPVP ok

version bump matches the API change (PVP)

Dependencies added: infinite-list, mtl, string-interpolate

Dependencies removed: interpolate

Dependency ranges changed: deepseq, ghc-bignum, ghc-prim, tasty, template-haskell, th-abstraction

API changes (from Hackage documentation)

- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Clock c15, Clash.Signal.Internal.Clock c16, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Clock c15, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Clock c14, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Clock c13, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Clock c12, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Clock c11, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Clock c10, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Clock c9, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Clock c8, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Clock c7, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Clock c6, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Clock c5, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Clock c4, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks: instance Clash.Clocks.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
- Clash.Clocks.Deriving: deriveClocksInstances :: Int -> Q [Dec]
- Clash.Explicit.Reset: instance Clash.XException.NFDataX Clash.Explicit.Reset.GlitchFilterState
- Clash.Explicit.Reset: instance Clash.XException.ShowX Clash.Explicit.Reset.GlitchFilterState
- Clash.Explicit.Reset: instance GHC.Generics.Generic Clash.Explicit.Reset.GlitchFilterState
- Clash.Explicit.Reset: instance GHC.Show.Show Clash.Explicit.Reset.GlitchFilterState
- Clash.Explicit.Signal: enable :: Enable dom -> Signal dom Bool -> Enable dom
- Clash.HaskellPrelude: maximum :: (Foldable t, Ord a) => t a -> a
- Clash.HaskellPrelude: minimum :: (Foldable t, Ord a) => t a -> a
- Clash.HaskellPrelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
- Clash.HaskellPrelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
- Clash.Prelude.BitIndex: (!) :: (BitPack a, Enum i) => a -> i -> Bit
- Clash.Prelude.BitIndex: lsb :: BitPack a => a -> Bit
- Clash.Prelude.BitIndex: msb :: BitPack a => a -> Bit
- Clash.Prelude.BitIndex: replaceBit :: (BitPack a, Enum i) => i -> Bit -> a -> a
- Clash.Prelude.BitIndex: setSlice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> BitVector ((m + 1) - n) -> a -> a
- Clash.Prelude.BitIndex: slice :: (BitPack a, BitSize a ~ ((m + 1) + i)) => SNat m -> SNat n -> a -> BitVector ((m + 1) - n)
- Clash.Prelude.BitIndex: split :: (BitPack a, BitSize a ~ (m + n), KnownNat n) => a -> (BitVector m, BitVector n)
- Clash.Prelude.BitReduction: reduceAnd :: BitPack a => a -> Bit
- Clash.Prelude.BitReduction: reduceOr :: BitPack a => a -> Bit
- Clash.Prelude.BitReduction: reduceXor :: BitPack a => a -> Bit
- Clash.Signal.Internal: clockTag :: Clock dom -> SSymbol dom
- Clash.Sized.Fixed: instance Clash.Class.BitPack.Internal.BitPack (rep (int GHC.TypeNats.+ frac)) => Clash.Class.BitPack.Internal.BitPack (Clash.Sized.Fixed.Fixed rep int frac)
- Clash.Sized.Vector: instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Foldable.Foldable (Clash.Sized.Vector.Vec n)
- Clash.Sized.Vector: instance (GHC.TypeNats.KnownNat n, 1 GHC.TypeNats.<= n) => Data.Traversable.Traversable (Clash.Sized.Vector.Vec n)
+ Clash.Annotations.SynthesisAttributes: annotate :: forall n dom a. Vec n (Attr String) -> Signal dom a -> Signal dom a
+ Clash.Annotations.SynthesisAttributes: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance GHC.Base.Functor Clash.Annotations.SynthesisAttributes.Attr
+ Clash.Annotations.SynthesisAttributes: instance GHC.Classes.Eq a => GHC.Classes.Eq (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance GHC.Classes.Ord a => GHC.Classes.Ord (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance GHC.Generics.Generic (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance GHC.Show.Show a => GHC.Show.Show (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: instance Language.Haskell.TH.Syntax.Lift a => Language.Haskell.TH.Syntax.Lift (Clash.Annotations.SynthesisAttributes.Attr a)
+ Clash.Annotations.SynthesisAttributes: markDebug :: Signal dom a -> Signal dom a
+ Clash.Class.BitPack.Internal: instance Clash.Class.BitPack.Internal.BitPack GHC.Types.Ordering
+ Clash.Clocks: class ClocksSync t where {
+ Clash.Clocks: clocksResetSynchronizer :: (ClocksSync t, KnownDomain domIn, ClocksResetSynchronizerCxt t) => ClocksSyncClocksInst t domIn -> Clock domIn -> t
+ Clash.Clocks: instance Clash.Clocks.Internal.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Internal.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Internal.Clocks (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Signal pllLock GHC.Types.Bool)
+ Clash.Clocks: instance Clash.Clocks.Internal.ClocksSync (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Reset c1)
+ Clash.Clocks: instance Clash.Clocks.Internal.ClocksSync (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Reset c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Reset c2)
+ Clash.Clocks: instance Clash.Clocks.Internal.ClocksSync (Clash.Signal.Internal.Clock c1, Clash.Signal.Internal.Reset c1, Clash.Signal.Internal.Clock c2, Clash.Signal.Internal.Reset c2, Clash.Signal.Internal.Clock c3, Clash.Signal.Internal.Reset c3)
+ Clash.Clocks: type ClocksSyncCxt t (domIn :: Domain) = (KnownDomain domIn, ClocksSync t, ClocksResetSynchronizerCxt t, Clocks (ClocksSyncClocksInst t domIn), ClocksCxt (ClocksSyncClocksInst t domIn))
+ Clash.Clocks: type NumOutClocksSync t (domIn :: Domain) = NumOutClocks (ClocksSyncClocksInst t domIn)
+ Clash.Explicit.BlockRam.Model: Conflict :: !MaybeX Bool -> !MaybeX Bool -> !MaybeX Bool -> Conflict
+ Clash.Explicit.BlockRam.Model: TdpbramModelConfig :: (MaybeX writeEnable -> MaybeX Bool) -> (MaybeX Bool -> MaybeX writeEnable -> MaybeX writeEnable) -> (Int -> MaybeX writeEnable -> a -> Seq a -> Seq a) -> TdpbramModelConfig writeEnable a
+ Clash.Explicit.BlockRam.Model: [cfRWA] :: Conflict -> !MaybeX Bool
+ Clash.Explicit.BlockRam.Model: [cfRWB] :: Conflict -> !MaybeX Bool
+ Clash.Explicit.BlockRam.Model: [cfWW] :: Conflict -> !MaybeX Bool
+ Clash.Explicit.BlockRam.Model: [tdpIsActiveWriteEnable] :: TdpbramModelConfig writeEnable a -> MaybeX writeEnable -> MaybeX Bool
+ Clash.Explicit.BlockRam.Model: [tdpMergeWriteEnable] :: TdpbramModelConfig writeEnable a -> MaybeX Bool -> MaybeX writeEnable -> MaybeX writeEnable
+ Clash.Explicit.BlockRam.Model: [tdpUpdateRam] :: TdpbramModelConfig writeEnable a -> Int -> MaybeX writeEnable -> a -> Seq a -> Seq a
+ Clash.Explicit.BlockRam.Model: accessRam :: forall nAddrs a writeEnable. (NFDataX a, HasCallStack) => SNat nAddrs -> (MaybeX writeEnable -> MaybeX Bool) -> (Int -> MaybeX writeEnable -> a -> Seq a -> Seq a) -> MaybeX Int -> MaybeX writeEnable -> a -> Seq a -> (a, Seq a)
+ Clash.Explicit.BlockRam.Model: cycleBoth :: forall nAddrs a writeEnable. (NFDataX a, HasCallStack) => SNat nAddrs -> TdpbramModelConfig writeEnable a -> a -> a -> Seq a -> (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) -> (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) -> (Seq a, a, a)
+ Clash.Explicit.BlockRam.Model: cycleOne :: forall nAddrs a writeEnable. (HasCallStack, NFDataX a) => SNat nAddrs -> TdpbramModelConfig writeEnable a -> a -> Seq a -> (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) -> (Seq a, a)
+ Clash.Explicit.BlockRam.Model: data Conflict
+ Clash.Explicit.BlockRam.Model: data TdpbramModelConfig writeEnable a
+ Clash.Explicit.BlockRam.Model: getConflict :: (MaybeX Bool, MaybeX Bool, MaybeX Int) -> (MaybeX Bool, MaybeX Bool, MaybeX Int) -> Maybe Conflict
+ Clash.Explicit.BlockRam.Model: instance GHC.Show.Show Clash.Explicit.BlockRam.Model.Conflict
+ Clash.Explicit.BlockRam.Model: tdpbramModel :: forall nAddrs domA domB a writeEnable. (HasCallStack, KnownNat nAddrs, KnownDomain domA, KnownDomain domB, NFDataX a) => TdpbramModelConfig writeEnable a -> Clock domA -> Signal domA Bool -> Signal domA (Index nAddrs) -> Signal domA writeEnable -> Signal domA a -> Clock domB -> Signal domB Bool -> Signal domB (Index nAddrs) -> Signal domB writeEnable -> Signal domB a -> (Signal domA a, Signal domB a)
+ Clash.Explicit.Mealy: mealyS :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (i -> State s o) -> s -> Signal dom i -> Signal dom o
+ Clash.Explicit.Mealy: mealySB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (i -> State s o) -> s -> Unbundled dom i -> Unbundled dom o
+ Clash.Explicit.Prelude: maximum :: Ord a => Vec (n + 1) a -> a
+ Clash.Explicit.Prelude: mealyS :: (KnownDomain dom, NFDataX s) => Clock dom -> Reset dom -> Enable dom -> (i -> State s o) -> s -> Signal dom i -> Signal dom o
+ Clash.Explicit.Prelude: mealySB :: (KnownDomain dom, NFDataX s, Bundle i, Bundle o) => Clock dom -> Reset dom -> Enable dom -> (i -> State s o) -> s -> Unbundled dom i -> Unbundled dom o
+ Clash.Explicit.Prelude: minimum :: Ord a => Vec (n + 1) a -> a
+ Clash.Explicit.Prelude: scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Explicit.Prelude: scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Explicit.Prelude.Safe: maximum :: Ord a => Vec (n + 1) a -> a
+ Clash.Explicit.Prelude.Safe: minimum :: Ord a => Vec (n + 1) a -> a
+ Clash.Explicit.Prelude.Safe: scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Explicit.Prelude.Safe: scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Explicit.Reset: andReset :: forall dom. HasSynchronousReset dom => Reset dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: noReset :: KnownDomain dom => Reset dom
+ Clash.Explicit.Reset: orReset :: forall dom. HasSynchronousReset dom => Reset dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: resetGlitchFilterWithReset :: forall dom glitchlessPeriod. (HasCallStack, KnownDomain dom, 1 <= glitchlessPeriod) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: unsafeAndReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: unsafeFromActiveHigh :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Reset: unsafeFromActiveLow :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Reset: unsafeOrReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: unsafeResetGlitchFilter :: forall dom glitchlessPeriod. (HasCallStack, KnownDomain dom, 1 <= glitchlessPeriod) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: unsafeToActiveHigh :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Reset: unsafeToActiveLow :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Signal: data DiffClock (dom :: Domain)
+ Clash.Explicit.Signal: type HasAsynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous)
+ Clash.Explicit.Signal: type HasDefinedInitialValues (dom :: Domain) = (KnownDomain dom, DomainInitBehavior dom ~ 'Defined)
+ Clash.Explicit.Signal: type HasSynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Synchronous)
+ Clash.Explicit.Signal: unsafeFromActiveHigh :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: unsafeFromActiveLow :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: unsafeToActiveHigh :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Signal: unsafeToActiveLow :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Explicit.Testbench: clockToDiffClock :: KnownDomain dom => Clock dom -> DiffClock dom
+ Clash.Intel.ClockGen: alteraPllSync :: forall t domIn. (HasAsynchronousReset domIn, ClocksSyncCxt t domIn, NumOutClocksSync t domIn <= 18) => Clock domIn -> Reset domIn -> t
+ Clash.Intel.ClockGen: altpllSync :: forall t domIn. (HasAsynchronousReset domIn, ClocksSyncCxt t domIn, NumOutClocksSync t domIn <= 5) => Clock domIn -> Reset domIn -> t
+ Clash.Intel.ClockGen: unsafeAlteraPll :: forall t domIn. (KnownDomain domIn, Clocks t, ClocksCxt t, NumOutClocks t <= 18) => Clock domIn -> Reset domIn -> t
+ Clash.Intel.ClockGen: unsafeAltpll :: forall t domIn. (KnownDomain domIn, Clocks t, ClocksCxt t, NumOutClocks t <= 5) => Clock domIn -> Reset domIn -> t
+ Clash.Magic: SimOnly :: a -> SimOnly a
+ Clash.Magic: clashCompileError :: forall a. HasCallStack => String -> a
+ Clash.Magic: clashSimulation :: Bool
+ Clash.Magic: data SimOnly a
+ Clash.Magic: instance Data.Foldable.Foldable Clash.Magic.SimOnly
+ Clash.Magic: instance Data.Traversable.Traversable Clash.Magic.SimOnly
+ Clash.Magic: instance GHC.Base.Applicative Clash.Magic.SimOnly
+ Clash.Magic: instance GHC.Base.Functor Clash.Magic.SimOnly
+ Clash.Magic: instance GHC.Base.Monad Clash.Magic.SimOnly
+ Clash.Magic: instance GHC.Base.Monoid a => GHC.Base.Monoid (Clash.Magic.SimOnly a)
+ Clash.Magic: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Clash.Magic.SimOnly a)
+ Clash.Magic: instance GHC.Classes.Eq a => GHC.Classes.Eq (Clash.Magic.SimOnly a)
+ Clash.Magic: instance GHC.Classes.Ord a => GHC.Classes.Ord (Clash.Magic.SimOnly a)
+ Clash.Num.Erroring: fromErroring :: Erroring a -> a
+ Clash.Num.Erroring: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Num.Erroring.Erroring a)
+ Clash.Num.Saturating: fromSaturating :: Saturating a -> a
+ Clash.Num.Saturating: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Num.Saturating.Saturating a)
+ Clash.Num.Wrapping: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Num.Wrapping.Wrapping a)
+ Clash.Num.Zeroing: fromZeroing :: Zeroing a -> a
+ Clash.Num.Zeroing: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Clash.Num.Zeroing.Zeroing a)
+ Clash.Prelude: data DiffClock (dom :: Domain)
+ Clash.Prelude: maximum :: Ord a => Vec (n + 1) a -> a
+ Clash.Prelude: mealyS :: (HiddenClockResetEnable dom, NFDataX s) => (i -> State s o) -> s -> Signal dom i -> Signal dom o
+ Clash.Prelude: mealySB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (i -> State s o) -> s -> Unbundled dom i -> Unbundled dom o
+ Clash.Prelude: minimum :: Ord a => Vec (n + 1) a -> a
+ Clash.Prelude: scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Prelude: scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Prelude: type HasAsynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous)
+ Clash.Prelude: type HasDefinedInitialValues (dom :: Domain) = (KnownDomain dom, DomainInitBehavior dom ~ 'Defined)
+ Clash.Prelude: type HasSynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Synchronous)
+ Clash.Prelude: unsafeFromActiveHigh :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Prelude: unsafeFromActiveLow :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Prelude: unsafeToActiveHigh :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Prelude: unsafeToActiveLow :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Prelude.Mealy: mealyS :: (HiddenClockResetEnable dom, NFDataX s) => (i -> State s o) -> s -> Signal dom i -> Signal dom o
+ Clash.Prelude.Mealy: mealySB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (i -> State s o) -> s -> Unbundled dom i -> Unbundled dom o
+ Clash.Prelude.Safe: maximum :: Ord a => Vec (n + 1) a -> a
+ Clash.Prelude.Safe: mealyS :: (HiddenClockResetEnable dom, NFDataX s) => (i -> State s o) -> s -> Signal dom i -> Signal dom o
+ Clash.Prelude.Safe: mealySB :: (HiddenClockResetEnable dom, NFDataX s, Bundle i, Bundle o) => (i -> State s o) -> s -> Unbundled dom i -> Unbundled dom o
+ Clash.Prelude.Safe: minimum :: Ord a => Vec (n + 1) a -> a
+ Clash.Prelude.Safe: scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Prelude.Safe: scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Prelude.Testbench: clockToDiffClock :: KnownDomain dom => Clock dom -> DiffClock dom
+ Clash.Signal: data DiffClock (dom :: Domain)
+ Clash.Signal: type HasAsynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous)
+ Clash.Signal: type HasDefinedInitialValues (dom :: Domain) = (KnownDomain dom, DomainInitBehavior dom ~ 'Defined)
+ Clash.Signal: type HasSynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Synchronous)
+ Clash.Signal: unsafeFromActiveHigh :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal: unsafeFromActiveLow :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal: unsafeToActiveHigh :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal: unsafeToActiveLow :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal.Internal: ClockA :: ClockAB
+ Clash.Signal.Internal: ClockAB :: ClockAB
+ Clash.Signal.Internal: ClockB :: ClockAB
+ Clash.Signal.Internal: ClockN :: SSymbol dom -> ClockN (dom :: Domain)
+ Clash.Signal.Internal: DiffClock :: ("p" ::: Clock dom) -> ("n" ::: ClockN dom) -> DiffClock (dom :: Domain)
+ Clash.Signal.Internal: Femtoseconds :: Int64 -> Femtoseconds
+ Clash.Signal.Internal: [clockNTag] :: ClockN (dom :: Domain) -> SSymbol dom
+ Clash.Signal.Internal: [clockPeriods] :: Clock (dom :: Domain) -> Maybe (Signal dom Femtoseconds)
+ Clash.Signal.Internal: [clockTag] :: Clock (dom :: Domain) -> SSymbol dom
+ Clash.Signal.Internal: clockTicks :: (KnownDomain domA, KnownDomain domB) => Clock domA -> Clock domB -> [ClockAB]
+ Clash.Signal.Internal: clockTicksEither :: Either Int64 (Signal domA Int64) -> Either Int64 (Signal domB Int64) -> [ClockAB]
+ Clash.Signal.Internal: data ClockAB
+ Clash.Signal.Internal: data DiffClock (dom :: Domain)
+ Clash.Signal.Internal: dynamicClockGen :: KnownDomain dom => Signal dom Femtoseconds -> Clock dom
+ Clash.Signal.Internal: fsToHz :: (HasCallStack, Fractional a) => Femtoseconds -> a
+ Clash.Signal.Internal: hzToFs :: HasCallStack => Ratio Natural -> Femtoseconds
+ Clash.Signal.Internal: instance Clash.XException.NFDataX Clash.Signal.Internal.ClockAB
+ Clash.Signal.Internal: instance Clash.XException.NFDataX Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.ClockAB
+ Clash.Signal.Internal: instance Control.DeepSeq.NFData Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance Data.Binary.Class.Binary Clash.Signal.Internal.InitBehavior
+ Clash.Signal.Internal: instance Data.Binary.Class.Binary Clash.Signal.Internal.ResetKind
+ Clash.Signal.Internal: instance Data.Binary.Class.Binary Clash.Signal.Internal.ResetPolarity
+ Clash.Signal.Internal: instance Data.Binary.Class.Binary Clash.Signal.Internal.VDomainConfiguration
+ Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.ClockAB
+ Clash.Signal.Internal: instance GHC.Classes.Eq Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance GHC.Classes.Ord Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.ClockAB
+ Clash.Signal.Internal: instance GHC.Generics.Generic Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.ClockN dom)
+ Clash.Signal.Internal: instance GHC.Show.Show (Clash.Signal.Internal.DiffClock dom)
+ Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.ClockAB
+ Clash.Signal.Internal: instance GHC.Show.Show Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: instance Language.Haskell.TH.Syntax.Lift Clash.Signal.Internal.Femtoseconds
+ Clash.Signal.Internal: mapFemtoseconds :: (Int64 -> Int64) -> Femtoseconds -> Femtoseconds
+ Clash.Signal.Internal: newtype ClockN (dom :: Domain)
+ Clash.Signal.Internal: newtype Femtoseconds
+ Clash.Signal.Internal: tbClockGen :: KnownDomain testDom => Signal testDom Bool -> Clock testDom
+ Clash.Signal.Internal: tbDynamicClockGen :: KnownDomain dom => Signal dom Femtoseconds -> Signal dom Bool -> Clock dom
+ Clash.Signal.Internal: type HasAsynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous)
+ Clash.Signal.Internal: type HasDefinedInitialValues (dom :: Domain) = (KnownDomain dom, DomainInitBehavior dom ~ 'Defined)
+ Clash.Signal.Internal: type HasSynchronousReset (dom :: Domain) = (KnownDomain dom, DomainResetKind dom ~ 'Synchronous)
+ Clash.Signal.Internal: unFemtoseconds :: Femtoseconds -> Int64
+ Clash.Signal.Internal: unsafeFromActiveHigh :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: unsafeFromActiveLow :: forall dom. KnownDomain dom => Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: unsafeToActiveHigh :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Signal.Internal: unsafeToActiveLow :: forall dom. KnownDomain dom => Reset dom -> Signal dom Bool
+ Clash.Sized.BitVector: (+>>.) :: forall n. KnownNat n => Bit -> BitVector n -> BitVector n
+ Clash.Sized.BitVector: (.<<+) :: forall n. KnownNat n => BitVector n -> Bit -> BitVector n
+ Clash.Sized.BitVector: hLit :: String -> ExpQ
+ Clash.Sized.BitVector: infixr 4 .<<+
+ Clash.Sized.BitVector: oLit :: String -> ExpQ
+ Clash.Sized.Fixed: instance (Clash.Class.BitPack.Internal.BitPack (rep (int GHC.TypeNats.+ frac)), GHC.TypeNats.KnownNat (Clash.Class.BitPack.Internal.BitSize (rep (int GHC.TypeNats.+ frac)))) => Clash.Class.BitPack.Internal.BitPack (Clash.Sized.Fixed.Fixed rep int frac)
+ Clash.Sized.Internal.BitVector: hLit :: String -> ExpQ
+ Clash.Sized.Internal.BitVector: oLit :: String -> ExpQ
+ Clash.Sized.Vector: instance GHC.TypeNats.KnownNat n => Data.Foldable.Foldable (Clash.Sized.Vector.Vec n)
+ Clash.Sized.Vector: instance GHC.TypeNats.KnownNat n => Data.Traversable.Traversable (Clash.Sized.Vector.Vec n)
+ Clash.Sized.Vector: maximum :: Ord a => Vec (n + 1) a -> a
+ Clash.Sized.Vector: minimum :: Ord a => Vec (n + 1) a -> a
+ Clash.Sized.Vector: scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.Sized.Vector: scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n + 1) a -> Vec (n + 1) a
+ Clash.XException: instance Clash.XException.NFDataX GHC.Types.Ordering
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.List.Infinite.Internal.Infinite a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (GHC.Base.NonEmpty a)
+ Clash.XException: instance Clash.XException.ShowX GHC.Types.Ordering
+ Clash.XException.MaybeX: andX :: MaybeX Bool -> MaybeX Bool -> MaybeX Bool
+ Clash.XException.MaybeX: data MaybeX a
+ Clash.XException.MaybeX: fromMaybeX :: MaybeX a -> a
+ Clash.XException.MaybeX: hasXToMaybeX :: (NFDataX a, NFData a) => a -> MaybeX a
+ Clash.XException.MaybeX: infixr 2 `orX`
+ Clash.XException.MaybeX: infixr 3 `andX`
+ Clash.XException.MaybeX: instance GHC.Base.Applicative Clash.XException.MaybeX.MaybeX
+ Clash.XException.MaybeX: instance GHC.Base.Functor Clash.XException.MaybeX.MaybeX
+ Clash.XException.MaybeX: instance GHC.Show.Show a => GHC.Show.Show (Clash.XException.MaybeX.MaybeX a)
+ Clash.XException.MaybeX: maybeX :: (String -> b) -> (a -> b) -> MaybeX a -> b
+ Clash.XException.MaybeX: orX :: MaybeX Bool -> MaybeX Bool -> MaybeX Bool
+ Clash.XException.MaybeX: pattern IsDefined :: forall a. a -> MaybeX a
+ Clash.XException.MaybeX: pattern IsX :: forall a. String -> MaybeX a
+ Clash.XException.MaybeX: toMaybeX :: a -> MaybeX a
+ Clash.Xilinx.ClockGen: unsafeClockWizard :: forall t domIn. (KnownDomain domIn, Clocks t, ClocksCxt t, NumOutClocks t <= 7) => Clock domIn -> Reset domIn -> t
+ Clash.Xilinx.ClockGen: unsafeClockWizardDifferential :: forall t domIn. (KnownDomain domIn, Clocks t, ClocksCxt t, NumOutClocks t <= 7) => DiffClock domIn -> Reset domIn -> t
- Clash.Annotations.SynthesisAttributes: Attr :: Symbol -> Attr
+ Clash.Annotations.SynthesisAttributes: Attr :: a -> Attr a
- Clash.Annotations.SynthesisAttributes: BoolAttr :: Symbol -> Bool -> Attr
+ Clash.Annotations.SynthesisAttributes: BoolAttr :: a -> Bool -> Attr a
- Clash.Annotations.SynthesisAttributes: IntegerAttr :: Symbol -> Integer -> Attr
+ Clash.Annotations.SynthesisAttributes: IntegerAttr :: a -> Integer -> Attr a
- Clash.Annotations.SynthesisAttributes: StringAttr :: Symbol -> Symbol -> Attr
+ Clash.Annotations.SynthesisAttributes: StringAttr :: a -> a -> Attr a
- Clash.Annotations.SynthesisAttributes: data Attr
+ Clash.Annotations.SynthesisAttributes: data Attr a
- Clash.Clocks: type family ClocksCxt t :: Constraint;
+ Clash.Clocks: type family ClocksResetSynchronizerCxt t :: Constraint;
- Clash.Explicit.BlockRam: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.BlockRam: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.BlockRam: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.BlockRam: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.BlockRam.Blob: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.BlockRam.Blob: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.BlockRam.File: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.BlockRam.File: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, NFDataX addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.Prelude: asyncRam :: (Enum addr, NFDataX addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.Prelude: asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
+ Clash.Explicit.Prelude: asyncRom :: (KnownNat n, Enum addr, NFDataX a) => Vec n a -> addr -> a
- Clash.Explicit.Prelude: asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
+ Clash.Explicit.Prelude: asyncRomPow2 :: (KnownNat n, NFDataX a) => Vec (2 ^ n) a -> Unsigned n -> a
- Clash.Explicit.Prelude: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRam1 :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.Prelude: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.Prelude: blockRamFile :: (KnownDomain dom, KnownNat m, Enum addr, NFDataX addr, HasCallStack) => Clock dom -> Enable dom -> SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.Prelude: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude: blockRamU :: forall n dom a r addr. (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => Clock dom -> Reset dom -> Enable dom -> ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude.Safe: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.Prelude.Safe: asyncRam :: (Enum addr, NFDataX addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.Prelude.Safe: asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
+ Clash.Explicit.Prelude.Safe: asyncRom :: (KnownNat n, Enum addr, NFDataX a) => Vec n a -> addr -> a
- Clash.Explicit.Prelude.Safe: asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
+ Clash.Explicit.Prelude.Safe: asyncRomPow2 :: (KnownNat n, NFDataX a) => Vec (2 ^ n) a -> Unsigned n -> a
- Clash.Explicit.Prelude.Safe: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Explicit.Prelude.Safe: blockRam :: (KnownDomain dom, HasCallStack, NFDataX a, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Explicit.Prelude.Safe: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Explicit.Prelude.Safe: blockRamBlob :: forall dom addr m n. (KnownDomain dom, Enum addr, NFDataX addr) => Clock dom -> Enable dom -> MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Explicit.RAM: asyncRam :: (Enum addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
+ Clash.Explicit.RAM: asyncRam :: (Enum addr, NFDataX addr, HasCallStack, KnownDomain wdom, KnownDomain rdom, NFDataX a) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom addr -> Signal wdom (Maybe (addr, a)) -> Signal rdom a
- Clash.Explicit.Reset: resetGlitchFilter :: forall dom glitchlessPeriod n. (KnownDomain dom, glitchlessPeriod ~ (n + 1)) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
+ Clash.Explicit.Reset: resetGlitchFilter :: forall dom glitchlessPeriod. (HasCallStack, HasDefinedInitialValues dom, 1 <= glitchlessPeriod) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
- Clash.Explicit.Reset: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Explicit.Reset: unsafeToReset :: KnownDomain dom => Signal dom Bool -> Reset dom
- Clash.Explicit.Signal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Explicit.Signal: [SDomainConfiguration] :: {sName :: SSymbol dom " Domain name", sPeriod :: SNat period " Period of clock in /ps/", sActiveEdge :: SActiveEdge edge " Active edge of the clock (not yet implemented)", sResetKind :: SResetKind reset " Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)", sInitBehavior :: SInitBehavior init " Whether the initial (or "power up") value of memory elements is unknown/undefined, or configurable to a specific value", sResetPolarity :: SResetPolarity polarity " Whether resets are active high or active low"} -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
- Clash.Explicit.Signal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Explicit.Signal: class (KnownSymbol dom, KnownNat (DomainPeriod dom)) => KnownDomain (dom :: Domain) where {
- Clash.Explicit.Signal: hzToPeriod :: HasCallStack => Ratio Natural -> Natural
+ Clash.Explicit.Signal: hzToPeriod :: (HasCallStack, Integral a) => Ratio Natural -> a
- Clash.Explicit.Signal: periodToHz :: Natural -> Ratio Natural
+ Clash.Explicit.Signal: periodToHz :: (HasCallStack, Fractional a) => Natural -> a
- Clash.Explicit.Signal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Explicit.Signal: unsafeToReset :: KnownDomain dom => Signal dom Bool -> Reset dom
- Clash.Explicit.Signal: veryUnsafeSynchronizer :: Int -> Int -> Signal dom1 a -> Signal dom2 a
+ Clash.Explicit.Signal: veryUnsafeSynchronizer :: Either Int (Signal dom1 Int) -> Either Int (Signal dom2 Int) -> Signal dom1 a -> Signal dom2 a
- Clash.Explicit.Signal: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Explicit.Signal: writeToBiSignal :: (HasCallStack, BitPack a, NFDataX a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
- Clash.Explicit.Testbench: outputVerifier :: forall l a testDom circuitDom. (KnownNat l, KnownDomain testDom, KnownDomain circuitDom, Eq a, ShowX a, 1 <= l) => Clock testDom -> Reset testDom -> Vec l a -> Signal circuitDom a -> Signal testDom Bool
+ Clash.Explicit.Testbench: outputVerifier :: forall l a testDom circuitDom. (KnownNat l, KnownDomain testDom, KnownDomain circuitDom, Eq a, ShowX a, 1 <= l) => Clock testDom -> Clock circuitDom -> Reset testDom -> Vec l a -> Signal circuitDom a -> Signal testDom Bool
- Clash.Explicit.Testbench: outputVerifierBitVector :: forall l n testDom circuitDom. (KnownNat l, KnownNat n, KnownDomain testDom, KnownDomain circuitDom, 1 <= l) => Clock testDom -> Reset testDom -> Vec l (BitVector n) -> Signal circuitDom (BitVector n) -> Signal testDom Bool
+ Clash.Explicit.Testbench: outputVerifierBitVector :: forall l n testDom circuitDom. (KnownNat l, KnownNat n, KnownDomain testDom, KnownDomain circuitDom, 1 <= l) => Clock testDom -> Clock circuitDom -> Reset testDom -> Vec l (BitVector n) -> Signal circuitDom (BitVector n) -> Signal testDom Bool
- Clash.Explicit.Testbench: outputVerifierWith :: forall l a testDom circuitDom. (KnownNat l, KnownDomain testDom, KnownDomain circuitDom, Eq a, ShowX a, 1 <= l) => (Clock testDom -> Reset testDom -> Signal testDom a -> Signal testDom a -> Signal testDom Bool -> Signal testDom Bool) -> Clock testDom -> Reset testDom -> Vec l a -> Signal circuitDom a -> Signal testDom Bool
+ Clash.Explicit.Testbench: outputVerifierWith :: forall l a testDom circuitDom. (KnownNat l, KnownDomain testDom, KnownDomain circuitDom, Eq a, ShowX a, 1 <= l) => (Clock testDom -> Reset testDom -> Signal testDom a -> Signal testDom a -> Signal testDom Bool -> Signal testDom Bool) -> Clock testDom -> Clock circuitDom -> Reset testDom -> Vec l a -> Signal circuitDom a -> Signal testDom Bool
- Clash.Intel.ClockGen: alteraPll :: (Clocks t, KnownDomain domIn, ClocksCxt t) => SSymbol name -> Clock domIn -> Reset domIn -> t
+ Clash.Intel.ClockGen: alteraPll :: forall t domIn name. (HasAsynchronousReset domIn, Clocks t, ClocksCxt t, NumOutClocks t <= 18) => SSymbol name -> Clock domIn -> Reset domIn -> t
- Clash.Intel.ClockGen: altpll :: forall domOut domIn name. (KnownDomain domIn, KnownDomain domOut) => SSymbol name -> Clock domIn -> Reset domIn -> (Clock domOut, Signal domOut Bool)
+ Clash.Intel.ClockGen: altpll :: forall domOut domIn name. (HasAsynchronousReset domIn, KnownDomain domOut) => SSymbol name -> Clock domIn -> Reset domIn -> (Clock domOut, Signal domOut Bool)
- Clash.Prelude: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Prelude: [SDomainConfiguration] :: {sName :: SSymbol dom " Domain name", sPeriod :: SNat period " Period of clock in /ps/", sActiveEdge :: SActiveEdge edge " Active edge of the clock (not yet implemented)", sResetKind :: SResetKind reset " Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)", sInitBehavior :: SInitBehavior init " Whether the initial (or "power up") value of memory elements is unknown/undefined, or configurable to a specific value", sResetPolarity :: SResetPolarity polarity " Whether resets are active high or active low"} -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
- Clash.Prelude: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: asyncRam :: (Enum addr, NFDataX addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
+ Clash.Prelude: asyncRom :: (KnownNat n, Enum addr, NFDataX a) => Vec n a -> addr -> a
- Clash.Prelude: asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
+ Clash.Prelude: asyncRomPow2 :: (KnownNat n, NFDataX a) => Vec (2 ^ n) a -> Unsigned n -> a
- Clash.Prelude: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr, NFDataX addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Prelude: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr, NFDataX addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude: blockRamFile :: (KnownNat m, Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Prelude: blockRamFile :: (KnownNat m, Enum addr, NFDataX addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Prelude: class (KnownSymbol dom, KnownNat (DomainPeriod dom)) => KnownDomain (dom :: Domain) where {
- Clash.Prelude: hzToPeriod :: HasCallStack => Ratio Natural -> Natural
+ Clash.Prelude: hzToPeriod :: (HasCallStack, Integral a) => Ratio Natural -> a
- Clash.Prelude: periodToHz :: Natural -> Ratio Natural
+ Clash.Prelude: periodToHz :: (HasCallStack, Fractional a) => Natural -> a
- Clash.Prelude: resetGlitchFilter :: forall dom glitchlessPeriod n. (KnownDomain dom, glitchlessPeriod ~ (n + 1)) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
+ Clash.Prelude: resetGlitchFilter :: forall dom glitchlessPeriod. (HasCallStack, HasDefinedInitialValues dom, 1 <= glitchlessPeriod) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
- Clash.Prelude: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Prelude: unsafeToReset :: KnownDomain dom => Signal dom Bool -> Reset dom
- Clash.Prelude: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Prelude: writeToBiSignal :: (HasCallStack, BitPack a, NFDataX a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
- Clash.Prelude.BlockRam: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.BlockRam: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr, NFDataX addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.BlockRam: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.BlockRam: blockRam1 :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => ResetStrategy r -> SNat n -> a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.BlockRam: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.BlockRam: blockRamU :: forall n dom a r addr. (HasCallStack, HiddenClockResetEnable dom, NFDataX a, Enum addr, NFDataX addr, 1 <= n) => ResetStrategy r -> SNat n -> (Index n -> a) -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.BlockRam.Blob: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Prelude.BlockRam.Blob: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr, NFDataX addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude.BlockRam.File: blockRamFile :: (KnownNat m, Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Prelude.BlockRam.File: blockRamFile :: (KnownNat m, Enum addr, NFDataX addr, HiddenClock dom, HiddenEnable dom, HasCallStack) => SNat n -> FilePath -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Prelude.RAM: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.RAM: asyncRam :: (Enum addr, NFDataX addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.ROM: asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
+ Clash.Prelude.ROM: asyncRom :: (KnownNat n, Enum addr, NFDataX a) => Vec n a -> addr -> a
- Clash.Prelude.ROM: asyncRom# :: forall n a. KnownNat n => Vec n a -> Int -> a
+ Clash.Prelude.ROM: asyncRom# :: forall n a. (KnownNat n, NFDataX a) => Vec n a -> Int -> a
- Clash.Prelude.ROM: asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
+ Clash.Prelude.ROM: asyncRomPow2 :: (KnownNat n, NFDataX a) => Vec (2 ^ n) a -> Unsigned n -> a
- Clash.Prelude.Safe: asyncRam :: (Enum addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.Safe: asyncRam :: (Enum addr, NFDataX addr, HiddenClock dom, HiddenEnable dom, HasCallStack, NFDataX a) => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.Safe: asyncRom :: (KnownNat n, Enum addr) => Vec n a -> addr -> a
+ Clash.Prelude.Safe: asyncRom :: (KnownNat n, Enum addr, NFDataX a) => Vec n a -> addr -> a
- Clash.Prelude.Safe: asyncRomPow2 :: KnownNat n => Vec (2 ^ n) a -> Unsigned n -> a
+ Clash.Prelude.Safe: asyncRomPow2 :: (KnownNat n, NFDataX a) => Vec (2 ^ n) a -> Unsigned n -> a
- Clash.Prelude.Safe: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
+ Clash.Prelude.Safe: blockRam :: (HasCallStack, HiddenClock dom, HiddenEnable dom, NFDataX a, Enum addr, NFDataX addr) => Vec n a -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
- Clash.Prelude.Safe: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
+ Clash.Prelude.Safe: blockRamBlob :: forall dom addr m n. (HiddenClock dom, HiddenEnable dom, Enum addr, NFDataX addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- Clash.Signal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Signal: [SDomainConfiguration] :: {sName :: SSymbol dom " Domain name", sPeriod :: SNat period " Period of clock in /ps/", sActiveEdge :: SActiveEdge edge " Active edge of the clock (not yet implemented)", sResetKind :: SResetKind reset " Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)", sInitBehavior :: SInitBehavior init " Whether the initial (or "power up") value of memory elements is unknown/undefined, or configurable to a specific value", sResetPolarity :: SResetPolarity polarity " Whether resets are active high or active low"} -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
- Clash.Signal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Signal: class (KnownSymbol dom, KnownNat (DomainPeriod dom)) => KnownDomain (dom :: Domain) where {
- Clash.Signal: hzToPeriod :: HasCallStack => Ratio Natural -> Natural
+ Clash.Signal: hzToPeriod :: (HasCallStack, Integral a) => Ratio Natural -> a
- Clash.Signal: periodToHz :: Natural -> Ratio Natural
+ Clash.Signal: periodToHz :: (HasCallStack, Fractional a) => Natural -> a
- Clash.Signal: resetGlitchFilter :: forall dom glitchlessPeriod n. (KnownDomain dom, glitchlessPeriod ~ (n + 1)) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
+ Clash.Signal: resetGlitchFilter :: forall dom glitchlessPeriod. (HasCallStack, HasDefinedInitialValues dom, 1 <= glitchlessPeriod) => SNat glitchlessPeriod -> Clock dom -> Reset dom -> Reset dom
- Clash.Signal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Signal: unsafeToReset :: KnownDomain dom => Signal dom Bool -> Reset dom
- Clash.Signal: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Signal: writeToBiSignal :: (HasCallStack, BitPack a, NFDataX a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
- Clash.Signal.BiSignal: writeToBiSignal :: (HasCallStack, BitPack a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
+ Clash.Signal.BiSignal: writeToBiSignal :: (HasCallStack, BitPack a, NFDataX a) => BiSignalIn ds d (BitSize a) -> Signal d (Maybe a) -> BiSignalOut ds d (BitSize a)
- Clash.Signal.Internal: Clock :: SSymbol dom -> Clock (dom :: Domain)
+ Clash.Signal.Internal: Clock :: SSymbol dom -> Maybe (Signal dom Femtoseconds) -> Clock (dom :: Domain)
- Clash.Signal.Internal: [SDomainConfiguration] :: SSymbol dom -> SNat period -> SActiveEdge edge -> SResetKind reset -> SInitBehavior init -> SResetPolarity polarity -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
+ Clash.Signal.Internal: [SDomainConfiguration] :: {sName :: SSymbol dom " Domain name", sPeriod :: SNat period " Period of clock in /ps/", sActiveEdge :: SActiveEdge edge " Active edge of the clock (not yet implemented)", sResetKind :: SResetKind reset " Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)", sInitBehavior :: SInitBehavior init " Whether the initial (or "power up") value of memory elements is unknown/undefined, or configurable to a specific value", sResetPolarity :: SResetPolarity polarity " Whether resets are active high or active low"} -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)
- Clash.Signal.Internal: class KnownSymbol dom => KnownDomain (dom :: Domain) where {
+ Clash.Signal.Internal: class (KnownSymbol dom, KnownNat (DomainPeriod dom)) => KnownDomain (dom :: Domain) where {
- Clash.Signal.Internal: hzToPeriod :: HasCallStack => Ratio Natural -> Natural
+ Clash.Signal.Internal: hzToPeriod :: (HasCallStack, Integral a) => Ratio Natural -> a
- Clash.Signal.Internal: invertReset :: Reset dom -> Reset dom
+ Clash.Signal.Internal: invertReset :: KnownDomain dom => Reset dom -> Reset dom
- Clash.Signal.Internal: periodToHz :: Natural -> Ratio Natural
+ Clash.Signal.Internal: periodToHz :: (HasCallStack, Fractional a) => Natural -> a
- Clash.Signal.Internal: unsafeToReset :: Signal dom Bool -> Reset dom
+ Clash.Signal.Internal: unsafeToReset :: KnownDomain dom => Signal dom Bool -> Reset dom
- Clash.XException: fromJustX :: HasCallStack => Maybe a -> a
+ Clash.XException: fromJustX :: (HasCallStack, NFDataX a) => Maybe a -> a
- Clash.XException: hasX :: NFData a => a -> Either String a
+ Clash.XException: hasX :: (NFData a, NFDataX a) => a -> Either String a
- Clash.XException: maybeHasX :: NFData a => a -> Maybe a
+ Clash.XException: maybeHasX :: (NFData a, NFDataX a) => a -> Maybe a
- Clash.Xilinx.ClockGen: clockWizard :: forall domIn domOut periodIn periodOut edge init polarity name. (KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity), KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity)) => SSymbol name -> Clock domIn -> Reset domIn -> (Clock domOut, Enable domOut)
+ Clash.Xilinx.ClockGen: clockWizard :: forall t domIn. (HasAsynchronousReset domIn, ClocksSyncCxt t domIn, NumOutClocksSync t domIn <= 7) => Clock domIn -> Reset domIn -> t
- Clash.Xilinx.ClockGen: clockWizardDifferential :: forall domIn domOut periodIn periodOut edge init polarity name. (KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity), KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity)) => SSymbol name -> Clock domIn -> Clock domIn -> Reset domIn -> (Clock domOut, Enable domOut)
+ Clash.Xilinx.ClockGen: clockWizardDifferential :: forall t domIn. (HasAsynchronousReset domIn, ClocksSyncCxt t domIn, NumOutClocksSync t domIn <= 7) => DiffClock domIn -> Reset domIn -> t

Files

CHANGELOG.md view
@@ -1,8 +1,147 @@ # Changelog for the Clash project++## 1.8.0++Release highlights:++* Support for GHC 9.2, 9.4, 9.6 and 9.8. While GHC 9.2 is supported, we recommend users to skip this version as there is a severe degradation of error message quality. With this change, Clash now supports GHC versions 8.6 through 9.8.+* Major overhaul of the clocking functionality in `Clash.Xilinx.ClockGen` and `Clash.Intel.ClockGen`, see their respective entries below+* `mealyS` function (and several variations) to make writing state machines using the strict `State` monad easier+* Overhaul of `resetGlitchFilter`, see its respective entries below.++Added:++* `altpllSync` and `alteraPllSync` in `Clash.Intel.ClockGen`. These replace the deprecated functions without the `Sync` suffix. Unlike the old functions, these functions are safe to use and have a reset signal for each output domain that can be used to keep the domain in reset while the clock output stabilizes. All PLL functions now also support multiple clock outputs like the old `alteraPll` did. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+*  A new clock type `DiffClock` is introduced to signify a differential clock signal that is passed to the design on two ports in antiphase. This is used by the differential Xilinx clock wizards in `Clash.Xilinx.ClockGen`. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+* `Clash.Explicit.Testbench.clockToDiffClock`, to create a differential clock signal in a test bench. It is not suitable for synthesizing a differential output in hardware. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+* `resetGlitchFilterWithReset`, which accomplishes the same task as `resetGlitchFilter` in domains with unknown initial values by adding a power-on reset input to reset the glitch filter itself. [#2544](https://github.com/clash-lang/clash-compiler/pull/2544)+* Convenience functions: `noReset`, `andReset`, `orReset` plus their unsafe counterparts [#2539](https://github.com/clash-lang/clash-compiler/pull/2539)+* Convenience constraint aliases: `HasSynchronousReset`, `HasAsynchronousReset`, and `HasDefinedInitialValues` [#2539](https://github.com/clash-lang/clash-compiler/pull/2539)+* `Clash.Prelude.Mealy.mealyS` and `Clash.Explicit.Mealy.mealyS` and their bundled equivalents `mealySB` which make writing state machines using the strict `State` monad easier. The tutorial has also been simplified by using this change. [#2484](https://github.com/clash-lang/clash-compiler/pull/2484)+* An experimental feature allowing clocks to vary their periods over time, called "dynamic clocks". Given that this is an experimental feature, it is not part of the public API. [#2295](https://github.com/clash-lang/clash-compiler/pull/2295)+* The prelude now exports `+>>.` and `.<<+`, which can be used to shift in a bit into a `BitVector` from the left or right respectively - similar to `+>>` and `<<+` for `Vec`s. [#2307](https://github.com/clash-lang/clash-compiler/pull/2307)+* `Clash.DataFiles.tclConnector` and the executable `static-files` in `clash-lib`. They provide the Tcl Connector, a Tcl script that allows Vivado to interact with the metadata generated by Clash (Quartus support will be added later). See `Clash.DataFiles.tclConnector` for further information. More documentation about the Tcl Connector and the Clash<->Tcl API will be made available later. [#2335](https://github.com/clash-lang/clash-compiler/pull/2335)+* Add `BitPack`, `NFDataX` and `ShowX` instances for `Ordering` [#2366](https://github.com/clash-lang/clash-compiler/pull/2366)+* Verilog users can now influence the "precision" part of the generated `timescale` pragma using `-fclash-timescale-precision`. [#2353](https://github.com/clash-lang/clash-compiler/pull/2353)+* Clash now includes blackboxes for `integerToFloat#`, `integerToDouble#` [#2342](https://github.com/clash-lang/clash-compiler/issues/2342)+* Instances `Arbitrary (Erroring a)`, `Arbitrary (Saturating a)`, `Arbitrary (Saturating a)`, and `Arbitrary (Zeroing a)` [#2356](https://github.com/clash-lang/clash-compiler/pull/2356)+* `Clash.Magic.clashSimulation`, a way to differentiate between Clash simulation and generating HDL. [#2473](https://github.com/clash-lang/clash-compiler/pull/2473)+* `Clash.Magic.clashCompileError`: make HDL generation error out with a custom error message. Simulation in Clash will also error when the function is evaluated, including a call stack. HDL generation unfortunately does not include a call stack. [#2399](https://github.com/clash-lang/clash-compiler/pull/2399)+* Added `Clash.XException.MaybeX`, a data structure with smart constructors that can help programmers deal with `XException` values in their blackbox model implementations [#2442](https://github.com/clash-lang/clash-compiler/pull/2442)+*  `Clash.Magic.SimOnly`, A container for data you only want to have around during simulation and is ignored during synthesis. Useful for carrying around things such as: a map of simulation/vcd traces, co-simulation state or meta-data, etc. [#2464](https://github.com/clash-lang/clash-compiler/pull/2464)+* `KnownNat (DomainPeriod dom)` as an implied constraint to `KnownDomain dom`. This reduces the amount of code needed to write - for example - clock speed dependent code. [#2541](https://github.com/clash-lang/clash-compiler/pull/2541)+* `Clash.Annotations.SynthesisAttributes.annotate`: a term level way of annotating signals with synthesis attributes [#2547](https://github.com/clash-lang/clash-compiler/pull/2547)+* `Clash.Annotations.SynthesisAttributes.markDebug`: a way of marking a signals "debug", instructing synthesizers to leave the signal alone and offer debug features [#2547](https://github.com/clash-lang/clash-compiler/pull/2547)+* Add hex and octal BitVector parsing. [#1772](https://github.com/clash-lang/clash-compiler/pull/2505)+* `1 <= n => Foldable1 (Vec n)` instance (`base-4.18+` only) [#2563](https://github.com/clash-lang/clash-compiler/pull/2563)+* You can now use `~PERIOD`, `~ISSYNC`, `~ISINITDEFINED` and `~ACTIVEEDGE` on arguments of type `Clock`, `Reset`, `Enable`,`ClockN` and `DiffClock`. [#2590](https://github.com/clash-lang/clash-compiler/pull/2590)++Removed:++* Deprecated module `Clash.Prelude.BitIndex`: functions have been moved to `Clash.Class.BitPack` [#2555](https://github.com/clash-lang/clash-compiler/pull/2555)+* Deprecated module `Clash.Prelude.BitReduction`: functions have been moved to `Clash.Class.BitPack` [#2555](https://github.com/clash-lang/clash-compiler/pull/2555)+* Deprecated function `Clash.Explicit.Signal.enable`: function has been renamed to `andEnable` [#2555](https://github.com/clash-lang/clash-compiler/pull/2555)+* The module `Clash.Clocks.Deriving` has been removed. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)++Deprecated:++* `unsafeFromLowPolarity`, `unsafeFromHighPolarity`, `unsafeToLowPolarity`, `unsafeToHighPolarity` have been replaced by `unsafeFromActiveLow`, `unsafeFromActiveHigh`, `unsafeToActiveLow`, `unsafeToActiveHigh`. While former ones will continue to exist, a deprecation warning has been added pointing to the latter ones. [#2540](https://github.com/clash-lang/clash-compiler/pull/2540)+* The functions `altpll` and `alteraPll` in `Clash.Intel.ClockGen` have been deprecated because they are unsafe to use while this is not apparent from the name. The `locked` output signal of these functions is an asynchronous signal which needs to be synchronized before it can be used (something the examples did in fact demonstrate). For the common use case, new functions are available, named `altpllSync` and `alteraPllSync`. These functions are safe. For advanced use cases, the old functionality can be obtained through `unsafeAltpll` and `unsafeAlteraPll`. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)++Changed:++* The wizards in `Clash.Xilinx.ClockGen` have been completely overhauled. The original functions were unsafe and broken in several ways. See the documentation in `Clash.Xilinx.ClockGen` for how to use the new functions. Significant changes are:+  * `clockWizard` and `clockWizardDifferential` now output a `Clock` and a `Reset` which can be directly used by logic. Previously, it outputted a clock and an asynchronous `locked` signal which first needed to be synchronized before it could be used (hence the old function being unsafe). Additionally, the original `locked` signal was strange: it mistakenly was an `Enable` instead of a `Signal dom Bool` and there was a polarity mismatch between Clash simulation and HDL. The `locked` signal was also not resampled to the output domain in Clash simulation.+  * There are new functions `unsafeClockWizard` and `unsafeClockWizardDifferential` for advanced use cases which directly expose the `locked` output of the wizard.+  * All clock generators now have the option to output multiple clocks from a single instance.+  * `clockWizardDifferential` now gets its input clock as a `DiffClock` type; use `clockToDiffClock` to generate this in your test bench if needed. Previously, the function received two clock inputs, but this generated `create_clock` statements in the top-level SDC file for both phases which is incorrect.+  * A constraint was removed: The _output_ clock domain no longer requires asynchronous resets. This was originally intended to signal that the outgoing lock signal is an asynchronous signal. The constraint does not convey this  information at all and is wrong; it also prevents using synchronous resets in the circuit as recommended by Xilinx. Note that if you use the `unsafe` functions, it is still necessary to synchronize the `locked` output in your design.+  * The port names of the primitives in HDL are now correctly lower case.+  * Add Tcl generation. This moves the responsibility of MMCM component generation from the user to `clashConnector.tcl`, which can be found in [`clash-lib:Clash.DataFiles`](https://hackage.haskell.org/package/clash-lib-1.8.0/docs/Clash-DataFiles.html).+  * The wizards now use the user-provided name as the name of the _instance_ rather than the name of the _IP core_. This change was also done for `Clash.Intel.ClockGen` in Clash v1.2.0 in March 2020, when Clash started generating Intel Qsys files. Before that, the user needed to generate a Qsys component manually. Now, in Clash v1.8.0, we also generate the Tcl for Xilinx wizards. When the user is responsible for creating the IP core, it makes sense to always set the component name to the user-provided value. But when that is also generated by Clash, that is no longer needed. Allowing users to set the instance name instead makes it possible to match on the instance in SDC files and such.+  [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+* The IP core generators in `Clash.Intel.ClockGen` now declare that their input domain needs to have asynchronous resets (`HasAsynchronousReset`), as the functions react asynchronously to their reset input and thus need to be glitch-free. The functions marked `unsafe` do not have this constraint; instead, the function documentation calls attention to the requirement. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+* `resetGlitchFilter` now uses a counter instead of shift register, allowing glitch filtering over much larger periods. [#2374](https://github.com/clash-lang/clash-compiler/pull/2374)+* `resetGlitchFilter` now filters glitches symmetrically, only deasserting the reset after the incoming reset has stabilized. For more information, read [#2374](https://github.com/clash-lang/clash-compiler/pull/2374).+* `resetGlitchFilter` does not support domains with unknown initial values anymore. Its previous behavior could lead to unstable circuits. Domains not supporting initial values should consider using `resetGlitchFilterWithReset` or `holdReset`. The previous behavior can still be attained through the new `unsafeResetGlitchFilter`. [#2544](https://github.com/clash-lang/clash-compiler/pull/2544)+* `fromJustX` now uses `deepErrorX` instead of `errorX`. This adds `NFDataX` constraints to `blockRam` like functions, `asyncRam` and `writeToBiSignal`. [#2113](https://github.com/clash-lang/clash-compiler/pull/2113)+*  All memory functions now use `deepErrorX` for `XException`s. This adds `NFDataX` constraints to `asyncRom`, `asyncRomPow2` and `asyncRom#`. [#2113](https://github.com/clash-lang/clash-compiler/pull/2113)+* Before this release, `scanl1` was re-exported from the Haskell Prelude. Clash's Prelude now exports a `Vec` specialized version. [#2172](https://github.com/clash-lang/clash-compiler/pull/2172)+* When generating (System)Verilog, Clash now sets the default net type to `none`. This means any implicitly declared signal in the design will trigger an error when elaborating the design. [#2174](https://github.com/clash-lang/clash-compiler/pull/2174)+* Blackbox templates no longer have the `outputReg` key, it has been replaced with the more general `outputUsage` which specifies how signals are used in terms of whether writes are++    * continuous (i.e. a concurrent context)+    * procedural non-blocking (i.e. `signal` in a VHDL process)+    * procedural blocking (i.e. `variable` in a VHDL process)++  The `~OUTPUTWIREREG` tag continues to work for backwards compatibility, but there is also a new `~OUTPUTUSAGE` tag which is recommended. In the future, the `~OUTPUTWIREREG` tag may be removed. [#2230](https://github.com/clash-lang/clash-compiler/pull/2230)+* `Clash.Explicit.Testbench.outputVerifier` now takes an additional clock as an argument: the clock used by the circuit under test. If your tests use the same domain for the test circuit and design under test, consider using `Clash.Explicit.Testbench.outputVerifier'`. [#2295](https://github.com/clash-lang/clash-compiler/pull/2295)+* `Clash.Explicit.Signal.veryUnsafeSynchronizer` now accepts either a static clock period or a dynamic one. If you don't use dynamic clocks, convert your calls to use `Left`. [#2295](https://github.com/clash-lang/clash-compiler/pull/2295)+* `SDomainConfiguration` is now a record, easing field access. [#2349](https://github.com/clash-lang/clash-compiler/pull/2349)+*  Generalized the return types of `periodToHz` and `hzToPeriod`. Use a type application (`periodToHz @(Ratio Natural)`, `hzToPeriod @Natural`) to get the old behavior back, in case type errors arise. [#2436](https://github.com/clash-lang/clash-compiler/pull/2436)+* `periodToHz` and `hzToPeriod` now throw an `ErrorCall` with call stack when called with the argument 0 (zero), instead of a `RatioZeroDenominator :: ArithException`. [#2436](https://github.com/clash-lang/clash-compiler/pull/2436)+* `hasX` now needs an `NFDataX` constraint, in addition to an `NFData` one. This API change was made to fix an issue where `hasX` would hide error calls in certain situations, see [#2450](https://github.com/clash-lang/clash-compiler/issues/2450).+* Clock generators now wait at least 100 ns before producing their first tick. This change has been implemented to account for Xilinx's GSR in clock synchronization primitives. This change does not affect Clash simulation. See [#2455](https://github.com/clash-lang/clash-compiler/issues/2455).+* From GHC 9.4.1 onwards the following types: `BiSignalOut`, `Index`, `Signed`, `Unsigned`, `File`, `Ref`, and `SimIO` are all encoded as `newtype` instead of `data` now that [#2511](https://github.com/clash-lang/clash-compiler/pull/2511) is merged. This means you can once again use `Data.Coerce.coerce` to coerce between these types and their underlying representation. [#2535](https://github.com/clash-lang/clash-compiler/pull/2535)+* The `Foldable (Vec n)` instance and `Traversable (Vec n)` instance no longer have the `1 <= n` constraint. `Foldable.{foldr1,foldl1,maximum,minimum}` functions now throw an error at run-/simulation-time, and also at HDL-generation time, for vectors of length zero. [#2563](https://github.com/clash-lang/clash-compiler/pull/2563)+* The `maximum` and `minimum` functions exported by `Clash.Prelude` work on non-empty vectors, instead of the more generic version from `Data.Foldable`. [#2563](https://github.com/clash-lang/clash-compiler/pull/2563)+* `unsafeToReset` and `invertReset` now have a KnownDomain constraint This was done in preparation for [Remove KnownDomain #2589](https://github.com/clash-lang/clash-compiler/pull/2589)++Fixed:++* `altpll` and `alteraPll` in `Clash.Intel.ClockGen` now account for the input domain's `ResetPolarity`. Before this fix, the reset was always interpreted as an active-high signal. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)+* Fix `alteraPll` `qsys` generation. PR [#2417](https://github.com/clash-lang/clash-compiler/pull/2417) (included in Clash v1.6.5) caused a bug in the generation of the `qsys` file: it generated a spurious extra output clock which was completely unused otherwise. [#2587](https://github.com/clash-lang/clash-compiler/pull/2587)+* Files in `clash-manifest.json` are now (correctly) listed in reverse topological order [#2334](https://github.com/clash-lang/clash-compiler/issues/2334)+* Dependencies in `clash-manifest.json` are now listed in reverse topological ordering [#2325](https://github.com/clash-lang/clash-compiler/issues/2325)+* Clash now renders undefined bits set via `-fclash-force-undefined` correctly [#2360](https://github.com/clash-lang/clash-compiler/issues/2360)+* `resetGen`'s documentation now mentions it is non-synthesizable ([#2375](https://github.com/clash-lang/clash-compiler/issues/2375))+* `trueDualPortBlockRam` now handles undefined values in its input correctly  [#2350](https://github.com/clash-lang/clash-compiler/issues/2350)+* `trueDualPortBlockRam` now correctly handles port enables when clock edges coincide [#2351](https://github.com/clash-lang/clash-compiler/issues/2351)+* `Clash.Primitives.DSL.deconstructProduct` now projects fields out of a product [#2469](https://github.com/clash-lang/clash-compiler/issues/2469)+* BiSignal test does not look through `Annotate` [#2472](https://github.com/clash-lang/clash-compiler/issues/2472)+* Port size not rendered when type has more than one `Annotate` [#2475](https://github.com/clash-lang/clash-compiler/pull/2475)+* Clash now preserves `NOINLINE` of functions being specialized [#2502](https://github.com/clash-lang/clash-compiler/issues/2502)+* When `convertReset` was used with two domains that had a different reset polarity, the polarity of the signal was not changed.+* Functional arguments of primitives cannot have 0-bit results [#2549](https://github.com/clash-lang/clash-compiler/issues/2549)+* If the source reset of `convertReset` is synchronous, a flip-flop in the source domain is inserted to filter glitches from the source reset. [#2573](https://github.com/clash-lang/clash-compiler/pull/2573)+* SystemVerilog backend: Assignment patterns for unpacked arrays now have an index for every element; improves QuestaSim compatibility. [#2595](https://github.com/clash-lang/clash-compiler/pull/2595)+* Name duplication in generated Verilog involving reset synchronizer [#2598](https://github.com/clash-lang/clash-compiler/issues/2598)++Internal added:++* `Clash.Primitives.DSL.instDecl` now accepts `TExpr`s instead of `LitHDL`s as generics/parameters. This allows for VHDL black boxes to use all possible generic types. To ease transition, `litTExpr` has been added to `Clash.Primitives.DSL`. [#2471](https://github.com/clash-lang/clash-compiler/issues/2471)+* `Clash.Core.TermLiteral.deriveTermToData` now works on records [#2270](https://github.com/clash-lang/clash-compiler/pull/2270)+* `Clash.Primitives.getVec` tries to get all elements in a Vector from an expression [#2483](https://github.com/clash-lang/clash-compiler/pull/2483)+* Added `Clash.Primitives.DSL.deconstructMaybe`. This DSL function makes it easy to deconstruct a `Maybe` into its constructor bit and data. This is often useful for primitives taking 'enable' and 'data' signals. [#2202](https://github.com/clash-lang/clash-compiler/pull/2202)+* Added `unsafeToActiveHigh` and `unsafeToActiveLow` to `Clash.Primitives.DSL`. [#2270](https://github.com/clash-lang/clash-compiler/pull/2270)+* Added `TermLiteral` instance for `Either` [#2329](https://github.com/clash-lang/clash-compiler/pull/2329)+* `Clash.Primitives.DSL.declareN`, a companion to `declare` which declares multiple signals in one go. [#2592](https://github.com/clash-lang/clash-compiler/pull/2592)++Internal changes:++* `Clash.Primitives.DSL.boolFromBit` is now polymorphic in its HDL backend. [#2202](https://github.com/clash-lang/clash-compiler/pull/2202)+* `Clash.Primitives.DSL.unsignedFromBitVector` is now polymorphic in its HDL backend. [#2202](https://github.com/clash-lang/clash-compiler/pull/2202)+* `Clash.Primitives.DSL.fromBV` now converts some `BitVector` expression into some type. [#2202](https://github.com/clash-lang/clash-compiler/pull/2202)+* Add `CompDecl` to `Clash.Netlist.Types.Declaration` to accomodate VHDL's `component` declarations.+* Black box functions declare their usage, necessary for implicit netlist usage analysis implemented in [#2230](https://github.com/clash-lang/clash-compiler/pull/2230)+* Added `showsTypePrec` to `TermLiteral` to make `TermLiteral SNat` work as expected. Deriving an instance is now a bit simpler. Instances which previously had to be defined as:++  ```haskell+  instance TermLiteral Bool where+    termToData = $(deriveTermToData ''Bool)+  ```++  can now be defined using:++  ```haskell+  deriveTermLiteral ''Bool+  ```+  [#2329](https://github.com/clash-lang/clash-compiler/pull/2329)+ ## 1.6.6 *Oct 2nd 2023* -* Support Aeson 2.2 [#2578](https://github.com/clash-lang/clash-compiler/pull/2578)-* Drop the snap package [#2439](https://github.com/clash-lang/clash-compiler/pull/2439)+* Support Aeson 2.2+* Dropped the snap package      The Clash snap package has not been a recommended way to use Clash for quite some time, and it is a hassle to support. @@ -63,7 +202,6 @@ Internal change:   * Clash now always generates non-extended identifiers for port names, so that generated names play nicer with different vendor tools. [#2142](https://github.com/clash-lang/clash-compiler/pull/2142)   * Top entity name available in netlist context. Top entity name used in generated name for include files. [#2146](https://github.com/clash-lang/clash-compiler/pull/2146)-  ## 1.6.2 *Feb 25th 2022* Fixed:
clash-prelude.cabal view
@@ -1,6 +1,6 @@ Cabal-version:        2.2 Name:                 clash-prelude-Version:              1.6.6+Version:              1.8.0 Synopsis:             Clash: a functional hardware description language - Prelude library Description:   Clash is a functional hardware description language that borrows both its@@ -140,6 +140,7 @@                       KindSignatures                       MagicHash                       NoStarIsType+                      PostfixOperators                       ScopedTypeVariables                       StandaloneDeriving                       TupleSections@@ -154,6 +155,12 @@   ghc-options:        -Wall -Wcompat -fexpose-all-unfoldings -fno-worker-wrapper   CPP-Options:        -DCABAL +  -- See https://github.com/clash-lang/clash-compiler/pull/2511+  if impl(ghc >= 9.4)+    CPP-Options: -DCLASH_OPAQUE=OPAQUE+  else+    CPP-Options: -DCLASH_OPAQUE=NOINLINE+   if flag(large-tuples)     CPP-Options: -DLARGE_TUPLES @@ -201,12 +208,12 @@                       Clash.Class.Resize                        Clash.Clocks-                      Clash.Clocks.Deriving                        Clash.Explicit.BlockRam                       Clash.Explicit.BlockRam.Blob                       Clash.Explicit.BlockRam.File                       Clash.Explicit.BlockRam.Internal+                      Clash.Explicit.BlockRam.Model                       Clash.Explicit.DDR                       Clash.Explicit.Mealy                       Clash.Explicit.Moore@@ -242,8 +249,6 @@                       Clash.NamedTypes                        Clash.Prelude-                      Clash.Prelude.BitIndex-                      Clash.Prelude.BitReduction                       Clash.Prelude.BlockRam                       Clash.Prelude.BlockRam.Blob                       Clash.Prelude.BlockRam.File@@ -293,6 +298,7 @@                        Clash.XException                       Clash.XException.Internal+                      Clash.XException.MaybeX                       Clash.XException.TH                        Clash.Xilinx.ClockGen@@ -304,6 +310,7 @@    other-modules:                       Clash.Class.AutoReg.Instances+                      Clash.Clocks.Internal                       Clash.CPP                       Clash.Signal.Bundle.Internal                       Language.Haskell.TH.Compat@@ -331,22 +338,23 @@                       containers                >= 0.4.0   && < 0.7,                       data-binary-ieee754       >= 0.4.4   && < 0.6,                       data-default-class        >= 0.1.2   && < 0.2,-                      deepseq                   >= 1.4.1.0 && < 1.5,+                      deepseq                   >= 1.4.1.0 && < 1.6,                       extra                     >= 1.6.17  && < 1.8,-                      ghc-prim                  >= 0.5.1.0 && < 0.8,+                      ghc-prim                  >= 0.5.1.0 && < 0.12,                       ghc-typelits-extra        >= 0.4     && < 0.5,                       ghc-typelits-knownnat     >= 0.7.2   && < 0.8,                       ghc-typelits-natnormalise >= 0.7.2   && < 0.8,                       hashable                  >= 1.2.1.0  && < 1.5,                       half                      >= 0.2.2.3 && < 1.0,-                      interpolate               >= 0.2     && < 0.3,+                      infinite-list           ^>= 0.1,                       lens                      >= 4.10    && < 5.3,-                      recursion-schemes         >= 5.1     && < 5.3,                       QuickCheck                >= 2.7     && < 2.15,+                      recursion-schemes         >= 5.1     && < 5.3,                       reflection                >= 2       && < 2.2,                       singletons                >= 2.0     && < 3.1,-                      template-haskell          >= 2.12.0.0 && < 2.18,-                      th-abstraction            >= 0.2.10 && < 0.5.0,+                      string-interpolate        ^>= 0.3,+                      template-haskell          >= 2.12.0.0 && < 2.22,+                      th-abstraction            >= 0.2.10 && < 0.6.0,                       th-lift                   >= 0.7.0    && < 0.9,                       th-orphans                >= 0.13.1   && < 1.0,                       text                      >= 0.11.3.1 && < 2.1,@@ -354,10 +362,11 @@                       transformers              >= 0.5.2.0 && < 0.7,                       type-errors               >= 0.2.0.0 && < 0.3,                       uniplate                  >= 1.6.12  && < 1.7,-                      vector                    >= 0.11    && < 1.0+                      vector                    >= 0.11    && < 1.0,+                      mtl                       >= 2.0     && < 3.0    if impl(ghc >= 9.0.0)-    Build-Depends:    ghc-bignum                >= 1.0      && < 1.3+    Build-Depends:    ghc-bignum                >= 1.0      && < 1.4   else     Build-Depends:    integer-gmp               >= 1.0.1.0  && < 2.0   if flag(large-tuples)@@ -387,7 +396,13 @@   import:           common-options   type:             exitcode-stdio-1.0   main-is:          unittests.hs-  ghc-options:      -Wall -Wcompat -threaded -with-rtsopts=-N+  ghc-options:      -Wall -Wcompat -threaded+  -- Note that multiple -with-rtsopts are not cumulative+  if flag(workaround-ghc-mmap-crash)+    ghc-options:    "-with-rtsopts=-N -xm20000000"+  else+    ghc-options:    -with-rtsopts=-N+   hs-source-dirs:   tests    if !flag(unittests)@@ -406,7 +421,7 @@       hedgehog      >= 1.0.3    && < 1.3,       hint          >= 0.7      && < 0.10,       quickcheck-classes-base >= 0.6 && < 1.0,-      tasty         >= 1.2      && < 1.5,+      tasty         >= 1.2      && < 1.6,       tasty-hedgehog >= 1.2.0,       tasty-hunit,       tasty-th,@@ -426,6 +441,7 @@                  Clash.Tests.DerivingDataReprTypes                  Clash.Tests.Fixed                  Clash.Tests.FixedExhaustive+                 Clash.Tests.MaybeX                  Clash.Tests.NFDataX                  Clash.Tests.NumNewtypes                  Clash.Tests.Ram@@ -437,6 +453,7 @@                  Clash.Tests.TopEntityGeneration                  Clash.Tests.Unsigned                  Clash.Tests.Vector+                 Clash.Tests.XException                   Clash.Tests.Laws.Enum                  Clash.Tests.Laws.SaturatingNum
src/Clash/Annotations/BitRepresentation.hs view
@@ -67,12 +67,12 @@ -- -- @ -- data Color = R | G | B--- {-# ANN module (DataReprAnn---                   $(liftQ [t|Color|])+-- {-# ANN module ('DataReprAnn'+--                   $('liftQ' [t|Color|]) --                   2---                   [ ConstrRepr 'R 0b11 0b00 []---                   , ConstrRepr 'G 0b11 0b01 []---                   , ConstrRepr 'B 0b11 0b10 []+--                   [ 'ConstrRepr' 'R 0b11 0b00 []+--                   , 'ConstrRepr' 'G 0b11 0b01 []+--                   , 'ConstrRepr' 'B 0b11 0b10 [] --                   ]) #-} -- @ --@@ -84,11 +84,11 @@ -- Or if we want to annotate @Maybe Color@: -- -- @--- {-# ANN module ( DataReprAnn---                    $(liftQ [t|Maybe Color|])+-- {-# ANN module ( 'DataReprAnn'+--                    $('liftQ' [t|Maybe Color|]) --                    2---                    [ ConstrRepr 'Nothing 0b11 0b11 []---                    , ConstrRepr 'Just 0b00 0b00 [0b11]+--                    [ 'ConstrRepr' 'Nothing 0b11 0b11 []+--                    , 'ConstrRepr' 'Just 0b00 0b00 [0b11] --                    ] ) #-} -- @ --
src/Clash/Annotations/BitRepresentation/Deriving.hs view
@@ -22,9 +22,6 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-}--- See: https://ghc.haskell.org/trac/ghc/ticket/14959. TODO: Consider putting--- the offending function (bitsToInteger') in a separate module.-{-# OPTIONS_GHC -O0 #-}  module Clash.Annotations.BitRepresentation.Deriving   (@@ -76,7 +73,7 @@ import           Data.Data                    (Data) import           Data.Containers.ListUtils    (nubOrd) import           Data.List-  (mapAccumL, zipWith4, sortOn, partition)+  (mapAccumL, zipWith4, sortOn, partition, uncons) import           Data.Typeable                (Typeable) import qualified Data.Map                     as Map import           Data.Maybe                   (fromMaybe)@@ -403,6 +400,10 @@   -- ^ Field derivator   -> Derivator deriveDataRepr constrDerivator fieldsDerivator typ = do+  let (fun, typeArgs) = collectTypeArgs typ+      tyConstrName = case fun of+        ConT t -> t+        _ -> error ("deriveDataRep: expecting type constructor, but got: " <> show fun)   info <- reify tyConstrName   case info of     (TyConI (DataD [] _constrName vars _kind dConstructors _clauses)) ->@@ -460,9 +461,6 @@     _ ->       fail $ "Could not derive dataRepr for: " ++ show info -    where-      (ConT tyConstrName, typeArgs) = collectTypeArgs typ- -- | Simple derivators change the (default) way Clash stores data types. It -- assumes no overlap between constructors and fields. simpleDerivator :: ConstructorType -> FieldsType -> Derivator@@ -559,19 +557,19 @@   | H `elem` xs'                 = [[L]]   | otherwise                    = [[H]]   where-    xs' = map head xs+    xs' = map (maybe (error "complementValues: expected at least 1 bit") fst . uncons) xs complementValues size [] = [replicate size U] complementValues size values =-  if | all (==U) (map head values') -> map (U:) (recc (map tail values'))-     | any (==X) (map head values') -> map (X:) (recc (map tail values'))+  if | all (maybe False ((==U) . fst) . uncons) values' -> map (U:) (recc (map (drop 1) values'))+     | any (maybe False ((==X) . fst) . uncons) values' -> map (X:) (recc (map (drop 1) values'))      | otherwise ->-        (map (L:) (recc (map tail lows))) ++-        (map (H:) (recc (map tail highs')))+        (map (L:) (recc (map (drop 1) lows))) +++        (map (H:) (recc (map (drop 1) highs')))   where     values'       = filter (any (/= U)) values     recc          = complementValues (size - 1)-    (highs, lows) = partition ((== H) . head) values'-    highs'        = highs ++ filter ((`elem` [X, U]) . head) values'+    (highs, lows) = partition (maybe False ((== H) . fst) . uncons) values'+    highs'        = highs ++ filter (maybe False ((`elem` [X, U]) . fst) . uncons) values'  -- | Generate all bitvalues the given type can assume. possibleValues@@ -580,9 +578,10 @@   -> Size   -> Q [[Bit']] possibleValues typeMap typ size =-  let (ConT typeName, _typeArgs) = collectTypeArgs typ in--  case Map.lookup typ typeMap of+  let typeName = case fst (collectTypeArgs typ) of+        ConT t -> t+        fun -> error ("possibleValues: expected a type constructor, but got" <> show fun)+  in case Map.lookup typ typeMap of     -- No custom data representation found.     Nothing -> do       info <- reify typeName@@ -640,7 +639,8 @@         let err = unwords [ "Could not derive packed maybe for:", show typ                           , ";", "Does its subtype have any space left to store"                           , "the constructor in?" ]-        packedM <- packedMaybe (size - 1) maybeTyp+        packedM <- packedMaybe (size - 1)+                    (maybe (error "Maybe type without argument") fst (uncons maybeTyps))         (fromMaybe (fail err) . fmap lift) packedM       else         fail $ unwords [ "You can only pass Maybe types to packedMaybeDerivator,"@@ -648,7 +648,7 @@     unexpected ->       fail $ "packedMaybeDerivator: unexpected constructor: " ++ show unexpected   where-    (maybeCon, head -> maybeTyp) = collectTypeArgs typ+    (maybeCon, maybeTyps) = collectTypeArgs typ  -- | Derive a compactly represented version of @Maybe a@. derivePackedMaybeAnnotation :: DataReprAnn -> Q [Dec]@@ -715,17 +715,17 @@ storeInFields _dataWidth _additionalMask [_] =   -- Last constructor is implict   [Embedded 0 0]-storeInFields dataWidth additionalMask constrs =+storeInFields dataWidth additionalMask constrs@(constr:constrRest) =   if commonMask == fullMask then     -- We can't store the constructor anywhere special, so we need a special     -- constructor bit stored besides fields-    External : storeInFields dataWidth additionalMask (tail constrs)+    External : storeInFields dataWidth additionalMask constrRest   else     -- Hooray, we can store it somewhere.     maskOrigins ++ (storeInFields dataWidth additionalMask' (drop storeSize constrs))    where-    headMask   = head constrs+    headMask   = constr     commonMask = (.|.) headMask additionalMask      -- Variables for the case that we can store something:@@ -800,10 +800,10 @@  group :: [Bit] -> [(Int, Bit)] group [] = []-group bs = (length head', head bs) : rest+group bs@(b:_) = (length head', b) : rest   where-    tail' = dropWhile (==head bs) bs-    head' = takeWhile (==head bs) bs+    tail' = dropWhile (==b) bs+    head' = takeWhile (==b) bs     rest  = group tail'  bitToExpr' :: (Int, Bit) -> Q Exp -- BitVector n@@ -895,7 +895,11 @@               (\v1 v2 -> [| $v1 ++# $v2 |])               (map (select $ map VarE fieldPackedNames) origins) +#if MIN_VERSION_template_haskell(2,18,0)+  return $ Match (ConP name [] (VarP <$> fieldNames)) (NormalB vec) fieldPackedDecls+#else   return $ Match (ConP name (VarP <$> fieldNames)) (NormalB vec) fieldPackedDecls+#endif  -- | Build a /pack/ function corresponding to given DataRepr buildPack@@ -918,7 +922,8 @@ -- This is used in the generated pack/unpack to not do anything in HDL. dontApplyInHDL :: (a -> b) -> a -> b dontApplyInHDL f a = f a-{-# NOINLINE dontApplyInHDL #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE dontApplyInHDL #-} {-# ANN dontApplyInHDL hasBlackBox #-}  buildUnpackField
src/Clash/Annotations/BitRepresentation/Util.hs view
@@ -17,7 +17,7 @@ import Clash.Annotations.BitRepresentation.Internal   (DataRepr'(..), ConstrRepr'(..)) import Data.Bits  (Bits, testBit, testBit, shiftR, (.|.))-import Data.List  (findIndex, group, mapAccumL)+import Data.List  (findIndex, group, mapAccumL, uncons) import Data.Tuple (swap)  data Bit@@ -142,7 +142,7 @@ bitRanges word = reverse $ map swap ranges   where     ranges  = map (\(ofs, grp) -> (ofs, ofs+length grp-1)) groups'-    groups' = filter (head . snd) groups+    groups' = filter (maybe False fst . uncons . snd) groups     groups  = snd $ mapAccumL offsets 0 (group bits)     bits    = bitsToBools word 
src/Clash/Annotations/Primitive.hs view
@@ -40,7 +40,7 @@   -- The commented code directly below this comment is affected by an old--- GHC bug: https://ghc.haskell.org/trac/ghc/ticket/5463. In short, NOINLINE+-- GHC bug: https://gitlab.haskell.org/ghc/ghc/-/issues/5463. In short, NOINLINE -- pragmas generated by Template Haskell, get ignored. We'd still like a better -- API than manually having to write all the guard/inline pragmas some day, -- so I'm leaving the code in for now.@@ -239,8 +239,8 @@ -- === Example of 'InlineYamlPrimitive' -- -- The following example shows off an inline HDL primitive template. It uses the--- [interpolate](https://hackage.haskell.org/package/interpolate) package for--- nicer multiline strings.+-- [string-interpolate](https://hackage.haskell.org/package/string-interpolate)+-- package for nicer multiline strings. -- -- @ -- {\-\# LANGUAGE QuasiQuotes \#-\}@@ -248,20 +248,19 @@ -- -- import           Clash.Annotations.Primitive -- import           Clash.Prelude--- import           Data.String.Interpolate      (i)--- import           Data.String.Interpolate.Util (unindent)+-- import           Data.String.Interpolate      (__i) ----- {\-\# ANN example (InlineYamlPrimitive [VHDL] $ unindent [i|---  BlackBox:---    kind: Declaration---    name: InlinePrimitive.example---    template: |----      -- begin InlinePrimitive example:---      ~GENSYM[example][0] : block---      ~RESULT <= 1 + ~ARG[0];---      end block;---      end InlinePrimitive example--- |]) \#-\}+-- {\-\# ANN example (InlineYamlPrimitive [VHDL] [__i|+--   BlackBox:+--     kind: Declaration+--     name: InlinePrimitive.example+--     template: |-+--       -- begin InlinePrimitive example:+--       ~GENSYM[example][0] : block+--       ~RESULT <= 1 + ~ARG[0];+--       end block;+--       -- end InlinePrimitive example+--   |]) \#-\} -- {\-\# NOINLINE example \#-\} -- example :: Signal System (BitVector 2) -> Signal System (BitVector 2) -- example = fmap succ
src/Clash/Annotations/SynthesisAttributes.hs view
@@ -1,31 +1,44 @@ {-|-  Copyright   :  (C) 2018, Google Inc.,-                     2021, QBayLogic B.V.+  Copyright   :  (C) 2018,      Google Inc.,+                     2021-2023, QBayLogic B.V.   License     :  BSD2 (see the file LICENSE)   Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com> -  API for synthesis attributes (sometimes refered to as "synthesis directives",+  API for synthesis attributes (sometimes referred to as "synthesis directives",   "pragmas", or "logic synthesis directives"). This is an experimental feature,   please report any unexpected or broken behavior to Clash's GitHub page   (<https://github.com/clash-lang/clash-compiler/issues>). -} +{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE NoGeneralizedNewtypeDeriving #-} {-# LANGUAGE PolyKinds #-}--{-# LANGUAGE Safe #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskellQuotes #-}  module Clash.Annotations.SynthesisAttributes   ( Attr(..)   , Annotate+  , annotate+  , markDebug   ) where -import GHC.TypeLits (Symbol)+import Control.DeepSeq (NFData)+import Data.Binary (Binary)+import Data.Hashable (Hashable) import Data.Kind (Type)+import Data.String.Interpolate (__i)+import GHC.Generics (Generic)+import Language.Haskell.TH.Syntax (Lift) +import Clash.Annotations.Primitive (Primitive(InlineYamlPrimitive), hasBlackBox)+import Clash.Signal.Internal (Signal)+import Clash.Sized.Vector (Vec(..))+ type Annotate (a :: Type) (attrs :: k) = a --- | Synthesis attributes are directives passed to sythesis tools, such as+-- | Synthesis attributes are directives passed to synthesis tools, such as -- Quartus. An example of such an attribute in VHDL: -- -- @@@ -94,16 +107,53 @@ -- -- This is an experimental feature, please report any unexpected or broken -- behavior to Clash's GitHub page (<https://github.com/clash-lang/clash-compiler/issues>).-data Attr-  = BoolAttr Symbol Bool+--+-- Use 'annotate' if you wish to annotate an intermediate signal. Its use is+-- preferred over type level annotations.+data Attr a+  = BoolAttr a Bool   -- ^ Attribute which argument is rendered as a bool. Example:   -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_direct_enable.htm>-  | IntegerAttr Symbol Integer+  | IntegerAttr a Integer   -- ^ Attribute which argument is rendered as a integer. Example:   -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_max_depth.htm>-  | StringAttr Symbol Symbol+  | StringAttr a a   -- ^ Attribute which argument is rendered as a string. Example:   -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_chip.htm>-  | Attr Symbol+  | Attr a   -- ^ Attribute rendered as constant. Example:   -- <https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#hdl/vlog/vlog_file_dir_keep.htm>+  deriving (Show, Generic, NFData, Binary, Lift, Eq, Ord, Hashable, Functor)++-- | Create a new identifier in HDL and inserts given synthesis attributes. The+-- name of the intermediate signal can be influenced using naming functions in+-- "Clash.Magic".+annotate :: forall n dom a . Vec n (Attr String) -> Signal dom a -> Signal dom a+annotate !_attrs !a = a+{-# CLASH_OPAQUE annotate #-}+{-# ANN annotate hasBlackBox #-}+{-# ANN annotate+  let primName = show 'annotate+  in InlineYamlPrimitive [minBound..] [__i|+    BlackBoxHaskell:+        name: #{primName}+        templateFunction: "Clash.Primitives.Annotations.SynthesisAttributes.annotateBBF"+        workInfo: Always+  |] #-}++-- | Insert attributes such that signals are preserved in major synthesis tools.+-- Also inserts "mark_debug", a way of signalling Vivado a signal should show up+-- in a list of signals desired for ILA/VIO insertion.+--+-- Attributes inserted: @keep@, @mark_debug@, @noprune@, and @preserve@.+markDebug :: Signal dom a -> Signal dom a+markDebug = annotate $+     BoolAttr "keep" True++  -- Vivado:+  :> BoolAttr "mark_debug" True++  -- Quartus:+  :> Attr "noprune"+  :> Attr "preserve"+  :> Nil
src/Clash/Annotations/TH.hs view
@@ -1,6 +1,6 @@ {-| -This module can automatically generate TopEntity definitions from 'Clash.NamedTypes'+This module can automatically generate TopEntity definitions from "Clash.NamedTypes" annotations. Annotations involving data\/type families must be inspected for correctness. Not all cases can be handled with automatic generation due to the difficulty of type manipulation in template Haskell. In particular annotations __inside__ the following is unlikely to work:@@ -372,7 +372,7 @@   applyFamilyBindings _ _ _ = error "familyTyMap called with non family argument!"  #if MIN_VERSION_template_haskell(2,15,0)-  tySynArgs (TySynEqn _ args _) = tail (unapp args)+  tySynArgs (TySynEqn _ args _) = drop 1 (unapp args) #else   tySynArgs (TySynEqn args _) = args #endif
src/Clash/Annotations/TopEntity.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -62,7 +62,11 @@ import Clash.Prelude import Clash.Intel.ClockGen -'Clash.Explicit.Signal.createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}+-- Define a synthesis domain with a clock with a period of 20000 /ps/. Signal+-- coming from the reset button is low when pressed, and high when not pressed.+'Clash.Explicit.Signal.createDomain'+  vSystem{vName=\"DomInput\", vPeriod=20000, vResetPolarity=ActiveLow}+-- Define a synthesis domain with a clock with a period of 50000 /ps/. 'Clash.Explicit.Signal.createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}  topEntity@@ -75,35 +79,19 @@   'Clash.Signal.exposeClockResetEnable'     ('Clash.Prelude.mealy' blinkerT initialStateBlinkerT . 'Clash.Prelude.isRising' 1)     clk50-    rstSync+    rst50     enaBtn     modeBtn  where   -- Start with the first LED turned on, in rotate mode, with the counter on zero   initialStateBlinkerT = (1, False, 0) -  -- Signal coming from the reset button is low when pressed, and high when-  -- not pressed. We convert this signal to the polarity of our domain with-  -- /unsafeFromLowPolarity/.-  rst = 'Clash.Signal.unsafeFromLowPolarity' ('Clash.Signal.unsafeFromReset' rstBtn)--  -- Instantiate a PLL: this stabilizes the incoming clock signal and indicates-  -- when the signal is stable. We're also using it to transform an incoming-  -- clock signal running at 20 MHz to a clock signal running at 50 MHz.-  (clk50, pllStable) =-    'Clash.Intel.ClockGen.altpll'-      \@Dom50-      (SSymbol @"altpll50")-      clk20-      rst--  -- Synchronize reset to clock signal coming from PLL. We want the reset to-  -- remain active while the PLL is NOT stable, hence the conversion with-  -- /unsafeFromLowPolarity/-  rstSync =-    'Clash.Prelude.resetSynchronizer'-      clk50-      ('Clash.Signal.unsafeFromLowPolarity' pllStable)+  -- Instantiate a PLL: this stabilizes the incoming clock signal and releases+  -- the reset output when the signal is stable. We're also using it to+  -- transform an incoming clock signal running at 20 MHz to a clock signal+  -- running at 50 MHz. Since the signature of topEntity already specifies the+  -- Dom50 domain, we don't need any type signatures to specify the domain here.+  (clk50, rst50) = 'Clash.Intel.ClockGen.altpllSync' clk20 rstBtn  blinkerT   :: (BitVector 8, Bool, Index 16650001)
src/Clash/CPP.hs view
@@ -1,7 +1,8 @@ {-|-Copyright  :  (C) 2019, Myrtle Software Ltd+Copyright  :  (C) 2019     , Myrtle Software Ltd,+                  2023     , QBayLogic B.V., License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}  {-# LANGUAGE CPP #-}@@ -10,6 +11,7 @@  module Clash.CPP  ( maxTupleSize+ , haddockOnly   -- ** Cabal flags  , fSuperStrict@@ -37,6 +39,13 @@  maxTupleSize :: Num a => a maxTupleSize = MAX_TUPLE_SIZE++haddockOnly :: Bool+#ifdef HADDOCK_ONLY+haddockOnly = True+#else+haddockOnly = False+#endif  -- | Whether clash-prelude was compiled with -fsuper-strict fSuperStrict :: Bool
src/Clash/Class/AutoReg/Instances.hs view
@@ -21,7 +21,7 @@ deriveAutoReg ''Down deriveAutoReg ''Ratio --- | __N.B.__: The documentation only shows instances up to /3/-tuples. By+-- | __NB__: The documentation only shows instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version.
src/Clash/Class/AutoReg/Internal.hs view
@@ -48,9 +48,6 @@ import           Language.Haskell.TH.Ppr  import           Control.Lens.Internal.TH     (conAppsT)-#if !(MIN_VERSION_th_abstraction(0,4,0))-import           Control.Lens.Internal.TH     (bndrName)-#endif  -- $setup -- >>> import Data.Maybe@@ -258,21 +255,12 @@ deriveAutoRegProduct tyInfo conInfo = go (constructorName conInfo) fieldInfos  where   tyNm = datatypeName tyInfo-  tyVarBndrs = datatypeVars tyInfo--#if MIN_VERSION_th_abstraction(0,4,0)-  toTyVar = VarT . tvName-#elif MIN_VERSION_th_abstraction(0,3,0)-  toTyVar = VarT . bndrName+#if MIN_VERSION_th_abstraction(0,3,0)+  tyArgs = datatypeInstTypes tyInfo #else-  toTyVar t = case t of-    VarT _ -> t-    SigT t' _ -> toTyVar t'-    _ -> error "deriveAutoRegProduct.toTv"+  tyArgs = datatypeVars tyInfo #endif--  tyVars = map toTyVar tyVarBndrs-  ty = conAppsT tyNm tyVars+  ty = conAppsT tyNm tyArgs    fieldInfos =     zip fieldNames (constructorFields conInfo)@@ -284,10 +272,15 @@    go :: Name -> [(Maybe Name,Type)] -> Q [Dec]   go dcNm fields = do-    args <- mapM newName ["clk", "rst", "en", "initVal", "input"]+    clkN     <- newName "clk"+    rstN     <- newName "rst"+    enN      <- newName "en"+    initValN <- newName "initVal"+    inputN   <- newName "input"     let-      [clkE, rstE, enE, initValE, inputE] = map varE args-      argsP = map varP args+      initValE = varE initValN+      inputE = varE inputN+      argsP = map varP [clkN, rstN, enN, initValN, inputN]       fieldNames = map fst fields        field :: Name -> Int -> DecQ@@ -308,6 +301,9 @@     initDecl <- valD initPat (normalB initValE) []      let+      clkE = varE clkN+      rstE = varE rstN+      enE  = varE enN       genAutoRegDecl :: PatQ -> ExpQ -> ExpQ -> Maybe Name -> DecsQ       genAutoRegDecl s v i nameM =         [d| $s = $nameMe autoReg $clkE $rstE $enE $i $v |]
src/Clash/Class/BitPack/BitIndex.hs view
@@ -5,6 +5,7 @@ Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} @@ -29,7 +30,7 @@ {-# INLINE (!) #-} -- | Get the bit at the specified bit index. ----- __NB:__ Bit indices are __DESCENDING__.+-- __NB__: Bit indices are __DESCENDING__. -- -- >>> pack (7 :: Unsigned 6) -- 0b00_0111@@ -44,22 +45,37 @@ (!) v i = index# (pack v) (fromEnum i)  {-# INLINE slice #-}--- | Get a slice between bit index @m@ and and bit index @n@.------ __NB:__ Bit indices are __DESCENDING__.------ >>> pack (7 :: Unsigned 6)--- 0b00_0111--- >>> slice d4 d2 (7 :: Unsigned 6)--- 0b001--- >>> slice d6 d4 (7 :: Unsigned 6)--- <BLANKLINE>--- <interactive>:...---     • Couldn't match type ‘7 + i0’ with ‘6’---         arising from a use of ‘slice’---       The type variable ‘i0’ is ambiguous---     • In the expression: slice d6 d4 (7 :: Unsigned 6)---       In an equation for ‘it’: it = slice d6 d4 (7 :: Unsigned 6)+{- | Get a slice between bit index @m@ and and bit index @n@.++__NB__: Bit indices are __DESCENDING__.++>>> pack (7 :: Unsigned 6)+0b00_0111+>>> slice d4 d2 (7 :: Unsigned 6)+0b001++#if __GLASGOW_HASKELL__ == 906+>>> slice d6 d4 (7 :: Unsigned 6)+<BLANKLINE>+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘slice’+        The type variable ‘i0’ is ambiguous+    • In the expression: slice d6 d4 (7 :: Unsigned 6)+      In an equation for ‘it’: it = slice d6 d4 (7 :: Unsigned 6)++#else+>>> slice d6 d4 (7 :: Unsigned 6)+<BLANKLINE>+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘slice’+      The type variable ‘i0’ is ambiguous+    • In the expression: slice d6 d4 (7 :: Unsigned 6)+      In an equation for ‘it’: it = slice d6 d4 (7 :: Unsigned 6)++#endif+-} slice   :: (BitPack a, BitSize a ~ ((m + 1) + i))   => SNat m@@ -85,7 +101,7 @@ {-# INLINE replaceBit #-} -- | Set the bit at the specified index ----- __NB:__ Bit indices are __DESCENDING__.+-- __NB__: Bit indices are __DESCENDING__. -- -- >>> pack (-5 :: Signed 6) -- 0b11_1011@@ -104,24 +120,39 @@ replaceBit i b v = unpack (replaceBit# (pack v) (fromEnum i) b)  {-# INLINE setSlice #-}--- | Set the bits between bit index @m@ and bit index @n@.------ __NB:__ Bit indices are __DESCENDING__.------ >>> pack (-5 :: Signed 6)--- 0b11_1011--- >>> setSlice d4 d3 0 (-5 :: Signed 6)--- -29--- >>> pack (-29 :: Signed 6)--- 0b10_0011--- >>> setSlice d6 d5 0 (-5 :: Signed 6)--- <BLANKLINE>--- <interactive>:...---     • Couldn't match type ‘7 + i0’ with ‘6’---         arising from a use of ‘setSlice’---       The type variable ‘i0’ is ambiguous---     • In the expression: setSlice d6 d5 0 (- 5 :: Signed 6)---       In an equation for ‘it’: it = setSlice d6 d5 0 (- 5 :: Signed 6)+{- | Set the bits between bit index @m@ and bit index @n@.++__NB__: Bit indices are __DESCENDING__.++>>> pack (-5 :: Signed 6)+0b11_1011+>>> setSlice d4 d3 0 (-5 :: Signed 6)+-29+>>> pack (-29 :: Signed 6)+0b10_0011++#if __GLASGOW_HASKELL__ == 906+>>> setSlice d6 d5 0 (-5 :: Signed 6)+<BLANKLINE>+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘setSlice’+        The type variable ‘i0’ is ambiguous+    • In the expression: setSlice d6 d5 0 (- 5 :: Signed 6)+      In an equation for ‘it’: it = setSlice d6 d5 0 (- 5 :: Signed 6)++#else+>>> setSlice d6 d5 0 (-5 :: Signed 6)+<BLANKLINE>+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘setSlice’+      The type variable ‘i0’ is ambiguous+    • In the expression: setSlice d6 d5 0 (- 5 :: Signed 6)+      In an equation for ‘it’: it = setSlice d6 d5 0 (- 5 :: Signed 6)++#endif+-} setSlice   :: (BitPack a, BitSize a ~ ((m + 1) + i))   => SNat m
src/Clash/Class/BitPack/Internal.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2017, Myrtle Software Ltd,-                  2021-2022  QBayLogic B.V.,+                  2021-2023  QBayLogic B.V.,                   2022,      Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>@@ -50,9 +50,9 @@ import Clash.Class.BitPack.Internal.TH (deriveBitPackTuples) import Clash.Class.Resize             (zeroExtend, resize) import Clash.Promoted.Nat             (SNat(..), snatToNum)-import Clash.Sized.BitVector          (Bit, BitVector, (++#)) import Clash.Sized.Internal.BitVector-  (pack#, split#, checkUnpackUndef, undefined#, unpack#, unsafeToNatural, isLike#)+  (pack#, split#, checkUnpackUndef, undefined#, unpack#, unsafeToNatural, isLike#,+   BitVector, Bit, (++#)) import Clash.XException  {- $setup@@ -79,6 +79,19 @@ -- instances, as even if @a@ has a statically known size, the length of the -- list cannot be known in advance. --+-- It is not possible to give data a custom bit representation by providing a+-- @BitPack@ instance. A @BitPack@ instance allows no creativity and should+-- always accurately reflect the bit representation of the data in HDL. You+-- should always @derive ('Generic', BitPack)@ unless you use a custom data+-- representation, in which case you should use+-- 'Clash.Annotations.BitRepresentation.Deriving.deriveBitPack'. Custom+-- encodings can be created with "Clash.Annotations.BitRepresentation" and+-- "Clash.Annotations.BitRepresentation.Deriving".+--+-- If the @BitPack@ instance does not accurately match the bit representation of+-- the data in HDL, Clash designs will exhibit incorrect behavior in various+-- places.+-- -- Clash provides some generic functions on packable types in the prelude, such -- as indexing into packable stuctures (see "Clash.Class.BitPack.BitIndex") and -- bitwise reduction of packable data (see "Clash.Class.BitPack.BitReduction").@@ -155,7 +168,8 @@ xToBV x =   unsafeDupablePerformIO (catch (evaluate x)                                 (\(XException _) -> return undefined#))-{-# NOINLINE xToBV #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xToBV #-} {-# ANN xToBV hasBlackBox #-}  -- | Pack both arguments to a 'BitVector' and use@@ -186,7 +200,7 @@ -- >>> isLike x1 x3 -- True ----- __N.B.__: Not synthesizable+-- __NB__: Not synthesizable -- isLike   :: (BitPack a)@@ -298,12 +312,14 @@  packFloat# :: Float -> BitVector 32 packFloat# = fromIntegral . floatToWord-{-# NOINLINE packFloat# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE packFloat# #-} {-# ANN packFloat# hasBlackBox #-}  unpackFloat# :: BitVector 32 -> Float unpackFloat# (unsafeToNatural -> w) = wordToFloat (fromIntegral w)-{-# NOINLINE unpackFloat# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpackFloat# #-} {-# ANN unpackFloat# hasBlackBox #-}  instance BitPack Double where@@ -313,12 +329,14 @@  packDouble# :: Double -> BitVector 64 packDouble# = fromIntegral . doubleToWord-{-# NOINLINE packDouble# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE packDouble# #-} {-# ANN packDouble# hasBlackBox #-}  unpackDouble# :: BitVector 64 -> Double unpackDouble# (unsafeToNatural -> w) = wordToDouble (fromIntegral w)-{-# NOINLINE unpackDouble# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpackDouble# #-} {-# ANN unpackDouble# hasBlackBox #-}  instance BitPack CUShort where@@ -336,7 +354,7 @@   pack   _ = minBound   unpack _ = () --- | __N.B.__: The documentation only shows instances up to /3/-tuples. By+-- | __NB__: The documentation only shows instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version.@@ -445,6 +463,8 @@   gUnpack _c _cc _b = U1  -- Instances derived using Generic+instance BitPack Ordering+ instance ( BitPack a          , BitPack b          ) => BitPack (Either a b)
src/Clash/Class/BitPack/Internal/TH.hs view
@@ -40,7 +40,9 @@    pure $ flip map [3..maxTupleSize] $ \tupleNum ->     let names  = take tupleNum allNames-        (v:vs) = fmap VarT names+        (v,vs) = case map VarT names of+                    (z:zs) -> (z,zs)+                    _ -> error "maxTupleSize <= 3"         tuple xs = foldl' AppT (TupleT $ length xs) xs          -- Instance declaration@@ -68,7 +70,9 @@                     retupName                     [ Clause                         [ TupP $ map VarP names ]-                        ( let (e:es) = map VarE names+                        ( let (e,es) = case map VarE names of+                                          (z:zs) -> (z,zs)+                                          _ -> error "maxTupleSize <= 3"                           in NormalB (mkTupE [e,mkTupE es])                         )                         []@@ -82,7 +86,9 @@             [ Clause                 [ VarP x ]                 ( NormalB $-                    let (p:ps) = map VarP names+                    let (p,ps) = case map VarP names of+                                   (z:zs) -> (z,zs)+                                   _ -> error "maxTupleSize <= 3"                     in                     LetE                       [ ValD
src/Clash/Class/Counter/Internal.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}  module Clash.Class.Counter.Internal where @@ -22,7 +23,7 @@ -- >>> import Clash.Sized.Signed (Signed) -- >>> import Clash.Sized.Unsigned (Unsigned) --- | 'Clash.Class.Counter.Counter' is a class that composes multiple counters+-- | t'Clash.Class.Counter.Counter' is a class that composes multiple counters -- into a single one. It is similar to odometers found in olds cars, -- once all counters reach their maximum they reset to zero - i.e. odometer -- rollover. See 'Clash.Class.Counter.countSucc' and 'Clash.Class.Counter.countPred'@@ -42,7 +43,7 @@ -- -- and have 'Clash.Class.Counter.countSucc' work as described. ----- __N.B.__: This class exposes four functions 'countMin', 'countMax',+-- __NB__: This class exposes four functions 'countMin', 'countMax', -- 'countSuccOverflow', and 'countPredOverflow'. These functions are considered -- an internal API. Users are encouraged to use 'Clash.Class.Counter.countSucc' -- and 'Clash.Class.Counter.countPred'.@@ -58,16 +59,16 @@   default countMax :: Bounded a => a   countMax = maxBound -  -- | Gets the successor of @a@. If it overflows, the left part of the tuple-  -- will be set to True.+  -- | Gets the successor of @a@. If it overflows, the first part of the tuple+  -- will be set to True and the second part wraps around to `countMin`.   countSuccOverflow :: a -> (Bool, a)   default countSuccOverflow :: (Eq a, Enum a, Bounded a) => a -> (Bool, a)   countSuccOverflow a     | a == maxBound = (True, countMin)     | otherwise = (False, succ a) -  -- | Gets the predecessor of @a@. If it overflows, the left part of the tuple-  -- will be set to True.+  -- | Gets the predecessor of @a@. If it underflows, the first part of the tuple+  -- will be set to True and the second part wraps around to `countMax`.   countPredOverflow :: a -> (Bool, a)   default countPredOverflow :: (Eq a, Enum a, Bounded a) => a -> (Bool, a)   countPredOverflow a@@ -116,7 +117,7 @@ -- >>> countSucc @T (0, 1, 1) -- (1,0,0) ----- __N.B.__: The documentation only shows the instances up to /3/-tuples. By+-- __NB__: The documentation only shows the instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version.
src/Clash/Class/Exp.hs view
@@ -63,7 +63,8 @@   -> Index (Max 2 (m ^ n)) expIndex# b e@SNat =   fromInteger (toInteger b P.^ snatToInteger e)-{-# NOINLINE expIndex# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE expIndex# #-} {-# ANN expIndex# hasBlackBox #-}  expSigned#@@ -73,7 +74,8 @@   -> Signed (Max 2 (m * n)) expSigned# b e@SNat =   fromInteger (toInteger b P.^ snatToInteger e)-{-# NOINLINE expSigned# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE expSigned# #-} {-# ANN expSigned# hasBlackBox #-}  expUnsigned#@@ -83,5 +85,6 @@   -> Unsigned (Max 1 (m * n)) expUnsigned# b e@SNat =   fromInteger (toInteger b P.^ snatToInteger e)-{-# NOINLINE expUnsigned# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE expUnsigned# #-} {-# ANN expUnsigned# hasBlackBox #-}
src/Clash/Class/Resize.hs view
@@ -88,7 +88,7 @@ -- you "know" /f a/ can't be out of bounds, but would like to have your -- assumptions checked. ----- __N.B.__: Check only affects simulation. I.e., no checks will be inserted+-- __NB__: Check only affects simulation. I.e., no checks will be inserted -- into the generated HDL checkedResize ::   forall a b f.@@ -104,7 +104,7 @@ -- when you "know" /f (a + b)/ can't be out of bounds, but would like to have your -- assumptions checked. ----- __N.B.__: Check only affects simulation. I.e., no checks will be inserted+-- __NB__: Check only affects simulation. I.e., no checks will be inserted -- into the generated HDL checkedTruncateB ::   forall a b f.
src/Clash/Clocks.hs view
@@ -1,32 +1,43 @@ {-| Copyright  :  (C) 2018, Google Inc                   2019, Myrtle Software Ltd+                  2023,      QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  Generic clock related utilities. -} -{-# LANGUAGE ConstrainedClassMethods #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} -module Clash.Clocks (Clocks(..)) where+{-# OPTIONS_GHC "-Wno-orphans" #-} -import Data.Kind (Constraint)+module Clash.Clocks+  ( Clocks(..)+  , ClocksSync(..)+  , ClocksSyncCxt+  , NumOutClocksSync+  ) where -import Clash.Signal.Internal-import Clash.Clocks.Deriving (deriveClocksInstances)+import Clash.Clocks.Internal+  (Clocks(..), ClocksSync(..), deriveClocksInstances, deriveClocksSyncInstances)+import Clash.Signal.Internal (Domain, KnownDomain) -class Clocks t where-  type ClocksCxt t :: Constraint+deriveClocksInstances -  clocks-    :: (KnownDomain domIn, ClocksCxt t)-    => Clock domIn-    -> Reset domIn-    -> t+type ClocksSyncCxt t (domIn :: Domain) =+  ( KnownDomain domIn+  , ClocksSync t+  , ClocksResetSynchronizerCxt t+  , Clocks (ClocksSyncClocksInst t domIn)+  , ClocksCxt (ClocksSyncClocksInst t domIn)+  ) -deriveClocksInstances 16+type NumOutClocksSync t (domIn :: Domain) =+  NumOutClocks (ClocksSyncClocksInst t domIn)++deriveClocksSyncInstances
− src/Clash/Clocks/Deriving.hs
@@ -1,80 +0,0 @@-{-|-Copyright  :  (C) 2018, Google Inc-                  2019, Myrtle Software Ltd-                  2023,      QBayLogic B.V.-License    :  BSD2 (see the file LICENSE)-Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>--}--{-# LANGUAGE CPP #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}--module Clash.Clocks.Deriving (deriveClocksInstances) where--import Control.Monad               (foldM)-import Clash.Explicit.Signal       (unsafeSynchronizer)-import Clash.Signal.Internal-import Language.Haskell.TH.Compat-import Language.Haskell.TH.Syntax-import Language.Haskell.TH.Lib-import Unsafe.Coerce               (unsafeCoerce)---- Derive instance for /n/ clocks-derive' :: Int -> Q Dec-derive' n = do-  -- (Clock d0, Clock d1, )-  instType0 <- foldM (\a n' -> AppT a <$> clkType n') (TupleT $ n + 1) [1..n]-  instType1 <- AppT instType0 <$> lockType-  let instHead = AppT (ConT $ mkName "Clocks") instType1--  cxtRHS0 <--    foldM (\a n' -> AppT a <$> knownDomainCxt n') (TupleT $ n + 1) [1..n]-  cxtRHS1 <- AppT cxtRHS0 <$> lockKnownDomainCxt-#if MIN_VERSION_template_haskell(2,15,0)-  let cxtLHS = AppT (ConT $ mkName "ClocksCxt") instType1-  let cxtTy  = TySynInstD (TySynEqn Nothing cxtLHS cxtRHS1)-#else-  let cxtTy  = TySynInstD (mkName "ClocksCxt") (TySynEqn [instType1] cxtRHS1)-#endif--  -- Function definition of 'clocks'-  let clk = mkName "clk"-  let rst = mkName "rst"--  -- Implementation of 'clocks'-  lockImpl <- [| unsafeSynchronizer clockGen clockGen-                   (unsafeToLowPolarity $(varE rst)) |]-  let noInline  = PragmaD $ InlineP (mkName "clocks") NoInline FunLike AllPhases-  let clkImpls  = replicate n (clkImpl clk)-  let instTuple = mkTupE $ clkImpls ++ [lockImpl]-  let funcBody  = NormalB instTuple-  let instFunc  = FunD (mkName "clocks") [Clause [VarP clk, VarP rst] funcBody []]--  return $ InstanceD Nothing [] instHead [cxtTy, instFunc, noInline]--  where-    -- | Generate type @Clock dom@ with fresh @dom@ variable-    clkType n' =-      let c = varT $ mkName ("c" ++ show n') in-      [t| Clock $c |]--    knownDomainCxt n' =-      let c = varT $ mkName ("c" ++ show n') in-      [t| KnownDomain $c |]--    -- | Generate type @Signal dom 'Bool@ with fresh @dom@ variable-    lockType =-      let c = varT $ mkName "pllLock" in-      [t| Signal $c Bool |]--    lockKnownDomainCxt =-      let p = varT $ mkName "pllLock" in-      [t| KnownDomain $p |]---    clkImpl clk = AppE (VarE 'unsafeCoerce) (VarE clk)---- Derive instances for up to and including to /n/ clocks-deriveClocksInstances :: Int -> Q [Dec]-deriveClocksInstances n = mapM derive' [1..n]
+ src/Clash/Clocks/Internal.hs view
@@ -0,0 +1,159 @@+{-|+Copyright  :  (C) 2018-2022, Google Inc+                  2019,      Myrtle Software Ltd+                  2023,      QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>+-}++{-# LANGUAGE ConstrainedClassMethods #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++module Clash.Clocks.Internal+  ( Clocks(..)+  , deriveClocksInstances+  , ClocksSync(..)+  , deriveClocksSyncInstances+  ) where++import Control.Monad.Extra (concatMapM)+import Data.Kind (Constraint, Type)+import GHC.TypeLits (Nat)+import Language.Haskell.TH hiding (Type)++import Clash.CPP (haddockOnly)+import Clash.Explicit.Reset (resetSynchronizer)+import Clash.Explicit.Signal (unsafeSynchronizer)+import Clash.Magic (setName)+import Clash.Promoted.Symbol (SSymbol(..))+import Clash.Signal.Internal+  (clockGen, Clock(..), Domain, KnownDomain, Reset, Signal, unsafeFromActiveLow,+   unsafeToActiveLow)++-- | __NB__: The documentation only shows instances up to /3/ output clocks. By+-- default, instances up to and including /18/ clocks will exist.+class Clocks t where+  type ClocksCxt t :: Constraint+  type NumOutClocks t :: Nat++  clocks ::+    (KnownDomain domIn, ClocksCxt t) =>+    Clock domIn ->+    Reset domIn ->+    t++-- Derive instance for /n/ clocks+deriveClocksInstance :: Int -> DecsQ+deriveClocksInstance n =+  [d| instance Clocks $instType where+        type ClocksCxt $instType = $cxtType+        type NumOutClocks $instType = $numOutClocks++        clocks (Clock _ Nothing) $(varP rst) = $funcImpl+        clocks _ _ = error "clocks: dynamic clocks unsupported"+        {-# CLASH_OPAQUE clocks #-}+    |]+ where+  clkTyVar m = varT $ mkName $ "c" <> show m+  clkTypes = map (\m -> [t| Clock $(clkTyVar m) |]) [1..n]+  lockTyVar = varT $ mkName "pllLock"+  -- (Clock c1, Clock c2, ..., Signal pllLock Bool)+  instType = foldl appT (tupleT $ n + 1) $+               clkTypes <> [ [t| Signal $lockTyVar Bool |] ]+  clkKnownDoms = map (\m -> [t| KnownDomain $(clkTyVar m) |]) [1..n]+  -- (KnownDomain c1, KnownDomain c2, ..., KnownDomain pllLock)+  cxtType = foldl appT (tupleT $ n + 1) $+              clkKnownDoms <> [ [t| KnownDomain $lockTyVar |] ]+  numOutClocks = litT . numTyLit $ toInteger n++  -- 'clocks' function+  rst = mkName "rst"+  lockImpl = [|+    unsafeSynchronizer clockGen clockGen (unsafeToActiveLow $(varE rst))+    |]+  clkImpls = replicate n [| Clock SSymbol Nothing |]+  funcImpl = tupE $ clkImpls <> [lockImpl]++-- Derive instances for up to and including 18 clocks, except when we are+-- generating Haddock+deriveClocksInstances :: DecsQ+deriveClocksInstances = concatMapM deriveClocksInstance [1..n]+ where+  n | haddockOnly = 3+    | otherwise   = 18++-- | __NB__: The documentation only shows instances up to /3/ output clocks. By+-- default, instances up to and including /18/ clocks will exist.+class ClocksSync t where+  type ClocksSyncClocksInst t (domIn :: Domain) :: Type+  type ClocksResetSynchronizerCxt t :: Constraint++  clocksResetSynchronizer ::+    ( KnownDomain domIn+    , ClocksResetSynchronizerCxt t+    ) =>+    ClocksSyncClocksInst t domIn ->+    Clock domIn ->+    t++-- Derive instance for /n/ clocks+deriveClocksSyncInstance :: Int -> DecsQ+deriveClocksSyncInstance n =+  [d|+    instance ClocksSync $instType where+      type ClocksSyncClocksInst $instType $domInTyVar = $clocksInstType+      type ClocksResetSynchronizerCxt $instType = $cxtType++      clocksResetSynchronizer pllOut $(varP clkIn) =+        let $pllPat = pllOut+        in $funcImpl+  |]+ where+  clkVarName m = mkName $ "c" <> show m+  clkTyVar :: Int -> TypeQ+  clkTyVar = varT . clkVarName+  clkAndRstTy m = [ [t| Clock $(clkTyVar m) |]+                  , [t| Reset $(clkTyVar m) |]+                  ]+  -- (Clock c1, Reset c1, Clock c2, Reset c2, ...)+  instType = foldl appT (tupleT $ n * 2) $ concatMap clkAndRstTy [1..n]+  domInTyVar = varT $ mkName "domIn"+  clkTypes = map (\m -> [t| Clock $(clkTyVar m) |]) [1..n]+  -- (Clock c1, Clock c2, ..., Signal domIn Bool)+  clocksInstType = foldl appT (tupleT $ n + 1) $+                     clkTypes <> [ [t| Signal $domInTyVar Bool |] ]+  -- (KnownDomain c1, KnownDomain c2, ...)+  cxtType+    | n == 1+    = [t| KnownDomain $(clkTyVar 1) |]+    | otherwise+    = foldl appT (tupleT n) $+        map (\m -> [t| KnownDomain $(clkTyVar m) |]) [1..n]++  -- 'clocksResetSynchronizer' function+  clkIn = mkName "clkIn"+  pllLock = mkName "pllLock"+  -- (c1, c2, ..., pllLock)+  pllPat = tupP $ map (varP . clkVarName) [1..n] <> [varP pllLock]+  syncImpl m =+    [|+      setName @"resetSynchronizer" (resetSynchronizer $(varE $ clkVarName m)+        (unsafeFromActiveLow+          (unsafeSynchronizer $(varE clkIn) $(varE $ clkVarName m)+                              $(varE pllLock))))+    |]+  clkAndRstExp m = [ varE $ clkVarName m+                   , syncImpl m+                   ]+  -- (c1, r1, c2, r2, ...) where rN is the synchronized reset for clock N+  funcImpl = tupE $ concatMap clkAndRstExp [1..n]++-- Derive instances for up to and including 18 clocks, except when we are+-- generating Haddock+deriveClocksSyncInstances :: DecsQ+deriveClocksSyncInstances = concatMapM deriveClocksSyncInstance [1..n]+ where+  n | haddockOnly = 3+    | otherwise   = 18
src/Clash/Explicit/BlockRam.hs view
@@ -2,7 +2,8 @@ Copyright  :  (C) 2013-2016, University of Twente,                   2016-2017, Myrtle Software Ltd,                   2017     , Google Inc.,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V.,+                  2022     , Google Inc., License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -36,7 +37,7 @@   | Load MemAddr Reg   | Store Reg MemAddr   | Nop-  deriving (Eq, Show)+  deriving (Eq, Show, Generic, NFDataX)  data Reg   = Zero@@ -49,7 +50,7 @@   deriving (Eq, Show, Enum, Generic, NFDataX)  data Operator = Add | Sub | Incr | Imm | CmpGt-  deriving (Eq, Show)+  deriving (Eq, Show, Generic, NFDataX)  data MachCode   = MachCode@@ -385,9 +386,12 @@  -} +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskellQuotes #-}  {-# LANGUAGE Trustworthy #-} @@ -422,42 +426,45 @@   ) where -import           Clash.HaskellPrelude+import Clash.HaskellPrelude -import           Control.Exception      (catch, throw)-import           Control.Monad          (forM_)-import           Control.Monad.ST       (ST, runST)-import           Control.Monad.ST.Unsafe (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO)-import           Data.Array.MArray      (newListArray)-import qualified Data.List              as L-import           Data.Maybe             (isJust, fromMaybe)-import           GHC.Arr-  (STArray, unsafeReadSTArray, unsafeWriteSTArray)-import qualified Data.Sequence          as Seq-import           Data.Sequence          (Seq)-import           Data.Tuple             (swap)-import           GHC.Generics           (Generic)-import           GHC.Stack              (HasCallStack, withFrozenCallStack)-import           GHC.TypeLits           (KnownNat, type (^), type (<=))-import           Unsafe.Coerce          (unsafeCoerce)+import Control.Exception (catch, throw)+import Control.Monad (forM_)+import Control.Monad.ST (ST, runST)+import Control.Monad.ST.Unsafe (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO)+import Data.Array.MArray (newListArray)+import Data.List.Infinite (Infinite(..), (...))+import Data.Maybe (isJust)+import Data.Sequence (Seq)+import Data.String.Interpolate (__i)+import GHC.Arr (STArray, unsafeReadSTArray, unsafeWriteSTArray)+import GHC.Generics (Generic)+import GHC.Stack (HasCallStack, withFrozenCallStack)+import GHC.TypeLits (KnownNat, type (^), type (<=))+import Unsafe.Coerce (unsafeCoerce) -import           Clash.Annotations.Primitive-  (hasBlackBox)-import           Clash.Class.Num        (SaturationMode(SatBound), satSucc)-import           Clash.Explicit.Signal  (KnownDomain, Enable, register, fromEnable)-import           Clash.Signal.Internal+import Clash.Annotations.Primitive+  (Primitive(InlineYamlPrimitive), HDL(..), hasBlackBox)+import Clash.Class.Num (SaturationMode(SatBound), satSucc)+import Clash.Explicit.BlockRam.Model (TdpbramModelConfig(..), tdpbramModel)+import Clash.Explicit.Signal (KnownDomain, Enable, register, fromEnable)+import Clash.Promoted.Nat (SNat(..))+import Clash.Signal.Bundle (unbundle)+import Clash.Signal.Internal   (Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)-import           Clash.Promoted.Nat     (SNat(..), snatToNum, natToNum)-import           Clash.Signal.Bundle    (unbundle, bundle)-import           Clash.Signal.Internal.Ambiguous (clockPeriod)-import           Clash.Sized.Unsigned   (Unsigned)-import           Clash.Sized.Index      (Index)-import           Clash.Sized.Vector     (Vec, replicate, iterateI)-import qualified Clash.Sized.Vector     as CV-import           Clash.XException-  (maybeIsX, NFDataX(deepErrorX), defaultSeqX, fromJustX, undefined,-   XException (..), seqX, isX, errorX)+import Clash.Sized.Index (Index)+import Clash.Sized.Unsigned (Unsigned)+import Clash.Sized.Vector (Vec, replicate, iterateI)+import Clash.XException+ (maybeIsX, NFDataX(deepErrorX), defaultSeqX, fromJustX, undefined,+ XException (..), seqX, errorX)+import Clash.XException.MaybeX (MaybeX(..), andX) +import qualified Data.Sequence as Seq+import qualified Data.List as L++import qualified Clash.Sized.Vector as CV+ {- $tdpbram A true dual-port block RAM has two fully independent, fully functional access ports: port A and port B. Either port can do both RAM reads and writes. These@@ -494,7 +501,7 @@  >>> :{ data Operator = Add | Sub | Incr | Imm | CmpGt-  deriving (Eq,Show)+  deriving (Eq, Show, Generic, NFDataX) :}  >>> :{@@ -505,7 +512,7 @@   | Load MemAddr Reg   | Store Reg MemAddr   | Nop-  deriving (Eq,Show)+  deriving (Eq, Show, Generic, NFDataX) :}  >>> :{@@ -770,7 +777,8 @@   :: ( KnownDomain dom      , HasCallStack      , NFDataX a-     , Enum addr )+     , Enum addr+     , NFDataX addr )   => Clock dom   -- ^ 'Clock' to synchronize to   -> Enable dom@@ -854,6 +862,7 @@      , HasCallStack      , NFDataX a      , Enum addr+     , NFDataX addr      , 1 <= n )   => Clock dom   -- ^ 'Clock' to synchronize to@@ -934,7 +943,8 @@     (CV.map       (\i -> deepErrorX $ "Initial value at index " <> show i <> " undefined.")       (iterateI @n succ (0 :: Int)))-{-# NOINLINE blockRamU# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE blockRamU# #-} {-# ANN blockRamU# hasBlackBox #-}  -- | A version of 'blockRam' that is initialized with the same value on all@@ -945,6 +955,7 @@      , HasCallStack      , NFDataX a      , Enum addr+     , NFDataX addr      , 1 <= n )   => Clock dom   -- ^ 'Clock' to synchronize to@@ -1022,7 +1033,8 @@ blockRam1# clk en n a =   -- TODO: Generalize to single BRAM primitive taking an initialization function   blockRam# clk en (replicate n a)-{-# NOINLINE blockRam1# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE blockRam1# #-} {-# ANN blockRam1# hasBlackBox #-}  -- | blockRAM primitive@@ -1049,7 +1061,7 @@   -- ^ Value to write (at address @w@)   -> Signal dom a   -- ^ Value of the BRAM at address @r@ from the previous clock cycle-blockRam# (Clock _) gen content = \rd wen waS wd -> runST $ do+blockRam# (Clock _ Nothing) gen content = \rd wen waS wd -> runST $ do   ramStart <- newListArray (0,szI-1) contentL   -- start benchmark only   -- ramStart <- unsafeThawSTArray ramArr@@ -1117,8 +1129,10 @@                              " not in range [0.." <> show szI <> ")"))        in forM_ [0..(szI-1)] (\j -> unsafeWriteSTArray s j d)   {-# INLINE safeUpdate #-}+blockRam# _ _ _ = error "blockRam#: dynamic clocks not supported" {-# ANN blockRam# hasBlackBox #-}-{-# NOINLINE blockRam# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE blockRam# #-}  -- | Create a read-after-write block RAM from a read-before-write one readNew@@ -1204,20 +1218,6 @@     clkA (isOp <$> opA) (isRamWrite <$> opA) (ramOpAddr <$> opA) (fromJustX . ramOpWriteVal <$> opA)     clkB (isOp <$> opB) (isRamWrite <$> opB) (ramOpAddr <$> opB) (fromJustX . ramOpWriteVal <$> opB) -toMaybeX :: a -> MaybeX a-toMaybeX a =-  case isX a of-    Left _ -> IsX-    Right _ -> IsDefined a--data MaybeX a = IsX | IsDefined !a--data Conflict = Conflict-  { cfRWA     :: !(MaybeX Bool) -- ^ Read/Write conflict for output A-  , cfRWB     :: !(MaybeX Bool) -- ^ Read/Write conflict for output B-  , cfWW      :: !(MaybeX Bool) -- ^ Write/Write conflict-  , cfAddress :: !(MaybeX Int) }- -- [Note: eta port names for trueDualPortBlockRam] -- -- By naming all the arguments and setting the -fno-do-lambda-eta-expansion GHC@@ -1233,238 +1233,258 @@ -- into its own module / architecture. trueDualPortBlockRamWrapper clkA enA weA addrA datA clkB enB weB addrB datB =   trueDualPortBlockRam# clkA enA weA addrA datA clkB enB weB addrB datB-{-# NOINLINE trueDualPortBlockRamWrapper #-}---- | Primitive of 'trueDualPortBlockRam'.-trueDualPortBlockRam#, trueDualPortBlockRamWrapper ::-  forall nAddrs domA domB a .-  ( HasCallStack-  , KnownNat nAddrs-  , KnownDomain domA-  , KnownDomain domB-  , NFDataX a-  )-  => Clock domA-  -- ^ Clock for port A-  -> Signal domA Bool-  -- ^ Enable for port A-  -> Signal domA Bool-  -- ^ Write enable for port A-  -> Signal domA (Index nAddrs)-  -- ^ Address to read from or write to on port A-  -> Signal domA a-  -- ^ Data in for port A; ignored when /write enable/ is @False@--  -> Clock domB-  -- ^ Clock for port B-  -> Signal domB Bool-  -- ^ Enable for port B-  -> Signal domB Bool-  -- ^ Write enable for port B-  -> Signal domB (Index nAddrs)-  -- ^ Address to read from or write to on port B-  -> Signal domB a-  -- ^ Data in for port B; ignored when /write enable/ is @False@+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE trueDualPortBlockRamWrapper #-} -  -> (Signal domA a, Signal domB a)-  -- ^ Outputs data on /next/ cycle. If write enable is @True@, the data written-  -- will be echoed. If write enable is @False@, the read data is returned. If-  -- port enable is @False@, it is /undefined/.-trueDualPortBlockRam# clkA enA weA addrA datA clkB enB weB addrB datB-  | snatToNum @Int (clockPeriod @domA) < snatToNum @Int (clockPeriod @domB)-  = swap (trueDualPortBlockRamModel labelB clkB enB weB addrB datB labelA clkA enA weA addrA datA)-  | otherwise-  =       trueDualPortBlockRamModel labelA clkA enA weA addrA datA labelB clkB enB weB addrB datB- where-  labelA = "Port A"-  labelB = "Port B"-{-# NOINLINE trueDualPortBlockRam# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE trueDualPortBlockRam# #-} {-# ANN trueDualPortBlockRam# hasBlackBox #-}+{-# ANN trueDualPortBlockRam# (+  let+    bbName = show 'trueDualPortBlockRam#+    _hasCallStack+     :< knownNatAddrs+     :< _knownDomainA+     :< _knownDomainB+     :< _nfdataX +     :< clockA+     :< enaA+     :< wenaA+     :< addrA+     :< datA --- | Haskell model for the primitive 'trueDualPortBlockRam#'.------ Warning: this model only works if @domFast@'s clock is faster (or equal to)--- @domSlow@'s clock.-trueDualPortBlockRamModel ::-  forall nAddrs domFast domSlow a .-  ( HasCallStack-  , KnownNat nAddrs-  , KnownDomain domSlow-  , KnownDomain domFast-  , NFDataX a-  ) =>+     :< clockB+     :< enaB+     :< wenaB+     :< addrB+     :< datB -  String ->-  Clock domSlow ->-  Signal domSlow Bool ->-  Signal domSlow Bool ->-  Signal domSlow (Index nAddrs) ->-  Signal domSlow a ->+     :< _ = ((0 :: Int)...) -  String ->-  Clock domFast ->-  Signal domFast Bool ->-  Signal domFast Bool ->-  Signal domFast (Index nAddrs) ->-  Signal domFast a ->+    symBlockName+     :< symDoutA+     :< symDoutB+     :< _ = ((0 :: Int)...)+  in InlineYamlPrimitive [VHDL] [__i|+    BlackBox:+      name: "#{bbName}"+      kind: Declaration+      template: |-+        -- trueDualPortBlockRam begin+        ~GENSYM[~RESULT_trueDualPortBlockRam][#{symBlockName}] : block+          -- Shared memory+          type mem_type is array ( ~LIT[#{knownNatAddrs}]-1 downto 0 ) of ~TYP[#{datA}];+          shared variable mem : mem_type;+          signal ~GENSYM[a_dout][#{symDoutA}] : ~TYP[#{datA}];+          signal ~GENSYM[b_dout][#{symDoutB}] : ~TYP[#{datB}];+        begin -  (Signal domSlow a, Signal domFast a)-trueDualPortBlockRamModel labelA !_clkA enA weA addrA datA labelB !_clkB enB weB addrB datB =-  ( startA :- outA-  , startB :- outB )- where-  (outA, outB) =-    go-      (Seq.fromFunction (natToNum @nAddrs) initElement)-      tB -- ensure 'go' hits fast clock first for 1 cycle, then execute slow-         -- clock for 1 cycle, followed by the regular cadence of 'ceil(tA / tB)'-         -- cycles for the fast clock followed by 1 cycle of the slow clock-      (bundle (enA, weA, fromIntegral <$> addrA, datA))-      (bundle (enB, weB, fromIntegral <$> addrB, datB))-      startA startB+          -- Port A+          process(~ARG[#{clockA}])+          begin+              if(rising_edge(~ARG[#{clockA}])) then+                    if(~ARG[#{enaA}]) then+                      if(~ARG[#{wenaA}]) then+                          mem(~IF~SIZE[~TYP[#{addrA}]]~THENto_integer(~ARG[#{addrA}])~ELSE0~FI) := ~ARG[#{datA}];+                      end if;+                      ~SYM[#{symDoutA}] <= mem(~IF~SIZE[~TYP[#{addrA}]]~THENto_integer(~ARG[#{addrA}])~ELSE0~FI);+                  end if;+              end if;+          end process; -  tA = snatToNum @Int (clockPeriod @domSlow)-  tB = snatToNum @Int (clockPeriod @domFast)+          -- Port B+          process(~ARG[#{clockB}])+          begin+              if(rising_edge(~ARG[#{clockB}])) then+                  if(~ARG[#{enaB}]) then+                      if(~ARG[#{wenaB}]) then+                          mem(~IF~SIZE[~TYP[#{addrB}]]~THENto_integer(~ARG[#{addrB}])~ELSE0~FI) := ~ARG[#{datB}];+                      end if;+                      ~SYM[#{symDoutB}] <= mem(~IF~SIZE[~TYP[#{addrB}]]~THENto_integer(~ARG[#{addrB}])~ELSE0~FI);+                  end if;+              end if;+          end process; -  startA = deepErrorX $ "trueDualPortBlockRam: " <> labelA <> ": First value undefined"-  startB = deepErrorX $ "trueDualPortBlockRam: " <> labelB <> ": First value undefined"+          ~RESULT <= (~SYM[#{symDoutA}], ~SYM[#{symDoutB}]);+        end block;+        -- end trueDualPortBlockRam+|]) #-}+{-# ANN trueDualPortBlockRam# (+  let+    bbName = show 'trueDualPortBlockRam#+    _hasCallStack+     :< knownNatAddrs+     :< knownDomainA+     :< knownDomainB+     :< _nfdataX -  initElement :: Int -> a-  initElement n =-    deepErrorX ("Unknown initial element; position " <> show n)+     :< clockA+     :< enaA+     :< wenaA+     :< addrA+     :< datA -  unknownEnableAndAddr :: String -> String -> Int -> a-  unknownEnableAndAddr enaMsg addrMsg n =-    deepErrorX ("Write enable and data unknown; position " <> show n <>-                "\nWrite enable error message: " <> enaMsg <>-                "\nAddress error message: " <> addrMsg)+     :< clockB+     :< enaB+     :< wenaB+     :< addrB+     :< datB -  unknownAddr :: String -> Int -> a-  unknownAddr msg n =-    deepErrorX ("Write enabled, but address unknown; position " <> show n <>-                "\nAddress error message: " <> msg)+     :< _ = ((0 :: Int)...)+    symMem+     :< symDoutA+     :< symDoutB+     :< _ = ((0 :: Int)...)+  in InlineYamlPrimitive [SystemVerilog] [__i|+    BlackBox:+      name: "#{bbName}"+      kind: Declaration+      template: |-+        // trueDualPortBlockRam begin+        // Shared memory+        logic [~SIZE[~TYP[#{datA}]]-1:0] ~GENSYM[mem][#{symMem}] [~LIT[#{knownNatAddrs}]-1:0]; -  getConflict :: Bool -> Bool -> Bool -> Int -> Bool -> Int -> Maybe Conflict-  getConflict enA_ enB_ wenA addrA_ wenB addrB_ =-    -- If port A or port B is writing on (potentially!) the same address,-    -- there's a conflict-    if sameAddr then Just conflict else Nothing-   where-    wenAX = toMaybeX wenA-    wenBX = toMaybeX wenB+        ~SIGD[~GENSYM[a_dout][#{symDoutA}]][#{datA}];+        ~SIGD[~GENSYM[b_dout][#{symDoutB}]][#{datB}]; -    mergeX IsX b = b-    mergeX a IsX = a-    mergeX (IsDefined a) (IsDefined b) = IsDefined (a && b)+        // Port A+        always @(~IF~ACTIVEEDGE[Rising][#{knownDomainA}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockA}]) begin+            if(~ARG[#{enaA}]) begin+                ~SYM[#{symDoutA}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI];+                if(~ARG[#{wenaA}]) begin+                    ~SYM[#{symDoutA}] <= ~ARG[#{datA}];+                    ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI] <= ~ARG[#{datA}];+                end+            end+        end -    conflict = Conflict-      { cfRWA     = if enB_ then wenBX else IsDefined False-      , cfRWB     = if enA_ then wenAX else IsDefined False-      , cfWW      = if enA_ && enB_ then mergeX wenAX wenBX else IsDefined False-      , cfAddress = toMaybeX addrA_ }+        // Port B+        always @(~IF~ACTIVEEDGE[Rising][#{knownDomainB}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockB}]) begin+            if(~ARG[#{enaB}]) begin+                ~SYM[#{symDoutB}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI];+                if(~ARG[#{wenaB}]) begin+                    ~SYM[#{symDoutB}] <= ~ARG[#{datB}];+                    ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI] <= ~ARG[#{datB}];+                end+            end+        end -    sameAddr =-      case (isX addrA_, isX addrB_) of-        (Left _, _) -> True-        (_, Left _) -> True-        _           -> addrA_ == addrB_+        assign ~RESULT = {~SYM[#{symDoutA}], ~SYM[#{symDoutB}]};+        // end trueDualPortBlockRam+|]) #-}+{-# ANN trueDualPortBlockRam# (+  let+    bbName = show 'trueDualPortBlockRam#+    _hasCallStack+     :< knownNatAddrs+     :< knownDomainA+     :< knownDomainB+     :< _nfdataX -  writeRam :: Bool -> Int -> a -> Seq a -> (Maybe a, Seq a)-  writeRam enable addr dat mem-    | Left enaMsg <- enableUndefined-    , Left addrMsg <- addrUndefined-    = let msg = "Unknown enable and address" <>-                "\nWrite enable error message: " <> enaMsg <>-                "\nAddress error message: " <> addrMsg-       in ( Just (deepErrorX msg)-          , Seq.fromFunction (natToNum @nAddrs)-                             (unknownEnableAndAddr enaMsg addrMsg) )-    | Left enaMsg <- enableUndefined-    = let msg = "Write enable unknown; position" <> show addr <>-                "\nWrite enable error message: " <> enaMsg-       in writeRam True addr (deepErrorX msg) mem-    | enable-    , Left addrMsg <- addrUndefined-    = ( Just (deepErrorX "Unknown address")-      , Seq.fromFunction (natToNum @nAddrs) (unknownAddr addrMsg) )-    | enable-    = (Just dat, Seq.update addr dat mem)-    | otherwise-    = (Nothing, mem)-   where-    enableUndefined = isX enable-    addrUndefined = isX addr+     :< clockA+     :< enaA+     :< wenaA+     :< addrA+     :< datA -  go ::-    Seq a ->-    Int ->-    Signal domSlow (Bool, Bool, Int, a) ->-    Signal domFast (Bool, Bool, Int, a) ->-    a -> a ->-    (Signal domSlow a, Signal domFast a)-  go ram0 relativeTime as0 bs0 =-    case compare relativeTime 0 of-      LT -> goSlow-      EQ -> goBoth-      GT -> goFast-   where-    (enA_, weA_, addrA_, datA_) :- as1 = as0-    (enB_, weB_, addrB_, datB_) :- bs1 = bs0+     :< clockB+     :< enaB+     :< wenaB+     :< addrB+     :< datB -    goBoth prevA prevB = outA2 `seqX` outB2 `seqX` (outA2 :- as2, outB2 :- bs2)-     where-      conflict = getConflict enA_ enB_ weA_ addrA_ weB_ addrB_+     :< _ = ((0 :: Int)...) -      (datA1_,datB1_) = case conflict of-        Just Conflict{cfWW=IsDefined True} ->-          ( deepErrorX "trueDualPortBlockRam: conflicting write/write queries"-          , deepErrorX "trueDualPortBlockRam: conflicting write/write queries" )-        Just Conflict{cfWW=IsX} ->-          ( deepErrorX "trueDualPortBlockRam: conflicting write/write queries"-          , deepErrorX "trueDualPortBlockRam: conflicting write/write queries" )-        _ -> (datA_,datB_)+    symMem+     :< symDoutA+     :< symDoutB+     :< _ = ((0 :: Int)...)+  in InlineYamlPrimitive [Verilog] [__i|+    BlackBox:+      name: "#{bbName}"+      kind: Declaration+      template: |-+        // trueDualPortBlockRam begin+        // Shared memory+        reg [~SIZE[~TYP[#{datA}]]-1:0] ~GENSYM[mem][#{symMem}] [~LIT[#{knownNatAddrs}]-1:0]; -      (wroteA,ram1) = writeRam weA_ addrA_ datA1_ ram0-      (wroteB,ram2) = writeRam weB_ addrB_ datB1_ ram1+        reg ~SIGD[~GENSYM[a_dout][#{symDoutA}]][#{datA}];+        reg ~SIGD[~GENSYM[b_dout][#{symDoutB}]][#{datB}]; -      outA1 = case conflict of-        Just Conflict{cfRWA=IsDefined True} ->-          deepErrorX "trueDualPortBlockRam: conflicting read/write queries"-        Just Conflict{cfRWA=IsX} ->-          deepErrorX "trueDualPortBlockRam: conflicting read/write queries"-        _ -> fromMaybe (ram0 `Seq.index` addrA_) wroteA+        // Port A+        always @(~IF~ACTIVEEDGE[Rising][#{knownDomainA}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockA}]) begin+            if(~ARG[#{enaA}]) begin+                ~SYM[#{symDoutA}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI];+                if(~ARG[#{wenaA}]) begin+                    ~SYM[#{symDoutA}] <= ~ARG[#{datA}];+                    ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI] <= ~ARG[#{datA}];+                end+            end+        end -      outB1 = case conflict of-        Just Conflict{cfRWB=IsDefined True} ->-          deepErrorX "trueDualPortBlockRam: conflicting read/write queries"-        Just Conflict{cfRWB=IsX} ->-          deepErrorX "trueDualPortBlockRam: conflicting read/write queries"-        _ -> fromMaybe (ram0 `Seq.index` addrB_) wroteB+        // Port B+        always @(~IF~ACTIVEEDGE[Rising][#{knownDomainB}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockB}]) begin+            if(~ARG[#{enaB}]) begin+                ~SYM[#{symDoutB}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI];+                if(~ARG[#{wenaB}]) begin+                    ~SYM[#{symDoutB}] <= ~ARG[#{datB}];+                    ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI] <= ~ARG[#{datB}];+                end+            end+        end -      outA2 = if enA_ then outA1 else prevA-      outB2 = if enB_ then outB1 else prevB-      (as2,bs2) = go ram2 (relativeTime - tB + tA) as1 bs1 outA2 outB2+        assign ~RESULT = {~SYM[#{symDoutA}], ~SYM[#{symDoutB}]}; -    -- 1 iteration here, as this is the slow clock.-    goSlow _ prevB | enA_ = out0 `seqX` (out0 :- as2, bs2)-     where-      (wrote, !ram1) = writeRam weA_ addrA_ datA_ ram0-      out0 = fromMaybe (ram1 `Seq.index` addrA_) wrote-      (as2, bs2) = go ram1 (relativeTime + tA) as1 bs0 out0 prevB+        // end trueDualPortBlockRam+|]) #-} -    goSlow prevA prevB = (prevA :- as2, bs2)-      where-        (as2,bs2) = go ram0 (relativeTime + tA) as1 bs0 prevA prevB+-- | Primitive for 'trueDualPortBlockRam'+--+trueDualPortBlockRam#, trueDualPortBlockRamWrapper ::+  forall nAddrs domA domB a .+  ( HasCallStack+  , KnownNat nAddrs+  , KnownDomain domA+  , KnownDomain domB+  , NFDataX a+  ) => -    -- 1 or more iterations here, as this is the fast clock. First iteration-    -- happens here.-    goFast prevA _ | enB_ = out0 `seqX` (as2, out0 :- bs2)-     where-      (wrote, !ram1) = writeRam weB_ addrB_ datB_ ram0-      out0 = fromMaybe (ram1 `Seq.index` addrB_) wrote-      (as2, bs2) = go ram1 (relativeTime - tB) as0 bs1 prevA out0+  Clock domA ->+  -- | Enable+  Signal domA Bool ->+  -- | Write enable+  Signal domA Bool ->+  -- | Address+  Signal domA (Index nAddrs) ->+  -- | Write data+  Signal domA a -> -    goFast prevA prevB = (as2, prevB :- bs2)-     where-       (as2,bs2) = go ram0 (relativeTime - tB) as0 bs1 prevA prevB+  Clock domB ->+  -- | Enable+  Signal domB Bool ->+  -- | Write enable+  Signal domB Bool ->+  -- | Address+  Signal domB (Index nAddrs) ->+  -- | Write data+  Signal domB a ->++  (Signal domA a, Signal domB a)+trueDualPortBlockRam# clkA enA weA addrA datA clkB enB weB addrB datB =+  tdpbramModel+    TdpbramModelConfig+      { tdpIsActiveWriteEnable = id+      , tdpMergeWriteEnable = andX+      , tdpUpdateRam = updateRam }+    clkA enA addrA weA datA+    clkB enB addrB weB datB+ where+  updateRam :: Int -> MaybeX Bool -> a -> Seq a -> Seq a+  updateRam addr writeEnable dat mem =+    case writeEnable of+      IsDefined False -> mem+      IsDefined True -> Seq.update addr dat mem+      IsX msg -> Seq.update addr dat $ deepErrorX $+          "Write enable unknown; position" <> show addr <>+        "\nWrite enable error message: " <> msg
src/Clash/Explicit/BlockRam/Blob.hs view
@@ -18,6 +18,7 @@ compatible with all tools consuming the generated HDL. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeApplications #-}@@ -62,7 +63,7 @@ import Clash.Sized.Internal.BitVector (Bit(..), BitVector(..)) import Clash.Sized.Internal.Unsigned (Unsigned) import Clash.XException-  (maybeIsX, deepErrorX, defaultSeqX, fromJustX, XException (..), seqX)+  (maybeIsX, deepErrorX, defaultSeqX, fromJustX, NFDataX, XException (..), seqX)  -- $setup -- >>> :set -XTemplateHaskell@@ -89,6 +90,7 @@   :: forall dom addr m n    . ( KnownDomain dom      , Enum addr+     , NFDataX addr      )   => Clock dom   -- ^ 'Clock' to synchronize to@@ -104,7 +106,7 @@   -- ^ (write address @w@, value to write)   -> Signal dom (BitVector m)   -- ^ Value of the BRAM at address @r@ from the previous clock cycle-blockRamBlob = \clk gen content rd wrM ->+blockRamBlob = \clk gen content@MemBlob{} rd wrM ->   let en       = isJust <$> wrM       (wr,din) = unbundle (fromJustX <$> wrM)   in blockRamBlob# clk gen content (fromEnum <$> rd) en (fromEnum <$> wr) din@@ -231,7 +233,8 @@        in forM_ [0..(szI-1)] (\j -> unsafeWriteSTArray s j d)   {-# INLINE safeUpdate #-} {-# ANN blockRamBlob# hasBlackBox #-}-{-# NOINLINE blockRamBlob# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE blockRamBlob# #-}  -- | Create a 'MemBlob' binding from a list of values --@@ -276,7 +279,7 @@ -- x = 1 -- :} -- <BLANKLINE>--- <interactive>:...: error:+-- <interactive>:...: error:... --     packBVs: cannot convert don't care values. Please specify a mapping to a definite value. -- -- Note how we hinted to @clashi@ that our multi-line command was a list of@@ -314,7 +317,7 @@   runs = litE . stringPrimL $ L.unpack runsB   endsLen = litE . integerL . toInteger $ L.length endsB   ends = litE . stringPrimL $ L.unpack endsB-  Right (len, runsB, endsB) = packed+  (len, runsB, endsB) = either error id packed   packed = packBVs care es  -- | Create a 'MemBlob' from a list of values@@ -351,7 +354,7 @@ -- 0b1_0000_1000 -- >>> $(memBlobTH Nothing es) -- <BLANKLINE>--- <interactive>:...: error:+-- <interactive>:...: error:... --     • packBVs: cannot convert don't care values. Please specify a mapping to a definite value. --     • In the untyped splice: $(memBlobTH Nothing es) memBlobTH@@ -381,5 +384,5 @@   runs = litE . stringPrimL $ L.unpack runsB   endsLen = litE . integerL . toInteger $ L.length endsB   ends = litE . stringPrimL $ L.unpack endsB-  Right (len, runsB, endsB) = packed+  (len, runsB, endsB) = either error id packed   packed = packBVs care es
src/Clash/Explicit/BlockRam/File.hs view
@@ -81,6 +81,7 @@ -}  {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-}  {-# LANGUAGE Unsafe #-}@@ -126,7 +127,7 @@   (Clock(..), Signal (..), Enable, KnownDomain, fromEnable, (.&&.)) import Clash.Signal.Bundle   (unbundle) import Clash.Sized.Unsigned  (Unsigned)-import Clash.XException      (errorX, maybeIsX, seqX, fromJustX, XException (..))+import Clash.XException      (maybeIsX, seqX, fromJustX, NFDataX(..), XException (..))  -- start benchmark only -- import GHC.Arr (unsafeFreezeSTArray, unsafeThawSTArray)@@ -218,7 +219,7 @@ -- * See "Clash.Sized.Fixed#creatingdatafiles" for more ideas on how to create -- your own data files. blockRamFile-  :: (KnownDomain dom, KnownNat m, Enum addr, HasCallStack)+  :: (KnownDomain dom, KnownNat m, Enum addr, NFDataX addr, HasCallStack)   => Clock dom   -- ^ 'Clock' to synchronize to   -> Enable dom@@ -336,7 +337,7 @@   -- ^ Value to write (at address @w@)   -> Signal dom (BitVector m)   -- ^ Value of the BRAM at address @r@ from the previous clock cycle-blockRamFile# (Clock _) ena sz file = \rd wen waS wd -> runST $ do+blockRamFile# (Clock _ Nothing) ena sz file = \rd wen waS wd -> runST $ do   ramStart <- newArray_ (0,szI)   unsafeIOToST (withFile file ReadMode (\h ->     forM_ [0..(szI-1)] (\i -> do@@ -349,7 +350,7 @@   -- end benchmark only   go     ramStart-    (withFrozenCallStack (errorX "blockRamFile: intial value undefined"))+    (withFrozenCallStack (deepErrorX "blockRamFile: intial value undefined"))     (fromEnable ena)     rd     (fromEnable ena .&&. wen)@@ -403,18 +404,19 @@       unsafeReadSTArray s i     else pure $       withFrozenCallStack-        (errorX ("blockRamFile: read address " <> show i <>+        (deepErrorX ("blockRamFile: read address " <> show i <>                 " not in range [0.." <> show szI <> ")"))   {-# INLINE safeAt #-} -  safeUpdate :: HasCallStack => Int -> a -> STArray s Int a -> ST s ()+  safeUpdate :: HasCallStack => Int -> BitVector m+             -> STArray s Int (BitVector m) -> ST s ()   safeUpdate i a s =     if (0 <= i) && (i < szI) then       unsafeWriteSTArray s i a     else       let d = withFrozenCallStack-                (errorX ("blockRamFile: write address " <> show i <>-                        " not in range [0.." <> show szI <> ")"))+                (deepErrorX ("blockRamFile: write address " <> show i <>+                             " not in range [0.." <> show szI <> ")"))       in forM_ [0..(szI-1)] (\j -> unsafeWriteSTArray s j d)   {-# INLINE safeUpdate #-} @@ -423,10 +425,13 @@                 Just i  -> fromInteger i                 Nothing -> undefined#   parseBV' = fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt-{-# NOINLINE blockRamFile# #-}+blockRamFile# _ _ _ _ = error "blockRamFile#: dynamic clocks not supported"++-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE blockRamFile# #-} {-# ANN blockRamFile# hasBlackBox #-} --- | __NB:__ Not synthesizable+-- | __NB__: Not synthesizable initMem :: KnownNat n => FilePath -> IO [BitVector n] initMem = fmap (map parseBV . lines) . readFile   where@@ -434,4 +439,5 @@                   Just i  -> fromInteger i                   Nothing -> error ("Failed to parse: " ++ s)     parseBV' = fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt-{-# NOINLINE initMem #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE initMem #-}
src/Clash/Explicit/BlockRam/Internal.hs view
@@ -147,7 +147,9 @@ unpackNats 0 _ _ _ = [] unpackNats len width runBs endBs   | width < 8 = ends-  | otherwise = go (head ends) runL runBs (tail ends)+  | otherwise = case ends of+                  (e0:es) -> go e0 runL runBs es+                  _ -> error ("unpackNats failed for:" <> show (len,width,runBs,endBs))  where   (runL, endL) = width `divMod` 8   ends = if endL == 0 then@@ -155,10 +157,17 @@          else            unpackEnds endL len $ unpackW64s endBs -  go val 0    runBs0 ~(end0:ends0) = val : go end0 runL runBs0 ends0+  go :: Natural -> Int -> B.ByteString -> [Natural] -> [Natural]+  go val 0    runBs0 ends0+    = let (end0,end0rest) = case ends0 of+            [] -> error "unpackNats: unexpected end of bytestring"+            (x:xs) -> (x,xs)+       in val : go end0 runL runBs0 end0rest   go _   _    runBs0 _             | B.null runBs0 = []   go val runC runBs0 ends0-    = let Just (runB, runBs1) = B.uncons runBs0+    = let (runB, runBs1) = case B.uncons runBs0 of+             Nothing -> error "unpackNats: unexpected end of bytestring"+             Just xs -> xs           val0 = val * 256 + fromIntegral runB       in go val0 (runC - 1) runBs1 ends0 @@ -170,7 +179,9 @@   go :: Int -> Word64 -> B.ByteString -> [Word64]   go 8 _   endBs | B.null endBs = []   go 0 val endBs = val : go 8 0 endBs-  go n val endBs = let Just (endB, endBs0) = B.uncons endBs+  go n val endBs = let (endB, endBs0) = case B.uncons endBs of+                          Nothing -> error "unpackW64s: unexpeded end of bytestring"+                          Just xs -> xs                        val0 = val * 256 + fromIntegral endB                    in go (n - 1) val0 endBs0 
+ src/Clash/Explicit/BlockRam/Model.hs view
@@ -0,0 +1,316 @@+{-|+Copyright  :  (C) 2023, QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>++Configurable model for true dual-port block RAM+-}++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RecordWildCards #-}++module Clash.Explicit.BlockRam.Model where++#if !MIN_VERSION_base(4,18,0)+import Control.Applicative (liftA2)+#endif+import Control.Exception (throw)+import Data.Sequence (Seq)+import GHC.Stack (HasCallStack)+import GHC.TypeNats (KnownNat)++import Clash.Promoted.Nat (SNat(..), natToNum)+import Clash.Signal.Bundle (Bundle(bundle))+import Clash.Signal.Internal+  (KnownDomain(..), Clock (..), Signal (..), ClockAB (..), clockTicks)+import Clash.Sized.Index (Index)+import Clash.XException (XException(..), NFDataX(..), seqX)+import Clash.XException.MaybeX (MaybeX(..), toMaybeX, andX)++import qualified Clash.XException.MaybeX as MaybeX++import qualified Data.Sequence as Seq++-- | Helper used in 'getConflict'+data Conflict = Conflict+  { cfRWA :: !(MaybeX Bool) -- ^ Read/Write conflict for output A+  , cfRWB :: !(MaybeX Bool) -- ^ Read/Write conflict for output B+  , cfWW  :: !(MaybeX Bool) -- ^ Write/Write conflict+  } deriving (Show)++-- | Determines whether there was a write-write or read-write conflict. A conflict+-- occurs when two ports tried to (potentially, in case of undefined values)+-- access the same address and one or both tried to write to it. See documentation+-- of 'Conflict' for more information.+getConflict ::+  -- | Port A: enable, write enable, address+  (MaybeX Bool, MaybeX Bool, MaybeX Int) ->+  -- | Port B: enable, write enable, address+  (MaybeX Bool, MaybeX Bool, MaybeX Int) ->+  -- | 'Just' if there is a (potential) write conflict, otherwise 'Nothing'+  Maybe Conflict+getConflict (enA, wenA, addrA) (enB, wenB, addrB)+  | IsDefined False <- sameAddrX = Nothing+  | otherwise                    = Just conflict+ where+  sameAddrX = liftA2 (==) addrA addrB++  conflict = Conflict+    { cfRWA = enA `andX` (enB `andX` wenB)+    , cfRWB = enB `andX` (enA `andX` wenA)+    , cfWW  = (enA `andX` enB) `andX` (wenA `andX` wenB)+    }++-- | Step through a cycle of a TDP block RAM where only one clock is active. Like+-- 'accessRam', it accounts for 'Clash.XException.XException' in all values+-- supplied by the user of the block RAM.+cycleOne ::+  forall nAddrs a writeEnable .+  ( HasCallStack+  , NFDataX a+  ) =>+  SNat nAddrs ->+  TdpbramModelConfig writeEnable a ->+  -- | Previous value+  a ->+  -- | Memory+  Seq a ->+  -- | Port: enable, address, write enable, write data+  (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) ->+  -- | Updated memory, output value+  (Seq a, a)+cycleOne SNat TdpbramModelConfig{..} prev ram0 = \case+  -- RAM is disabled, so we do nothing+  (IsDefined False, _, _, _) ->+    (ram0, prev)++  -- RAM is (potentially) enabled, so we run write RAM logic+  (ena, addr, byteEna0, dat) ->+    let+      byteEna1 = tdpMergeWriteEnable ena byteEna0+      (out0, !ram1) =+        accessRam (SNat @nAddrs) tdpIsActiveWriteEnable tdpUpdateRam addr byteEna1 dat ram0++      out1 = MaybeX.maybeX (throw . XException) (const out0) ena+    in+      (ram1, out1)++-- | Step through a cycle of a TDP block RAM where the clock edges of port A and+-- port B coincided. Like 'accessRam', it accounts for 'Clash.XException.XException'+-- in all values supplied by the user of the block RAM.+cycleBoth ::+  forall nAddrs a writeEnable.+  ( NFDataX a+  , HasCallStack+  ) =>+  SNat nAddrs ->+  TdpbramModelConfig writeEnable a ->+  -- | Previous value for port A+  a ->+  -- | Previous value for port B+  a ->+  -- | Memory+  Seq a ->+  -- | Port A: enable, address, write enable, write data+  (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) ->+  -- | Port B: enable, address, write enable, write data+  (MaybeX Bool, MaybeX Int, MaybeX writeEnable, a) ->+  -- | Updated memory, output value A, output value B+  (Seq a, a, a)+cycleBoth+  SNat TdpbramModelConfig{..} prevA prevB ram0+  (enAx, addrAx, byteEnaAx0, datA)+  (enBx, addrBx, byteEnaBx0, datB) = (ram2, outA2, outB2)+ where+  conflict =+    getConflict+      (enAx, tdpIsActiveWriteEnable byteEnaAx1, addrAx)+      (enBx, tdpIsActiveWriteEnable byteEnaBx1, addrBx)++  writeWriteError = deepErrorX "conflicting write/write queries"+  readWriteError = deepErrorX "conflicting read/write queries"++  byteEnaAx1 = tdpMergeWriteEnable enAx byteEnaAx0+  byteEnaBx1 = tdpMergeWriteEnable enBx byteEnaBx0++  (datA1, datB1) = case conflict of+    Just Conflict{cfWW=IsDefined True} -> (writeWriteError, writeWriteError)+    Just Conflict{cfWW=IsX _} -> (writeWriteError, writeWriteError)+    _ -> (datA, datB)++  (outA0, ram1) =+    accessRam (SNat @nAddrs) tdpIsActiveWriteEnable tdpUpdateRam addrAx byteEnaAx1 datA1 ram0+  (outB0, ram2) =+    accessRam (SNat @nAddrs) tdpIsActiveWriteEnable tdpUpdateRam addrBx byteEnaBx1 datB1 ram1++  outA1 = case conflict of+    Just Conflict{cfRWA=IsDefined True} -> readWriteError+    Just Conflict{cfRWA=IsX _} -> readWriteError+    _ -> outA0++  outB1 = case conflict of+    Just Conflict{cfRWB=IsDefined True} -> readWriteError+    Just Conflict{cfRWB=IsX _} -> readWriteError+    _ -> outB0++  outA2 = if MaybeX.fromMaybeX enAx then outA1 else prevA+  outB2 = if MaybeX.fromMaybeX enBx then outB1 else prevB++-- | Access a RAM and account for undefined values in the address, write enable,+-- and data to write. Return read after write value.+accessRam ::+  forall nAddrs a writeEnable .+  ( NFDataX a+  , HasCallStack ) =>+  SNat nAddrs ->+  -- | Determine whether a write enable is active+  (MaybeX writeEnable -> MaybeX Bool) ->+  -- | Update memory with a defined address+  (Int -> MaybeX writeEnable -> a -> Seq a -> Seq a) ->+  -- | Address+  MaybeX Int ->+  -- | Byte enable+  MaybeX writeEnable ->+  -- | Data to write+  a ->+  -- | Memory to write to+  Seq a ->+  -- | (Read after write value, new memory)+  (a, Seq a)+accessRam SNat tdpIsActiveWriteEnable updateMem addrX byteEnableX dat mem0+  -- Read (do nothing)+  | IsDefined False <- tdpIsActiveWriteEnable byteEnableX+  = (mem0 `Seq.index` MaybeX.fromMaybeX addrX, mem0)++  -- Undefined address and write enable or (partially) unknown+  | IsX addrMsg <- addrX+  = ( deepErrorX $ "Unknown address" <> "\nAddress error message: " <> addrMsg+    , Seq.fromFunction (natToNum @nAddrs) (unknownAddr addrMsg) )++  -- Write with defined address+  | IsDefined addr <- addrX+  , mem1 <- updateMem addr byteEnableX dat mem0+  = (mem1 `Seq.index` addr, mem1)+ where+  unknownAddr :: String -> Int -> a+  unknownAddr msg n =+    deepErrorX ("Write enabled or undefined, but address unknown; position " <> show n <>+                "\nAddress error message: " <> msg)++data TdpbramModelConfig writeEnable a = TdpbramModelConfig+  { tdpIsActiveWriteEnable :: MaybeX writeEnable -> MaybeX Bool+  -- ^ Determine whether a write enable is active++  , tdpMergeWriteEnable :: MaybeX Bool -> MaybeX writeEnable -> MaybeX writeEnable+  -- ^ Merge global enable with write enable++  , tdpUpdateRam :: Int -> MaybeX writeEnable -> a -> Seq a -> Seq a+  -- ^ Update memory with a defined address+  }++-- | Haskell model for a true dual-port block RAM which is polymorphic in its+-- write enables+--+tdpbramModel ::+  forall nAddrs domA domB a writeEnable .+  ( HasCallStack+  , KnownNat nAddrs+  , KnownDomain domA+  , KnownDomain domB+  , NFDataX a+  ) =>+  TdpbramModelConfig writeEnable a ->++  Clock domA ->+  -- | Enable+  Signal domA Bool ->+  -- | Address+  Signal domA (Index nAddrs) ->+  -- | Write enable+  Signal domA writeEnable ->+  -- | Write data+  Signal domA a ->++  Clock domB ->+  -- | Enable+  Signal domB Bool ->+  -- | Address+  Signal domB (Index nAddrs) ->+  -- | Write byte enable+  Signal domB writeEnable ->+  -- | Write data+  Signal domB a ->++  (Signal domA a, Signal domB a)+tdpbramModel+  config+  clkA enA addrA byteEnaA datA+  clkB enB addrB byteEnaB datB =+  ( startA :- outA+  , startB :- outB )+ where+  (outA, outB) =+    go+      (Seq.fromFunction (natToNum @nAddrs) initElement)+      (clockTicks clkA clkB)+      (bundle (enA, byteEnaA, fromIntegral <$> addrA, datA))+      (bundle (enB, byteEnaB, fromIntegral <$> addrB, datB))+      startA startB++  startA = deepErrorX $ "Port A: First value undefined"+  startB = deepErrorX $ "Port B: First value undefined"++  initElement :: Int -> a+  initElement n =+    deepErrorX ("Unknown initial element; position " <> show n)++  go ::+    Seq a ->+    [ClockAB] ->+    Signal domA (Bool, writeEnable, Int, a) ->+    Signal domB (Bool, writeEnable, Int, a) ->+    a -> a ->+    (Signal domA a, Signal domB a)+  go _ [] _ _ =+    error "tdpbramModel#.go: `ticks` should have been an infinite list"+  go ram0 (tick:ticks) as0 bs0 =+    case tick of+      ClockA -> goA+      ClockB -> goB+      ClockAB -> goBoth+   where+    (  toMaybeX -> enAx+     , toMaybeX -> byteEnaAx+     , toMaybeX -> addrAx+     , datA0+     ) :- as1 = as0++    (  toMaybeX -> enBx+     , toMaybeX -> byteEnaBx+     , toMaybeX -> addrBx+     , datB0+     ) :- bs1 = bs0++    portA = (enAx, addrAx, byteEnaAx, datA0)+    portB = (enBx, addrBx, byteEnaBx, datB0)++    goBoth prevA prevB = outA1 `seqX` outB1 `seqX` (outA1 :- as2, outB1 :- bs2)+     where+      (ram1, outA1, outB1) =+        cycleBoth+          (SNat @nAddrs) config+          prevA prevB ram0 portA portB+      (as2, bs2) = go ram1 ticks as1 bs1 outA1 outB1++    goA prevA prevB = out `seqX` (out :- as2, bs2)+     where+      (ram1, out) = cycleOne (SNat @nAddrs) config prevA ram0 portA+      (as2, bs2) = go ram1 ticks as1 bs0 out prevB++    goB prevA prevB = out `seqX` (as2, out :- bs2)+     where+      (ram1, out) = cycleOne (SNat @nAddrs) config prevB ram0 portB+      (as2, bs2) = go ram1 ticks as0 bs1 prevA out
src/Clash/Explicit/DDR.hs view
@@ -92,7 +92,7 @@   -> a   -> Signal fast a   -> Signal slow (a,a)-ddrIn# (Clock _) (unsafeToHighPolarity -> hRst) (fromEnable -> ena) i0 i1 i2 =+ddrIn# (Clock _ Nothing) (unsafeToActiveHigh -> hRst) (fromEnable -> ena) i0 i1 i2 =   case resetKind @fast of     SAsynchronous ->       goAsync@@ -133,7 +133,10 @@            :- (as `seq` if e then goAsync (o2',o3',o4') rs es xs                              else goAsync (o0',o1',o2') rs es xs) -{-# NOINLINE ddrIn# #-}+ddrIn# _ _ _ _ _ _ =+  error "ddrIn#: dynamic clocks not supported"+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ddrIn# #-} {-# ANN ddrIn# hasBlackBox #-}  -- | DDR output primitive@@ -183,5 +186,6 @@     xs' = register# clk rst en (errorX "ddrOut: unreachable error") i0 xs     ys' = register# clk rst en (deepErrorX "ddrOut: initial value undefined") i0 ys     zipSig (a :- as) (b :- bs) = a :- b :- zipSig as bs-{-# NOINLINE ddrOut# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ddrOut# #-} {-# ANN ddrOut# hasBlackBox #-}
src/Clash/Explicit/Mealy.hs view
@@ -2,6 +2,7 @@   Copyright  :  (C) 2013-2016, University of Twente,                     2017     , Google Inc.                     2019     , Myrtle Software Ltd+                    2023     , Alex Mason   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -19,7 +20,9 @@ module Clash.Explicit.Mealy   ( -- * Mealy machines with explicit clock and reset ports     mealy+  , mealyS   , mealyB+  , mealySB   ) where @@ -27,17 +30,59 @@   (KnownDomain, Bundle (..), Clock, Reset, Signal, Enable, register) import           Clash.XException      (NFDataX) +import           Control.Monad.State.Strict+  (State, runState)+ {- $setup->>> :set -XDataKinds -XTypeApplications->>> import Clash.Explicit.Prelude+>>> :set -XDataKinds -XTypeApplications -XDeriveGeneric -XDeriveAnyClass+>>> import Clash.Explicit.Prelude as C+>>> import Clash.Explicit.Mealy (mealyS) >>> import qualified Data.List as L+>>> import Control.Lens (Lens', (%=), (-=), uses, use)+>>> import Control.Monad.State.Strict (State) >>> :{ let macT s (x,y) = (s',s)       where         s' = x * y + s :} ->>> let mac clk rst en = mealy clk rst en macT 0+>>> mac clk rst en = mealy clk rst en macT 0++>>> :{+data DelayState = DelayState { _history :: Vec 4 Int , _untilValid :: Index 4 } deriving (Generic,NFDataX)+:}++>>> :{+history :: Lens' DelayState (Vec 4 Int)+history f = \(DelayState d u) -> (`DelayState` u) <$> f d+:}++>>> :{+untilValid :: Lens' DelayState (Index 4)+untilValid f = \(DelayState d u) -> DelayState d <$> f u+:}++>>> :{+delayS :: Int -> State DelayState (Maybe Int)+delayS n = do+  history   %= (n +>>)+  remaining <- use untilValid+  if remaining > 0+  then do+     untilValid -= 1+     return Nothing+   else do+     out <- uses history C.last+     return (Just out)+:}++>>> let initialDelayState = DelayState (C.repeat 0) maxBound++>>> :{+delayTop :: Clock System -> Reset System -> Enable System -> Signal System Int -> Signal System (Maybe Int)+delayTop clk rst en = mealyS clk rst en delayS initialDelayState+:}+ -}  -- | Create a synchronous function from a combinational function describing@@ -106,6 +151,64 @@         in  o {-# INLINABLE mealy #-} +-- | Create a synchronous function from a combinational function describing+-- a mealy machine using the state monad. This can be particularly useful+-- when combined with lenses or optics to replicate imperative algorithms.+--+-- @+-- data DelayState = DelayState+--   { _history    :: Vec 4 Int+--   , _untilValid :: Index 4+--   }+--   deriving (Generic, NFDataX)+-- makeLenses ''DelayState+--+-- initialDelayState = DelayState (repeat 0) maxBound+--+-- delayS :: Int -> State DelayState (Maybe Int)+-- delayS n = do+--   history   %= (n +>>)+--   remaining <- use untilValid+--   if remaining > 0+--   then do+--      untilValid -= 1+--      return Nothing+--    else do+--      out <- uses history last+--      return (Just out)+--+-- delayTop ::'KnownDomain' dom+--   => 'Clock' dom+--   -> 'Reset' dom+--   -> 'Enable' dom+--   -> ('Signal' dom Int -> 'Signal' dom (Maybe Int))+-- delayTop clk rst en = 'mealyS' clk rst en delayS initialDelayState+-- @+--+-- >>> L.take 7 $ simulate (delayTop systemClockGen systemResetGen enableGen) [-100,1,2,3,4,5,6,7,8]+-- [Nothing,Nothing,Nothing,Nothing,Just 1,Just 2,Just 3]+--+mealyS+  :: ( KnownDomain dom+     , NFDataX s )+  => Clock dom+  -- ^ 'Clock' to synchronize to+  -> Reset dom+  -> Enable dom+  -- ^ Global enable+  -> (i -> State s o)+  -- ^ Transfer function in mealy machine handling inputs using @Control.Monad.Strict.State s@.+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealyS clk rst en f iS =+  \i -> let (o,s') = unbundle $ (runState . f) <$> i <*> s+            s      = register clk rst en iS s'+        in o+{-# INLINABLE mealyS #-}+ -- | A version of 'mealy' that does automatic 'Bundle'ing -- -- Given a function @f@ of type:@@ -149,3 +252,23 @@  -- of the mealy machine mealyB clk rst en f iS i = unbundle (mealy clk rst en f iS (bundle i)) {-# INLINE mealyB #-}+++-- | A version of 'mealyS' that does automatic 'Bundle'ing, see 'mealyB' for details.+mealySB+  :: ( KnownDomain dom+     , NFDataX s+     , Bundle i+     , Bundle o )+  => Clock dom+  -> Reset dom+  -> Enable dom+  -> (i -> State s o)+  -- ^ Transfer function in mealy machine handling inputs using @Control.Monad.Strict.State s@.+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)+ -- ^ Synchronous sequential function with input and output matching that+ -- of the mealy machine+mealySB clk rst en f iS i = unbundle (mealyS clk rst en f iS (bundle i))+{-# INLINE mealySB #-}
src/Clash/Explicit/Prelude.hs view
@@ -2,7 +2,8 @@ Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.                   2019     , Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V.,+                  2022     , Myrtle.ai, License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -10,6 +11,7 @@ defined in "Clash.Prelude". -} +{-# LANGUAGE CPP #-} {-# LANGUAGE NoImplicitPrelude #-}  {-# LANGUAGE Unsafe #-}@@ -20,7 +22,9 @@ module Clash.Explicit.Prelude   ( -- * Creating synchronous sequential circuits     mealy+  , mealyS   , mealyB+  , mealySB   , moore   , mooreB   , registerB@@ -147,6 +151,9 @@ import Data.Bits import Data.Default.Class import GHC.TypeLits+#if MIN_VERSION_base(4,18,0)+  hiding (SNat, SSymbol, fromSNat)+#endif import GHC.TypeLits.Extra import Language.Haskell.TH.Syntax  (Lift(..)) import Clash.HaskellPrelude
src/Clash/Explicit/Prelude/Safe.hs view
@@ -12,6 +12,7 @@ defined in "Clash.Prelude". -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoGeneralizedNewtypeDeriving #-} {-# LANGUAGE NoImplicitPrelude #-}@@ -116,6 +117,9 @@ import Data.Bits import GHC.Generics (Generic, Generic1) import GHC.TypeLits+#if MIN_VERSION_base(4,18,0)+  hiding (SNat, SSymbol, fromSNat)+#endif import GHC.TypeLits.Extra import Clash.HaskellPrelude import qualified Prelude
src/Clash/Explicit/RAM.hs view
@@ -38,11 +38,12 @@ import Clash.Annotations.Primitive (hasBlackBox) import Clash.Explicit.Signal (unbundle, KnownDomain, andEnable) import Clash.Promoted.Nat    (SNat (..), snatToNum, pow2SNat)-import Clash.Signal.Internal (Clock (..), Signal (..), Enable, fromEnable)+import Clash.Signal.Internal+  (Clock (..), ClockAB (..), Signal (..), Enable, fromEnable, clockTicks) import Clash.Signal.Internal.Ambiguous (clockPeriod) import Clash.Sized.Unsigned  (Unsigned) import Clash.XException-  (defaultSeqX, errorX, fromJustX, maybeIsX, NFDataX)+  (defaultSeqX, deepErrorX, fromJustX, maybeIsX, NFDataX)  -- | Create a RAM with space for 2^@n@ elements --@@ -89,6 +90,7 @@ -- RAM. asyncRam   :: ( Enum addr+     , NFDataX addr      , HasCallStack      , KnownDomain wdom      , KnownDomain rdom@@ -141,15 +143,15 @@   -- ^ Value to write (at address @w@)   -> Signal rdom a   -- ^ Value of the RAM at address @r@-asyncRam# !_ !_ en sz rd we wr din = dout+asyncRam# wClk rClk en sz rd we wr din = dout   where     ramI = Seq.replicate               szI-              (withFrozenCallStack (errorX "asyncRam: initial value undefined"))+              (withFrozenCallStack (deepErrorX "asyncRam: initial value undefined"))     en0 = fromEnable (andEnable en we)     dout = if rPeriod == wPeriod            then goSingle ramI rd en0 wr din-           else go 0 ramI rd en0 wr din+           else go (clockTicks wClk rClk) ramI rd en0 wr din     rPeriod = snatToNum (clockPeriod @rdom) :: Int     wPeriod = snatToNum (clockPeriod @wdom) :: Int     szI = snatToNum sz :: Int@@ -161,23 +163,19 @@           o    = ram `safeAt` r       in  o :- (o `defaultSeqX` wt `seq` dt `seq` goSingle ram0 rs es ws ds) -    -- Given-    --   tR = absolute time of next active edge of read clock-    --   tW = absolute time of next active edge of write clock-    -- relTime is defined as relTime = tW - tR-    ---    -- Put differently, relative time 0 points at the next active edge of the-    -- read clock, and relTime points at the next active edge of the write-    -- clock.-    go :: Int -> Seq.Seq a -> Signal rdom Int -> Signal wdom Bool+    go :: [ClockAB] -> Seq.Seq a -> Signal rdom Int -> Signal wdom Bool        -> Signal wdom Int -> Signal wdom a -> Signal rdom a-    go   relTime !ram rt@(~(r :- rs)) et@(~(e :- es)) wt@(~(w :- ws))-         dt@(~(d :- ds))-      | relTime < 0 = let ram0 = upd ram e w d-                      in wt `seq` dt `seq`-                         go (relTime + wPeriod) ram0 rt es ws ds-      | otherwise   = let o = ram `safeAt` r-                      in o :- (o `defaultSeqX` go (relTime - rPeriod) ram rs et wt dt)+    go [] _ _ _ _ _ = error "asyncRam#.go: `ticks` should have been an infinite list"+    go (tick:ticks) !ram rt@(~(r :- rs)) et@(~(e :- es)) wt@(~(w :- ws)) dt@(~(d :- ds)) =+      case tick of+        ClockA  ->+          let ram0 = upd ram e w d+          in  wt `seq` dt `seq` go ticks ram0 rt es ws ds+        ClockB  ->+          let o = ram `safeAt` r+          in  o :- (o `defaultSeqX` go ticks ram rs et wt dt)+        ClockAB ->+          go (ClockB:ClockA:ticks) ram rt et wt dt      upd ram we0 waddr d = case maybeIsX we0 of       Nothing -> case maybeIsX waddr of@@ -200,7 +198,7 @@         Seq.index s i       else         withFrozenCallStack-          (errorX ("asyncRam: read address " ++ show i +++          (deepErrorX ("asyncRam: read address " ++ show i ++                    " not in range [0.." ++ show szI ++ ")"))     {-# INLINE safeAt #-} @@ -210,9 +208,10 @@         Seq.update i a s       else         let d = withFrozenCallStack-                  (errorX ("asyncRam: write address " ++ show i +++                  (deepErrorX ("asyncRam: write address " ++ show i ++                            " not in range [0.." ++ show szI ++ ")"))         in d <$ s     {-# INLINE safeUpdate #-}-{-# NOINLINE asyncRam# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE asyncRam# #-} {-# ANN asyncRam# hasBlackBox #-}
src/Clash/Explicit/ROM.hs view
@@ -10,6 +10,7 @@ -}  {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} @@ -139,5 +140,6 @@         (deepErrorX ("rom: address " ++ show i ++                      " not in range [0.." ++ show szI ++ ")"))   {-# INLINE safeAt #-}-{-# NOINLINE rom# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rom# #-} {-# ANN rom# hasBlackBox #-}
src/Clash/Explicit/ROM/Blob.hs view
@@ -19,6 +19,7 @@ -}  {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE Trustworthy #-}  {-# OPTIONS_HADDOCK show-extensions #-}@@ -149,5 +150,6 @@         (deepErrorX ("romBlob: address " ++ show i ++                      " not in range [0.." ++ show szI ++ ")"))   {-# INLINE safeAt #-}-{-# NOINLINE romBlob# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE romBlob# #-} {-# ANN romBlob# hasBlackBox #-}
src/Clash/Explicit/ROM/File.hs view
@@ -77,6 +77,7 @@ @ -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}  {-# LANGUAGE Unsafe #-}@@ -225,5 +226,6 @@       deepErrorX ("romFile: address " ++ show i ++                   " not in range [0.." ++ show szI ++ ")")   {-# INLINE safeAt #-}-{-# NOINLINE romFile# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE romFile# #-} {-# ANN romFile# hasBlackBox #-}
src/Clash/Explicit/Reset.hs view
@@ -1,13 +1,17 @@ {-|-Copyright  :  (C) 2020-2021, QBayLogic B.V.+Copyright  :  (C) 2020-2023, QBayLogic B.V.,+                  2022-2023, Google LLC License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  Utilities to deal with resets. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TypeFamilies #-}  {-# OPTIONS_GHC -fplugin=GHC.TypeLits.Normalise #-}@@ -17,10 +21,15 @@   ( -- Defined in this module     resetSynchronizer   , resetGlitchFilter+  , resetGlitchFilterWithReset+  , unsafeResetGlitchFilter   , holdReset   , convertReset+  , noReset+  , andReset, unsafeAndReset+  , orReset, unsafeOrReset -    -- Reexports+    -- Re-exports   , Reset   , resetGen   , resetGenN@@ -28,33 +37,79 @@   , systemResetGen   , unsafeToReset   , unsafeFromReset-  , unsafeToHighPolarity-  , unsafeToLowPolarity+  , unsafeToActiveHigh+  , unsafeToActiveLow+  , unsafeFromActiveHigh+  , unsafeFromActiveLow++  -- * Deprecated   , unsafeFromHighPolarity   , unsafeFromLowPolarity+  , unsafeToHighPolarity+  , unsafeToLowPolarity   ) where -import           Data.Bits (testBit, shiftL, (.|.)) import           Data.Type.Equality ((:~:)(Refl))-import           GHC.Generics (Generic) -import           Clash.Class.BitPack (pack)-import           Clash.Class.Resize (resize) import           Clash.Class.Num (satSucc, SaturationMode(SatBound))-import           Clash.Explicit.Mealy import           Clash.Explicit.Signal+import           Clash.Explicit.Synchronizer (dualFlipFlopSynchronizer) import           Clash.Promoted.Nat import           Clash.Signal.Internal-import           Clash.Sized.BitVector (BitVector) import           Clash.Sized.Index (Index)-import           Clash.XException (NFDataX, ShowX) -import           GHC.TypeLits (type (+), KnownNat)+import           GHC.Stack (HasCallStack)+import           GHC.TypeLits (type (+), type (<=))  {- $setup >>> import Clash.Explicit.Prelude -} +-- | A reset that is never asserted+noReset :: KnownDomain dom => Reset dom+noReset = unsafeFromActiveHigh (pure False)++-- | Output reset will be asserted when either one of the input resets is+-- asserted+orReset ::+  forall dom .+  HasSynchronousReset dom =>+  Reset dom ->+  Reset dom ->+  Reset dom+orReset = unsafeOrReset++-- | Output reset will be asserted when either one of the input resets is+-- asserted. This function is considered unsafe because it can be used on+-- domains with components with asynchronous resets, where use of this function+-- can introduce glitches triggering a reset.+unsafeOrReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom+unsafeOrReset (unsafeFromReset -> rst0) (unsafeFromReset -> rst1) =+  unsafeToReset $+    case resetPolarity @dom of+      SActiveHigh -> rst0 .||. rst1+      SActiveLow  -> rst0 .&&. rst1++-- | Output reset will be asserted when both input resets are asserted+andReset ::+  forall dom .+  HasSynchronousReset dom =>+  Reset dom ->+  Reset dom ->+  Reset dom+andReset = unsafeAndReset++-- | Output reset will be asserted when both input resets are asserted. This+-- function is considered unsafe because it can be used on domains with+-- components with asynchronous resets, where use of this function can introduce+-- glitches triggering a reset.+unsafeAndReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom+unsafeAndReset (unsafeFromReset -> rst0) (unsafeFromReset -> rst1) =+  unsafeToReset $+    case resetPolarity @dom of+      SActiveHigh -> rst0 .&&. rst1+      SActiveLow  -> rst0 .||. rst1+ -- | The resetSynchronizer will synchronize an incoming reset according to -- whether the domain is synchronous or asynchronous. --@@ -103,9 +158,14 @@ -- === __Example 2__ -- Similar to /Example 1/ this circuit detects a rising bit (i.e., a transition -- from 0 to 1) in a given argument. It takes a clock that is not stable yet and--- a reset singal that is not synchronized to any other signals. It stabalizes+-- a reset signal that is not synchronized to any other signals. It stabilizes -- the clock and then synchronizes the reset signal. --+--+-- Note that the function 'Clash.Intel.ClockGen.altpllSync' provides this+-- functionality in a convenient form, obviating the need for+-- @resetSynchronizer@ for this use case.+-- -- @ -- topEntity --   :: Clock  System@@ -113,8 +173,8 @@ --   -> Signal System Bit --   -> Signal System (BitVector 8) -- topEntity clk rst key1 =---     let  (pllOut,pllStable) = altpll (SSymbol @"altpll50") clk rst---          rstSync            = 'resetSynchronizer' pllOut (unsafeToHighPolarity pllStable)+--     let  (pllOut,pllStable) = unsafeAltpll clk rst+--          rstSync            = 'resetSynchronizer' pllOut (unsafeFromActiveLow pllStable) --     in   exposeClockResetEnable leds pllOut rstSync enableGen --   where --     key1R  = isRising 1 key1@@ -174,54 +234,168 @@                          $ delay clk enableGen isActiveHigh                          $ delay clk enableGen isActiveHigh                          $ unsafeFromReset rst-{-# NOINLINE resetSynchronizer #-} -- Give reset synchronizer its own HDL file -data GlitchFilterState = Idle | InReset-  deriving (Generic, NFDataX, Show, ShowX)- -- | Filter glitches from reset signals by only triggering a reset after it has--- been asserted for /glitchlessPeriod/ cycles. It will then stay asserted for--- as long as the given reset was asserted consecutively.+-- been asserted for /glitchlessPeriod/ cycles. Similarly, it will stay+-- asserted until a /glitchlessPeriod/ number of deasserted cycles have been+-- observed. ----- If synthesized on a domain with initial values, 'resetGlitchFilter' will--- output an asserted reset for /glitchlessPeriod/ cycles (plus any cycles added--- by the given reset). If initial values can't be used, it will only output--- defined reset values after /glitchlessPeriod/ cycles.+-- This circuit can only be used on platforms supporting initial values. This+-- restriction can be worked around by using 'unsafeResetGlitchFilter' but this+-- is not recommended. --+-- On platforms without initial values, you should instead use+-- 'resetGlitchFilterWithReset' with an additional power-on reset, or+-- 'holdReset' if filtering is only needed on deassertion.+--+-- At power-on, the reset will be asserted. If the filtered reset input remains+-- unasserted, the output reset will deassert after /glitchlessPeriod/ clock+-- cycles.+--+-- If @resetGlitchFilter@ is used in a domain with asynchronous resets+-- ('Asynchronous'), @resetGlitchFilter@ will first synchronize the reset input+-- with 'dualFlipFlopSynchronizer'.+-- -- === __Example 1__--- >>> let sampleResetN n = sampleN n . unsafeToHighPolarity--- >>> let resetFromList = unsafeFromHighPolarity . fromList--- >>> let rst = resetFromList [True, True, False, False, True, False, False, True, True, False, True]--- >>> sampleResetN 12 (resetGlitchFilter d2 systemClockGen rst)--- [True,True,True,True,False,False,False,False,False,True,True,False]+-- >>> let sampleResetN n = sampleN n . unsafeToActiveHigh+-- >>> let resetFromList = unsafeFromActiveHigh . fromList+-- >>> let rst = resetFromList [True, True, False, False, True, False, False, True, True, False, True, True]+-- >>> sampleResetN 12 (resetGlitchFilter d2 (clockGen @XilinxSystem) rst)+-- [True,True,True,True,False,False,False,False,False,True,True,True] resetGlitchFilter-  :: forall dom glitchlessPeriod n-   . ( KnownDomain dom-     , glitchlessPeriod ~ (n + 1) )+  :: forall dom glitchlessPeriod+   . ( HasCallStack+     , HasDefinedInitialValues dom+     , 1 <= glitchlessPeriod+     )   => SNat glitchlessPeriod   -- ^ Consider a reset signal to be properly asserted after having seen the   -- reset asserted for /glitchlessPeriod/ cycles straight.   -> Clock dom   -> Reset dom   -> Reset dom-resetGlitchFilter SNat clk rst =-  unsafeToReset (mealy clk noReset enableGen go Idle shiftReg)+resetGlitchFilter = unsafeResetGlitchFilter+{-# INLINE resetGlitchFilter #-}++-- | Filter glitches from reset signals by only triggering a reset after it has+-- been asserted for /glitchlessPeriod/ cycles. Similarly, it will stay+-- asserted until a /glitchlessPeriod/ number of deasserted cycles have been+-- observed.+--+-- On platforms without initial values ('Unknown'), 'resetGlitchFilter' cannot+-- be used and you should use 'resetGlitchFilterWithReset' with an additional+-- power-on reset, or 'holdReset' if filtering is only needed on deassertion.+--+-- @unsafeResetGlitchFilter@ allows breaking the requirement of initial values,+-- but by doing so it is possible that the design starts up with a period of up+-- to /2 * glitchlessPeriod/ clock cycles where the reset output is unasserted+-- (or longer in the case of glitches on the filtered reset input). This can+-- cause a number of problems. The outputs\/tri-states of the design might+-- output random things, including coherent but incorrect streams of data. This+-- might have grave repercussions in the design's environment (sending network+-- packets, overwriting non-volatile memory, in extreme cases destroying+-- controlled equipment or causing harm to living beings, ...).+--+-- Without initial values, the synthesized result of @unsafeResetGlitchFilter@+-- eventually correctly outputs a filtered version of the reset input. However,+-- in simulation, it will indefinitely output an undefined value. This happens+-- both in Clash simulation and in HDL simulation. Therefore, simulation should+-- not include the @unsafeResetGlitchFilter@.+--+-- If @unsafeResetGlitchFilter@ is used in a domain with asynchronous resets+-- ('Asynchronous'), @unsafeResetGlitchFilter@ will first synchronize the reset+-- input with 'dualFlipFlopSynchronizer'.+unsafeResetGlitchFilter+  :: forall dom glitchlessPeriod+   . ( HasCallStack+     , KnownDomain dom+     , 1 <= glitchlessPeriod+     )+  => SNat glitchlessPeriod+  -- ^ Consider a reset signal to be properly asserted after having seen the+  -- reset asserted for /glitchlessPeriod/ cycles straight.+  -> Clock dom+  -> Reset dom+  -> Reset dom+unsafeResetGlitchFilter glitchlessPeriod clk =+  resetGlitchFilter# glitchlessPeriod reg dffSync  where-  shiftReg =-    delay clk enableGen noGlitch (shiftInLsb <$> shiftReg <*> unsafeFromReset rst)+  reg = delay clk enableGen+  dffSync = dualFlipFlopSynchronizer clk clk noReset enableGen+{-# INLINE unsafeResetGlitchFilter #-} -  go gfs sreg-    | sreg == noGlitch = (InReset, asserted)-    | Idle <- gfs = (Idle, not asserted)-    | otherwise = (if msb == asserted then InReset else Idle, msb)-   where-    msb = testBit sreg (natToNum @n)+-- | Filter glitches from reset signals by only triggering a reset after it has+-- been asserted for /glitchlessPeriod/ cycles. Similarly, it will stay+-- asserted until a /glitchlessPeriod/ number of deasserted cycles have been+-- observed.+--+-- Compared to 'resetGlitchFilter', this function adds an additional power-on+-- reset input. As soon as the power-on reset asserts, the reset output will+-- assert, and after the power-on reset deasserts, the reset output will stay+-- asserted for another /glitchlessPeriod/ clock cycles. This is identical+-- behavior to 'holdReset' where it concerns the power-on reset, and differs+-- from the filtered reset, which will only cause an assertion after+-- /glitchlessPeriod/ cycles.+--+-- If @resetGlitchFilterWithReset@ is used in a domain with asynchronous resets+-- ('Asynchronous'), @resetGlitchFilterWithReset@ will first synchronize the+-- reset input with 'dualFlipFlopSynchronizer'.+resetGlitchFilterWithReset+  :: forall dom glitchlessPeriod+   . ( HasCallStack+     , KnownDomain dom+     , 1 <= glitchlessPeriod+     )+  => SNat glitchlessPeriod+  -- ^ Consider a reset signal to be properly asserted after having seen the+  -- reset asserted for /glitchlessPeriod/ cycles straight.+  -> Clock dom+  -> Reset dom+  -- ^ The power-on reset for the glitch filter itself+  -> Reset dom+  -- ^ The reset that will be filtered+  -> Reset dom+resetGlitchFilterWithReset glitchlessPeriod clk ownRst =+  resetGlitchFilter# glitchlessPeriod reg dffSync+ where+  reg = register clk ownRst enableGen+  dffSync = dualFlipFlopSynchronizer clk clk ownRst enableGen+{-# INLINE resetGlitchFilterWithReset #-} -  noGlitch :: BitVector glitchlessPeriod-  noGlitch = if asserted then maxBound else minBound+resetGlitchFilter#+  :: forall dom glitchlessPeriod state+   . ( HasCallStack+     , KnownDomain dom+     , 1 <= glitchlessPeriod+     , state ~ (Bool, Index glitchlessPeriod)+     )+  => SNat glitchlessPeriod+  -> (   state+      -> Signal dom state+      -> Signal dom state+     )+  -> (   Bool+      -> Signal dom Bool+      -> Signal dom Bool+     )+  -> Reset dom+  -> Reset dom+resetGlitchFilter# SNat reg dffSync rstIn0 =+  let s' = go <$> s <*> rstIn2+      s  = reg (asserted, 0) s'+  in unsafeToReset $ fst <$> s+ where+  rstIn1 = unsafeFromReset rstIn0+  rstIn2 =+    case resetKind @dom of+      SAsynchronous -> dffSync asserted rstIn1+      SSynchronous -> rstIn1 -  noReset :: Reset dom-  noReset = unsafeToReset (pure (not asserted))+  go :: state -> Bool -> state+  go (state, count) reset+    | reset == state    = (state,     0)+    | count == maxBound = (not state, 0)+    | otherwise         = (state,     count + 1)    asserted :: Bool   asserted =@@ -229,15 +403,11 @@       SActiveHigh -> True       SActiveLow -> False -  shiftInLsb :: forall m. KnownNat m => BitVector (m + 1) -> Bool -> BitVector (m + 1)-  shiftInLsb bv s = shiftL bv 1 .|. resize (pack s)-{-# NOINLINE resetGlitchFilter #-} -- Give reset glitch filter its own HDL file- -- | Hold reset for a number of cycles relative to an incoming reset signal. -- -- Example: ----- >>> let sampleWithReset = sampleN 8 . unsafeToHighPolarity+-- >>> let sampleWithReset = sampleN 8 . unsafeToActiveHigh -- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (resetGenN (SNat @3))) -- [True,True,True,True,True,False,False,False] --@@ -246,7 +416,7 @@ -- intermediate assertions of the reset signal: -- -- >>> let rst = fromList [True, False, False, False, True, False, False, False]--- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (unsafeFromHighPolarity rst))+-- >>> sampleWithReset (holdReset @System clockGen enableGen (SNat @2) (unsafeFromActiveHigh rst)) -- [True,True,True,False,True,True,True,False] -- holdReset@@ -262,7 +432,7 @@   -- ^ Reset to extend   -> Reset dom holdReset clk en SNat rst =-  unsafeFromHighPolarity ((/=maxBound) <$> counter)+  unsafeFromActiveHigh ((/=maxBound) <$> counter)  where   counter :: Signal dom (Index (n+1))   counter = register clk rst en 0 (satSucc SatBound <$> counter)@@ -270,6 +440,9 @@ -- | Convert between different types of reset, adding a synchronizer when -- the domains are not the same. See 'resetSynchronizer' for further details -- about reset synchronization.+--+-- If @domA@ has 'Synchronous' resets, a flip-flop is inserted in @domA@ to+-- filter glitches. This adds one @domA@ clock cycle delay. convertReset   :: forall domA domB    . ( KnownDomain domA@@ -279,10 +452,25 @@   -> Clock domB   -> Reset domA   -> Reset domB-convertReset clkA clkB rstA0 = rstA2+convertReset clkA clkB rstA0 = rstB1  where-  rstA1 = unsafeToReset (unsafeSynchronizer clkA clkB (unsafeFromReset rstA0))+  rstA1 = unsafeFromReset rstA0   rstA2 =+    case (resetPolarity @domA, resetPolarity @domB) of+      (SActiveLow, SActiveLow)   -> rstA1+      (SActiveHigh, SActiveHigh) -> rstA1+      _                          -> not <$> rstA1+  rstA3 =+    case resetKind @domA of+      SSynchronous -> delay clkA enableGen assertedA rstA2+      _            -> rstA2+  rstB0 = unsafeToReset $ unsafeSynchronizer clkA clkB rstA3+  rstB1 =     case (sameDomain @domA @domB) of       Just Refl -> rstA0-      Nothing   -> resetSynchronizer clkB rstA1+      Nothing   -> resetSynchronizer clkB rstB0+  assertedA :: Bool+  assertedA =+    case resetPolarity @domA of+      SActiveHigh -> True+      SActiveLow  -> False
src/Clash/Explicit/Signal.hs view
@@ -1,9 +1,9 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2019, Myrtle Software,-                  2017     , Google Inc.+                  2017-2022, Google Inc.                   2020     , Ben Gamari,-                  2021     , QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -131,6 +131,7 @@  -} +{-# LANGUAGE CPP #-} {-# LANGUAGE ExplicitNamespaces #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}@@ -171,6 +172,13 @@   , DomainResetKind   , DomainInitBehavior   , DomainResetPolarity+    -- *** Convenience types #conveniencetypes#+    -- **** Simplifying+    -- $conveniencetypes++  , HasSynchronousReset+  , HasAsynchronousReset+  , HasDefinedInitialValues     -- ** Default domains   , System   , XilinxSystem@@ -195,6 +203,7 @@   , enableGen     -- * Clock   , Clock+  , DiffClock   , periodToHz   , hzToPeriod     -- ** Synchronization primitive@@ -204,13 +213,12 @@   , Reset   , unsafeToReset   , unsafeFromReset-  , unsafeToHighPolarity-  , unsafeToLowPolarity-  , unsafeFromHighPolarity-  , unsafeFromLowPolarity+  , unsafeToActiveHigh+  , unsafeToActiveLow+  , unsafeFromActiveHigh+  , unsafeFromActiveLow     -- * Basic circuit functions   , andEnable-  , enable -- DEPRECATED   , dflipflop   , delay   , delayMaybe@@ -265,9 +273,18 @@   , readFromBiSignal   , writeToBiSignal   , mergeBiSignalOuts++  -- * Deprecated+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+  , unsafeToHighPolarity+  , unsafeToLowPolarity   ) where +import           Data.Bifunctor                 (bimap)+import           Data.Int                       (Int64)+import           Data.List                      (uncons) import           Data.Maybe                     (isJust) import           GHC.TypeLits                   (type (<=)) @@ -327,18 +344,48 @@  -} +{- $conveniencetypes++If you want to write part of your Clash design as domain-polymorphic functions,+it can be practical to define a design-wide constraint synonym that captures the+characteristics of the clock domains of the design. Such a constraint synonym+can be used as a constraint on all domain-polymorphic functions in the design,+regardless of whether they actually need the constraints from this section.++@+type DesignDomain dom =+  ( 'HasSynchronousReset' dom+  , 'HasDefinedInitialValues' dom+  )++type DesignDomainHidden dom =+  ( DesignDomain dom+  , t'Clash.Signal.HiddenClockResetEnable' dom+  )++myFunc ::+  DesignDomainHidden dom =>+  'Signal' dom [...]+@++This way, you don't have to think about which constraints the function you're+writing has exactly, and the constraint is succinct.+-}+ -- **Clock -- | Clock generator for the 'System' clock domain. ----- __NB__: should only be used for simulation, and __not__ for the /testBench/+-- __NB__: Should only be used for simulation, and __not__ for the /testBench/ -- function. For the /testBench/ function, used 'Clash.Explicit.Testbench.tbSystemClockGen' systemClockGen   :: Clock System systemClockGen = clockGen --- | Reset generator for the 'System' clock domain.+-- | Reset generator for use in simulation, for the 'System' clock domain.+-- Asserts the reset for a single cycle. ----- __NB__: should only be used for simulation or the \testBench\ function.+-- __NB__: While this can be used in the @testBench@ function, it cannot be+-- synthesized to hardware. -- -- === __Example__ --@@ -351,7 +398,7 @@ --   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+--     done           = exposeClockResetEnable (expectedOutput (topEntity \<$\> testInput)) clk rst --     clk            = tbSystemClockGen (not <\$\> done) --     rst            = 'systemResetGen' -- @@@ -446,11 +493,19 @@   -- ^ 'Clock' of the outgoing signal   -> Signal dom1 a   -> Signal dom2 a-unsafeSynchronizer _clk1 _clk2 =-  veryUnsafeSynchronizer-    (snatToNum (clockPeriod @dom1))-    (snatToNum (clockPeriod @dom2))-{-# INLINE unsafeSynchronizer #-}+unsafeSynchronizer clk1 clk2 =+  go (clockTicks clk1 clk2)+ where+  go :: [ClockAB] -> Signal dom1 a -> Signal dom2 a+  go [] _ = error "unsafeSynchronizer.go: `ticks` should have been an infinite list"+  go (tick:ticks) ass@(~(a :- as)) =+    case tick of+      ClockA  -> go ticks as+      ClockB  -> a :- go ticks ass+      ClockAB -> go (ClockB:ClockA:ticks) ass+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeSynchronizer #-}+{-# ANN unsafeSynchronizer hasBlackBox #-}  -- | Same as 'unsafeSynchronizer', but with manually supplied clock periods. --@@ -472,27 +527,35 @@ -- -- with values appearing from the "future". veryUnsafeSynchronizer-  :: Int-  -- ^ Period of clock belonging to @dom1@-  -> Int-  -- ^ Period of clock belonging to @dom2@+  :: Either Int (Signal dom1 Int)+  -- ^ Period of clock belonging to @dom1@. 'Left' if clock has a static period,+  -- 'Right' if periods are dynamic.+  -> Either Int (Signal dom2 Int)+  -- ^ Period of clock belonging to @dom2@. 'Left' if clock has a static period,+  -- 'Right' if periods are dynamic.   -> Signal dom1 a   -> Signal dom2 a-veryUnsafeSynchronizer t1 t2-  -- this case is just an optimization for when the periods are the same-  | t1 == t2 = same--  | otherwise = go 0--  where-  same :: Signal dom1 a -> Signal dom2 a-  same (s :- ss) = s :- same ss+veryUnsafeSynchronizer t1e t2e =+  go (clockTicksEither (toInt64 t1e) (toInt64 t2e))+ where+  -- TODO: deprecate 'veryUnsafeSynchronizer' or change its type signature to use+  --       'Int64' to prevent issues down the road if/when we switch to represent+  --       clock periods using femtoseconds.+  toInt64 ::+    forall dom .+    Either Int (Signal dom Int) ->+    Either Int64 (Signal dom Int64)+  toInt64 = bimap fromIntegral (fmap fromIntegral) -  go :: Int -> Signal dom1 a -> Signal dom2 a-  go relativeTime (a :- s)-    | relativeTime <= 0 = a :- go (relativeTime + t2) (a :- s)-    | otherwise = go (relativeTime - t1) s-{-# NOINLINE veryUnsafeSynchronizer #-}+  go :: [ClockAB] -> Signal dom1 a -> Signal dom2 a+  go [] _ = error "veryUnsafeSynchronizer.go: `ticks` should have been an infinite list"+  go (tick:ticks) ass@(~(a :- as)) =+    case tick of+      ClockA  -> go ticks as+      ClockB  -> a :- go ticks ass+      ClockAB -> go (ClockB:ClockA:ticks) ass+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE veryUnsafeSynchronizer #-} {-# ANN veryUnsafeSynchronizer hasBlackBox #-}  -- * Basic circuit functions@@ -505,17 +568,7 @@   -> Enable dom andEnable e0 e1 =   toEnable (fromEnable e0 .&&. e1)-{-# INLINE enable #-}---- | Merge enable signal with signal of bools by applying the boolean AND--- operation.-enable-  :: Enable dom-  -> Signal dom Bool-  -> Enable dom-enable = andEnable-{-# DEPRECATED enable-  "Use 'andEnable' instead. This function will be removed in Clash 1.8." #-}+{-# INLINE andEnable #-}  -- | Special version of 'delay' that doesn't take enable signals of any kind. -- Initial value will be undefined.@@ -570,7 +623,7 @@   -> Signal dom (Maybe a)   -> Signal dom a delayMaybe = \clk gen dflt i ->-  delay# clk (enable gen (isJust <$> i)) dflt (fromJustX <$> i)+  delay# clk (andEnable gen (isJust <$> i)) dflt (fromJustX <$> i) {-# INLINE delayMaybe #-}  -- | Version of 'delay' that only updates when its third argument is asserted.@@ -593,7 +646,7 @@   -> Signal dom a   -> Signal dom a delayEn = \clk gen dflt en i ->-  delay# clk (enable gen en) dflt i+  delay# clk (andEnable gen en) dflt i {-# INLINE delayEn #-}  -- | \"@'register' clk rst en i s@\" delays the values in 'Signal' /s/ for one@@ -655,7 +708,7 @@   -> Signal dom (Maybe a)   -> Signal dom a regMaybe = \clk rst en initial iM ->-  register# clk rst (enable en (fmap isJust iM)) initial initial (fmap fromJustX iM)+  register# clk rst (andEnable en (fmap isJust iM)) initial initial (fmap fromJustX iM) {-# INLINE regMaybe #-}  -- | Version of 'register' that only updates its content when its fourth@@ -690,7 +743,7 @@   -> Signal dom a   -> Signal dom a regEn = \clk rst gen initial en i ->-  register# clk rst (enable gen en) initial initial i+  register# clk rst (andEnable gen en) initial initial i {-# INLINE regEn #-}  -- * Simulation functions@@ -726,7 +779,8 @@   clk = clockGen   en  = enableGen   out = simulate (f clk rst en) inp-{-# NOINLINE simulateWithReset #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE simulateWithReset #-}  -- | Same as 'simulateWithReset', but only sample the first /Int/ output values. simulateWithResetN@@ -790,7 +844,7 @@  -- | Like 'fromList', but resets on reset and has a defined reset value. ----- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])+-- >>> let rst = unsafeFromActiveHigh (fromList [True, True, False, False, True, False]) -- >>> let res = fromListWithReset @System rst Nothing [Just 'a', Just 'b', Just 'c'] -- >>> sampleN 6 res -- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']@@ -804,7 +858,7 @@   -> [a]   -> Signal dom a fromListWithReset rst resetValue vals =-  go (unsafeToHighPolarity rst) vals+  go (unsafeToActiveHigh rst) vals  where   go (r :- rs) _ | r = resetValue :- go rs vals   go (_ :- rs) [] = deepErrorX "fromListWithReset: input ran out" :- go rs []@@ -832,7 +886,8 @@ sampleWithReset nReset f0 =   let f1 = f0 clockGen (resetGenN @dom nReset) enableGen in   drop (snatToNum nReset) (sample f1)-{-# NOINLINE sampleWithReset #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE sampleWithReset #-}  -- | Get a fine list of /m/ samples from a 'Signal', while asserting the reset line -- for /n/ clock cycles. 'sampleWithReset' does not return the first /n/ cycles,@@ -940,6 +995,6 @@         . (" cycles until value " ++) $ showX value   (before, after) = break check $ sample s   nSamples = length before-  value = head after+  value = maybe (error "impossible") fst (uncons after)  {-# RULES "sequenceAVecSignal" Clash.Sized.Vector.traverse# (\x -> x) = vecBundle# #-}
src/Clash/Explicit/SimIO.hs view
@@ -50,6 +50,9 @@ #endif import Data.IORef import GHC.TypeLits+#if MIN_VERSION_base(4,18,0)+  hiding (SNat)+#endif import Prelude hiding (getChar, putChar, getLine) import qualified System.IO as IO import System.IO.Unsafe@@ -77,7 +80,8 @@  fmapSimIO# :: (a -> b) -> SimIO a -> SimIO b fmapSimIO# f (SimIO m) = SimIO (fmap f m)-{-# NOINLINE fmapSimIO# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fmapSimIO# #-} {-# ANN fmapSimIO# hasBlackBox #-}  instance Applicative SimIO where@@ -86,16 +90,20 @@  pureSimIO# :: a -> SimIO a pureSimIO# a = SimIO (pure a)-{-# NOINLINE pureSimIO# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE pureSimIO# #-} {-# ANN pureSimIO# hasBlackBox #-}  apSimIO# :: SimIO (a -> b) -> SimIO a -> SimIO b apSimIO# (SimIO f) (SimIO m) = SimIO (f <*> m)-{-# NOINLINE apSimIO# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE apSimIO# #-} {-# ANN apSimIO# hasBlackBox #-}  instance Monad SimIO where+#if !MIN_VERSION_base(4,16,0)   return = pureSimIO#+#endif   (>>=)  = bindSimIO#  bindSimIO# :: SimIO a -> (a -> SimIO b) -> SimIO b@@ -104,7 +112,8 @@ #else bindSimIO# (SimIO m) k = SimIO (m >>= (\x -> x `seqX` coerce k x)) #endif-{-# NOINLINE bindSimIO# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE bindSimIO# #-} {-# ANN bindSimIO# hasBlackBox #-}  -- | Display a string on /stdout/@@ -113,7 +122,8 @@   -- ^ String you want to display   -> SimIO () display s = SimIO (putStrLn s)-{-# NOINLINE display #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE display #-} {-# ANN display hasBlackBox #-}  -- | Finish the simulation with an exit code@@ -122,7 +132,8 @@   -- ^ The exit code you want to return at the end of the simulation   -> SimIO a finish i = return (error (show i))-{-# NOINLINE finish #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE finish #-} {-# ANN finish hasBlackBox #-}  -- | Mutable reference@@ -138,13 +149,15 @@   -- ^ The starting value   -> SimIO (Reg a) reg a = SimIO (Reg <$> newIORef a)-{-# NOINLINE reg #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE reg #-} {-# ANN reg hasBlackBox #-}  -- | Read value from a mutable reference readReg :: Reg a -> SimIO a readReg (Reg a) = SimIO (readIORef a)-{-# NOINLINE readReg #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE readReg #-} {-# ANN readReg hasBlackBox #-}  -- | Write new value to the mutable reference@@ -155,7 +168,8 @@   -- ^ The new value   -> SimIO () writeReg (Reg r) a = SimIO (writeIORef r a)-{-# NOINLINE writeReg #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE writeReg #-} {-# ANN writeReg hasBlackBox #-}  -- | File handle@@ -213,7 +227,8 @@ openFile fp "ab+" = coerce (IO.openBinaryFile fp IO.AppendMode) #endif openFile _  m     = error ("openFile unknown mode: " ++ show m)-{-# NOINLINE openFile #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE openFile #-} {-# ANN openFile hasBlackBox #-}  -- | Close a file@@ -221,7 +236,8 @@   :: File   -> SimIO () closeFile (File fp) = SimIO (IO.hClose fp)-{-# NOINLINE closeFile #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE closeFile #-} {-# ANN closeFile hasBlackBox #-}  -- | Read one character from a file@@ -230,7 +246,8 @@   -- ^ File to read from   -> SimIO Char getChar (File fp) = SimIO (IO.hGetChar fp)-{-# NOINLINE getChar #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE getChar #-} {-# ANN getChar hasBlackBox #-}  -- | Insert a character into a buffer specified by the file@@ -241,7 +258,8 @@   -- ^ Buffer to insert to   -> SimIO () putChar c (File fp) = SimIO (IO.hPutChar fp c)-{-# NOINLINE putChar #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE putChar #-} {-# ANN putChar hasBlackBox #-}  -- | Read one line from a file@@ -264,7 +282,8 @@    rep []     vs          = vs    rep (x:xs) (Cons _ vs) = Cons (toEnum (fromEnum x)) (rep xs vs)    rep _      Nil         = Nil-{-# NOINLINE getLine #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE getLine #-} {-# ANN getLine hasBlackBox #-}  -- | Determine whether we've reached the end of the file@@ -273,7 +292,8 @@   -- ^ File we want to inspect   -> SimIO Bool isEOF (File fp) = SimIO (IO.hIsEOF fp)-{-# NOINLINE isEOF #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE isEOF #-} {-# ANN isEOF hasBlackBox #-}  -- | Set the position of the next operation on the file@@ -290,7 +310,8 @@   -- * 2: From the end of the file   -> SimIO Int seek (File fp) pos mode = SimIO (IO.hSeek fp (toEnum mode) pos >> return 0)-{-# NOINLINE seek #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE seek #-} {-# ANN seek hasBlackBox #-}  -- | Set the position of the next operation to the beginning of the file@@ -298,7 +319,8 @@   :: File   -> SimIO Int rewind (File fp) = SimIO (IO.hSeek fp IO.AbsoluteSeek 0 >> return 0)-{-# NOINLINE rewind #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rewind #-} {-# ANN rewind hasBlackBox #-}  -- | Returns the offset from the beginning of the file (in bytes).@@ -307,7 +329,8 @@   -- ^ File we want to inspect   -> SimIO Integer tell (File fp) = SimIO (IO.hTell fp)-{-# NOINLINE tell #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tell #-} {-# ANN tell hasBlackBox #-}  -- | Write any buffered output to file@@ -315,7 +338,8 @@   :: File   -> SimIO () flush (File fp) = SimIO (IO.hFlush fp)-{-# NOINLINE flush #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE flush #-} {-# ANN flush hasBlackBox #-}  -- | Simulation-level I/O environment that can be synthesized to HDL-level I\/O.@@ -373,4 +397,5 @@  where   go q@(~(k :- ks)) s =     (:-) <$> unSimIO (f s k) <*> unsafeInterleaveIO ((q `seq` go ks s))-{-# NOINLINE mealyIO #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE mealyIO #-}
src/Clash/Explicit/Synchronizer.hs view
@@ -41,10 +41,10 @@ import Clash.Explicit.Mealy        (mealyB) import Clash.Explicit.BlockRam     (RamOp (..), trueDualPortBlockRam) import Clash.Explicit.Signal-  (Clock, Reset, Signal, Enable, register, unsafeSynchronizer, fromEnable, (.&&.))+  (Clock, Reset, Signal, Enable, register, unsafeSynchronizer, fromEnable,+  (.&&.), mux, KnownDomain) import Clash.Promoted.Nat          (SNat (..)) import Clash.Promoted.Nat.Literals (d0)-import Clash.Signal                (mux, KnownDomain) import Clash.Sized.BitVector       (BitVector, (++#)) import Clash.XException            (NFDataX, fromJustX) 
src/Clash/Explicit/Testbench.hs view
@@ -1,12 +1,13 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,-                  2017     , Google Inc.+                  2017-2022, Google Inc.                   2019     , Myrtle Software Ltd,-                  2021     , QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -} +{-# LANGUAGE CPP #-} {-# LANGUAGE TypeFamilies #-}  {-# LANGUAGE Unsafe #-}@@ -26,6 +27,7 @@   , tbClockGen   , tbEnableGen   , tbSystemClockGen+  , clockToDiffClock    , outputVerifier   , outputVerifier'@@ -39,20 +41,19 @@  import Control.Exception     (catch, evaluate) import Debug.Trace           (trace)-import Data.Type.Equality    ((:~:)(..))-import Data.Proxy            (Proxy(..))-import GHC.TypeLits          (KnownNat, type (+), sameSymbol, type (<=))+import GHC.TypeLits          (KnownNat, type (+), type (<=)) import Prelude               hiding ((!!), length) import System.IO.Unsafe      (unsafeDupablePerformIO)  import Clash.Annotations.Primitive (hasBlackBox) import Clash.Class.Num       (satSucc, SaturationMode(SatBound)) import Clash.Promoted.Nat    (SNat(..))-import Clash.Promoted.Symbol (SSymbol (..))+import Clash.Promoted.Symbol (SSymbol(..)) import Clash.Explicit.Signal   (Clock, Reset, System, Signal, toEnable, fromList, register,   unbundle, unsafeSynchronizer)-import Clash.Signal.Internal (Clock (..), Reset (..))+import Clash.Signal.Internal+  (ClockN (..), DiffClock (..), Reset (..), tbClockGen) import Clash.Signal          (mux, KnownDomain, Enable) import Clash.Sized.Index     (Index) import Clash.Sized.Internal.BitVector@@ -114,7 +115,8 @@   where     eqX a b = unsafeDupablePerformIO (catch (evaluate (a == b))                                             (\(_ :: XException) -> return False))-{-# NOINLINE assert #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE assert #-} {-# ANN assert hasBlackBox #-}  -- | The same as 'assert', but can handle don't care bits in its expected value.@@ -148,7 +150,8 @@   where     eqX a b = unsafeDupablePerformIO (catch (evaluate (a `isLike#` b))                                             (\(_ :: XException) -> return False))-{-# NOINLINE assertBitVector #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE assertBitVector #-} {-# ANN assertBitVector hasBlackBox #-}  @@ -213,8 +216,8 @@   -- ^ Signal to verify   -> Signal dom Bool   -- ^ Indicator that all samples are verified-outputVerifier' =-  outputVerifier @l @a @dom @dom+outputVerifier' clk =+  outputVerifier @l @a clk clk {-# INLINE outputVerifier' #-}  -- | Compare a signal (coming from a circuit) to a vector of samples. If a@@ -275,6 +278,8 @@   => Clock testDom   -- ^ Clock to which the test bench is synchronized (but not necessarily   -- the circuit under test)+  -> Clock circuitDom+  -- ^ Clock to which the circuit under test is synchronized   -> Reset testDom   -- ^ Reset line of test bench   -> Vec l a@@ -305,8 +310,8 @@   -- ^ Signal to verify   -> Signal dom Bool   -- ^ Indicator that all samples are verified-outputVerifierBitVector' =-  outputVerifierBitVector @l @n @dom @dom+outputVerifierBitVector' clk =+  outputVerifierBitVector @l @n clk clk {-# INLINE outputVerifierBitVector' #-}  -- | Same as 'outputVerifier', but can handle don't care bits in its@@ -322,6 +327,8 @@   => Clock testDom   -- ^ Clock to which the test bench is synchronized (but not necessarily   -- the circuit under test)+  -> Clock circuitDom+  -- ^ Clock to which the circuit under test is synchronized   -> Reset testDom   -- ^ Reset line of test bench   -> Vec l (BitVector n)@@ -355,6 +362,8 @@   -> Clock testDom   -- ^ Clock to which the test bench is synchronized (but not necessarily   -- the circuit under test)+  -> Clock circuitDom+  -- ^ Clock to which the circuit under test is synchronized   -> Reset testDom   -- ^ Reset line of test bench   -> Vec l a@@ -363,25 +372,20 @@   -- ^ Signal to verify   -> Signal testDom Bool   -- ^ True if all samples are verified-outputVerifierWith assertF clk rst samples i0 =-    let i1    = sync i0+outputVerifierWith assertF clkTest clkCircuit rst samples i0 =+    let i1    = unsafeSimSynchronizer clkCircuit clkTest i0         en    = toEnable (pure True)-        (s,o) = unbundle (genT <$> register clk rst en 0 s)+        (s,o) = unbundle (genT <$> register clkTest rst en 0 s)         (e,f) = unbundle o-        f'    = register clk rst en False f+        f'    = register clkTest rst en False f         -- Only assert while not finished-    in  mux f' f' $ assertF clk rst i1 e f'+    in  mux f' f' $ assertF clkTest rst i1 e f'   where     genT :: Index l -> (Index l,(a,Bool))     genT s = (s',(samples !! s,finished))       where         s' = satSucc SatBound s         finished = s == maxBound-    sync :: Signal circuitDom a-         -> Signal testDom a-    sync = case sameSymbol (Proxy @circuitDom) (Proxy @testDom) of-             Just Refl -> id-             Nothing   -> unsafeSimSynchronizer (Clock SSymbol) clk {-# INLINABLE outputVerifierWith #-}  -- | Ignore signal for a number of cycles, while outputting a static value.@@ -421,72 +425,18 @@   testClk = tbClockGen done   circuitClk = tbClockGen (unsafeSynchronizer testClk circuitClk done) --- | Clock generator to be used in the /testBench/ function.------ To be used like:------ @--- clkSystem en = tbClockGen @System en--- @------ === __Example__------ @--- module Example where------ import "Clash.Explicit.Prelude"--- import "Clash.Explicit.Testbench"------ -- Fast domain: twice as fast as \"Slow\"--- 'Clash.Explicit.Prelude.createDomain' 'Clash.Explicit.Prelude.vSystem'{vName=\"Fast\", vPeriod=10}------ -- Slow domain: twice as slow as \"Fast\"--- 'Clash.Explicit.Prelude.createDomain' 'Clash.Explicit.Prelude.vSystem'{vName=\"Slow\", vPeriod=20}------ topEntity---   :: 'Clock' \"Fast\"---   -> 'Reset' \"Fast\"---   -> 'Enable' \"Fast\"---   -> 'Clock' \"Slow\"---   -> 'Signal' \"Fast\" (Unsigned 8)---   -> 'Signal' \"Slow\" (Unsigned 8, Unsigned 8)--- topEntity clk1 rst1 en1 clk2 i =---   let h = register clk1 rst1 en1 0 (register clk1 rst1 en1 0 i)---       l = register clk1 rst1 en1 0 i---   in  unsafeSynchronizer clk1 clk2 (bundle (h, l))------ testBench---   :: 'Signal' \"Slow\" Bool--- testBench = done---   where---     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)---     notDone        = not \<$\> done---     clkA1          = 'tbClockGen' \@\"Fast\" (unsafeSynchronizer clkB2 clkA1 notDone)---     clkB2          = 'tbClockGen' \@\"Slow\" notDone---     rstA1          = 'Clash.Signal.resetGen' \@\"Fast\"---     rstB2          = 'Clash.Signal.resetGen' \@\"Slow\"--- @-tbClockGen-  :: KnownDomain testDom-  => Signal testDom Bool-  -> Clock testDom-tbClockGen done = Clock (done `seq` SSymbol)-{-# NOINLINE tbClockGen #-}-{-# ANN tbClockGen hasBlackBox #-}- -- | Enable signal that's always enabled. Because it has a blackbox definition -- this enable signal is opaque to other blackboxes. It will therefore never -- be optimized away. tbEnableGen :: Enable tag tbEnableGen = toEnable (pure True)-{-# NOINLINE tbEnableGen #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tbEnableGen #-} {-# ANN tbEnableGen hasBlackBox #-}  -- | Clock generator for the 'System' clock domain. ----- __NB__: can be used in the /testBench/ function+-- __NB__: Can be used in the /testBench/ function -- -- === __Example__ --@@ -498,7 +448,7 @@ -- testBench = done --   where --     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil)---     expectedOutput = outputVerifier ((1:>2:>3:>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@@ -508,6 +458,31 @@   -> Clock System tbSystemClockGen = tbClockGen +-- | Convert a single-ended clock to a differential clock+--+-- The 'tbClockGen' function generates a single-ended clock. This function will+-- output the two phases of a differential clock corresponding to that+-- single-ended clock.+--+-- This function is only meant to be used in the /testBench/ function, not to+-- create a differential output in hardware.+--+-- Example:+--+-- @+-- clk = clockToDiffClock $ tbClockGen (not \<\$\> done)+-- @+clockToDiffClock ::+  KnownDomain dom =>+  -- | Single-ended input+  Clock dom ->+  -- | Differential output+  DiffClock dom+clockToDiffClock clk = DiffClock clk (ClockN SSymbol)+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE clockToDiffClock #-}+{-# ANN clockToDiffClock hasBlackBox #-}+ -- | Cross clock domains in a way that is unsuitable for hardware but good -- enough for simulation. --@@ -526,5 +501,6 @@   -> Signal dom1 a   -> Signal dom2 a unsafeSimSynchronizer = unsafeSynchronizer-{-# NOINLINE unsafeSimSynchronizer #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeSimSynchronizer #-} {-# ANN unsafeSimSynchronizer hasBlackBox #-}
src/Clash/Explicit/Verification.hs view
@@ -1,5 +1,6 @@ {-| Copyright  :  (C) 2019, Myrtle Software Ltd+                  2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -11,7 +12,9 @@ The verification API is currently experimental and subject to change. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE QuasiQuotes #-}  module Clash.Explicit.Verification   ( -- * Types@@ -57,9 +60,10 @@  import           Data.Text  (Text) import           Data.Maybe (Maybe(Just))+import           Data.String.Interpolate (__i)  import           Clash.Annotations.Primitive-  (Primitive(InlinePrimitive), HDL(..))+  (Primitive(InlineYamlPrimitive), HDL(..)) import           Clash.Signal.Internal (KnownDomain, Signal, Clock, Reset) import           Clash.XException      (errorX, hwSeqX) @@ -256,8 +260,13 @@   pure (errorX (concat [       "Simulation for Clash.Verification not yet implemented. If you need this,"     , " create an issue at https://github.com/clash-compiler/clash-lang/issues." ]))-{-# NOINLINE check #-}-{-# ANN check (InlinePrimitive [Verilog, SystemVerilog, VHDL] "[ { \"BlackBoxHaskell\" : { \"name\" : \"Clash.Explicit.Verification.check\", \"templateFunction\" : \"Clash.Primitives.Verification.checkBBF\"}} ]") #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE check #-}+{-# ANN check (InlineYamlPrimitive [Verilog, SystemVerilog, VHDL] [__i|+  BlackBoxHaskell:+    name: Clash.Explicit.Verification.check+    templateFunction: Clash.Primitives.Verification.checkBBF+  |]) #-}  -- | Same as 'check', but doesn't require a design to explicitly carried to -- top-level.
src/Clash/HaskellPrelude.hs view
@@ -24,9 +24,9 @@  import Prelude hiding   ((++), (!!), concat, concatMap, 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, undefined, (^),-   getChar, putChar, getLine, (&&), (||), not)+   iterate, last, length, map, odd, repeat, replicate, reverse, scanl, scanl1,+   scanr, scanr1, splitAt, tail, take, unzip, unzip3, zip, zip3, zipWith, zipWith3, undefined,+   (^), getChar, putChar, getLine, (&&), (||), not, maximum, minimum)  import qualified Prelude import GHC.Magic (noinline)
src/Clash/Intel/ClockGen.hs view
@@ -1,204 +1,463 @@ {-| Copyright  :  (C) 2017-2018, Google Inc                   2019     , Myrtle Software-                  2022     , QBayLogic B.V.+                  2022-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -PLL and other clock-related components for Intel (Altera) FPGAs--A PLL generates a stable clock signal for your circuit at a selectable-frequency.+This module contains functions for instantiating clock generators on Intel+FPGA's. -If you haven't determined the frequency you want the circuit to run at, the-predefined 100 MHz domain `Clash.Signal.System` can be a good starting point.-The datasheet for your FPGA specifies lower and upper limits, but the true-maximum frequency is determined by your circuit. The 'altpll' and 'alteraPll'-components below show an example for when the oscillator connected to the FPGA-runs at 50 MHz. If the oscillator runs at 100 MHz, change @DomInput@ to:+We suggest you use a clock generator even if your oscillator runs at the+frequency you want to run your circuit at. -@-'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=10000}-@+A clock generator generates a stable clock signal for your design at a+configurable frequency. A clock generator in an FPGA is frequently referred to+as a PLL (Phase-Locked Loop). Intel also refers to them as PLL's in general but+because this is not consistently the case among FPGA vendors, we choose the+more generic term /clock generator/. -We suggest you always use a PLL even if your oscillator runs at the frequency-you want to run your circuit at.+For most use cases, you would create two or more synthesis domains describing+the oscillator input and the domains you wish to use in your design, and use+the [regular functions](#g:regular) below to generate the clocks and resets of+the design from the oscillator input. There are use cases not covered by this+simpler approach, and the [unsafe functions](#g:unsafe) are provided as a means+to build advanced reset managers for the output domains. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}  module Clash.Intel.ClockGen-  ( altpll+  ( -- * Choosing domains+    -- $domains++    -- ** Caution: actual output frequency+    -- $caution++    -- * Using+    -- $using++    -- ** Example+    -- $example++    -- ** Type checking errors+    -- $error++    -- * Regular functions #regular#+    altpllSync+  , alteraPllSync+    -- * Unsafe functions #unsafe#+    -- $unsafe++    -- ** Example+    -- $unsafe_example+  , unsafeAltpll+  , unsafeAlteraPll+    -- * Deprecated+  , altpll   , alteraPll   ) where +import GHC.TypeLits (type (<=))+ import Clash.Annotations.Primitive (hasBlackBox)-import Clash.Clocks           (Clocks (..))-import Clash.Promoted.Symbol  (SSymbol)+import Clash.Clocks+  (Clocks(..), ClocksSync(..), ClocksSyncCxt, NumOutClocksSync)+import Clash.Magic (setName)+import Clash.Promoted.Symbol (SSymbol) import Clash.Signal.Internal-  (Signal, Clock, Reset, KnownDomain (..))+  (Signal, Clock, Reset, KnownDomain, HasAsynchronousReset) +{- $domains+Synthesis domains are denoted by the type-parameter+@dom :: t'Clash.Signal.Domain'@ as occurring in for instance+@t'Clash.Signal.Signal' dom a@; see "Clash.Signal" for more information. For+each domain, there is only a single clock signal which clocks that domain;+mixing clock signals is a design error. Conversely, it is possible to clock+multiple domains using the same clock signal, in complex designs. --- | A clock source that corresponds to the Intel/Quartus \"ALTPLL\" component--- (Arria GX, Arria II, Stratix IV, Stratix III, Stratix II, Stratix,---  Cyclone 10 LP, Cyclone IV, Cyclone III, Cyclone II, Cyclone)--- with settings to provide a stable 'Clock' from a single free-running input------ Only works when configured with:------ * 1 reference clock--- * 1 output clock--- * a reset input port--- * a locked output port+For the clock generator inputs, create a domain with the correct clock frequency+and reset polarity. For instance, if the clock input is a free-running clock at+a frequency of 50 MHz (a period of 20 ns or 20,000 ps), and the reset input+connected to the clock generator is /active-low/, the following will instantiate+the required input domain:++@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+@++If you haven't determined the frequency you want the design to run at, the+predefined 100 MHz domain t'Clash.Signal.System' can be a good starting point.+The datasheet for your FPGA specifies lower and upper limits, but the true+maximum frequency is determined by your design.++Supposing you need a clock running at 150 MHz for your design, the following+will instantiate a suitable domain:++@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}+@++As the clock generator always reacts asynchronously to its reset input, it will+require that the @DomInput@ domain has asynchronous resets. The /unsafe/+functions below do not enforce this requirement on the domain (but they still+react asynchronously).+-}++{- $caution+The clock generator in the FPGA is limited in which clock frequencies it can+generate, especially when one clock generator has multiple outputs. The clock+generator will pick the attainable frequency closest to the requested frequency+(or possibly fail to synthesize). You can check the frequency that the IP core+chose by loading your design into the Quartus GUI. In the /Project Navigator/,+choose the /Hierarchy/ view and find your clock generator instance.+Double-click the instance to open Platform Designer and choose /Edit/+/Parameters.../. In the /Output Clocks/ page, the relevant column is /Actual/+/Settings/. If the actual value differs, copy the actual value back to the+Clash design.+-}++{- $using+The functions in this module will instantiate an Intel IP core for a clock+generator with 1 reference clock input and a reset input, and one or more output+clocks and a @locked@ output.++The [regular functions](#g:regular) incorporate 'Clash.Signal.resetSynchronizer'+to convert the @locked@ output port into a proper 'Reset' signal for the domains+which will keep the circuit in reset while the clock is still stabilizing.++The clock generator will react asynchronously to the incoming reset input. When+the reset input is asserted, the clock generator's @locked@ output will+deassert, in turn causing the 'Reset' output(s) of these functions to assert.++You can use 'Clash.Magic.setName' to give the IP instance a specific name, which+can be useful if you need to refer to the instance in Synopsys Design+Constraints files.++The output of the function for /n/ output clocks is a /2n/-tuple with clock and+reset outputs. The compiler needs to be able to fully determine the types of the+individual tuple elements from the context; the clock generator function itself+will not constrain them. If the types of the tuple elements cannot be inferred,+you can use pattern type signatures to specify the types. Supposing the+referenced domains have been created with 'Clash.Signal.createDomain', an+instance with a single output clock can be instantiated using:++@+(clk150 :: 'Clock' Dom150, rst150 :: 'Reset' Dom150) = 'alteraPllSync' clkIn rstIn+@++An instance with two clocks can be instantiated using++@+( clk100 :: 'Clock' Dom100+  , rst100 :: 'Reset' Dom100+  , clk150 :: 'Clock' Dom150+  , rst150 :: 'Reset' Dom150) = 'alteraPllSync' clkIn rstIn+@++and so on up to 18 clocks, following the general pattern @('Clock' dom1, 'Reset'+dom1, 'Clock' dom2, 'Reset' dom2, ..., 'Clock' dom/n/, 'Reset' dom/n/)@.++These examples show 'alteraPllSync' but it is the same for 'altpllSync' except+that it supports up to 5 clocks.++If you need access to the @locked@ output to build a more advanced reset+manager, you should use the [unsafe functions](#g:unsafe) instead.+-}++{- $example++When the oscillator connected to the FPGA runs at 50 MHz and the external reset+signal is /active-low/, this will generate a 150 MHz clock for use by the+circuit:++@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}++topEntity+  :: 'Clock' DomInput+  -> 'Reset' DomInput+  -> t'Clash.Signal.Signal' Dom150 Int+  -> t'Clash.Signal.Signal' Dom150 Int+topEntity clkIn rstIn = 'Clash.Signal.exposeClockResetEnable' (register 0) clk rst 'Clash.Signal.enableGen'+ where+  (clk, rst) = 'alteraPllSync' clkIn rstIn+@+-}++{- $error+When type checking cannot infer the types of the tuple elements, or they have+the wrong type, the GHC compiler will complain about satisfying @NumOutClocks@.+The error message on GHC 9.4 and up is:++@+    • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+                        (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+                           ([...])+                           DomInput) <= 18+    • In the expression: alteraPllSync clkIn rstIn+@++On older GHC versions, the error message is:++@+    • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+                             (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+                                ([...])+                                DomInput)+                           <=? 18’+                     with ‘'True’+        arising from a use of ‘alteraPllSync’+    • In the expression: alteraPllSync clkIn rstIn+@++The above error message is also emitted when trying to instantiate more than 18+output clocks, as it will fail to find an instance. As 'altpllSync' supports no+more than 5 clocks, trying to instantiate between 6 and 18 output clocks will+also cause a type checking error. On GHC 9.4 and up, the error for attempting to+instantiate 6 clocks is:++@+    • Cannot satisfy: 6 <= 5+    • In the expression: altpllSync clkIn rstIn+@++On older GHC versions, the error message is less clear:++@+    • Couldn't match type ‘'False’ with ‘'True’+        arising from a use of ‘altpllSync’+    • In the expression: altpllSync clkIn rstIn+@+-}++{- $unsafe+These functions are provided for the cases where the [regular+functions](#g:regular) cannot provide the desired behavior, like when+implementing certain advanced reset managers. These functions directly expose+the /asynchronous/ @locked@ output of the clock generator, which will assert+when the output clocks are stable. @locked@ is usually connected to reset+circuitry to keep the circuit in reset while the clock is still stabilizing.++The output of the function for /n/ output clocks is an /n+1/-tuple with /n/+clock outputs and a @locked@ signal. The compiler needs to be able to fully+determine the types of the individual tuple elements from the context; the clock+generator function itself will not constrain them. If the types of the tuple+elements cannot be inferred, you can use pattern type signatures to specify the+types. Supposing the referenced domains have been created with+'Clash.Signal.createDomain', an instance with a single output clock can be+instantiated using:++@+(clk150 :: 'Clock' Dom150, locked :: t'Clash.Signal.Signal' Dom150 'Bool') = 'unsafeAlteraPll' clkIn rstIn+@++An instance with two clocks can be instantiated using++@+(clk100 :: 'Clock' Dom100+  , clk150 :: 'Clock' Dom150+  , locked :: t'Clash.Signal.Signal' Dom100 'Bool') = 'unsafeAlteraPll' clkIn rstIn+@++and so on up to 18 clocks, following the general pattern @('Clock' dom1, 'Clock'+dom2, ..., 'Clock' dom/n/, t'Clash.Signal.Signal' pllLock Bool)@.++These examples show 'unsafeAlteraPll' but it is the same for 'unsafeAltpll'+except that it supports up to 5 clocks.++Though the @locked@ output is specified as a @t'Clash.Signal.Signal' pllLock+'Bool'@, it is an asynchronous signal and will need to be synchronized before it+can be used as a (reset) signal. While in the examples above the+@locked@ output has been assigned the domain of one of the output clocks, the+domain @pllLock@ is left unrestricted. If the lock signal is to be used in+multiple domains, the @pllLock@ domain should probably be set to @domIn@ (the+domain of the input clock and reset). While in HDL+'Clash.Explicit.Signal.unsafeSynchronizer' is just a wire, in Haskell simulation+it does actually resample the signal, and by setting @pllLock@ to @domIn@, there+is no resampling of the simulated lock signal. The simulated lock signal is+simply the inverse of the reset input: @locked@ is asserted whenever the reset+input is deasserted and vice versa.+-}++{- $unsafe_example+@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}++topEntity+  :: 'Clock' DomInput+  -> 'Reset' DomInput+  -> t'Clash.Signal.Signal' Dom150 Int+  -> t'Clash.Signal.Signal' Dom150 Int+topEntity clkIn rstIn = 'Clash.Signal.exposeClockResetEnable' (register 0) clk rst 'Clash.Signal.enableGen'+ where+  (clk, locked) = 'unsafeAlteraPll' clkIn rstIn+  rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromActiveLow' locked)+@++'Clash.Signal.resetSynchronizer' will keep the reset asserted when @locked@ is+'False', hence the use of @'Clash.Signal.unsafeFromActiveLow' locked@.+-}++-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"ALTPLL\" IP core (Arria GX, Arria II, Stratix IV, Stratix III, Stratix II,+-- Stratix, Cyclone 10 LP, Cyclone IV, Cyclone III, Cyclone II, Cyclone) with 1+-- reference clock input and a reset input and 1 to 5 output clocks and a+-- @locked@ output. ----- The PLL lock output is asserted when the clock is stable, and is usually--- connected to reset circuitry to keep the circuit in reset while the clock is--- still stabilizing.+-- This function incorporates 'Clash.Signal.resetSynchronizer's to convert the+-- @locked@ output port into proper 'Reset' signals for the output domains which+-- will keep the circuit in reset while the clock is still stabilizing. -- -- See also the [ALTPLL (Phase-Locked Loop) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_altpll.pdf)------ === Example------ ==== Using a PLL------ When the oscillator connected to the FPGA runs at 50 MHz and the external--- reset signal is /active low/, this will generate a 100 MHz clock for the--- @'Clash.Signal.System'@ domain:------ @--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000}------ topEntity---   :: 'Clock' DomInput---   -> 'Signal' DomInput 'Bool'---   -> [...]--- topEntity clkInp rstInp = [...]---  where---   (clk, pllStable) =---     'altpll' \@'Clash.Signal.System' ('SSymbol' \@\"altpll50to100\") clkInp---            ('Clash.Signal.unsafeFromLowPolarity' rstInp)---   rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromLowPolarity' pllStable)--- @------ 'Clash.Signal.resetSynchronizer' will keep the reset asserted when--- @pllStable@ is 'False', hence the use of--- @'Clash.Signal.unsafeFromLowPolarity' pllStable@. Your circuit will have--- signals of type @'Signal' 'Clash.Signal.System'@ and all the clocks and--- resets of your components will be the @clk@ and @rst@ signals generated here--- (modulo local resets, which will be based on @rst@ or never asserted at all--- if the component doesn't need a reset).------ ==== Specifying the output frequency------ If you don't have a top-level type signature specifying the output clock--- domain, you can use type applications to specify it, e.g.:------ @--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom100MHz\", vPeriod=10000}+altpllSync ::+  forall t domIn .+  ( HasAsynchronousReset domIn+  , ClocksSyncCxt t domIn+  , NumOutClocksSync t domIn <= 5+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+altpllSync clkIn rstIn =+  clocksResetSynchronizer (unsafeAltpll clkIn rstIn) clkIn++-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"ALTPLL\" IP core (Arria GX, Arria II, Stratix IV, Stratix III, Stratix II,+-- Stratix, Cyclone 10 LP, Cyclone IV, Cyclone III, Cyclone II, Cyclone) with 1+-- reference clock input and a reset input and 1 output clock and a @locked@+-- output. ----- -- outputs a clock running at 100 MHz--- (clk100, pllLocked) = 'altpll' \@Dom100MHz ('SSymbol' \@\"altpll50to100\") clk50 rst50--- @-altpll-  :: forall domOut domIn name-   . (KnownDomain domIn, KnownDomain domOut)-  => SSymbol name-  -- ^ Name of the component instance+-- This function is deprecated because the @locked@ output is an asynchronous+-- signal. This means the user is required to add a synchronizer and as such+-- this function is unsafe. The common use case is now covered by 'altpllSync'+-- and 'unsafeAltpll' offers the functionality of this deprecated function for+-- advanced use cases.+altpll ::+  forall domOut domIn name .+  ( HasAsynchronousReset domIn+  , KnownDomain domOut+  ) =>+  -- | Name of the component instance   --   -- Instantiate as follows: @(SSymbol \@\"altpll50\")@-  -> Clock domIn-  -- ^ Free running clock (e.g. a clock pin connected to a crystal oscillator)-  -> Reset domIn-  -- ^ Reset for the PLL-  -> (Clock domOut, Signal domOut Bool)-  -- ^ (Stable PLL clock, PLL lock)-altpll !_ = knownDomain @domIn `seq` knownDomain @domOut `seq` clocks-{-# NOINLINE altpll #-}-{-# ANN altpll hasBlackBox #-}+  SSymbol name ->+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  -- | (Output clock, Clock generator locked)+  (Clock domOut, Signal domOut Bool)+altpll _ = setName @name unsafeAltpll+{-# INLINE altpll #-}+{-# DEPRECATED altpll "This function is unsafe. Please see documentation of the function for alternatives." #-} --- | A clock source that corresponds to the Intel/Quartus \"Altera PLL\"--- component (Arria V, Stratix V, Cyclone V) with settings to provide a stable--- 'Clock' from a single free-running input+-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"ALTPLL\" IP core (Arria GX, Arria II, Stratix IV, Stratix III, Stratix II,+-- Stratix, Cyclone 10 LP, Cyclone IV, Cyclone III, Cyclone II, Cyclone) with 1+-- reference clock input and a reset input and 1 to 5 output clocks and a+-- @locked@ output. ----- Only works when configured with:+-- __NB__: Because the clock generator reacts asynchronously to the incoming+-- reset input, the signal __must__ be glitch-free. ----- * 1 reference clock--- * 1-16 output clocks--- * a reset input port--- * a locked output port+-- See also the [ALTPLL (Phase-Locked Loop) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_altpll.pdf)+unsafeAltpll ::+  forall t domIn .+  ( KnownDomain domIn+  , Clocks t+  , ClocksCxt t+  , NumOutClocks t <= 5+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+unsafeAltpll = clocks+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeAltpll #-}+{-# ANN unsafeAltpll hasBlackBox #-}++-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"Altera PLL\" IP core (Arria V, Stratix V, Cyclone V) with 1 reference clock+-- input and a reset input and 1 to 18 output clocks and a @locked@ output. ----- The PLL lock output is asserted when the clocks are stable, and is usually--- connected to reset circuitry to keep the circuit in reset while the clocks--- are still stabilizing.+-- This function incorporates 'Clash.Signal.resetSynchronizer's to convert the+-- @locked@ output port into proper 'Reset' signals for the output domains which+-- will keep the circuit in reset while the clock is still stabilizing. -- -- See also the [Altera Phase-Locked Loop (Altera PLL) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/altera_pll.pdf)------ === Specifying outputs------ The number of output clocks depends on this function's inferred result type.--- An instance with a single output clock can be instantiated using:------ @--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom100MHz\", vPeriod=10000}------ (clk100 :: 'Clock' Dom100MHz, pllLocked) =---   'alteraPll' ('SSymbol' \@\"alterapll50to100\") clk50 rst50--- @------ An instance with two clocks can be instantiated using------ @--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom100MHz\", vPeriod=10000}--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"Dom150MHz\", vPeriod='Clash.Signal.hzToPeriod' 150e6}------ (clk100 :: 'Clock' Dom100MHz, clk150 :: 'Clock' Dom150MHz, pllLocked) =---   'alteraPll' ('SSymbol' \@\"alterapllmulti\") clk50 rst50--- @------ and so on up to 16 clocks.------ If you don't have a top-level type signature specifying the output clock--- domains, you can specify them using a pattern type signature, as shown here.------ === Example------ When the oscillator connected to the FPGA runs at 50 MHz and the external--- reset signal is /active low/, this will generate a 100 MHz clock for the--- @'Clash.Signal.System'@ domain:------ @--- 'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000}------ topEntity---   :: 'Clock' DomInput---   -> 'Signal' DomInput 'Bool'---   -> [...]--- topEntity clkInp rstInp = [...]---  where---   (clk :: 'Clock' 'Clash.Signal.System', pllStable :: 'Signal' 'Clash.Signal.System' 'Bool')---     'alteraPll' ('SSymbol' \@\"alterapll50to100\") clkInp---               ('Clash.Signal.unsafeFromLowPolarity' rstInp)---   rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromLowPolarity' pllStable)--- @+alteraPllSync ::+  forall t domIn .+  ( HasAsynchronousReset domIn+  , ClocksSyncCxt t domIn+  , NumOutClocksSync t domIn <= 18+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+alteraPllSync clkIn rstIn =+  clocksResetSynchronizer (unsafeAlteraPll clkIn rstIn) clkIn++-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"Altera PLL\" IP core (Arria V, Stratix V, Cyclone V) with 1 reference clock+-- input and a reset input and 1 to 18 output clocks and a @locked@ output. ----- 'Clash.Signal.resetSynchronizer' will keep the reset asserted when--- @pllStable@ is 'False', hence the use of--- @'Clash.Signal.unsafeFromLowPolarity' pllStable@. Your circuit will have--- signals of type @'Signal' 'Clash.Signal.System'@ and all the clocks and--- resets of your components will be the @clk@ and @rst@ signals generated here--- (modulo local resets, which will be based on @rst@ or never asserted at all--- if the component doesn't need a reset).-alteraPll-  :: (Clocks t, KnownDomain domIn, ClocksCxt t)-  => SSymbol name-  -- ^ Name of the component instance+-- This function is deprecated because the @locked@ output is an asynchronous+-- signal. This means the user is required to add a synchronizer and as such+-- this function is unsafe. The common use case is now covered by+-- 'alteraPllSync' and 'unsafeAlteraPll' offers the functionality of this+-- deprecated function for advanced use cases.+alteraPll ::+  forall t domIn name .+  ( HasAsynchronousReset domIn+  , Clocks t+  , ClocksCxt t+  , NumOutClocks t <= 18+  ) =>+  -- | Name of the component instance   --   -- Instantiate as follows: @(SSymbol \@\"alterapll50\")@-  -> Clock domIn-  -- ^ Free running clock (e.g. a clock pin connected to a crystal oscillator)-  -> Reset domIn-  -- ^ Reset for the PLL-  -> t-alteraPll !_ = clocks-{-# NOINLINE alteraPll #-}-{-# ANN alteraPll hasBlackBox #-}+  SSymbol name ->+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+alteraPll _ = setName @name unsafeAlteraPll+{-# INLINE alteraPll #-}+{-# DEPRECATED alteraPll "This function is unsafe. Please see documentation of the function for alternatives." #-}++-- | Instantiate an Intel clock generator corresponding to the Intel/Quartus+-- \"Altera PLL\" IP core (Arria V, Stratix V, Cyclone V) with 1 reference clock+-- input and a reset input and 1 to 18 output clocks and a @locked@ output.+--+-- __NB__: Because the clock generator reacts asynchronously to the incoming+-- reset input, the signal __must__ be glitch-free.+--+-- See also the [Altera Phase-Locked Loop (Altera PLL) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/altera_pll.pdf)+unsafeAlteraPll ::+  forall t domIn .+  ( KnownDomain domIn+  , Clocks t+  , ClocksCxt t+  , NumOutClocks t <= 18+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+unsafeAlteraPll = clocks+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeAlteraPll #-}+{-# ANN unsafeAlteraPll hasBlackBox #-}
src/Clash/Intel/DDR.hs view
@@ -54,7 +54,8 @@   -> Signal slow (BitVector m,BitVector m)   -- ^ normal speed output pairs altddioIn _devFam clk rst en = withFrozenCallStack ddrIn# clk rst en 0 0 0-{-# NOINLINE altddioIn #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE altddioIn #-} {-# ANN altddioIn hasBlackBox #-}  -- | Intel specific variant of 'ddrOut' implemented using the ALTDDIO_OUT IP core.@@ -97,5 +98,6 @@   -> Signal slow (BitVector m)   -> Signal fast (BitVector m) altddioOut# _ clk rst en = ddrOut# clk rst en 0-{-# NOINLINE altddioOut# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE altddioOut# #-} {-# ANN altddioOut# hasBlackBox #-}
src/Clash/Magic.hs view
@@ -1,5 +1,5 @@ {-|-  Copyright   :  (C) 2019, Myrtle Software Ltd+  Copyright   :  (C) 2019-2023, Myrtle Software Ltd   License     :  BSD2 (see the file LICENSE)   Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com> @@ -16,6 +16,10 @@ (VHDL) / modules ((System)Verilog) and their ports. -} +{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+ module Clash.Magic   (   -- ** Functions to control names of identifiers in HDL@@ -30,30 +34,42 @@   -- ** Functions to control Clash's (de)duplication mechanisms   , deDup   , noDeDup++  -- ** Utilities to differentiate between simulation and generating HDL+  , clashSimulation+  , SimOnly (..)++  -- * Static assertions+  , clashCompileError   ) where +import Data.String.Interpolate     (__i)+import GHC.Stack                   (HasCallStack, withFrozenCallStack) import Clash.NamedTypes            ((:::)) import GHC.TypeLits                (Nat,Symbol) import Clash.Promoted.Symbol       (SSymbol)-import Clash.Annotations.Primitive (hasBlackBox)+import Clash.Annotations.Primitive (Primitive(..), hasBlackBox)  -- | Prefix instance and register names with the given 'Symbol' prefixName   :: forall (name :: Symbol) a . a -> name ::: a prefixName = id-{-# NOINLINE prefixName #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE prefixName #-}  -- | Suffix instance and register names with the given 'Symbol' suffixName   :: forall (name :: Symbol) a . a -> name ::: a suffixName = id-{-# NOINLINE suffixName #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE suffixName #-}  -- | Suffix instance and register names with the given 'Nat' suffixNameFromNat   :: forall (name :: Nat) a . a -> name ::: a suffixNameFromNat = id-{-# NOINLINE suffixNameFromNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE suffixNameFromNat #-}  -- | Suffix instance and register names with the given 'Symbol', but add it -- in front of other suffixes.@@ -76,7 +92,8 @@ suffixNameP   :: forall (name :: Symbol) a . a -> name ::: a suffixNameP = id-{-# NOINLINE suffixNameP #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE suffixNameP #-}  -- | Suffix instance and register names with the given 'Nat', but add it in -- front of other suffixes.@@ -99,7 +116,8 @@ suffixNameFromNatP   :: forall (name :: Nat) a . a -> name ::: a suffixNameFromNatP = id-{-# NOINLINE suffixNameFromNatP #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE suffixNameFromNatP #-}  -- | Name the instance or register with the given 'Symbol', instead of using -- an auto-generated name. Pre- and suffixes annotated with 'prefixName' and@@ -108,7 +126,8 @@ setName   :: forall (name :: Symbol) a . a -> name ::: a setName = id-{-# NOINLINE setName #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE setName #-}  -- | Name a given term, such as one of type 'Clash.Signal.Signal', using the -- given 'SSymbol'. Results in a declaration with the name used as the@@ -127,7 +146,8 @@   -- ^ A hint for a name   -> a -> a nameHint = seq-{-# NOINLINE nameHint #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE nameHint #-} {-# ANN nameHint hasBlackBox #-}  -- | Force deduplication, i.e. share a function or operator between multiple@@ -174,7 +194,8 @@ deDup   :: forall a . a -> a deDup = id-{-# NOINLINE deDup #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE deDup #-}  -- | Do not deduplicate, i.e. /keep/, an applied function inside a -- case-alternative; do not try to share the function between multiple@@ -233,4 +254,57 @@ noDeDup   :: forall a . a -> a noDeDup = id-{-# NOINLINE noDeDup #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE noDeDup #-}++-- | 'True' in Haskell/Clash simulation. Replaced by 'False' when generating HDL.+clashSimulation :: Bool+clashSimulation = True+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE clashSimulation #-}++-- | A container for data you only want to have around during simulation and+-- is ignored during synthesis. Useful for carrying around things such as:+--+--   * A map of simulation/vcd traces+--   * Co-simulation state or meta-data+--   * etc.+data SimOnly a = SimOnly a+  deriving (Eq, Ord, Foldable, Traversable)+{-# ANN SimOnly hasBlackBox #-}++instance Functor SimOnly where+  fmap f (SimOnly a) = SimOnly (f a)++instance Applicative SimOnly where+  pure = SimOnly+  (SimOnly f) <*> (SimOnly a) = SimOnly (f a)++instance Monad SimOnly where+  (SimOnly a) >>= f = f a++instance Semigroup a => Semigroup (SimOnly a) where+  (SimOnly a) <> (SimOnly b) = SimOnly (a <> b)++instance Monoid a => Monoid (SimOnly a) where+  mempty = SimOnly mempty++-- | Same as 'error' but will make HDL generation fail if included in the+-- final circuit.+--+-- This is useful for the error case of static assertions.+--+-- Note that the error message needs to be a literal, and during HDL generation+-- the error message does not include a stack trace, so it had better be+-- descriptive.+clashCompileError :: forall a . HasCallStack => String -> a+clashCompileError msg = withFrozenCallStack $ error msg+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE clashCompileError #-}+{-# ANN clashCompileError (+  let primName = 'clashCompileError+  in InlineYamlPrimitive [minBound..] [__i|+    BlackBoxHaskell:+      name: #{primName}+      templateFunction: Clash.Primitives.Magic.clashCompileErrorBBF+    |]) #-}
src/Clash/Num/Erroring.hs view
@@ -8,7 +8,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-}  module Clash.Num.Erroring-  ( Erroring(fromErroring)+  ( Erroring+  , fromErroring  -- exported here because haddock https://github.com/haskell/haddock/issues/456   , toErroring   ) where @@ -19,6 +20,7 @@ import Data.Functor.Compose (Compose(..)) import Data.Hashable (Hashable) import GHC.TypeLits (KnownNat, type (+))+import Test.QuickCheck (Arbitrary)  import Clash.Class.BitPack (BitPack) import Clash.Class.Num (SaturationMode(SatError), SaturatingNum(..))@@ -35,7 +37,8 @@ newtype Erroring a =   Erroring { fromErroring :: a }   deriving newtype-    ( Binary+    ( Arbitrary+    , Binary     , Bits     , BitPack     , Bounded@@ -126,6 +129,7 @@   toRational = coerce (toRational @a)  instance (Integral a, SaturatingNum a) => Integral (Erroring a) where+  -- NOTE the seemingly duplicate "y < 0 && y == -1" guards against unsigned types   quotRem x y     | x == minBound && y < 0 && y == -1 =         (errorX "Erroring.quotRem: result exceeds maxBound", 0)
src/Clash/Num/Overflowing.hs view
@@ -159,6 +159,7 @@   toRational = toRational . fromOverflowing  instance (Integral a, SaturatingNum a) => Integral (Overflowing a) where+  -- NOTE the seemingly duplicate "y < 0 && y == -1" guards against unsigned types   quotRem (Overflowing x a) (Overflowing y b)     | x == minBound && y < 0 && y == -1 =         withOverflow True
src/Clash/Num/Saturating.hs view
@@ -8,7 +8,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-}  module Clash.Num.Saturating-  ( Saturating(fromSaturating)+  ( Saturating+  , fromSaturating  -- exported here because haddock https://github.com/haskell/haddock/issues/456   , toSaturating   ) where @@ -19,6 +20,7 @@ import Data.Functor.Compose (Compose(..)) import Data.Hashable (Hashable) import GHC.TypeLits (KnownNat, type (+))+import Test.QuickCheck (Arbitrary)  import Clash.Class.BitPack (BitPack) import Clash.Class.Num (SaturationMode(SatBound), SaturatingNum(..))@@ -35,7 +37,8 @@ newtype Saturating a =   Saturating { fromSaturating :: a }   deriving newtype-    ( Binary+    ( Arbitrary+    , Binary     , Bits     , BitPack     , Bounded@@ -127,6 +130,7 @@   toRational = coerce (toRational @a)  instance (Integral a, SaturatingNum a) => Integral (Saturating a) where+  -- NOTE the seemingly duplicate "y < 0 && y == -1" guards against unsigned types   quotRem x y     | x == minBound && y < 0 && y == -1 = (maxBound, 0)     | otherwise = coerce (quotRem @a) x y
src/Clash/Num/Wrapping.hs view
@@ -19,6 +19,7 @@ import Data.Functor.Compose (Compose(..)) import Data.Hashable (Hashable) import GHC.TypeLits (KnownNat, type (+))+import Test.QuickCheck (Arbitrary)  import Clash.Class.BitPack (BitPack) import Clash.Class.Num (SaturationMode(SatWrap), SaturatingNum(..))@@ -35,7 +36,8 @@ newtype Wrapping a =   Wrapping { fromWrapping :: a }   deriving newtype-    ( Binary+    ( Arbitrary+    , Binary     , Bits     , BitPack     , Bounded
src/Clash/Num/Zeroing.hs view
@@ -8,7 +8,8 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-}  module Clash.Num.Zeroing-  ( Zeroing(fromZeroing)+  ( Zeroing+  , fromZeroing  -- exported here because haddock https://github.com/haskell/haddock/issues/456   , toZeroing   ) where @@ -19,6 +20,7 @@ import Data.Functor.Compose (Compose(..)) import Data.Hashable (Hashable) import GHC.TypeLits (KnownNat, type (+))+import Test.QuickCheck (Arbitrary)  import Clash.Class.BitPack (BitPack) import Clash.Class.Num (SaturationMode(SatZero), SaturatingNum(..))@@ -34,7 +36,8 @@ newtype Zeroing a =   Zeroing { fromZeroing :: a }   deriving newtype-    ( Binary+    ( Arbitrary+    , Binary     , Bits     , BitPack     , Bounded@@ -126,6 +129,7 @@   toRational = coerce (toRational @a)  instance (Integral a, SaturatingNum a) => Integral (Zeroing a) where+  -- NOTE the seemingly duplicate "y < 0 && y == -1" guards against unsigned types   quotRem x y     | x == minBound && y < 0 && y == -1 = (0, 0)     | otherwise = coerce (quotRem @a) x y
src/Clash/Prelude.hs view
@@ -2,7 +2,7 @@   Copyright   :  (C) 2013-2016, University of Twente,                      2017-2019, Myrtle Software Ltd                      2017     , Google Inc.,-                     2021-2022, QBayLogic B.V.+                     2021-2023, QBayLogic B.V.   License     :  BSD2 (see the file LICENSE)   Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com> @@ -45,7 +45,9 @@ module Clash.Prelude   ( -- * Creating synchronous sequential circuits     mealy+  , mealyS   , mealyB+  , mealySB   , (<^>)   , moore   , mooreB@@ -176,6 +178,9 @@ import           Data.Kind (Type, Constraint) import           GHC.Stack                   (HasCallStack) import           GHC.TypeLits+#if MIN_VERSION_base(4,18,0)+  hiding (SNat, SSymbol, fromSNat)+#endif import           GHC.TypeLits.Extra import           Language.Haskell.TH.Syntax  (Lift(..)) import           Clash.HaskellPrelude
− src/Clash/Prelude/BitIndex.hs
@@ -1,18 +0,0 @@-{-|-Copyright  :  (C) 2013-2016, University of Twente-                  2021,      QBayLogic B.V.-License    :  BSD2 (see the file LICENSE)-Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>--}--module Clash.Prelude.BitIndex {-# DEPRECATED "Use Clash.Class.BitPack instead. This module will be removed in Clash 1.8." #-}-  ( (!)-  , slice-  , split-  , replaceBit-  , setSlice-  , msb-  , lsb-  ) where--import Clash.Class.BitPack.BitIndex
− src/Clash/Prelude/BitReduction.hs
@@ -1,13 +0,0 @@-{-|-Copyright  :  (C) 2013-2016, University of Twente-                  2021,      QBayLogic B.V.-License    :  BSD2 (see the file LICENSE)-Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>--}--module Clash.Prelude.BitReduction {-# DEPRECATED "Use Clash.Class.BitPack instead. This module will be removed in Clash 1.8." #-}-  ( reduceAnd-  , reduceOr-  , reduceXor ) where--import Clash.Class.BitPack.BitReduction
src/Clash/Prelude/BlockRam.hs view
@@ -36,7 +36,7 @@   | Load MemAddr Reg   | Store Reg MemAddr   | Nop-  deriving (Eq, Show)+  deriving (Eq, Show, Generic, NFDataX)  data Reg   = Zero@@ -49,7 +49,7 @@   deriving (Eq, Show, Enum, Generic, NFDataX)  data Operator = Add | Sub | Incr | Imm | CmpGt-  deriving (Eq, Show)+  deriving (Eq, Show, Generic, NFDataX)  data MachCode   = MachCode@@ -448,7 +448,7 @@  >>> :{ data Operator = Add | Sub | Incr | Imm | CmpGt-  deriving (Eq,Show)+  deriving (Eq, Show, Generic, NFDataX) :}  >>> :{@@ -459,7 +459,7 @@   | Load MemAddr Reg   | Store Reg MemAddr   | Nop-  deriving (Eq,Show)+  deriving (Eq, Show, Generic, NFDataX) :}  >>> :{@@ -716,7 +716,7 @@      , HiddenEnable dom      , NFDataX a      , Enum addr-     )+     , NFDataX addr )   => Vec n a   -- ^ Initial content of the BRAM, also determines the size, @n@, of the BRAM   --@@ -739,6 +739,7 @@      , HiddenClockResetEnable dom      , NFDataX a      , Enum addr+     , NFDataX addr      , 1 <= n )   => E.ResetStrategy r   -- ^ Whether to clear BRAM on asserted reset ('Clash.Explicit.BlockRam.ClearOnReset')@@ -767,6 +768,7 @@      , HiddenClockResetEnable dom      , NFDataX a      , Enum addr+     , NFDataX addr      , 1 <= n )   => E.ResetStrategy r   -- ^ Whether to clear BRAM on asserted reset ('Clash.Explicit.BlockRam.ClearOnReset')@@ -834,16 +836,35 @@   (hideEnable (hideClock E.blockRamPow2) cnt rd wrM) {-# INLINE blockRamPow2 #-} --- | Create a read-after-write block RAM from a read-before-write one------ >>> :t readNew (blockRam (0 :> 1 :> Nil))--- readNew (blockRam (0 :> 1 :> Nil))---   :: ...---      ...---      ...---      ...---      ... =>---      Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a+{- | Create a read-after-write block RAM from a read-before-write one++#if __GLASGOW_HASKELL__ >= 908 && !defined(CLASH_MULTIPLE_HIDDEN)+>>> :t readNew (blockRam (0 :> 1 :> Nil))+readNew (blockRam (0 :> 1 :> Nil))+  :: ...+     ...+     ... =>+     Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a++#elif __GLASGOW_HASKELL__ >= 902 && !defined(CLASH_MULTIPLE_HIDDEN)+>>> :t readNew (blockRam (0 :> 1 :> Nil))+readNew (blockRam (0 :> 1 :> Nil))+  :: ...+     ... =>+     Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a++#else+>>> :t readNew (blockRam (0 :> 1 :> Nil))+readNew (blockRam (0 :> 1 :> Nil))+  :: ...+     ...+     ...+     ...+     ... =>+     Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a++#endif+-} readNew   :: ( HiddenClockResetEnable dom      , NFDataX a
src/Clash/Prelude/BlockRam/Blob.hs view
@@ -42,6 +42,7 @@ import Clash.Signal (hideClock, hideEnable, HiddenClock, HiddenEnable, Signal) import Clash.Sized.BitVector (BitVector) import Clash.Sized.Unsigned (Unsigned)+import Clash.XException (NFDataX)  -- | Create a block RAM with space for @n@ elements --@@ -62,6 +63,7 @@    . ( HiddenClock dom      , HiddenEnable dom      , Enum addr+     , NFDataX addr      )   => E.MemBlob n m   -- ^ Initial content of the BRAM, also determines the size, @n@, of the BRAM
src/Clash/Prelude/BlockRam/File.hs view
@@ -102,6 +102,7 @@   (HiddenClock, HiddenEnable, Signal, hideClock, hideEnable) import           Clash.Sized.BitVector        (BitVector) import           Clash.Sized.Unsigned         (Unsigned)+import           Clash.XException             (NFDataX)  -- | Create a block RAM with space for 2^@n@ elements --@@ -181,6 +182,7 @@ blockRamFile   :: ( KnownNat m      , Enum addr+     , NFDataX addr      , HiddenClock dom      , HiddenEnable dom      , HasCallStack )
src/Clash/Prelude/DataFlow.hs view
@@ -20,7 +20,7 @@ {-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise       #-} {-# OPTIONS_HADDOCK show-extensions #-} -module Clash.Prelude.DataFlow {-# DEPRECATED "Module will be removed in future versions of clash-prelude in favor of clash-protocols. See: https://github.com/clash-lang/clash-protocols/." #-}+module Clash.Prelude.DataFlow {-# DEPRECATED "Module will be removed in Clash 1.10 in favor of clash-protocols. See: https://github.com/clash-lang/clash-protocols/." #-}   ( -- * Data types     DataFlow (..)     -- * Creating DataFlow circuits
src/Clash/Prelude/Mealy.hs view
@@ -2,6 +2,7 @@   Copyright  :  (C) 2013-2016, University of Twente,                     2017     , Google Inc.                     2019     , Myrtle Software Ltd+                    2023     , Alex Mason   License    :  BSD2 (see the file LICENSE)   Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> @@ -20,7 +21,9 @@ module Clash.Prelude.Mealy   ( -- * Mealy machine synchronized to the system clock     mealy+  , mealyS   , mealyB+  , mealySB   , (<^>)   ) where@@ -29,9 +32,15 @@ import           Clash.Signal import           Clash.XException           (NFDataX) +import           Control.Monad.State.Strict (State)+ {- $setup->>> :set -XDataKinds -XTypeApplications->>> import Clash.Prelude+>>> :set -XDataKinds -XTypeApplications -XDeriveGeneric -XDeriveAnyClass+>>> import Clash.Prelude as C+>>> import Clash.Prelude.Mealy (mealyS)+>>> import qualified Data.List as L+>>> import Control.Lens (Lens', (%=), (-=), uses, use)+>>> import Control.Monad.State.Strict (State) >>> :{ let macT s (x,y) = (s',s)       where@@ -39,6 +48,41 @@     mac = mealy macT 0 :} +>>> :{+data DelayState = DelayState { _history :: Vec 4 Int , _untilValid :: Index 4 } deriving (Generic,NFDataX)+:}++>>> :{+history :: Lens' DelayState (Vec 4 Int)+history f = \(DelayState d u) -> (`DelayState` u) <$> f d+:}++>>> :{+untilValid :: Lens' DelayState (Index 4)+untilValid f = \(DelayState d u) -> DelayState d <$> f u+:}++>>> :{+delayS :: Int -> State DelayState (Maybe Int)+delayS n = do+  history   %= (n +>>)+  remaining <- use untilValid+  if remaining > 0+  then do+     untilValid -= 1+     return Nothing+   else do+     out <- uses history C.last+     return (Just out)+:}++>>> let initialDelayState = DelayState (C.repeat 0) maxBound++>>> :{+delayTop :: HiddenClockResetEnable dom => Signal dom Int -> Signal dom (Maybe Int)+delayTop = mealyS delayS initialDelayState+:}+ -}  -- | Create a synchronous function from a combinational function describing@@ -128,6 +172,70 @@   -- of the mealy machine mealyB = hideClockResetEnable E.mealyB {-# INLINE mealyB #-}+++-- | Create a synchronous function from a combinational function describing+-- a mealy machine using the state monad. This can be particularly useful+-- when combined with lenses or optics to replicate imperative algorithms.+--+-- @+-- data DelayState = DelayState+--   { _history    :: Vec 4 Int+--   , _untilValid :: Index 4+--   }+--   deriving (Generic, NFDataX)+-- makeLenses ''DelayState+--+-- initialDelayState = DelayState (repeat 0) maxBound+--+-- delayS :: Int -> State DelayState (Maybe Int)+-- delayS n = do+--   history   %= (n +>>)+--   remaining <- use untilValid+--   if remaining > 0+--   then do+--      untilValid -= 1+--      return Nothing+--    else do+--      out <- uses history last+--      return (Just out)+--+-- delayTop :: HiddenClockResetEnable dom  => 'Signal' dom Int -> 'Signal' dom (Maybe Int)+-- delayTop = 'mealyS' delayS initialDelayState+-- @+--+-- >>> L.take 7 $ simulate @System delayTop [1,2,3,4,5,6,7,8]+-- [Nothing,Nothing,Nothing,Just 1,Just 2,Just 3,Just 4]+-- ...+--+mealyS+  :: ( HiddenClockResetEnable dom+     , NFDataX s )+  => (i -> State s o)+  --  ^ Transfer function in mealy machine handling inputs using @Control.Monad.Strict.State s@.+  -> s+  -- ^ Initial state+  -> (Signal dom i -> Signal dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealyS = hideClockResetEnable E.mealyS+{-# INLINE mealyS #-}++-- | A version of 'mealyS' that does automatic 'Bundle'ing, see 'mealyB' for details.+mealySB+  :: ( HiddenClockResetEnable dom+     , NFDataX s+     , Bundle i+     , Bundle o  )+  => (i -> State s o)+  --  ^ Transfer function in mealy machine handling inputs using @Control.Monad.Strict.State s@.+  -> s+  -- ^ Initial state+  -> (Unbundled dom i -> Unbundled dom o)+  -- ^ Synchronous sequential function with input and output matching that+  -- of the mealy machine+mealySB = hideClockResetEnable E.mealySB+{-# INLINE mealySB #-}  -- | Infix version of 'mealyB' (<^>)
src/Clash/Prelude/RAM.hs view
@@ -46,6 +46,7 @@ -- RAM. asyncRam   :: ( Enum addr+     , NFDataX addr      , HiddenClock dom      , HiddenEnable dom      , HasCallStack
src/Clash/Prelude/ROM.hs view
@@ -9,6 +9,7 @@ ROMs -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} @@ -41,7 +42,7 @@ import           Clash.Sized.Unsigned (Unsigned) import           Clash.Sized.Vector   (Vec, length, toList) -import           Clash.XException     (NFDataX, errorX)+import           Clash.XException     (NFDataX, deepErrorX)  -- | An asynchronous/combinational ROM with space for @n@ elements --@@ -54,7 +55,10 @@ -- 'Clash.Prelude.ROM.Blob.asyncRomBlob' for different approaches that scale -- well. asyncRom-  :: (KnownNat n, Enum addr)+  :: ( KnownNat n+     , Enum addr+     , NFDataX a+     )   => Vec n a   -- ^ ROM content, also determines the size, @n@, of the ROM   --@@ -77,7 +81,9 @@ -- 'Clash.Prelude.ROM.Blob.asyncRomBlobPow2' for different approaches that scale -- well. asyncRomPow2-  :: KnownNat n+  :: ( KnownNat n+     , NFDataX a+     )   => Vec (2^n) a   -- ^ ROM content   --@@ -91,7 +97,10 @@  -- | asyncRom primitive asyncRom#-  :: forall n a . KnownNat n+  :: forall n a+   . ( KnownNat n+     , NFDataX a+     )   => Vec n a   -- ^ ROM content, also determines the size, @n@, of the ROM   --@@ -111,9 +120,10 @@         unsafeAt arr i       else         withFrozenCallStack-          (errorX ("asyncRom: address " ++ show i ++-                  " not in range [0.." ++ show szI ++ ")"))-{-# NOINLINE asyncRom# #-}+          (deepErrorX ("asyncRom: address " ++ show i +++                       " not in range [0.." ++ show szI ++ ")"))+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE asyncRom# #-} {-# ANN asyncRom# hasBlackBox #-}  -- | A ROM with a synchronous read port, with space for @n@ elements
src/Clash/Prelude/ROM/Blob.hs view
@@ -18,6 +18,7 @@ the generated HDL. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE Trustworthy #-}  {-# OPTIONS_HADDOCK show-extensions #-}@@ -118,7 +119,8 @@           (deepErrorX ("asyncRom: address " ++ show i ++                        " not in range [0.." ++ show szI ++ ")")) {-# ANN asyncRomBlob# hasBlackBox #-}-{-# NOINLINE asyncRomBlob# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE asyncRomBlob# #-}  -- | A ROM with a synchronous read port, with space for @n@ elements --
src/Clash/Prelude/ROM/File.hs view
@@ -74,6 +74,7 @@ @ -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}  {-# LANGUAGE Unsafe #-}@@ -255,7 +256,8 @@     mem     = unsafePerformIO (initMem file)     content = listArray (0,szI-1) mem     szI     = snatToNum sz-{-# NOINLINE asyncRomFile# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE asyncRomFile# #-} {-# ANN asyncRomFile# hasBlackBox #-}  -- | A ROM with a synchronous read port, with space for @n@ elements
src/Clash/Prelude/Safe.hs view
@@ -30,6 +30,7 @@   Some circuit examples can be found in "Clash.Examples". -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoGeneralizedNewtypeDeriving #-}@@ -41,7 +42,9 @@ module Clash.Prelude.Safe   ( -- * Creating synchronous sequential circuits     mealy+  , mealyS   , mealyB+  , mealySB   , (<^>)   , moore   , mooreB@@ -135,6 +138,9 @@ import           GHC.Generics (Generic, Generic1)  import           GHC.TypeLits+#if MIN_VERSION_base(4,18,0)+  hiding (SNat, SSymbol, fromSNat)+#endif import           GHC.TypeLits.Extra import           Clash.HaskellPrelude @@ -147,7 +153,7 @@ import           Clash.Prelude.BlockRam import           Clash.Prelude.BlockRam.Blob import qualified Clash.Explicit.Prelude.Safe as E-import           Clash.Prelude.Mealy         (mealy, mealyB, (<^>))+import           Clash.Prelude.Mealy         (mealy, mealyB, mealyS, mealySB, (<^>)) import           Clash.Prelude.Moore         (moore, mooreB) import           Clash.Prelude.RAM           (asyncRam,asyncRamPow2) import           Clash.Prelude.ROM           (asyncRom,asyncRomPow2,rom,romPow2)
src/Clash/Prelude/Testbench.hs view
@@ -2,7 +2,7 @@ Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Google Inc.                   2019     , Myrtle Software Ltd,-                  2021     , QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -26,6 +26,7 @@   , E.tbClockGen   , E.tbEnableGen   , E.tbSystemClockGen+  , E.clockToDiffClock   ) where 
src/Clash/Promoted/Nat.hs view
@@ -225,8 +225,10 @@ -- __NB__: Not synthesizable predUNat :: UNat (n+1) -> UNat n predUNat (USucc x) = x+#if __GLASGOW_HASKELL__ != 902 predUNat UZero     =   error "predUNat: impossible: 0 minus 1, -1 is not a natural number"+#endif  -- | Subtract two unary-encoded natural numbers --@@ -267,7 +269,8 @@ -- | Power of two singleton natural numbers powSNat :: SNat a -> SNat b -> SNat (a^b) powSNat SNat SNat = SNat-{-# NOINLINE powSNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE powSNat #-} {-# ANN powSNat hasBlackBox #-} infixr 8 `powSNat` @@ -295,7 +298,8 @@              -> SNat x              -> SNat (FLog base x) flogBaseSNat SNat SNat = SNat-{-# NOINLINE flogBaseSNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE flogBaseSNat #-} {-# ANN flogBaseSNat hasBlackBox #-}  -- | Ceiling of the logarithm of a natural number@@ -304,7 +308,8 @@              -> SNat x              -> SNat (CLog base x) clogBaseSNat SNat SNat = SNat-{-# NOINLINE clogBaseSNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE clogBaseSNat #-} {-# ANN clogBaseSNat hasBlackBox #-}  -- | Exact integer logarithm of a natural number@@ -315,7 +320,8 @@             -> SNat x             -> SNat (Log base x) logBaseSNat SNat SNat = SNat-{-# NOINLINE logBaseSNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE logBaseSNat #-} {-# ANN logBaseSNat hasBlackBox #-}  -- | Power of two of a singleton natural number@@ -482,7 +488,9 @@ -- -- __NB__: Not synthesizable log2BNat :: BNat (2^n) -> BNat n+#if __GLASGOW_HASKELL__ != 902 log2BNat BT = error "log2BNat: log2(0) not defined"+#endif log2BNat (B1 x) = case stripZeros x of   BT -> BT   _  -> error "log2BNat: impossible: 2^n ~ 2x+1"
src/Clash/Promoted/Nat/Unsafe.hs view
@@ -5,6 +5,7 @@ Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -} +{-# LANGUAGE CPP #-} {-# LANGUAGE Unsafe #-}  module Clash.Promoted.Nat.Unsafe@@ -20,5 +21,6 @@ -- | I hope you know what you're doing unsafeSNat :: Integer -> SNat k unsafeSNat i = reifyNat i $ (\p -> unsafeCoerce (snatProxy p))-{-# NOINLINE unsafeSNat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeSNat #-} {-# ANN unsafeSNat hasBlackBox #-}
src/Clash/Signal.hs view
@@ -2,7 +2,7 @@ Copyright  :  (C) 2013-2016, University of Twente,                   2016-2019, Myrtle Software Ltd,                   2017     , Google Inc.,-                  2021     , QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -106,6 +106,13 @@   , DomainResetKind   , DomainInitBehavior   , DomainResetPolarity+    -- *** Convenience types+    -- **** Simplifying+    -- $conveniencetypes++  , HasSynchronousReset+  , HasAsynchronousReset+  , HasDefinedInitialValues     -- ** Default domains   , System   , XilinxSystem@@ -125,6 +132,7 @@   , resetPolarity     -- * Clock   , Clock+  , DiffClock   , periodToHz   , hzToPeriod #ifdef CLASH_MULTIPLE_HIDDEN@@ -135,10 +143,10 @@   , Reset   , unsafeToReset   , unsafeFromReset-  , unsafeToHighPolarity-  , unsafeToLowPolarity-  , unsafeFromHighPolarity-  , unsafeFromLowPolarity+  , unsafeToActiveHigh+  , unsafeToActiveLow+  , unsafeFromActiveHigh+  , unsafeFromActiveLow #ifdef CLASH_MULTIPLE_HIDDEN   , convertReset #endif@@ -261,11 +269,18 @@   , HiddenClockName   , HiddenResetName   , HiddenEnableName++    -- * Deprecated+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+  , unsafeToHighPolarity+  , unsafeToLowPolarity   ) where  import           Control.Arrow.Transformer.Automaton (Automaton) import           GHC.TypeLits          (type (<=))+import           Data.List             (uncons) import           Data.Proxy            (Proxy(..)) import           Prelude import           Test.QuickCheck       (Property, property)@@ -317,6 +332,34 @@  -} +{- $conveniencetypes++If you want to write part of your Clash design as domain-polymorphic functions,+it can be practical to define a design-wide constraint synonym that captures the+characteristics of the clock domains of the design. Such a constraint synonym+can be used as a constraint on all domain-polymorphic functions in the design,+regardless of whether they actually need the constraints from this section.++@+type DesignDomain dom =+  ( 'HasSynchronousReset' dom+  , 'HasDefinedInitialValues' dom+  )++type DesignDomainHidden dom =+  ( DesignDomain dom+  , 'HiddenClockResetEnable' dom+  )++myFunc ::+  DesignDomainHidden dom =>+  'Signal' dom [...]+@++This way, you don't have to think about which constraints the function you're+writing has exactly, and the constraint is succinct.+-}+ {- $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@@ -406,7 +449,7 @@ 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':+components such as PLLs:  @ topEntity@@ -415,9 +458,8 @@   -> 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)-    in   'exposeClockResetEnable' leds pllOut rstSync enableGen+    let  (pllOut,pllRst) = 'Clash.Intel.ClockGen.altpllSync' clk rst+    in   'exposeClockResetEnable' leds pllOut pllRst enableGen   where     key1R  = isRising 1 key1     leds   = mealy blinkerT (1, False, 0) key1R@@ -432,9 +474,8 @@   -> 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)-    in   'withClockResetEnable' pllOut rstSync enableGen leds+    let  (pllOut,pllRst) = 'Clash.Intel.ClockGen.altpllSync' clk rst+    in   'withClockResetEnable' pllOut pllRst enableGen leds   where     key1R  = isRising 1 key1     leds   = mealy blinkerT (1, False, 0) key1R@@ -1800,7 +1841,8 @@   -> [a] sample s =   E.sample (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sample #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE sample #-}  -- | Get a list of /n/ samples from a 'Signal' --@@ -1829,7 +1871,8 @@ sampleN n s0 =   let s1 = exposeClockResetEnable @dom s0 clockGen resetGen enableGen in   E.sampleN n s1-{-# NOINLINE sampleN #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE 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/@@ -1850,7 +1893,8 @@ sampleWithReset nReset f0 =   let f1 = exposeClockResetEnable f0 clockGen (resetGenN @dom nReset) enableGen in   drop (snatToNum nReset) (E.sample f1)-{-# NOINLINE sampleWithReset #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE 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,@@ -1895,7 +1939,8 @@   -> [a] sample_lazy s =   E.sample_lazy (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sample_lazy #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE sample_lazy #-}  -- | Lazily get a list of /n/ samples from a 'Signal' --@@ -1920,7 +1965,8 @@   -> [a] sampleN_lazy n s =   E.sampleN_lazy n (exposeClockResetEnable @dom s clockGen resetGen enableGen)-{-# NOINLINE sampleN_lazy #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE sampleN_lazy #-}  -- * Simulation functions @@ -1951,7 +1997,9 @@   -- and/or enable.   -> [a]   -> [b]-simulate f as = simulateWithReset (SNat @1) (head as) f as+simulate f as = simulateWithReset (SNat @1) rval f as+  where+    rval = maybe (error "simulate: no stimuli") fst (uncons as) {-# INLINE simulate #-}  -- | Same as 'simulate', but only sample the first /Int/ output values.@@ -1969,7 +2017,9 @@   -- (and reset)   -> [a]   -> [b]-simulateN n f as = simulateWithResetN (SNat @1) (head as) n f as+simulateN n f as = simulateWithResetN (SNat @1) rval n f as+  where+    rval = maybe (error "simulate: no stimuli") fst (uncons as) {-# INLINE simulateN #-}  -- | Same as 'simulate', but with the reset line asserted for /n/ cycles. Similar@@ -2037,8 +2087,9 @@   -> [b] simulate_lazy f0 =   let f1 = exposeClockResetEnable @dom f0 clockGen resetGen enableGen in-  tail . E.simulate_lazy f1 . dup1-{-# NOINLINE simulate_lazy #-}+  drop 1 . E.simulate_lazy f1 . dup1+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE simulate_lazy #-}  -- | Simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a list of -- samples of type @a@@@ -2063,7 +2114,7 @@   -> [a]   -> [b] simulateB f0 =-  tail . E.simulateB f1 . dup1+  drop 1 . E.simulateB f1 . dup1  where   f1 =     withSpecificClockResetEnable@@ -2073,7 +2124,8 @@       enableGen       (const f0)       (Proxy @dom)-{-# NOINLINE simulateB #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE simulateB #-}  -- | /Lazily/ simulate a (@'Unbundled' a -> 'Unbundled' b@) function given a -- list of samples of type @a@@@ -2095,7 +2147,7 @@   -> [a]   -> [b] simulateB_lazy f0 =-  tail . E.simulateB_lazy f1 . dup1+  drop 1 . E.simulateB_lazy f1 . dup1  where   f1 =     withSpecificClockResetEnable@@ -2105,7 +2157,8 @@       enableGen       (const f0)       (Proxy @dom)-{-# NOINLINE simulateB_lazy #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE simulateB_lazy #-}  dup1 :: [a] -> [a] dup1 (x:xs) = x:x:xs@@ -2225,7 +2278,7 @@ -- -- Example: ----- >>> sampleN @System 8 (unsafeToHighPolarity (holdReset (SNat @2)))+-- >>> sampleN @System 8 (unsafeToActiveHigh (holdReset (SNat @2))) -- [True,True,True,False,False,False,False,False] -- -- 'holdReset' holds the reset for an additional 2 clock cycles for a total@@ -2243,7 +2296,7 @@  -- | Like 'fromList', but resets on reset and has a defined reset value. ----- >>> let rst = unsafeFromHighPolarity (fromList [True, True, False, False, True, False])+-- >>> let rst = unsafeFromActiveHigh (fromList [True, True, False, False, True, False]) -- >>> let res = withReset rst (fromListWithReset Nothing [Just 'a', Just 'b', Just 'c']) -- >>> sampleN @System 6 res -- [Nothing,Nothing,Just 'a',Just 'b',Nothing,Just 'a']@@ -2285,4 +2338,5 @@ signalAutomaton f0 =   let f1 = exposeClockResetEnable @dom f0 clockGen resetGen enableGen in   E.signalAutomaton f1-{-# NOINLINE signalAutomaton #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE signalAutomaton #-}
src/Clash/Signal/BiSignal.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2017, Google Inc.                   2019, Myrtle Software Ltd-                  2022, QBayLogic B.V.+                  2022-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -127,7 +127,7 @@ import qualified Clash.Sized.Vector         as V import           Clash.Sized.Vector         (Vec) import           Clash.Signal.Internal      (Signal(..), Domain, head#, tail#)-import           Clash.XException           (errorX, fromJustX)+import           Clash.XException           (errorX, fromJustX, NFDataX)  import           GHC.TypeLits               (KnownNat, Nat) import           GHC.Stack                  (HasCallStack)@@ -203,7 +203,7 @@ -- -- as it is not safe to coerce the default behaviour, synthesis domain or width -- of the data in the signal.-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0) data BiSignalOut (ds :: BiSignalDefault) (dom :: Domain) (n :: Nat)   = BiSignalOut ![Signal dom (Maybe (BitVector n))] #else@@ -214,13 +214,13 @@ type instance HasDomain dom1 (BiSignalOut ds dom2 n) = DomEq dom1 dom2 type instance TryDomain t (BiSignalOut ds dom n) = 'Found dom --- | __NB__ Not synthesizable+-- | __NB__: Not synthesizable instance Semigroup (BiSignalOut defaultState dom n) where   (BiSignalOut b1) <> (BiSignalOut b2) = BiSignalOut (b1 ++ b2)  -- | Monoid instance to support concatenating ----- __NB__ Not synthesizable+-- __NB__: Not synthesizable instance Monoid (BiSignalOut defaultState dom n) where   mempty = BiSignalOut [] @@ -245,7 +245,8 @@     SFloating -> fromMaybe (errorX " undefined value on BiSignalIn") <$> s     SPullDown  -> fromMaybe minBound <$> s     SPullUp    -> fromMaybe maxBound <$> s-{-# NOINLINE readFromBiSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE readFromBiSignal# #-} {-# ANN readFromBiSignal# hasBlackBox #-}  -- | Read the value from an __inout__ port@@ -265,7 +266,8 @@   => Vec n (BiSignalOut defaultState dom m)   -> BiSignalOut defaultState dom m mergeBiSignalOuts = mconcat . V.toList-{-# NOINLINE mergeBiSignalOuts #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE mergeBiSignalOuts #-} {-# ANN mergeBiSignalOuts hasBlackBox #-}  writeToBiSignal#@@ -277,12 +279,13 @@   -> BiSignalOut ds d n -- writeToBiSignal# = writeToBiSignal# writeToBiSignal# _ maybeSignal _ _ = BiSignalOut [maybeSignal]-{-# NOINLINE writeToBiSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE writeToBiSignal# #-} {-# ANN writeToBiSignal# hasBlackBox #-}  -- | Write to an __inout__ port writeToBiSignal-  :: (HasCallStack, BitPack a)+  :: (HasCallStack, BitPack a, NFDataX a)   => BiSignalIn ds d (BitSize a)   -> Signal d (Maybe a)   -- ^ Value to write@@ -324,5 +327,6 @@      -- Recursive step     biSignalOut' = veryUnsafeToBiSignalIn $ BiSignalOut $ map tail# signals-{-# NOINLINE veryUnsafeToBiSignalIn #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE veryUnsafeToBiSignalIn #-} {-# ANN veryUnsafeToBiSignalIn hasBlackBox #-}
src/Clash/Signal/Bundle.hs view
@@ -142,7 +142,7 @@ instance Bundle (Signed n) instance Bundle (Unsigned n) --- | __N.B.__: The documentation only shows instances up to /3/-tuples. By+-- | __NB__: The documentation only shows instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version.@@ -155,7 +155,8 @@   bundle   = vecBundle#   unbundle = sequenceA . fmap lazyV -{-# NOINLINE vecBundle# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE vecBundle# #-} {-# ANN vecBundle# hasBlackBox #-} vecBundle# :: Vec n (Signal t a) -> Signal t (Vec n a) vecBundle# = traverse# id
src/Clash/Signal/Bundle/Internal.hs view
@@ -1,14 +1,16 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-}  module Clash.Signal.Bundle.Internal (deriveBundleTuples, idPrimitive) where  import           Control.Monad.Extra         (concatMapM)-import           Clash.Annotations.Primitive (Primitive(InlinePrimitive))+import           Clash.Annotations.Primitive (Primitive(InlineYamlPrimitive)) import           Clash.CPP                   (maxTupleSize) import           Clash.Signal.Internal       (Signal((:-))) import           Clash.XException            (seqX)-import           Data.List                   (foldl')+import           Data.List                   (foldl', uncons)+import           Data.String.Interpolate     (__i) import qualified Language.Haskell.TH.Syntax  as TH import           Language.Haskell.TH import           Language.Haskell.TH.Compat@@ -17,8 +19,11 @@ idPrimitive nm =   PragmaD . AnnP (ValueAnnotation nm) <$> TH.liftData ip  where-  ipJson = "[{\"Primitive\": {\"name\": \"" ++ show nm ++ "\", \"primType\": \"Function\"}}]"-  ip = InlinePrimitive [minBound..maxBound] ipJson+  ip = InlineYamlPrimitive [minBound..] [__i|+         Primitive:+           name: #{nm}+           primType: Function+         |]  -- | Contruct all the tuple instances for Bundle. deriveBundleTuples@@ -130,13 +135,13 @@           UInfixE             (LamE (map VarP aPrimeNames) (mkTupE (map VarE aPrimeNames)))             (VarE '(<$>))-            (VarE (head aNames))+            (VarE (maybe (error "impossible") fst (uncons aNames)))          bundleFBody =           foldl'             (\e n -> UInfixE e (VarE '(<*>)) (VarE n))             bundleFmap-            (tail aNames)+            (drop 1 aNames)          bundleF =           FunD
src/Clash/Signal/Delayed.hs view
@@ -89,29 +89,39 @@   -> DSignal dom (n + d) a delayed = hideClockResetEnable E.delayed --- | Delay a 'DSignal' for @d@ periods, where @d@ is derived from the context.------ @--- delay2---   :: HiddenClockResetEnable dom---   => Int---   -> 'DSignal' dom n Int---   -> 'DSignal' dom (n + 2) Int--- delay2 = 'delayedI'--- @------ >>> sampleN @System 7 (toSignal (delay2 (-1) (dfromList [0..])))--- [-1,-1,-1,1,2,3,4]------ Or @d@ can be specified using type application:------ >>> :t delayedI @3--- delayedI @3---   :: (...---       ...---       ...---       ...) =>---      a -> DSignal dom n a -> DSignal dom (n + 3) a+{- | Delay a 'DSignal' for @d@ periods, where @d@ is derived from the context.++@+delay2+  :: HiddenClockResetEnable dom+  => Int+  -> 'DSignal' dom n Int+  -> 'DSignal' dom (n + 2) Int+delay2 = 'delayedI'+@++>>> sampleN @System 7 (toSignal (delay2 (-1) (dfromList [0..])))+[-1,-1,-1,1,2,3,4]++Or @d@ can be specified using type application:++#if __GLASGOW_HASKELL__ >= 902+>>> :t delayedI @3+delayedI @3+  :: ... =>+     a -> DSignal dom n a -> DSignal dom (n + 3) a++#else+>>> :t delayedI @3+delayedI @3+  :: (...+      ...+      ...+      ...) =>+     a -> DSignal dom n a -> DSignal dom (n + 3) a++#endif+-} delayedI   :: ( KnownNat d      , NFDataX a
src/Clash/Signal/Delayed/Bundle.hs view
@@ -18,7 +18,9 @@   , TaggedEmptyTuple(..)   ) where +#if !MIN_VERSION_base(4,18,0) import           Control.Applicative           (liftA2)+#endif import           GHC.TypeLits                  (KnownNat) import           Prelude                       hiding (head, map, tail) 
src/Clash/Signal/Internal.hs view
@@ -1,8 +1,8 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017-2019, Myrtle Software Ltd-                  2017     , Google Inc.,-                  2021-2022, QBayLogic B.V.+                  2017-2022, Google Inc.,+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -13,6 +13,9 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-}@@ -63,6 +66,13 @@   , DomainConfigurationResetKind   , DomainConfigurationInitBehavior   , DomainConfigurationResetPolarity++    -- *** Convenience types++  , HasSynchronousReset+  , HasAsynchronousReset+  , HasDefinedInitialValues+     -- ** Default domains   , System   , XilinxSystem@@ -76,9 +86,13 @@   , createDomain     -- * Clocks   , Clock (..)-  , clockTag+  , ClockN (..)+  , DiffClock (..)   , hzToPeriod   , periodToHz+  , ClockAB (..)+  , clockTicks+  , clockTicksEither     -- ** Enabling   , Enable(..)   , toEnable@@ -88,10 +102,10 @@   , Reset(..)   , unsafeToReset   , unsafeFromReset-  , unsafeToHighPolarity-  , unsafeToLowPolarity-  , unsafeFromHighPolarity-  , unsafeFromLowPolarity+  , unsafeToActiveHigh+  , unsafeToActiveLow+  , unsafeFromActiveHigh+  , unsafeFromActiveLow   , invertReset     -- * Basic circuits   , delay#@@ -102,6 +116,14 @@   , mux     -- * Simulation and testbench functions   , clockGen+  , tbClockGen+  , Femtoseconds(..)  -- experimental, do not expose in public API+  , fsToHz            -- experimental, do not expose in public API+  , hzToFs            -- experimental, do not expose in public API+  , unFemtoseconds    -- experimental, do not expose in public API+  , mapFemtoseconds   -- experimental, do not expose in public API+  , tbDynamicClockGen -- experimental, do not expose in public API+  , dynamicClockGen   -- experimental, do not expose in public API   , resetGen   , resetGenN     -- * Boolean connectives@@ -138,27 +160,38 @@   , traverse#   -- * EXTREMELY EXPERIMENTAL   , joinSignal#++  -- * Deprecated+  , unsafeFromHighPolarity+  , unsafeFromLowPolarity+  , unsafeToHighPolarity+  , unsafeToLowPolarity   ) where  import Data.IORef                 (IORef, atomicModifyIORef, newIORef, readIORef) import Type.Reflection            (Typeable) import Control.Arrow.Transformer.Automaton-import Control.Applicative        (liftA2, liftA3)+#if !MIN_VERSION_base(4,18,0)+import Control.Applicative        (liftA2)+#endif+import Control.Applicative        (liftA3) import Control.DeepSeq            (NFData) import Clash.Annotations.Primitive (hasBlackBox, dontTranslate) import Data.Binary                (Binary) import Data.Char                  (isAsciiUpper, isAlphaNum, isAscii)+import Data.Coerce                (coerce) import Data.Data                  (Data) import Data.Default.Class         (Default (..)) import Data.Hashable              (Hashable)+import Data.Int                   (Int64) import Data.Maybe                 (isJust) import Data.Proxy                 (Proxy(..)) import Data.Ratio                 (Ratio) import Data.Type.Equality         ((:~:)) import GHC.Generics               (Generic)-import GHC.Stack                  (HasCallStack)-import GHC.TypeLits               (KnownSymbol, Nat, Symbol, type (<=), sameSymbol)+import GHC.Stack                  (HasCallStack, withFrozenCallStack)+import GHC.TypeLits               (KnownSymbol, KnownNat, Nat, Symbol, type (<=), sameSymbol) import Language.Haskell.TH.Syntax -- (Lift (..), Q, Dec) import Language.Haskell.TH.Compat import Numeric.Natural            (Natural)@@ -167,6 +200,7 @@                                    property)  import Clash.CPP                  (fStrictMapSignal)+import Clash.NamedTypes import Clash.Promoted.Nat         (SNat (..), snatToNum, snatToNatural) import Clash.Promoted.Symbol      (SSymbol (..), ssymbolToString) import Clash.XException@@ -179,7 +213,10 @@ >>> import Clash.Prelude (SSymbol(..)) >>> import Clash.Signal.Internal >>> import Clash.Promoted.Nat+>>> import Clash.Promoted.Nat.Literals >>> import Clash.XException+>>> import Data.Ratio (Ratio)+>>> import Numeric.Natural (Natural) >>> type System = "System" >>> let systemClockGen = clockGen @System >>> let systemResetGen = resetGen @System@@ -188,7 +225,6 @@ >>> let registerA = register -} - -- * Signal  -- | Determines clock edge memory elements are sensitive to. Not yet@@ -219,7 +255,7 @@   -- ^ Elements respond /synchronously/ to changes in their reset input. This   -- means that changes in their reset input won't take effect until the next   -- active clock edge. Common on Xilinx FPGA platforms.-  deriving (Show, Read, Eq, Ord, Generic, NFData, Data, Hashable)+  deriving (Show, Read, Eq, Ord, Generic, NFData, Data, Hashable, Binary)  -- | Singleton version of 'ResetKind' data SResetKind (resetKind :: ResetKind) where@@ -239,7 +275,7 @@   -- ^ Reset is considered active if underlying signal is 'True'.   | ActiveLow   -- ^ Reset is considered active if underlying signal is 'False'.-  deriving (Eq, Ord, Show, Read, Generic, NFData, Data, Hashable)+  deriving (Eq, Ord, Show, Read, Generic, NFData, Data, Hashable, Binary)  -- | Singleton version of 'ResetPolarity' data SResetPolarity (polarity :: ResetPolarity) where@@ -260,7 +296,7 @@   -- ^ If applicable, power up value of a memory element is defined. Applies to   -- 'Clash.Signal.register's for example, but not to   -- 'Clash.Prelude.BlockRam.blockRam'.-  deriving (Show, Read, Eq, Ord, Generic, NFData, Data, Hashable)+  deriving (Show, Read, Eq, Ord, Generic, NFData, Data, Hashable, Binary)  data SInitBehavior (init :: InitBehavior) where   SUnknown :: SInitBehavior 'Unknown@@ -343,6 +379,32 @@ type DomainResetKind (dom :: Domain) =   DomainConfigurationResetKind (KnownConf dom) +-- | Convenience type to constrain a domain to have synchronous resets. Example+-- usage:+--+-- @+-- myFunc :: HasSynchronousReset dom => ...+-- @+--+-- Using this type implies 'KnownDomain'.+--+-- [Click here for usage hints]("Clash.Explicit.Signal#g:conveniencetypes")+type HasSynchronousReset (dom :: Domain) =+  (KnownDomain dom, DomainResetKind dom ~ 'Synchronous)++-- | Convenience type to constrain a domain to have asynchronous resets. Example+-- usage:+--+-- @+-- myFunc :: HasAsynchronousReset dom => ...+-- @+--+-- Using this type implies 'KnownDomain'.+--+-- [Click here for usage hints]("Clash.Explicit.Signal#g:conveniencetypes")+type HasAsynchronousReset (dom :: Domain) =+  (KnownDomain dom, DomainResetKind dom ~ 'Asynchronous)+ -- | Convenience type to help to extract the initial value behavior from a -- domain. Example usage: --@@ -352,6 +414,22 @@ type DomainInitBehavior (dom :: Domain) =   DomainConfigurationInitBehavior (KnownConf dom) +-- | Convenience type to constrain a domain to have initial values. Example+-- usage:+--+-- @+-- myFunc :: HasDefinedInitialValues dom => ...+-- @+--+-- Using this type implies 'KnownDomain'.+--+-- Note that there is no @UnknownInitialValues dom@ as a component that works+-- without initial values will also work if it does have them.+--+-- [Click here for usage hints]("Clash.Explicit.Signal#g:conveniencetypes")+type HasDefinedInitialValues (dom :: Domain) =+  (KnownDomain dom, DomainInitBehavior dom ~ 'Defined)+ -- | Convenience type to help to extract the reset polarity from a domain. -- Example usage: --@@ -363,22 +441,21 @@  -- | Singleton version of 'DomainConfiguration' data SDomainConfiguration (dom :: Domain) (conf :: DomainConfiguration) where-  SDomainConfiguration-    :: SSymbol dom-    -- Domain name ^-    -> SNat period-    -- Period of clock in /ps/ ^-    -> SActiveEdge edge-    -- Active edge of the clock (not yet-    -- implemented) ^-    -> SResetKind reset-    -- Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive) ^-    -> SInitBehavior init-    -- Whether the initial (or "power up") value of memory elements is-    -- unknown/undefined, or configurable to a specific value ^-    -> SResetPolarity polarity-    -- Whether resets are active high or active low ^-    -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)+  SDomainConfiguration ::+    { sName :: SSymbol dom+      -- ^ Domain name+    , sPeriod :: SNat period+    -- ^ Period of clock in /ps/+    , sActiveEdge :: SActiveEdge edge+    -- ^ Active edge of the clock (not yet implemented)+    , sResetKind :: SResetKind reset+    -- ^ Whether resets are synchronous (edge-sensitive) or asynchronous (level-sensitive)+    , sInitBehavior :: SInitBehavior init+    -- ^ Whether the initial (or "power up") value of memory elements is+    -- unknown/undefined, or configurable to a specific value+    , sResetPolarity :: SResetPolarity polarity+    -- ^ Whether resets are active high or active low+    } -> SDomainConfiguration dom ('DomainConfiguration dom period edge reset init polarity)  deriving instance Show (SDomainConfiguration dom conf) @@ -386,20 +463,20 @@  -- | A 'KnownDomain' constraint indicates that a circuit's behavior depends on -- some properties of a domain. See 'DomainConfiguration' for more information.-class KnownSymbol dom => KnownDomain (dom :: Domain) where+class (KnownSymbol dom, KnownNat (DomainPeriod dom)) => KnownDomain (dom :: Domain) where   type KnownConf dom :: DomainConfiguration   -- | Returns 'SDomainConfiguration' corresponding to an instance's 'DomainConfiguration'.   --   -- Example usage:   --   -- >>> knownDomain @System-  -- SDomainConfiguration (SSymbol @"System") (SNat @10000) SRising SAsynchronous SDefined SActiveHigh+  -- SDomainConfiguration {sName = SSymbol @"System", sPeriod = SNat @10000, sActiveEdge = SRising, sResetKind = SAsynchronous, sInitBehavior = SDefined, sResetPolarity = SActiveHigh}   knownDomain :: SDomainConfiguration dom (KnownConf dom)  -- | Version of 'knownDomain' that takes a 'SSymbol'. For example: -- -- >>> knownDomainByName (SSymbol @"System")--- SDomainConfiguration (SSymbol @"System") (SNat @10000) SRising SAsynchronous SDefined SActiveHigh+-- SDomainConfiguration {sName = SSymbol @"System", sPeriod = SNat @10000, sActiveEdge = SRising, sResetKind = SAsynchronous, sInitBehavior = SDefined, sResetPolarity = SActiveHigh} knownDomainByName   :: forall dom    . KnownDomain dom@@ -502,7 +579,7 @@   , vResetPolarity :: ResetPolarity   -- ^ Corresponds to '_resetPolarity' on 'DomainConfiguration'   }-  deriving (Eq, Generic, NFData, Show, Read)+  deriving (Eq, Generic, NFData, Show, Read, Binary)  -- | Convert 'SDomainConfiguration' to 'VDomainConfiguration'. Should be used in combination with -- 'createDomain' only.@@ -719,7 +796,8 @@   -- See -fstrict-mapSignal documentation in clash-prelude.cabal   theSeq = if fStrictMapSignal then seqX else flip const   go ~(xs@(a :- as)) = f a :- (a `theSeq` (xs `seq` go as))-{-# NOINLINE mapSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE mapSignal# #-} {-# ANN mapSignal# hasBlackBox #-}  instance Applicative (Signal dom) where@@ -728,12 +806,14 @@  signal# :: a -> Signal dom a signal# a = let s = a :- s in s-{-# NOINLINE signal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE signal# #-} {-# ANN signal# hasBlackBox #-}  appSignal# :: Signal dom (a -> b) -> Signal dom a -> Signal dom b appSignal# (f :- fs) xs@(~(a :- as)) = f a :- (xs `seq` appSignal# fs as) -- See [NOTE: Lazy ap]-{-# NOINLINE appSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE appSignal# #-} {-# ANN appSignal# hasBlackBox #-}  instance NFDataX a => NFDataX (Signal domain a) where@@ -774,7 +854,8 @@ -- Is currently treated as 'id' by the Clash compiler. joinSignal# :: Signal dom (Signal dom a) -> Signal dom a joinSignal# ~(xs :- xss) = head# xs :- joinSignal# (mapSignal# tail# xss)-{-# NOINLINE joinSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE joinSignal# #-} {-# ANN joinSignal# hasBlackBox #-}  instance Num a => Num (Signal dom a) where@@ -803,7 +884,8 @@ -- * The @z@ element will never be used. foldr# :: (a -> b -> b) -> b -> Signal dom a -> b foldr# f z (a :- s) = a `f` (foldr# f z s)-{-# NOINLINE foldr# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE foldr# #-} {-# ANN foldr# hasBlackBox #-}  instance Traversable (Signal dom) where@@ -811,7 +893,8 @@  traverse# :: Applicative f => (a -> f b) -> Signal dom a -> f (Signal dom b) traverse# f (a :- s) = (:-) <$> f a <*> traverse# f s-{-# NOINLINE traverse# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traverse# #-} {-# ANN traverse# hasBlackBox #-}  -- * Clocks, resets, and enables@@ -837,19 +920,47 @@ enableGen = toEnable (pure True)  -- | A clock signal belonging to a domain named /dom/.-data Clock (dom :: Domain) = Clock (SSymbol dom)+data Clock (dom :: Domain) = Clock+  { -- | Domain associated with the clock+    clockTag :: SSymbol dom +    -- | Periods of the clock. This is an experimental feature used to simulate+    -- clock frequency correction mechanisms. Currently, all ways to contruct+    -- such a clock are hidden from the public API.+  , clockPeriods :: Maybe (Signal dom Femtoseconds)+  }+ instance Show (Clock dom) where-  show (Clock dom) = "<Clock: " ++ ssymbolToString dom ++ ">"+  show (Clock dom Nothing) = "<Clock: " ++ ssymbolToString dom ++ ">"+  show (Clock dom _) = "<Dynamic clock: " ++ ssymbolToString dom ++ ">" --- | Extract dom symbol from Clock-clockTag-  :: Clock dom-  -> SSymbol dom-clockTag (Clock dom) = dom+-- | The negative or inverted phase of a differential clock signal. HDL+-- generation will treat it the same as 'Clock', except that no @create_clock@+-- command is issued in the SDC file for 'ClockN'. Used in 'DiffClock'.+newtype ClockN (dom :: Domain) = ClockN { clockNTag :: SSymbol dom } +instance Show (ClockN dom) where+  show (ClockN dom) = "<ClockN: " ++ ssymbolToString dom ++ ">"++-- | A differential clock signal belonging to a domain named /dom/. The clock+-- input of a design with such an input has two ports which are in antiphase.+-- The first input is the positive phase, the second the negative phase. When+-- using 'Clash.Annotations.TH.makeTopEntity', the names of the inputs will end+-- in @_p@ and @_n@ respectively.+--+-- To create a differential clock in a test bench, you can use+-- 'Clash.Explicit.Testbench.clockToDiffClock'.+data DiffClock (dom :: Domain) =+  DiffClock ("p" ::: Clock dom) ("n" ::: ClockN dom)++instance Show (DiffClock dom) where+  show (DiffClock (Clock dom Nothing) _) =+    "<DiffClock: " ++ ssymbolToString dom ++ ">"+  show (DiffClock (Clock dom _) _) =+    "<Dynamic DiffClock: " ++ ssymbolToString dom ++ ">"+ -- | Clock generator for simulations. Do __not__ use this clock generator for--- the /testBench/ function, use 'Clash.Explicit.Testbench.tbClockGen' instead.+-- the /testBench/ function, use 'tbClockGen' instead. -- -- To be used like: --@@ -861,22 +972,157 @@ clockGen   :: KnownDomain dom   => Clock dom-clockGen = Clock SSymbol-{-# NOINLINE clockGen #-}-{-# ANN clockGen hasBlackBox #-}+clockGen = tbClockGen (pure True) +-- | Clock generator to be used in the /testBench/ function.+--+-- To be used like:+--+-- @+-- clkSystem en = tbClockGen @System en+-- @+--+-- === __Example__+--+-- @+-- module Example where+--+-- import "Clash.Explicit.Prelude"+-- import "Clash.Explicit.Testbench"+--+-- -- Fast domain: twice as fast as \"Slow\"+-- 'Clash.Explicit.Prelude.createDomain' 'Clash.Explicit.Prelude.vSystem'{vName=\"Fast\", vPeriod=10}+--+-- -- Slow domain: twice as slow as \"Fast\"+-- 'Clash.Explicit.Prelude.createDomain' 'Clash.Explicit.Prelude.vSystem'{vName=\"Slow\", vPeriod=20}+--+-- topEntity+--   :: 'Clock' \"Fast\"+--   -> 'Reset' \"Fast\"+--   -> 'Enable' \"Fast\"+--   -> 'Clock' \"Slow\"+--   -> 'Signal' \"Fast\" (Unsigned 8)+--   -> 'Signal' \"Slow\" (Unsigned 8, Unsigned 8)+-- topEntity clk1 rst1 en1 clk2 i =+--   let h = register clk1 rst1 en1 0 (register clk1 rst1 en1 0 i)+--       l = register clk1 rst1 en1 0 i+--   in  unsafeSynchronizer clk1 clk2 (bundle (h, l))+--+-- testBench+--   :: 'Signal' \"Slow\" Bool+-- testBench = done+--   where+--     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)+--     notDone        = not \<$\> done+--     clkA1          = 'tbClockGen' \@\"Fast\" (unsafeSynchronizer clkB2 clkA1 notDone)+--     clkB2          = 'tbClockGen' \@\"Slow\" notDone+--     rstA1          = 'Clash.Signal.resetGen' \@\"Fast\"+--     rstB2          = 'Clash.Signal.resetGen' \@\"Slow\"+-- @+tbClockGen+  :: KnownDomain testDom+  => Signal testDom Bool+  -> Clock testDom+tbClockGen done = Clock (done `seq` SSymbol) Nothing+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tbClockGen #-}+{-# ANN tbClockGen hasBlackBox #-} +-- | Femtoseconds expressed as an 'Int64'. Is a newtype to prevent accidental+-- mixups with picoseconds - the unit used in 'DomainConfiguration'.+--+newtype Femtoseconds = Femtoseconds Int64+  -- No 'Integral' instance to prevent accidental picoseconds / femtoseconds mixup+  deriving (Show, Eq, Generic, NFDataX, NFData, Lift, Ord) --- | Reset generator+-- | Strip newtype wrapper 'Femtoseconds'+unFemtoseconds :: Femtoseconds -> Int64+unFemtoseconds (Femtoseconds fs) = fs++-- | Map 'Int64' fields in 'Femtoseconds'+mapFemtoseconds :: (Int64 -> Int64) -> Femtoseconds -> Femtoseconds+mapFemtoseconds f (Femtoseconds fs) = Femtoseconds (f fs)++-- | Clock generator with dynamic clock periods for simulations. This is an+-- experimental feature and hence not part of the public API. -- -- To be used like: -- -- @+-- clkSystem = dynamicClockGen @System+-- @+--+-- See 'DomainConfiguration' for more information on how to use synthesis domains.+dynamicClockGen ::+  KnownDomain dom =>+  -- | Clock period in /femto/seconds.+  --+  -- * __NB__: Beware that the periods are given in femtoseconds; this differs+  --           from the usual unit Clash uses to represent period length,+  --           picoseconds.+  --+  -- * __NB__: Beware that not all simulators support femtoseconds. For example,+  --           Vivado's XSIM will round down to nearest picoseconds.+  --+  -- * __NB__: Beware that, by default, Clash will define @`timescale 100fs/100fs@+  --           in its generated Verilog. The latter will make simulators round+  --           time to 100fs. If you rely on more precision you should pass+  --           @-fclash-timescale-precision 1fs@ to Clash.+  Signal dom Femtoseconds ->+  Clock dom+dynamicClockGen periods = tbDynamicClockGen periods (pure True)++-- | Clock generator with dynamic clock periods for simulations. This is an+-- experimental feature and hence not part of the public API. Like 'tbClockGen'+--+--+-- To be used like:+--+-- @+-- clkSystem = dynamicClockGen @System+-- @+--+-- See 'DomainConfiguration' for more information on how to use synthesis domains.+tbDynamicClockGen ::+  KnownDomain dom =>+  -- | Clock period in /femto/seconds.+  --+  -- * __NB__: Beware that the periods are given in femtoseconds; this differs+  --           from the usual unit Clash uses to represent period length,+  --           picoseconds.+  --+  -- * __NB__: Beware that not all simulators support femtoseconds. For example,+  --           Vivado's XSIM will round down to nearest picoseconds.+  --+  -- * __NB__: Beware that, by default, Clash will define @`timescale 100fs/100fs@+  --           in its generated Verilog. The latter will make simulators round+  --           time to 100fs. If you rely on more precision you should pass+  --           @-fclash-timescale-precision 1fs@ to Clash.+  Signal dom Femtoseconds ->+  Signal dom Bool ->+  Clock dom+tbDynamicClockGen periods ena =+  Clock (ena `seq` periods `seq` SSymbol) (Just periods)+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tbDynamicClockGen #-}+{-# ANN tbDynamicClockGen hasBlackBox #-}+++-- | Reset generator for simulation purposes. Asserts the reset for a single+-- cycle.+--+-- To be used like:+--+-- @ -- rstSystem = resetGen @System -- @ -- -- See 'Clash.Explicit.Testbench.tbClockGen' for example usage. --+-- __NB__: While this can be used in the @testBench@ function, it cannot be+-- synthesized to hardware. resetGen   :: forall dom    . KnownDomain dom@@ -884,19 +1130,22 @@ resetGen = resetGenN (SNat @1) {-# INLINE resetGen #-} --- | Generate reset that's asserted for the first /n/ cycles.+-- | Reset generator for simulation purposes. Asserts the reset for the first /n/+-- cycles. -- -- To be used like: -- -- @--- rstSystem5 = resetGen @System (SNat @5)+-- rstSystem5 = resetGen @System d5 -- @ -- -- Example usage: ----- >>> sampleN 7 (unsafeToHighPolarity (resetGenN @System (SNat @3)))+-- >>> sampleN 7 (unsafeToActiveHigh (resetGenN @System d3)) -- [True,True,True,False,False,False,False] --+-- __NB__: While this can be used in the @testBench@ function, it cannot be+-- synthesized to hardware. resetGenN   :: forall dom n    . (KnownDomain dom, 1 <= n)@@ -905,9 +1154,10 @@   -> Reset dom resetGenN n =   let asserted = replicate (snatToNum n) True in-  unsafeFromHighPolarity (fromList (asserted ++ repeat False))+  unsafeFromActiveHigh (fromList (asserted ++ repeat False)) {-# ANN resetGenN hasBlackBox #-}-{-# NOINLINE resetGenN #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resetGenN #-}   -- | A reset signal belonging to a domain called /dom/.@@ -935,15 +1185,33 @@ -- loops. In case of synchronous resets it can lead to -- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of -- asynchronous resets.-unsafeToHighPolarity+unsafeToActiveHigh   :: forall dom    . KnownDomain dom   => Reset dom   -> Signal dom Bool-unsafeToHighPolarity (unsafeFromReset -> r) =+unsafeToActiveHigh (unsafeFromReset -> r) =   case resetPolarityProxy (Proxy @dom) of     SActiveHigh -> r     SActiveLow -> not <$> r+{-# INLINE unsafeToActiveHigh #-}++-- | Convert a reset to an active high reset. Has no effect if reset is already+-- an active high reset. Is unsafe because it can introduce:+--+-- * <Clash-Explicit-Signal.html#metastability meta-stability>+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeToHighPolarity+  :: forall dom+   . KnownDomain dom+  => Reset dom+  -> Signal dom Bool+unsafeToHighPolarity = unsafeToActiveHigh+{-# DEPRECATED unsafeToHighPolarity "Use 'unsafeToActiveHigh' instead. This function will be removed in Clash 1.12." #-} {-# INLINE unsafeToHighPolarity #-}  -- | Convert a reset to an active low reset. Has no effect if reset is already@@ -955,15 +1223,33 @@ -- loops. In case of synchronous resets it can lead to -- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of -- asynchronous resets.-unsafeToLowPolarity+unsafeToActiveLow   :: forall dom    . KnownDomain dom   => Reset dom   -> Signal dom Bool-unsafeToLowPolarity (unsafeFromReset -> r) =+unsafeToActiveLow (unsafeFromReset -> r) =   case resetPolarityProxy (Proxy @dom) of     SActiveHigh -> not <$> r     SActiveLow -> r+{-# INLINE unsafeToActiveLow #-}++-- | Convert a reset to an active low reset. Has no effect if reset is already+-- an active low reset. It is unsafe because it can introduce:+--+-- * <Clash-Explicit-Signal.html#metastability meta-stability>+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeToLowPolarity+  :: forall dom+   . KnownDomain dom+  => Reset dom+  -> Signal dom Bool+unsafeToLowPolarity = unsafeToActiveLow+{-# DEPRECATED unsafeToLowPolarity "Use 'unsafeToActiveLow' instead. This function will be removed in Clash 1.12." #-} {-# INLINE unsafeToLowPolarity #-}  -- | 'unsafeFromReset' is unsafe because it can introduce:@@ -975,13 +1261,14 @@ -- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of -- asynchronous resets. ----- __NB__: You probably want to use 'unsafeToLowPolarity' or--- 'unsafeToHighPolarity'.+-- __NB__: You probably want to use 'unsafeToActiveLow' or+-- 'unsafeToActiveHigh'. unsafeFromReset   :: Reset dom   -> Signal dom Bool unsafeFromReset (Reset r) = r-{-# NOINLINE unsafeFromReset #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeFromReset #-} {-# ANN unsafeFromReset hasBlackBox #-}  -- | 'unsafeToReset' is unsafe. For asynchronous resets it is unsafe@@ -989,13 +1276,15 @@ -- it can lead to <Clash-Explicit-Signal.html#metastability meta-stability> -- issues in the presence of asynchronous resets. ----- __NB__: You probably want to use 'unsafeFromLowPolarity' or--- 'unsafeFromHighPolarity'.+-- __NB__: You probably want to use 'unsafeFromActiveLow' or+-- 'unsafeFromActiveHigh'. unsafeToReset-  :: Signal dom Bool+  :: KnownDomain dom+  => Signal dom Bool   -> Reset dom unsafeToReset r = Reset r-{-# NOINLINE unsafeToReset #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeToReset #-} {-# ANN unsafeToReset hasBlackBox #-}  -- | Interpret a signal of bools as an active high reset and convert it to@@ -1011,7 +1300,24 @@   => Signal dom Bool   -- ^ Reset signal that's 'True' when active, and 'False' when inactive.   -> Reset dom-unsafeFromHighPolarity r =+unsafeFromHighPolarity = unsafeFromActiveHigh+{-# DEPRECATED unsafeFromHighPolarity "Use 'unsafeFromActiveHigh' instead. This function will be removed in Clash 1.12." #-}+{-# INLINE unsafeFromHighPolarity #-}++-- | Interpret a signal of bools as an active high reset and convert it to+-- a reset signal corresponding to the domain's setting.+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeFromActiveHigh+  :: forall dom+   . KnownDomain dom+  => Signal dom Bool+  -- ^ Reset signal that's 'True' when active, and 'False' when inactive.+  -> Reset dom+unsafeFromActiveHigh r =   unsafeToReset $     case resetPolarityProxy (Proxy @dom) of       SActiveHigh -> r@@ -1030,14 +1336,31 @@   => Signal dom Bool   -- ^ Reset signal that's 'False' when active, and 'True' when inactive.   -> Reset dom-unsafeFromLowPolarity r =+unsafeFromLowPolarity = unsafeFromActiveLow+{-# DEPRECATED unsafeFromLowPolarity "Use 'unsafeFromActiveLow' instead. This function will be removed in Clash 1.12." #-}+{-# INLINE unsafeFromLowPolarity #-}++-- | Interpret a signal of bools as an active low reset and convert it to+-- a reset signal corresponding to the domain's setting.+--+-- For asynchronous resets it is unsafe because it can cause combinatorial+-- loops. In case of synchronous resets it can lead to+-- <Clash-Explicit-Signal.html#metastability meta-stability> in the presence of+-- asynchronous resets.+unsafeFromActiveLow+  :: forall dom+   . KnownDomain dom+  => Signal dom Bool+  -- ^ Reset signal that's 'False' when active, and 'True' when inactive.+  -> Reset dom+unsafeFromActiveLow r =   unsafeToReset $     case resetPolarityProxy (Proxy @dom) of       SActiveHigh -> not <$> r       SActiveLow -> r  -- | Invert reset signal-invertReset :: Reset dom -> Reset dom+invertReset :: KnownDomain dom => Reset dom -> Reset dom invertReset = unsafeToReset . fmap not . unsafeFromReset  infixr 2 .||.@@ -1089,7 +1412,7 @@   -> a   -> Signal dom a   -> Signal dom a-delay# (Clock dom) (fromEnable -> en) powerUpVal0 =+delay# (Clock dom _) (fromEnable -> en) powerUpVal0 =     go powerUpVal1 en   where     powerUpVal1 :: a@@ -1104,7 +1427,8 @@       let o' = if e then x else o       -- See [Note: register strictness annotations]       in  o `defaultSeqX` o :- (as `seq` go o' es xs)-{-# NOINLINE delay# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE delay# #-} {-# ANN delay# hasBlackBox #-}  -- | A register with a power up and reset value. Power up values are not@@ -1131,13 +1455,14 @@   -- ^ Reset value   -> Signal dom a   -> Signal dom a-register# clk@(Clock dom) rst ena powerUpVal resetVal =+register# clk@(Clock dom _) rst ena powerUpVal resetVal =   case knownDomainByName dom of     SDomainConfiguration _name _period _edge SSynchronous _init _polarity ->       syncRegister# clk rst ena powerUpVal resetVal     SDomainConfiguration _name _period _edge SAsynchronous _init _polarity ->       asyncRegister# clk rst ena powerUpVal resetVal-{-# NOINLINE register# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE register# #-} {-# ANN register# hasBlackBox #-}  -- | Acts like 'id' if given domain allows powerup values, but returns a@@ -1150,7 +1475,7 @@   => Clock dom   -> a   -> a-registerPowerup# (Clock dom) a =+registerPowerup# (Clock dom _) a =   case knownDomainByName dom of     SDomainConfiguration _dom _period _edge _sync SDefined _polarity -> a     SDomainConfiguration _dom _period _edge _sync SUnknown _polarity ->@@ -1174,7 +1499,7 @@   -- ^ Reset value   -> Signal dom a   -> Signal dom a-asyncRegister# clk (unsafeToHighPolarity -> rst) (fromEnable -> ena) initVal resetVal =+asyncRegister# clk (unsafeToActiveHigh -> rst) (fromEnable -> ena) initVal resetVal =   go (registerPowerup# clk initVal) rst ena  where   go o (r :- rs) enas@(~(e :- es)) as@(~(x :- xs)) =@@ -1182,7 +1507,8 @@         oE = if r then resetVal else (if e then x else o)         -- [Note: register strictness annotations]     in  o `defaultSeqX` oR :- (as `seq` enas `seq` go oE rs es xs)-{-# NOINLINE asyncRegister# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE asyncRegister# #-} {-# ANN asyncRegister# hasBlackBox #-}  -- | Version of 'register#' that simulates a register on a synchronous@@ -1203,7 +1529,7 @@   -- ^ Reset value   -> Signal dom a   -> Signal dom a-syncRegister# clk (unsafeToHighPolarity -> rst) (fromEnable -> ena) initVal resetVal =+syncRegister# clk (unsafeToActiveHigh -> rst) (fromEnable -> ena) initVal resetVal =   go (registerPowerup# clk initVal) rst ena  where   go o rt@(~(r :- rs)) enas@(~(e :- es)) as@(~(x :- xs)) =@@ -1211,7 +1537,8 @@         oR = if r then resetVal else oE         -- [Note: register strictness annotations]     in  o `defaultSeqX` o :- (rt `seq` enas `seq` as `seq` go oR rs es xs)-{-# NOINLINE syncRegister# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE syncRegister# #-} {-# ANN syncRegister# dontTranslate #-}  -- | The above type is a generalization for:@@ -1437,30 +1764,89 @@ simulate_lazy :: (Signal dom1 a -> Signal dom2 b) -> [a] -> [b] simulate_lazy f = sample_lazy . f . fromList_lazy --- | Calculate the period, in __ps__, given a frequency in __Hz__+-- | Calculate the period in __ps__, given a frequency in __Hz__ ----- i.e. to calculate the clock period for a circuit to run at 240 MHz we get+-- I.e., to calculate the clock period for a circuit to run at 240 MHz we get -- -- >>> hzToPeriod 240e6 -- 4166 ----- __NB__: This function is /not/ synthesizable+-- If the value @hzToPeriod@ is applied to is not of the type 'Ratio'+-- 'Natural', you can use @hzToPeriod ('realToFrac' f)@. Note that if @f@ is+-- negative, @realToFrac@ will give an @'Control.Exception.Underflow' ::+-- t'Control.Exception.ArithException'@ without a call stack, making debugging+-- cumbersome. ----- __NB__: This function is lossy. I.e.,  periodToHz . hzToPeriod /= id.-hzToPeriod :: HasCallStack => Ratio Natural -> Natural-hzToPeriod freq = floor ((1.0 / freq) / 1.0e-12)+-- Before Clash 1.8, this function always returned a 'Natural'. To get the old+-- behavior of this function, use a type application:+--+-- >>> hzToPeriod @Natural 240e6+-- 4166+--+-- * __NB__: This function is not synthesizable+-- * __NB__: This function is lossy. I.e., @periodToHz . hzToPeriod /= id@.+hzToPeriod :: (HasCallStack, Integral a) => Ratio Natural -> a+hzToPeriod freq+  | freq > 0  = floor ((1.0 / freq) / 1e-12)+  | otherwise = withFrozenCallStack $ error "Zero frequency" --- | Calculate the frequence in __Hz__, given the period in __ps__+-- | Calculate the period in __fs__, given a frequency in __Hz__ ----- i.e. to calculate the clock frequency of a clock with a period of 5000 ps:+-- I.e., to calculate the clock period for a circuit to run at 240 MHz we get --+-- >>> hzToFs 240e6+-- Femtoseconds 4166666+--+-- If the value @hzToFs@ is applied to is not of the type 'Ratio' 'Natural', you+-- can use @hzToFs ('realToFrac' f)@. Note that if @f@ is negative, @realToFrac@+-- will give an @'Control.Exception.Underflow' ::+-- t'Control.Exception.ArithException'@ without a call stack, making debugging+-- cumbersome.+--+-- * __NB__: This function is not synthesizable+-- * __NB__: This function is lossy. I.e.,  @fsToHz . hzToFs /= id@.+hzToFs :: HasCallStack => Ratio Natural -> Femtoseconds+hzToFs freq+  | freq > 0  = Femtoseconds (floor ((1.0 / freq) / 1e-15))+  | otherwise = withFrozenCallStack $ error "Zero frequency"++-- | Calculate the frequency in __Hz__, given the period in __ps__+--+-- I.e., to calculate the clock frequency of a clock with a period of 5000 ps:+-- -- >>> periodToHz 5000+-- 2.0e8+--+-- Note that if @p@ in @periodToHz ('fromIntegral' p)@ is negative,+-- @fromIntegral@ will give an @'Control.Exception.Underflow' ::+-- t'Control.Exception.ArithException'@ without a call stack, making debugging+-- cumbersome.+--+-- Before Clash 1.8, this function always returned a 'Ratio'+-- 'Natural'. To get the old behavior of this function, use a type application:+--+-- >>> periodToHz @(Ratio Natural) 5000 -- 200000000 % 1 ----- __NB__: This function is /not/ synthesizable-periodToHz :: Natural -> Ratio Natural-periodToHz period = 1.0 / (1.0e-12 * fromIntegral period)+-- __NB__: This function is not synthesizable+periodToHz :: (HasCallStack, Fractional a) => Natural -> a+periodToHz period+  | period > 0 = fromRational $ 1.0 / (fromIntegral period * 1e-12)+  | otherwise  = withFrozenCallStack $ error "Zero period" +-- | Calculate the frequency in __Hz__, given the period in __fs__+--+-- I.e., to calculate the clock frequency of a clock with a period of 5000 fs:+--+-- >>> fsToHz (Femtoseconds 5000)+-- 2.0e11+--+-- __NB__: This function is not synthesizable+fsToHz :: (HasCallStack, Fractional a) => Femtoseconds -> a+fsToHz (Femtoseconds period)+  | period > 0 = fromRational $ 1.0 / (fromIntegral period * 1e-15)+  | otherwise  = withFrozenCallStack $ error "Zero period"+ -- | Build an 'Automaton' from a function over 'Signal's. -- -- __NB__: Consumption of continuation of the 'Automaton' must be affine; that@@ -1489,7 +1875,8 @@         return (out, next)    go inputRefs (dut inputs)-{-# NOINLINE signalAutomaton #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE signalAutomaton #-}  infiniteRefList :: a -> IO (Signal dom (IORef a)) infiniteRefList val = go@@ -1498,3 +1885,85 @@     rest <- unsafeInterleaveIO go     ref  <- newIORef val     return (ref :- rest)++data ClockAB+  -- | Clock edge A produced+  = ClockA+  -- | Clock edge B produced+  | ClockB+  -- | Clock edges coincided+  | ClockAB+  deriving (Generic, Eq, Show, NFData, NFDataX)++-- | Given two clocks, produce a list of clock ticks indicating which clock+-- (or both) ticked. Can be used in components handling multiple clocks, such+-- as @unsafeSynchronizer@ or dual clock FIFOs.+--+-- If your primitive does not care about coincided clock edges, it should - by+-- convention - replace it by @ClockB:ClockA:@.+clockTicks ::+  (KnownDomain domA, KnownDomain domB) =>+  Clock domA ->+  Clock domB ->+  [ClockAB]+clockTicks clkA clkB = clockTicksEither (toEither clkA) (toEither clkB)+ where+  toEither ::+    forall dom.+    KnownDomain dom =>+    Clock dom ->+    Either Int64 (Signal dom Int64)+  toEither (Clock _ maybePeriods)+    | Just periods <- maybePeriods =+        Right (unFemtosecondsSignal periods)+    | SDomainConfiguration{sPeriod} <- knownDomain @dom =+        -- Convert to femtoseconds - dynamic clocks use them+        Left (1000 * snatToNum sPeriod)++  -- Coerce whole signal instead of `fmap coerce` to prevent useless constructor+  -- packing and unpacking.+  unFemtosecondsSignal :: forall dom . Signal dom Femtoseconds -> Signal dom Int64+  unFemtosecondsSignal = coerce++-- | Given two clock periods, produce a list of clock ticks indicating which clock+-- (or both) ticked. Can be used in components handling multiple clocks, such+-- as @unsafeSynchronizer@ or dual clock FIFOs.+--+-- If your primitive does not care about coincided clock edges, it should - by+-- convention - replace it by @ClockB:ClockA:@.+clockTicksEither ::+  Either Int64 (Signal domA Int64) ->+  Either Int64 (Signal domB Int64) ->+  [ClockAB]+clockTicksEither clkA clkB =+  case (clkA, clkB) of+    (Left  tA, Left  tB) | tA == tB -> repeat ClockAB+    (Left  tA, Left  tB) -> goStatic 0 tA tB+    (Right tA, Right tB) -> goDynamic 0 tA tB+    (Left  tA, Right tB) -> clockTicksEither (Right (pure tA)) (Right tB)+    (Right tA, Left  tB) -> clockTicksEither (Right tA) (Right (pure tB))+ where+  -- Given+  --   tAbsA = absolute time of next active edge of clock A+  --   tAbsB = absolute time of next active edge of clock B+  -- relativeTime is defined as relativeTime = tAbsB - tAbsA+  --+  -- Put differently, relative time 0 points at the next active edge of+  -- clock A, and relativeTime points at the next active edge of clock B.++  goStatic :: Int64 -> Int64 -> Int64 -> [ClockAB]+  goStatic relativeTime tA tB =+    case compare relativeTime 0 of+      LT -> ClockB  : goStatic (relativeTime + tB)      tA tB+      EQ -> ClockAB : goStatic (relativeTime - tA + tB) tA tB+      GT -> ClockA  : goStatic (relativeTime - tA)      tA tB++  goDynamic :: Int64 -> Signal domA Int64 -> Signal domB Int64 -> [ClockAB]+  goDynamic relativeTime tsA@(~(tA :- tsA0)) tsB@(~(tB :- tsB0)) =+    -- Even though we lazily match on the signal's constructor, this shouldn't+    -- build up a significant chain of chunks as 'relativeTime' gets evaluated+    -- every iteration.+    case compare relativeTime 0 of+      LT -> ClockB  : goDynamic (relativeTime + tB)      tsA  tsB0+      EQ -> ClockAB : goDynamic (relativeTime - tA + tB) tsA0 tsB0+      GT -> ClockA  : goDynamic (relativeTime - tA)      tsA0 tsB
src/Clash/Signal/Internal/Ambiguous.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} @@ -21,9 +23,10 @@   => SNat period clockPeriod =   case knownDomain @dom of-    SDomainConfiguration _dom period _edge _sync _init _polarity ->-      period-{-# NOINLINE clockPeriod #-}+    SDomainConfiguration{sPeriod} ->+      sPeriod+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE clockPeriod #-} -- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662  -- | Get 'ActiveEdge' from a KnownDomain context. Example usage:@@ -41,9 +44,10 @@   => SActiveEdge edge activeEdge =   case knownDomain @dom of-    SDomainConfiguration _dom _period edge _sync _init _polarity ->-      edge-{-# NOINLINE activeEdge #-}+    SDomainConfiguration{sActiveEdge} ->+      sActiveEdge+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE activeEdge #-} -- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662  -- | Get 'ResetKind' from a KnownDomain context. Example usage:@@ -61,9 +65,10 @@   => SResetKind sync resetKind =   case knownDomain @dom of-    SDomainConfiguration _dom _period _edge sync _init _polarity ->-      sync-{-# NOINLINE resetKind #-}+    SDomainConfiguration{sResetKind} ->+      sResetKind+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resetKind #-} -- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662  -- | Get 'InitBehavior' from a KnownDomain context. Example usage:@@ -81,9 +86,10 @@   => SInitBehavior init initBehavior =   case knownDomain @dom of-    SDomainConfiguration _dom _period _edge _sync init_ _polarity ->-      init_-{-# NOINLINE initBehavior #-}+    SDomainConfiguration{sInitBehavior} ->+      sInitBehavior+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE initBehavior #-} -- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662  -- | Get 'ResetPolarity' from a KnownDomain context. Example usage:@@ -101,9 +107,10 @@   => SResetPolarity polarity resetPolarity =   case knownDomain @dom of-    SDomainConfiguration _dom _period _edge _sync _init polarity ->-      polarity-{-# NOINLINE resetPolarity #-}+    SDomainConfiguration{sResetPolarity} ->+      sResetPolarity+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resetPolarity #-} -- @NOINLINE: https://github.com/clash-lang/clash-compiler/issues/662  -- | Like 'knownDomain but yields a 'VDomainConfiguration'. Should only be used
src/Clash/Signal/Trace.hs view
@@ -47,6 +47,7 @@ -} {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-} @@ -96,7 +97,7 @@ import qualified Clash.Sized.Vector    as Vector import           Clash.Class.BitPack   (BitPack, BitSize, pack, unpack) import           Clash.Promoted.Nat    (snatToNum, SNat(..))-import           Clash.Signal.Internal (sample)+import           Clash.Signal.Internal (Signal ((:-)), sample) import           Clash.XException      (deepseqX, NFDataX) import           Clash.Sized.Internal.BitVector   (BitVector(BV))@@ -110,7 +111,7 @@ import           Data.Char             (ord, chr) import           Data.IORef   (IORef, atomicModifyIORef', atomicWriteIORef, newIORef, readIORef)-import           Data.List             (foldl1', foldl', unzip4, transpose)+import           Data.List             (foldl1', foldl', unzip4, transpose, uncons) import qualified Data.Map.Strict       as Map import           Data.Maybe            (fromMaybe, catMaybes) import qualified Data.Text             as Text@@ -140,7 +141,8 @@ -- | Map of traces used by the non-internal trace and dumpvcd functions. traceMap# :: IORef TraceMap traceMap# = unsafePerformIO (newIORef Map.empty)-{-# NOINLINE traceMap# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceMap# #-}  mkTrace   :: HasCallStack@@ -183,7 +185,8 @@       , signal)  where   width = snatToNum (SNat @(BitSize a))-{-# NOINLINE traceSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceSignal# #-}  -- | Trace a single vector signal: each element in the vector will show up as -- a different trace. If the trace name already exists, this function will emit@@ -209,12 +212,13 @@  where   trace' i s = traceSignal# traceMap period (name' i) s   name' i    = vecTraceName ++ "_" ++ show i-{-# NOINLINE traceVecSignal# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceVecSignal# #-}  -- | Trace a single signal. Will emit an error if a signal with the same name -- was previously registered. ----- __NB__ Works correctly when creating VCD files from traced signal in+-- __NB__: Works correctly when creating VCD files from traced signal in -- multi-clock circuits. However 'traceSignal1' might be more convenient to -- use when the domain of your circuit is polymorphic. traceSignal@@ -230,16 +234,17 @@   -> Signal dom a traceSignal traceName signal =   case knownDomain @dom of-    SDomainConfiguration _dom period _edge _reset _init _polarity ->+    SDomainConfiguration{sPeriod} ->       unsafePerformIO $-        traceSignal# traceMap# (snatToNum period) traceName signal-{-# NOINLINE traceSignal #-}+        traceSignal# traceMap# (snatToNum sPeriod) traceName signal+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceSignal #-} {-# ANN traceSignal hasBlackBox #-}  -- | Trace a single signal. Will emit an error if a signal with the same name -- was previously registered. ----- __NB__ associates the traced signal with a clock period of /1/, which+-- __NB__: Associates the traced signal with a clock period of /1/, which -- results in incorrect VCD files when working with circuits that have -- multiple clocks. Use 'traceSignal' when working with circuits that have -- multiple clocks.@@ -254,14 +259,15 @@   -> Signal dom a traceSignal1 traceName signal =   unsafePerformIO (traceSignal# traceMap# 1 traceName signal)-{-# NOINLINE traceSignal1 #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceSignal1 #-} {-# ANN traceSignal1 hasBlackBox #-}  -- | Trace a single vector signal: each element in the vector will show up as -- a different trace. If the trace name already exists, this function will emit -- an error. ----- __NB__ Works correctly when creating VCD files from traced signal in+-- __NB__: Works correctly when creating VCD files from traced signal in -- multi-clock circuits. However 'traceSignal1' might be more convenient to -- use when the domain of your circuit is polymorphic. traceVecSignal@@ -278,17 +284,18 @@   -> Signal dom (Vec (n+1) a) traceVecSignal traceName signal =   case knownDomain @dom of-    SDomainConfiguration _dom period _edge _reset _init _polarity ->+    SDomainConfiguration{sPeriod} ->       unsafePerformIO $-        traceVecSignal# traceMap# (snatToNum period) traceName signal-{-# NOINLINE traceVecSignal #-}+        traceVecSignal# traceMap# (snatToNum sPeriod) traceName signal+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceVecSignal #-} {-# ANN traceVecSignal hasBlackBox #-}  -- | Trace a single vector signal: each element in the vector will show up as -- a different trace. If the trace name already exists, this function will emit -- an error. ----- __NB__ associates the traced signal with a clock period of /1/, which+-- __NB__: Associates the traced signal with a clock period of /1/, which -- results in incorrect VCD files when working with circuits that have -- multiple clocks. Use 'traceSignal' when working with circuits that have -- multiple clocks.@@ -304,7 +311,8 @@   -> Signal dom (Vec (n+1) a) traceVecSignal1 traceName signal =   unsafePerformIO $ traceVecSignal# traceMap# 1 traceName signal-{-# NOINLINE traceVecSignal1 #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traceVecSignal1 #-} {-# ANN traceVecSignal1 hasBlackBox #-}  iso8601Format :: UTCTime -> String@@ -340,8 +348,8 @@       error $ "dumpVCD: no traces found. Extend the given trace names."   | Map.size traceMap > 126 - 33 =       Left $ "Tracemap contains more than 93 traces, which is not supported by VCD."-  | not $ null $ offensiveNames =-      Left $ unwords [ "Trace '" ++ head offensiveNames ++ "' contains"+  | (nm:_) <- offensiveNames =+      Left $ unwords [ "Trace '" ++ nm ++ "' contains"                      , "non-printable ASCII characters, which is not"                      , "supported by VCD." ]   | otherwise =@@ -406,7 +414,7 @@   initValues       = map Text.pack $ zipWith ($) formatters inits    formatters = zipWith format widths labels-  inits = map head valuess'+  inits = map (maybe (error "dumpVCD##: empty value") fst . uncons) valuess'   tails = map changed valuess'    -- | Format single value according to VCD spec@@ -558,14 +566,14 @@   -> IO () waitForTraces# traceMap signal traceNames = do   atomicWriteIORef traceMap Map.empty-  rest <- foldM go (sample signal) traceNames-  return $ deepseqX (head rest) ()+  rest <- foldM go signal traceNames+  seq rest (return ())  where-  go s nm = do+  go (s0 :- ss) nm = do     m <- readIORef traceMap     if Map.member nm m then-      return s+      deepseqX s0 (return ss)     else       deepseqX-        (head s)-        (go (tail s) nm)+        s0+        (go ss nm)
src/Clash/Sized/BitVector.hs view
@@ -1,5 +1,6 @@ {-| Copyright  :  (C) 2013-2016, University of Twente+                  2022     , Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}@@ -23,11 +24,47 @@   , maxIndex#     -- ** Construction   , bLit+  , hLit+  , oLit     -- ** Concatenation   , (++#)+    -- * Modification+  , (+>>.)+  , (.<<+)     -- ** Pattern matching   , bitPattern   ) where  import Clash.Sized.Internal.BitVector+import Clash.Promoted.Nat (natToNum)+import Data.Bits (shiftL, shiftR)+import GHC.TypeNats (KnownNat)++{- $setup+>>> :set -XNumericUnderscores+-}++infixr 4 +>>.+-- | Shift in a bit from the MSB side of a 'BitVector'. Equal to right shifting+-- the 'BitVector' by one and replacing the MSB with the bit to be shifted in.+--+-- >>> 1 +>>. 0b1111_0000 :: BitVector 8+-- 0b1111_1000+-- >>> 0 +>>. 0b1111_0000 :: BitVector 8+-- 0b0111_1000+--+(+>>.) :: forall n. KnownNat n => Bit -> BitVector n -> BitVector n+b +>>. bv = replaceBit# (shiftR bv 1) (natToNum @n - 1) b++infixr 4 .<<++-- | Shift in a bit from the LSB side of a 'BitVector'. Equal to left shifting+-- the 'BitVector' by one and replacing the LSB with the bit to be shifted in.+--+-- >>> 0b1111_0000 .<<+ 0 :: BitVector 8+-- 0b1110_0000+-- >>> 0b1111_0000 .<<+ 1 :: BitVector 8+-- 0b1110_0001+--+(.<<+) :: forall n. KnownNat n => BitVector n -> Bit -> BitVector n+bv .<<+ b = replaceBit# (shiftL bv 1) 0 b
src/Clash/Sized/Fixed.hs view
@@ -11,7 +11,7 @@ * 'Fixed' has an instance for 'Fractional' meaning you use fractional   literals @(3.75 :: 'SFixed' 4 18)@. * Both integer literals and fractional literals are clipped to 'minBound' and-  'maxBound'. __NB__ Needs the `-XNegativeLiterals` language extension to work+  'maxBound'. __NB__: Needs the `-XNegativeLiterals` language extension to work   for signed numbers. * There is no 'Floating' instance for 'Fixed', but you can use @$$('fLit' d)@   to create 'Fixed' point literal from 'Double' constant at compile-time.@@ -547,7 +547,7 @@                              | otherwise  = res                      in  Fixed (fromInteger sat) -instance (BitPack (rep (int + frac))) => BitPack (Fixed rep int frac) where+instance (BitPack (rep (int + frac)), KnownNat (BitSize (rep (int + frac)))) => BitPack (Fixed rep int frac) where   type BitSize (Fixed rep int frac) = BitSize (rep (int + frac))   pack   (Fixed fRep) = pack fRep   unpack bv           = Fixed (unpack bv)@@ -734,7 +734,7 @@  -- | Convert, at run-time, a 'Double' to a 'Fixed'-point. ----- __NB__: this function is /not/ synthesizable+-- __NB__: This function is /not/ synthesizable -- -- = Creating data-files #creatingdatafiles# --
src/Clash/Sized/Index.hs view
@@ -15,11 +15,11 @@   (Index, bv2i, fromSNat) where -import GHC.TypeLits               (KnownNat, type (^))-import GHC.TypeLits.Extra         (CLog) -- documentation only+import GHC.TypeLits (KnownNat, type (^))+import GHC.TypeLits.Extra (CLog) -- documentation only -import Clash.Promoted.Nat         (SNat (..), pow2SNat)-import Clash.Sized.BitVector      (BitVector)+import Clash.Promoted.Nat (SNat (..), pow2SNat)+import Clash.Sized.Internal.BitVector (BitVector) import Clash.Sized.Internal.Index  -- | An alternative implementation of 'Clash.Class.BitPack.unpack' for the
src/Clash/Sized/Internal/BitVector.hs view
@@ -3,6 +3,7 @@                   2019     , Gergő Érdi                   2016-2019, Myrtle Software Ltd,                   2021-2022, QBayLogic B.V.+                  2023     , Nadia Chambers License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -57,6 +58,8 @@   , maxIndex#     -- ** Construction   , bLit+  , hLit+  , oLit   , undefined#     -- ** Concatenation   , (++#)@@ -141,6 +144,7 @@ import Data.Typeable              (Typeable, typeOf) import GHC.Generics               (Generic) import Data.Maybe                 (fromMaybe)+import Numeric                    (readOct, readHex) import GHC.Exts   (Word#, Word (W#), eqWord#, int2Word#, isTrue#, uncheckedShiftRL#) #if MIN_VERSION_base(4,15,0)@@ -260,13 +264,15 @@  -- * Constructions -- ** Initialisation-{-# NOINLINE high #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE high #-} {-# ANN high hasBlackBox #-} -- | logic '1' high :: Bit high = Bit 0 1 -{-# NOINLINE low #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE low #-} {-# ANN low hasBlackBox #-} -- | logic '0' low :: Bit@@ -305,12 +311,14 @@  eq## :: Bit -> Bit -> Bool eq## b1 b2 = eq# (pack# b1) (pack# b2)-{-# NOINLINE eq## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE eq## #-} {-# ANN eq## hasBlackBox #-}  neq## :: Bit -> Bit -> Bool neq## b1 b2 = neq# (pack# b1) (pack# b2)-{-# NOINLINE neq## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE neq## #-} {-# ANN neq## hasBlackBox #-}  instance Ord Bit where@@ -321,16 +329,20 @@  lt##,ge##,gt##,le## :: Bit -> Bit -> Bool lt## b1 b2 = lt# (pack# b1) (pack# b2)-{-# NOINLINE lt## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lt## #-} {-# ANN lt## hasBlackBox #-} ge## b1 b2 = ge# (pack# b1) (pack# b2)-{-# NOINLINE ge## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ge## #-} {-# ANN ge## hasBlackBox #-} gt## b1 b2 = gt# (pack# b1) (pack# b2)-{-# NOINLINE gt## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE gt## #-} {-# ANN gt## hasBlackBox #-} le## b1 b2 = le# (pack# b1) (pack# b2)-{-# NOINLINE le## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE le## #-} {-# ANN le## hasBlackBox #-}  instance Enum Bit where@@ -339,7 +351,8 @@  toEnum## :: Int -> Bit toEnum## = fromInteger## 0## . toInteger-{-# NOINLINE toEnum## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toEnum## #-} {-# ANN toEnum## hasBlackBox #-}  instance Bounded Bit where@@ -360,7 +373,8 @@  fromInteger## :: Word# -> Integer -> Bit fromInteger## m# i = Bit ((W# m#) `mod` 2) (fromInteger i `mod` 2)-{-# NOINLINE fromInteger## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromInteger## #-} {-# ANN fromInteger## hasBlackBox #-}  instance Real Bit where@@ -405,23 +419,27 @@ and##, or##, xor## :: Bit -> Bit -> Bit and## (Bit m1 v1) (Bit m2 v2) = Bit mask (v1 .&. v2 .&. complement mask)   where mask = (m1.&.v2 .|. m1.&.m2 .|. m2.&.v1)-{-# NOINLINE and## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE and## #-} {-# ANN and## hasBlackBox #-}  or## (Bit m1 v1) (Bit m2 v2) = Bit mask ((v1 .|. v2) .&. complement mask)   where mask = m1 .&. complement v2 .|.  m1.&.m2  .|.  m2 .&. complement v1-{-# NOINLINE or## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE or## #-} {-# ANN or## hasBlackBox #-}  xor## (Bit m1 v1) (Bit m2 v2) = Bit mask ((v1 `xor` v2) .&. complement mask)   where mask = m1 .|. m2-{-# NOINLINE xor## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xor## #-} {-# ANN xor## hasBlackBox #-}  complement## :: Bit -> Bit complement## (Bit m v) = Bit m (complementB v .&. complementB m)   where complementB (W# b#) = W# (int2Word# (eqWord# b# 0##))-{-# NOINLINE complement## #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE complement## #-} {-# ANN complement## hasBlackBox #-}  -- *** BitPack@@ -431,7 +449,8 @@ #else pack# (Bit (W# m) (W# b)) = BV (NatS# m) (NatS# b) #endif-{-# NOINLINE pack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE pack# #-} {-# ANN pack# hasBlackBox #-}  unpack# :: BitVector 1 -> Bit@@ -444,7 +463,8 @@   go (NatS# w) = W# w   go (NatJ# w) = W# (bigNatToWord w) #endif-{-# NOINLINE unpack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpack# #-} {-# ANN unpack# hasBlackBox #-}  -- * Instances@@ -509,9 +529,9 @@ -- >>> $(bLit "1.0.") -- 0b1.0. ----- __N.B.__: From Clash 1.6 an onwards 'bLit' will deduce the size of the---           BitVector from the given string and annotate the splice it---           produces accordingly.+-- __NB__: From Clash 1.6 an onwards 'bLit' will deduce the size of the+-- BitVector from the given string and annotate the splice it produces+-- accordingly. bLit :: String -> ExpQ bLit s = pure (SigE body typ)  where@@ -537,18 +557,88 @@            "Clash.Sized.Internal.bLit: unknown character: "         ++ show c ++ " in input: " ++ cs0 +-- | Create a hexadecimal literal+--+-- >>> $(hLit "dead")+-- 0b1101_1110_1010_1101+--+-- Don't care digits set 4 bits:+--+-- >>> $(hLit "de..")+-- 0b1101_1110_...._....+hLit :: String -> ExpQ+hLit s = pure (SigE body typ)+  where+    typ = ConT ''BitVector `AppT` LitT (NumTyLit (toInteger n))+    body = VarE 'fromInteger# `AppE` iLit mask `AppE` iLit value +    iLit = LitE . IntegerL . toInteger+    (n, BV mask value) = read16# s :: (Natural, BitVector n)++read16# :: String -> (Natural, BitVector n)+read16# cs0 = (fromIntegral $ 4 * length cs1, BV m v)+  where+    cs1 = filter (/= '_') cs0+    (vs, ms) = unzip $ map readHexDigit cs1+    combineHexDigits = foldl (\b a -> 16*b+a) 0+    v = combineHexDigits vs+    m = combineHexDigits ms+    -- The dot is a don't care, which applies to a whole digit.+    readHexDigit '.' = (0, 0xf)+    readHexDigit c = case readHex [c] of+      [(n,  "")] -> (n, 0)+      _ -> error $+             "Clash.Sized.Internal.hLit: unknown character: "+             ++ show c ++ " in input: " ++ cs0++-- | Create an octal literal+--+-- >>> $(oLit "5234")+-- 0b1010_1001_1100+--+-- Don't care digits set 3 bits:+--+-- >>> $(oLit "52..")+-- 0b1010_10.._....+oLit :: String -> ExpQ+oLit s = pure (SigE body typ)+  where+    typ = ConT ''BitVector `AppT` LitT (NumTyLit (toInteger n))+    body = VarE 'fromInteger# `AppE` iLit mask `AppE` iLit value++    iLit = LitE . IntegerL . toInteger+    (n, BV mask value) = read8# s :: (Natural, BitVector n)++read8# :: String -> (Natural, BitVector n)+read8# cs0 = (fromIntegral $ 3 * length cs1, BV m v)+  where+    cs1 = filter (/= '_') cs0+    (vs, ms) = unzip $ map readOctDigit cs1+    combineOctDigits = foldl (\b a -> 8*b+a) 0+    v = combineOctDigits vs+    m = combineOctDigits ms+    -- The dot is a don't care, which applies to a whole digit.+    readOctDigit '.' = (0, 0o7)+    readOctDigit c = case readOct [c] of+      [(n,  "")] -> (n, 0)+      _ -> error $+             "Clash.Sized.Internal.oLit: unknown character: "+             ++ show c ++ " in input: " ++ cs0++ instance KnownNat n => Eq (BitVector n) where   (==) = eq#   (/=) = neq# -{-# NOINLINE eq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE eq# #-} {-# ANN eq# hasBlackBox #-} eq# :: KnownNat n => BitVector n -> BitVector n -> Bool eq# (BV 0 v1) (BV 0 v2 ) = v1 == v2 eq# bv1 bv2 = undefErrorI "==" bv1 bv2 -{-# NOINLINE neq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE neq# #-} {-# ANN neq# hasBlackBox #-} neq# :: KnownNat n => BitVector n -> BitVector n -> Bool neq# (BV 0 v1) (BV 0 v2) = v1 /= v2@@ -561,19 +651,23 @@   (<=) = le#  lt#,ge#,gt#,le# :: KnownNat n => BitVector n -> BitVector n -> Bool-{-# NOINLINE lt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lt# #-} {-# ANN lt# hasBlackBox #-} lt# (BV 0 n) (BV 0 m) = n < m lt# bv1 bv2 = undefErrorI "<" bv1 bv2-{-# NOINLINE ge# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ge# #-} {-# ANN ge# hasBlackBox #-} ge# (BV 0 n) (BV 0 m) = n >= m ge# bv1 bv2 = undefErrorI ">=" bv1 bv2-{-# NOINLINE gt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE gt# #-} {-# ANN gt# hasBlackBox #-} gt# (BV 0 n) (BV 0 m) = n > m gt# bv1 bv2 = undefErrorI ">" bv1 bv2-{-# NOINLINE le# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE le# #-} {-# ANN le# hasBlackBox #-} le# (BV 0 n) (BV 0 m) = n <= m le#  bv1 bv2 = undefErrorI "<=" bv1 bv2@@ -592,12 +686,14 @@  toEnum# :: forall n. KnownNat n => Int -> BitVector n toEnum# = fromInteger# 0 . toInteger-{-# NOINLINE toEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toEnum# #-} {-# ANN toEnum# hasBlackBox #-}  fromEnum# :: forall n. KnownNat n => BitVector n -> Int fromEnum# = fromEnum . toInteger#-{-# NOINLINE fromEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromEnum# #-} {-# ANN fromEnum# hasBlackBox #-}  enumFrom# :: forall n. KnownNat n => BitVector n -> [BitVector n]@@ -608,7 +704,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif enumFrom# bv = undefErrorU "enumFrom" bv-{-# NOINLINE enumFrom# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFrom# #-}  enumFromThen#   :: forall n@@ -627,7 +724,8 @@   m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif enumFromThen# bv1 bv2 = undefErrorP "enumFromThen" bv1 bv2-{-# NOINLINE enumFromThen# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThen# #-}  enumFromTo#   :: forall n@@ -642,7 +740,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif enumFromTo# bv1 bv2 = undefErrorP "enumFromTo" bv1 bv2-{-# NOINLINE enumFromTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromTo# #-}  enumFromThenTo#   :: forall n@@ -658,7 +757,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif enumFromThenTo# bv1 bv2 bv3 = undefErrorP3 "enumFromTo" bv1 bv2 bv3-{-# NOINLINE enumFromThenTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThenTo# #-}   instance KnownNat n => Bounded (BitVector n) where@@ -667,12 +767,14 @@  minBound# :: BitVector n minBound# = BV 0 0-{-# NOINLINE minBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minBound# #-} {-# ANN minBound# hasBlackBox #-}  maxBound# :: forall n. KnownNat n => BitVector n maxBound# = let m = 1 `shiftL` natToNum @n in BV 0 (m-1)-{-# NOINLINE maxBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE maxBound# #-} {-# ANN maxBound# hasBlackBox #-}  -- | __NB__: 'fromInteger'/'fromIntegral' can cause unexpected truncation, as@@ -688,7 +790,8 @@   fromInteger = fromInteger# 0  (+#),(-#),(*#) :: forall n . KnownNat n => BitVector n -> BitVector n -> BitVector n-{-# NOINLINE (+#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (+#) #-} {-# ANN (+#) hasBlackBox #-} (+#) = go   where@@ -701,7 +804,8 @@     m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE (-#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (-#) #-} {-# ANN (-#) hasBlackBox #-} (-#) = go   where@@ -714,7 +818,8 @@     m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE (*#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (*#) #-} {-# ANN (*#) hasBlackBox #-} (*#) = go  where@@ -727,7 +832,8 @@   m = (1 `shiftL` fromInteger (natVal (Proxy @n))) - 1 #endif -{-# NOINLINE negate# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE negate# #-} {-# ANN negate# hasBlackBox #-} negate# :: forall n . KnownNat n => BitVector n -> BitVector n negate# = go@@ -741,7 +847,8 @@   m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE fromInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromInteger# #-} {-# ANN fromInteger# hasBlackBox #-} fromInteger# :: KnownNat n => Natural -> Integer -> BitVector n fromInteger# m i = sz `seq` mx@@ -763,13 +870,15 @@   type MResult (BitVector m) (BitVector n) = BitVector (m + n)   mul = times# -{-# NOINLINE plus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE plus# #-} {-# ANN plus# hasBlackBox #-} plus# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (Max m n + 1) plus# (BV 0 a) (BV 0 b) = BV 0 (a + b) plus# bv1 bv2 = undefErrorP "add" bv1 bv2 -{-# NOINLINE minus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minus# #-} {-# ANN minus# hasBlackBox #-} minus# :: forall m n . (KnownNat m, KnownNat n) => BitVector m -> BitVector n                                                 -> BitVector (Max m n + 1)@@ -784,7 +893,8 @@   m = 1 `shiftL` fromInteger (natVal (Proxy @(Max m n + 1))) #endif -{-# NOINLINE times# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE times# #-} {-# ANN times# hasBlackBox #-} times# :: (KnownNat m, KnownNat n) => BitVector m -> BitVector n -> BitVector (m + n) times# (BV 0 a) (BV 0 b) = BV 0 (a * b)@@ -806,16 +916,19 @@   toInteger   = toInteger#  quot#,rem# :: KnownNat n => BitVector n -> BitVector n -> BitVector n-{-# NOINLINE quot# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE quot# #-} {-# ANN quot# hasBlackBox #-} quot# (BV 0 i) (BV 0 j) = BV 0 (i `quot` j) quot# bv1 bv2 = undefErrorP "quot" bv1 bv2-{-# NOINLINE rem# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rem# #-} {-# ANN rem# hasBlackBox #-} rem# (BV 0 i) (BV 0 j) = BV 0 (i `rem` j) rem# bv1 bv2 = undefErrorP "rem" bv1 bv2 -{-# NOINLINE toInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toInteger# #-} {-# ANN toInteger# hasBlackBox #-} toInteger# :: KnownNat n => BitVector n -> Integer toInteger# (BV 0 i) = naturalToInteger i@@ -854,7 +967,8 @@ countTrailingZerosBV = V.foldl (\l r -> if eq## r low then 1 + l else 0) 0 . V.bv2v {-# INLINE countTrailingZerosBV #-} -{-# NOINLINE reduceAnd# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE reduceAnd# #-} {-# ANN reduceAnd# hasBlackBox #-} reduceAnd# :: KnownNat n => BitVector n -> Bit reduceAnd# bv@(BV 0 i) = Bit 0 (W# (int2Word# (dataToTag# check)))@@ -873,7 +987,8 @@     sz    = natVal bv     maxI  = (2 ^ sz) - 1 -{-# NOINLINE reduceOr# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE reduceOr# #-} {-# ANN reduceOr# hasBlackBox #-} reduceOr# :: KnownNat n => BitVector n -> Bit reduceOr# (BV 0 i) = Bit 0 (W# (int2Word# (dataToTag# check)))@@ -885,7 +1000,8 @@   complementN = complementMod $ natVal bv   defI = i .&. (complementN m) -{-# NOINLINE reduceXor# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE reduceXor# #-} {-# ANN reduceXor# hasBlackBox #-} reduceXor# :: KnownNat n => BitVector n -> Bit reduceXor# (BV 0 i) = Bit 0 (fromIntegral (popCount i `mod` 2))@@ -896,7 +1012,8 @@  -- * Accessors -- ** Length information-{-# NOINLINE size# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE size# #-} {-# ANN size# hasBlackBox #-} size# :: KnownNat n => BitVector n -> Int #if MIN_VERSION_base(4,15,0)@@ -905,7 +1022,8 @@ size# bv = fromInteger (natVal bv) #endif -{-# NOINLINE maxIndex# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE maxIndex# #-} {-# ANN maxIndex# hasBlackBox #-} maxIndex# :: KnownNat n => BitVector n -> Int #if MIN_VERSION_base(4,15,0)@@ -915,7 +1033,8 @@ #endif  -- ** Indexing-{-# NOINLINE index# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE index# #-} {-# ANN index# hasBlackBox #-} index# :: KnownNat n => BitVector n -> Int -> Bit index# bv@(BV m v) i@@ -935,7 +1054,8 @@                          , "..0]"                          ] -{-# NOINLINE msb# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE msb# #-} {-# ANN msb# hasBlackBox #-} -- | MSB msb# :: forall n . KnownNat n => BitVector n -> Bit@@ -961,14 +1081,16 @@   msbN (NatJ# bn) = W# (bigNatToWord (shiftRBigNat bn (i# GHC.Exts.-# 1#))) #endif -{-# NOINLINE lsb# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lsb# #-} {-# ANN lsb# hasBlackBox #-} -- | LSB lsb# :: BitVector n -> Bit lsb# (BV m v) = Bit (W# (int2Word# (dataToTag# (testBit m 0))))                     (W# (int2Word# (dataToTag# (testBit v 0)))) -{-# NOINLINE slice# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE slice# #-} {-# ANN slice# hasBlackBox #-} slice# :: BitVector (m + 1 + i) -> SNat m -> SNat n -> BitVector (m + 1 - n) slice# (BV msk i) m n = BV (shiftR (msk .&. mask) n')@@ -982,7 +1104,8 @@ -- * Constructions  -- ** Concatenation-{-# NOINLINE (++#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (++#) #-} {-# ANN (++#) hasBlackBox #-} -- | Concatenate two 'BitVector's (++#) :: KnownNat m => BitVector n -> BitVector m -> BitVector (n + m)@@ -999,7 +1122,8 @@ #endif  -- * Modifying BitVectors-{-# NOINLINE replaceBit# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE replaceBit# #-} {-# ANN replaceBit# hasBlackBox #-} replaceBit# :: KnownNat n => BitVector n -> Int -> Bit -> BitVector n replaceBit# bv@(BV m v) i (Bit mb b)@@ -1023,7 +1147,8 @@                           , "..0]"                           ] -{-# NOINLINE setSlice# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE setSlice# #-} {-# ANN setSlice# hasBlackBox #-} setSlice#   :: forall m i n@@ -1045,7 +1170,8 @@  where   complementN = complementMod (natVal (Proxy @(m + 1 + i))) -{-# NOINLINE split# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE split# #-} {-# ANN split# hasBlackBox #-} split#   :: forall n m@@ -1071,7 +1197,8 @@   in  (BV lMask l, BV rMask r)  and#, or#, xor# :: forall n . KnownNat n => BitVector n -> BitVector n -> BitVector n-{-# NOINLINE and# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE and# #-} {-# ANN and# hasBlackBox #-} and# =   \(BV m1 v1) (BV m2 v2) ->@@ -1080,7 +1207,8 @@   where     complementN = complementMod (natVal (Proxy @n)) -{-# NOINLINE or# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE or# #-} {-# ANN or# hasBlackBox #-} or# =   \(BV m1 v1) (BV m2 v2) ->@@ -1089,7 +1217,8 @@   where     complementN = complementMod (natVal (Proxy @n)) -{-# NOINLINE xor# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xor# #-} {-# ANN xor# hasBlackBox #-} xor# =   \(BV m1 v1) (BV m2 v2) ->@@ -1098,7 +1227,8 @@   where     complementN = complementMod (natVal (Proxy @n)) -{-# NOINLINE complement# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE complement# #-} {-# ANN complement# hasBlackBox #-} complement# :: forall n . KnownNat n => BitVector n -> BitVector n complement# = \(BV m v) -> BV m (complementN v .&. complementN m)@@ -1107,7 +1237,8 @@ shiftL#, shiftR#, rotateL#, rotateR#   :: forall n . KnownNat n => BitVector n -> Int -> BitVector n -{-# NOINLINE shiftL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftL# #-} {-# ANN shiftL# hasBlackBox #-} shiftL# = \(BV msk v) i ->   if | i < 0@@ -1125,14 +1256,16 @@   m = 1 `shiftL` sz #endif -{-# NOINLINE shiftR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftR# #-} {-# ANN shiftR# hasBlackBox #-} shiftR# (BV m v) i   | i < 0     = error               $ "'shiftR' undefined for negative number: " ++ show i   | otherwise = BV (shiftR m i) (shiftR v i) -{-# NOINLINE rotateL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateL# #-} {-# ANN rotateL# hasBlackBox #-} rotateL# =   \(BV msk v) b ->@@ -1167,7 +1300,8 @@   m  = 1 `shiftL` sz #endif -{-# NOINLINE rotateR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateR# #-} {-# ANN rotateR# hasBlackBox #-} rotateR# =   \(BV msk v) b ->@@ -1223,7 +1357,8 @@ #else   where m = 1 `shiftL` fromInteger (natVal (Proxy @a)) #endif-{-# NOINLINE truncateB# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE truncateB# #-} {-# ANN truncateB# hasBlackBox #-}  instance KnownNat n => Lift (BitVector n) where@@ -1361,7 +1496,8 @@   where     ty = typeOf res     res = undefError (show ty ++ ".unpack") [bv]-{-# NOINLINE checkUnpackUndef #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE checkUnpackUndef #-} {-# ANN checkUnpackUndef hasBlackBox #-}  -- | Create a BitVector with all its bits undefined@@ -1373,7 +1509,8 @@   let m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif   in  BV (m-1) 0-{-# NOINLINE undefined# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE undefined# #-} {-# ANN undefined# hasBlackBox #-}  -- | Check if one BitVector is similar to another, interpreting undefined bits@@ -1402,7 +1539,8 @@     in  e' == c' && e' == c''  where   complementN = complementMod (natVal (Proxy @n))-{-# NOINLINE isLike# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE isLike# #-}  fromBits :: [Bit] -> Integer fromBits = L.foldl (\v b -> v `shiftL` 1 .|. fromIntegral b) 0
src/Clash/Sized/Internal/Index.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2019, Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -112,7 +112,7 @@ import qualified Clash.Sized.Internal.BitVector as BV import Clash.Promoted.Nat         (SNat(..), snatToNum, natToInteger, leToPlusKN) import Clash.XException-  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)+  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX, seqX)  {- $setup >>> import Clash.Sized.Internal.Index@@ -157,7 +157,7 @@ -- -- as it is not safe to coerce between 'Index'es with different ranges. To -- change the size, use the functions in the 'Resize' class.-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0) data Index (n :: Nat) =     -- | The constructor, 'I', and the field, 'unsafeToInteger', are not     -- synthesizable.@@ -172,7 +172,8 @@  {-# ANN I hasBlackBox #-} -{-# NOINLINE size# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE size# #-} size# :: (KnownNat n, 1 <= n) => Index n -> Int size# = BV.size# . pack# @@ -191,12 +192,14 @@ fromSNat :: (KnownNat m, n + 1 <= m) => SNat n -> Index m fromSNat = snatToNum -{-# NOINLINE pack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE pack# #-} {-# ANN pack# hasBlackBox #-} pack# :: Index n -> BitVector (CLog 2 n) pack# (I i) = BV 0 (naturalFromInteger i) -{-# NOINLINE unpack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpack# #-} {-# ANN unpack# hasBlackBox #-} unpack# :: (KnownNat n, 1 <= n) => BitVector (CLog 2 n) -> Index n unpack# (BV 0 i) = fromInteger_INLINE (naturalToInteger i)@@ -206,12 +209,14 @@   (==) = eq#   (/=) = neq# -{-# NOINLINE eq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE eq# #-} {-# ANN eq# hasBlackBox #-} eq# :: (Index n) -> (Index n) -> Bool (I n) `eq#` (I m) = n == m -{-# NOINLINE neq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE neq# #-} {-# ANN neq# hasBlackBox #-} neq# :: (Index n) -> (Index n) -> Bool (I n) `neq#` (I m) = n /= m@@ -223,16 +228,20 @@   (<=) = le#  lt#,ge#,gt#,le# :: Index n -> Index n -> Bool-{-# NOINLINE lt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lt# #-} {-# ANN lt# hasBlackBox #-} lt# (I n) (I m) = n < m-{-# NOINLINE ge# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ge# #-} {-# ANN ge# hasBlackBox #-} ge# (I n) (I m) = n >= m-{-# NOINLINE gt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE gt# #-} {-# ANN gt# hasBlackBox #-} gt# (I n) (I m) = n > m-{-# NOINLINE le# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE le# #-} {-# ANN le# hasBlackBox #-} le# (I n) (I m) = n <= m @@ -250,29 +259,35 @@  toEnum# :: forall n. KnownNat n => Int -> Index n toEnum# = fromInteger# . toInteger-{-# NOINLINE toEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toEnum# #-} {-# ANN toEnum# hasBlackBox #-}  fromEnum# :: forall n. KnownNat n => Index n -> Int fromEnum# = fromEnum . toInteger#-{-# NOINLINE fromEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromEnum# #-} {-# ANN fromEnum# hasBlackBox #-}  enumFrom# :: forall n. KnownNat n => Index n -> [Index n] enumFrom# x = [x .. maxBound]-{-# NOINLINE enumFrom# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFrom# #-}  enumFromThen# :: forall n. KnownNat n => Index n -> Index n -> [Index n] enumFromThen# x y = if x <= y then [x, y .. maxBound] else [x, y .. minBound]-{-# NOINLINE enumFromThen# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThen# #-}  enumFromTo# :: Index n -> Index n -> [Index n] enumFromTo# x y = map I [unsafeToInteger x .. unsafeToInteger y]-{-# NOINLINE enumFromTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromTo# #-}  enumFromThenTo# :: Index n -> Index n -> Index n -> [Index n] enumFromThenTo# x1 x2 y = map I [unsafeToInteger x1, unsafeToInteger x2 .. unsafeToInteger y]-{-# NOINLINE enumFromThenTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThenTo# #-}  instance KnownNat n => Bounded (Index n) where   minBound = fromInteger# 0@@ -283,7 +298,8 @@   case natToInteger @n of     0 -> errorX "maxBound of 'Index 0' is undefined"     n -> fromInteger_INLINE (n - 1)-{-# NOINLINE maxBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE maxBound# #-} {-# ANN maxBound# hasBlackBox #-}  -- | Operators report an error on overflow and underflow@@ -301,15 +317,18 @@   fromInteger = fromInteger#  (+#),(-#),(*#) :: KnownNat n => Index n -> Index n -> Index n-{-# NOINLINE (+#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (+#) #-} {-# ANN (+#) hasBlackBox #-} (+#) (I a) (I b) = fromInteger_INLINE $ a + b -{-# NOINLINE (-#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (-#) #-} {-# ANN (-#) hasBlackBox #-} (-#) (I a) (I b) = fromInteger_INLINE $ a - b -{-# NOINLINE (*#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (*#) #-} {-# ANN (*#) hasBlackBox #-} (*#) (I a) (I b) = fromInteger_INLINE $ a * b @@ -318,7 +337,8 @@ negate# i = maxBound -# i +# 1  fromInteger# :: KnownNat n => Integer -> Index n-{-# NOINLINE fromInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromInteger# #-} {-# ANN fromInteger# hasBlackBox #-} fromInteger# = fromInteger_INLINE {-# INLINE fromInteger_INLINE #-}@@ -337,11 +357,13 @@   mul = times#  plus#, minus# :: Index m -> Index n -> Index (m + n - 1)-{-# NOINLINE plus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE plus# #-} {-# ANN plus# hasBlackBox #-} plus# (I a) (I b) = I (a + b) -{-# NOINLINE minus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minus# #-} {-# ANN minus# hasBlackBox #-} minus# (I a) (I b) =   let z   = a - b@@ -350,15 +372,16 @@       res = if z < 0 then err else I z   in  res -{-# NOINLINE times# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE times# #-} {-# ANN times# hasBlackBox #-} times# :: Index m -> Index n -> Index (((m - 1) * (n - 1)) + 1) times# (I a) (I b) = I (a * b)  instance (KnownNat n, 1 <= n) => SaturatingNum (Index n) where-  satAdd SatWrap !a !b =+  satAdd SatWrap a b =     case natToInteger @n of-      1 -> fromInteger# 0+      1 -> a +# b       _ -> leToPlusKN @1 @n $         case plus# a b of           z | let m = fromInteger# (natToInteger @n)@@ -396,9 +419,9 @@        then fromInteger# 0        else a -# b -  satMul SatWrap !a !b =+  satMul SatWrap a b =     case natToInteger @n of-      1 -> fromInteger# 0+      1 -> a *# b       2 -> case a of {0 -> 0; _ -> b}       _ -> leToPlusKN @1 @n $         case times# a b of@@ -423,9 +446,9 @@           , z > m -> maxBound#         z -> resize# z -  satSucc SatError !a =+  satSucc SatError a =     case natToInteger @n of-      1 -> errorX "Index.satSucc: overflow"+      1 -> a `seqX` errorX "Index.satSucc: overflow"       _ -> satAdd SatError a $ fromInteger# 1   satSucc satMode !a =     case natToInteger @n of@@ -433,9 +456,9 @@       _ -> satAdd satMode a $ fromInteger# 1   {-# INLINE satSucc #-} -  satPred SatError !a =+  satPred SatError a =     case natToInteger @n of-      1 -> errorX "Index.satPred: underflow"+      1 -> a `seqX` errorX "Index.satPred: underflow"       _ -> satSub SatError a $ fromInteger# 1   satPred satMode !a =     case natToInteger @n of@@ -459,14 +482,17 @@   toInteger   = toInteger#  quot#,rem# :: Index n -> Index n -> Index n-{-# NOINLINE quot# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE quot# #-} {-# ANN quot# hasBlackBox #-} (I a) `quot#` (I b) = I (a `div` b)-{-# NOINLINE rem# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rem# #-} {-# ANN rem# hasBlackBox #-} (I a) `rem#` (I b) = I (a `rem` b) -{-# NOINLINE toInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toInteger# #-} {-# ANN toInteger# hasBlackBox #-} toInteger# :: Index n -> Integer toInteger# (I n) = n@@ -510,7 +536,8 @@  resize# :: KnownNat m => Index n -> Index m resize# (I i) = fromInteger_INLINE i-{-# NOINLINE resize# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resize# #-} {-# ANN resize# hasBlackBox #-}  instance KnownNat n => Lift (Index n) where
src/Clash/Sized/Internal/Signed.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016     , Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -184,7 +184,7 @@ -- -- as it is not safe to coerce between different width Signed. To change the -- width, use the functions in the 'Clash.Class.Resize.Resize' class.-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0) data Signed (n :: Nat) =     -- | The constructor, 'S', and the field, 'unsafeToInteger', are not     -- synthesizable.@@ -203,7 +203,8 @@   deepErrorX = errorX   rnfX = rwhnfX -{-# NOINLINE size# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE size# #-} {-# ANN size# hasBlackBox #-} size# :: KnownNat n => Signed n -> Int size# bv = fromInteger (natVal bv)@@ -230,13 +231,15 @@   pack   = packXWith pack#   unpack = unpack# -{-# NOINLINE pack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE pack# #-} {-# ANN pack# hasBlackBox #-} pack# :: forall n . KnownNat n => Signed n -> BitVector n pack# (S i) = let m = 1 `shiftL0` fromInteger (natVal (Proxy @n))               in  if i < 0 then BV 0 (naturalFromInteger (m + i)) else BV 0 (naturalFromInteger i) -{-# NOINLINE unpack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpack# #-} {-# ANN unpack# hasBlackBox #-} unpack# :: forall n . KnownNat n => BitVector n -> Signed n unpack# (BV 0 i) =@@ -249,12 +252,14 @@   (==) = eq#   (/=) = neq# -{-# NOINLINE eq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE eq# #-} {-# ANN eq# hasBlackBox #-} eq# :: Signed n -> Signed n -> Bool eq# (S v1) (S v2) = v1 == v2 -{-# NOINLINE neq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE neq# #-} {-# ANN neq# hasBlackBox #-} neq# :: Signed n -> Signed n -> Bool neq# (S v1) (S v2) = v1 /= v2@@ -266,16 +271,20 @@   (<=) = le#  lt#,ge#,gt#,le# :: Signed n -> Signed n -> Bool-{-# NOINLINE lt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lt# #-} {-# ANN lt# hasBlackBox #-} lt# (S n) (S m) = n < m-{-# NOINLINE ge# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ge# #-} {-# ANN ge# hasBlackBox #-} ge# (S n) (S m) = n >= m-{-# NOINLINE gt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE gt# #-} {-# ANN gt# hasBlackBox #-} gt# (S n) (S m) = n > m-{-# NOINLINE le# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE le# #-} {-# ANN le# hasBlackBox #-} le# (S n) (S m) = n <= m @@ -307,12 +316,14 @@  toEnum# :: forall n. KnownNat n => Int -> Signed n toEnum# = fromInteger# . toInteger-{-# NOINLINE toEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toEnum# #-} {-# ANN toEnum# hasBlackBox #-}  fromEnum# :: forall n. KnownNat n => Signed n -> Int fromEnum# = fromEnum . toInteger#-{-# NOINLINE fromEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromEnum# #-} {-# ANN fromEnum# hasBlackBox #-}  enumFrom# :: forall n. KnownNat n => Signed n -> [Signed n]@@ -320,7 +331,8 @@   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1-{-# NOINLINE enumFrom# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFrom# #-}  enumFromThen# :: forall n. KnownNat n => Signed n -> Signed n -> [Signed n] enumFromThen# x y =@@ -331,21 +343,24 @@   sz = fromInteger (natVal (Proxy @n)) - 1   mB = 1 `shiftL` sz   mask = mB - 1-{-# NOINLINE enumFromThen# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThen# #-}  enumFromTo# :: forall n. KnownNat n => Signed n -> Signed n -> [Signed n] enumFromTo# x y = map (fromInteger_INLINE sz mB mask) [unsafeToInteger x .. unsafeToInteger y]   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1-{-# NOINLINE enumFromTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromTo# #-}  enumFromThenTo# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n -> [Signed n] enumFromThenTo# x1 x2 y = map (fromInteger_INLINE sz mB mask) [unsafeToInteger x1, unsafeToInteger x2 .. unsafeToInteger y]   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1-{-# NOINLINE enumFromThenTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThenTo# #-}   instance KnownNat n => Bounded (Signed n) where@@ -357,7 +372,8 @@   case natToNatural @n of     0 -> 0     n -> S (negate $ 2 ^ (n - 1))-{-# NOINLINE minBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minBound# #-} {-# ANN minBound# hasBlackBox #-}  maxBound# :: forall n. KnownNat n => Signed n@@ -365,7 +381,8 @@   case natToNatural @n of     0 -> 0     n -> S (2 ^ (n - 1) - 1)-{-# NOINLINE maxBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE maxBound# #-} {-# ANN maxBound# hasBlackBox #-}  -- | Operators do @wrap-around@ on overflow@@ -384,7 +401,8 @@   fromInteger = fromInteger#  (+#), (-#), (*#) :: forall n . KnownNat n => Signed n -> Signed n -> Signed n-{-# NOINLINE (+#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (+#) #-} {-# ANN (+#) hasBlackBox #-} (+#) =   \(S a) (S b) ->@@ -398,7 +416,8 @@  where   m = 1 `shiftL0` fromInteger (natVal (Proxy @n) -1) -{-# NOINLINE (-#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (-#) #-} {-# ANN (-#) hasBlackBox #-} (-#) =   \(S a) (S b) ->@@ -412,7 +431,8 @@  where   m  = 1 `shiftL0` fromInteger (natVal (Proxy @n) -1) -{-# NOINLINE (*#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (*#) #-} {-# ANN (*#) hasBlackBox #-} (*#) = \(S a) (S b) -> fromInteger_INLINE sz mB mask (a * b)   where sz   = fromInteger (natVal (Proxy @n)) - 1@@ -420,7 +440,8 @@         mask = mB - 1  negate#,abs# :: forall n . KnownNat n => Signed n -> Signed n-{-# NOINLINE negate# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE negate# #-} {-# ANN negate# hasBlackBox #-} negate# =   \(S n) ->@@ -429,7 +450,8 @@  where   m = 1 `shiftL0` fromInteger (natVal (Proxy @n) -1) -{-# NOINLINE abs# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE abs# #-} {-# ANN abs# hasBlackBox #-} abs# =   \(S n) ->@@ -438,7 +460,8 @@  where   m = 1 `shiftL0` fromInteger (natVal (Proxy @n) -1) -{-# NOINLINE fromInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromInteger# #-} {-# ANN fromInteger# hasBlackBox #-} fromInteger# :: forall n . KnownNat n => Integer -> Signed (n :: Nat) fromInteger# = fromInteger_INLINE sz mB mask@@ -463,15 +486,18 @@   mul = times#  plus#, minus# :: Signed m -> Signed n -> Signed (Max m n + 1)-{-# NOINLINE plus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE plus# #-} {-# ANN plus# hasBlackBox #-} plus# (S a) (S b) = S (a + b) -{-# NOINLINE minus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minus# #-} {-# ANN minus# hasBlackBox #-} minus# (S a) (S b) = S (a - b) -{-# NOINLINE times# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE times# #-} {-# ANN times# hasBlackBox #-} times# :: Signed m -> Signed n -> Signed (m + n) times# (S a) (S b) = S (a * b)@@ -491,7 +517,8 @@   divMod  n d = (n `div#`  d,n `mod#` d)   toInteger   = toInteger# -{-# NOINLINE quot# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE quot# #-} {-# ANN quot# hasBlackBox #-} quot# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n quot# (S a) (S b)@@ -500,12 +527,14 @@  where   S minB = minBound @(Signed n) -{-# NOINLINE rem# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rem# #-} {-# ANN rem# hasBlackBox #-} rem# :: Signed n -> Signed n -> Signed n rem# (S a) (S b) = S (a `rem` b) -{-# NOINLINE div# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE div# #-} {-# ANN div# hasBlackBox #-} div# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n div# (S a) (S b)@@ -514,12 +543,14 @@  where   S minB = minBound @(Signed n) -{-# NOINLINE mod# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE mod# #-} {-# ANN mod# hasBlackBox #-} mod# :: Signed n -> Signed n -> Signed n mod# (S a) (S b) = S (a `mod` b) -{-# NOINLINE toInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toInteger# #-} {-# ANN toInteger# hasBlackBox #-} toInteger# :: Signed n -> Integer toInteger# (S n) = n@@ -552,28 +583,32 @@   popCount s        = popCount (pack# s)  and#,or#,xor# :: forall n . KnownNat n => Signed n -> Signed n -> Signed n-{-# NOINLINE and# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE and# #-} {-# ANN and# hasBlackBox #-} and# = \(S a) (S b) -> fromInteger_INLINE sz mB mask (a .&. b)   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1 -{-# NOINLINE or# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE or# #-} {-# ANN or# hasBlackBox #-} or# = \(S a) (S b) -> fromInteger_INLINE sz mB mask (a .|. b)   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1 -{-# NOINLINE xor# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xor# #-} {-# ANN xor# hasBlackBox #-} xor# = \(S a) (S b) -> fromInteger_INLINE sz mB mask (xor a b)   where sz   = fromInteger (natVal (Proxy @n)) - 1         mB   = 1 `shiftL` sz         mask = mB - 1 -{-# NOINLINE complement# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE complement# #-} {-# ANN complement# hasBlackBox #-} complement# :: forall n . KnownNat n => Signed n -> Signed n complement# = \(S a) -> fromInteger_INLINE sz mB mask (complement a)@@ -582,7 +617,8 @@         mask = mB - 1  shiftL#,shiftR#,rotateL#,rotateR# :: forall n . KnownNat n => Signed n -> Int -> Signed n-{-# NOINLINE shiftL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftL# #-} {-# ANN shiftL# hasBlackBox #-} shiftL# = \(S n) b ->   if | b < 0     -> error $ "'shiftL' undefined for negative number: " ++ show b@@ -593,7 +629,8 @@   mB   = 1 `shiftL` sz   mask = mB - 1 -{-# NOINLINE shiftR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftR# #-} {-# ANN shiftR# hasBlackBox #-} shiftR# =   \(S n) b ->@@ -606,7 +643,8 @@   mB   = 1 `shiftL` sz   mask = mB - 1 -{-# NOINLINE rotateL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateL# #-} {-# ANN rotateL# hasBlackBox #-} rotateL# =   \(S n) b ->@@ -626,7 +664,8 @@   mB    = 1 `shiftL` sz1   maskM = mB - 1 -{-# NOINLINE rotateR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateR# #-} {-# ANN rotateR# hasBlackBox #-} rotateR# =   \(S n) b ->@@ -656,7 +695,8 @@   zeroExtend s = unpack# (0 ++# pack s)   truncateB    = truncateB# -{-# NOINLINE resize# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resize# #-} {-# ANN resize# hasBlackBox #-} resize# :: forall m n . (KnownNat n, KnownNat m) => Signed n -> Signed m resize# s@(S i)@@ -675,7 +715,8 @@                    then S (i' - mask)                    else S i' -{-# NOINLINE truncateB# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE truncateB# #-} {-# ANN truncateB# hasBlackBox #-} truncateB# :: forall m n . KnownNat m => Signed (m + n) -> Signed m truncateB# = \(S n) -> fromInteger_INLINE sz mB mask n
src/Clash/Sized/Internal/Unsigned.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016     , Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -92,7 +92,11 @@ import Data.Proxy                     (Proxy (..)) import Text.Read                      (Read (..), ReadPrec) import Text.Printf                    (PrintfArg (..), printf)+#if MIN_VERSION_base(4,16,0)+import GHC.Exts                       (wordToWord8#, wordToWord16#, wordToWord32#)+#else import GHC.Exts                       (narrow8Word#, narrow16Word#, narrow32Word#)+#endif import GHC.Generics                   (Generic) #if MIN_VERSION_base(4,15,0) import GHC.Num.BigNat                 (bigNatToWord, bigNatToWord#)@@ -196,7 +200,7 @@ -- -- as it is not safe to coerce between different width Unsigned. To change the -- width, use the functions in the 'Clash.Class.Resize.Resize' class.-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0) data Unsigned (n :: Nat) =     -- | The constructor, 'U', and the field, 'unsafeToNatural', are not     -- synthesizable.@@ -211,7 +215,8 @@  {-# ANN U hasBlackBox #-} -{-# NOINLINE size# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE size# #-} {-# ANN size# hasBlackBox #-} size# :: KnownNat n => Unsigned n -> Int #if MIN_VERSION_base(4,15,0)@@ -246,12 +251,14 @@   pack   = packXWith pack#   unpack = unpack# -{-# NOINLINE pack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE pack# #-} {-# ANN pack# hasBlackBox #-} pack# :: Unsigned n -> BitVector n pack# (U i) = BV 0 i -{-# NOINLINE unpack# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unpack# #-} {-# ANN unpack# hasBlackBox #-} unpack# :: KnownNat n => BitVector n -> Unsigned n unpack# (BV 0 i) = U i@@ -261,12 +268,14 @@   (==) = eq#   (/=) = neq# -{-# NOINLINE eq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE eq# #-} {-# ANN eq# hasBlackBox #-} eq# :: Unsigned n -> Unsigned n -> Bool eq# (U v1) (U v2) = v1 == v2 -{-# NOINLINE neq# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE neq# #-} {-# ANN neq# hasBlackBox #-} neq# :: Unsigned n -> Unsigned n -> Bool neq# (U v1) (U v2) = v1 /= v2@@ -278,16 +287,20 @@   (<=) = le#  lt#,ge#,gt#,le# :: Unsigned n -> Unsigned n -> Bool-{-# NOINLINE lt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lt# #-} {-# ANN lt# hasBlackBox #-} lt# (U n) (U m) = n < m-{-# NOINLINE ge# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE ge# #-} {-# ANN ge# hasBlackBox #-} ge# (U n) (U m) = n >= m-{-# NOINLINE gt# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE gt# #-} {-# ANN gt# hasBlackBox #-} gt# (U n) (U m) = n > m-{-# NOINLINE le# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE le# #-} {-# ANN le# hasBlackBox #-} le# (U n) (U m) = n <= m @@ -304,10 +317,9 @@    pred n     | n == minBound =-        error $ "'pred' was called on (" <> show @(Unsigned n) maxBound <> " :: "-             <> "Unsigned " <> show (natToNatural @n) <> ") and caused an "-             <> "underflow. Use 'satPred' and specify a SaturationMode if you "-             <> "need other behavior."+        error $ "'pred' was called on (0 :: Unsigned " <> show (natToNatural @n)+             <> ") and caused an overflow. Use 'satPred' and specify a "+             <> "SaturationMode if you need other behavior."     | otherwise = n -# fromInteger# 1    toEnum         = toEnum#@@ -319,12 +331,14 @@  toEnum# :: forall n. KnownNat n => Int -> Unsigned n toEnum# = fromInteger# . toInteger-{-# NOINLINE toEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toEnum# #-} {-# ANN toEnum# hasBlackBox #-}  fromEnum# :: forall n. KnownNat n => Unsigned n -> Int fromEnum# = fromEnum . toInteger#-{-# NOINLINE fromEnum# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromEnum# #-} {-# ANN fromEnum# hasBlackBox #-}  enumFrom# :: forall n. KnownNat n => Unsigned n -> [Unsigned n]@@ -334,7 +348,8 @@ #else   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif-{-# NOINLINE enumFrom# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFrom# #-}  enumFromThen# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n] enumFromThen# = \x y -> toUnsigneds [unsafeToNatural x, unsafeToNatural y .. bound x y]@@ -346,7 +361,8 @@ #else   m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif-{-# NOINLINE enumFromThen# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThen# #-}  enumFromTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n] enumFromTo# = \x y -> map (U . (`mod` m)) [unsafeToNatural x .. unsafeToNatural y]@@ -355,7 +371,8 @@ #else   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif-{-# NOINLINE enumFromTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromTo# #-}  enumFromThenTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n] enumFromThenTo# = \x1 x2 y -> map (U . (`mod` m)) [unsafeToNatural x1, unsafeToNatural x2 .. unsafeToNatural y]@@ -364,7 +381,8 @@ #else   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif-{-# NOINLINE enumFromThenTo# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE enumFromThenTo# #-}  instance KnownNat n => Bounded (Unsigned n) where   minBound = minBound#@@ -372,12 +390,14 @@  minBound# :: Unsigned n minBound# = U 0-{-# NOINLINE minBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minBound# #-} {-# ANN minBound# hasBlackBox #-}  maxBound# :: forall n. KnownNat n => Unsigned n maxBound# = let m = 1 `shiftL` (natToNum @n) in  U (m - 1)-{-# NOINLINE maxBound# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE maxBound# #-} {-# ANN maxBound# hasBlackBox #-}  -- | __NB__: 'fromInteger'/'fromIntegral' can cause unexpected truncation, as@@ -393,7 +413,8 @@   fromInteger = fromInteger#  (+#),(-#),(*#) :: forall n . KnownNat n => Unsigned n -> Unsigned n -> Unsigned n-{-# NOINLINE (+#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (+#) #-} {-# ANN (+#) hasBlackBox #-} (+#) = \(U i) (U j) -> U (addMod m i j) #if MIN_VERSION_base(4,15,0)@@ -402,7 +423,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE (-#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (-#) #-} {-# ANN (-#) hasBlackBox #-} (-#) = \(U i) (U j) -> U (subMod m i j) #if MIN_VERSION_base(4,15,0)@@ -411,7 +433,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE (*#) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (*#) #-} {-# ANN (*#) hasBlackBox #-} (*#) = \(U i) (U j) -> U (mulMod2 m i j) #if MIN_VERSION_base(4,15,0)@@ -420,7 +443,8 @@   where m = (1 `shiftL` fromInteger (natVal (Proxy @n))) - 1 #endif -{-# NOINLINE negate# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE negate# #-} {-# ANN negate# hasBlackBox #-} negate# :: forall n . KnownNat n => Unsigned n -> Unsigned n negate# = \(U i) -> U (negateMod m i)@@ -430,7 +454,8 @@   where m = 1 `shiftL` fromInteger (natVal (Proxy @n)) #endif -{-# NOINLINE fromInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromInteger# #-} {-# ANN fromInteger# hasBlackBox #-} fromInteger# :: forall n . KnownNat n => Integer -> Unsigned n #if MIN_VERSION_base(4,15,0)@@ -450,12 +475,14 @@   type MResult (Unsigned m) (Unsigned n) = Unsigned (m + n)   mul = times# -{-# NOINLINE plus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE plus# #-} {-# ANN plus# hasBlackBox #-} plus# :: Unsigned m -> Unsigned n -> Unsigned (Max m n + 1) plus# (U a) (U b) = U (a + b) -{-# NOINLINE minus# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE minus# #-} {-# ANN minus# hasBlackBox #-} minus# :: forall m n . (KnownNat m, KnownNat n) => Unsigned m -> Unsigned n                                                 -> Unsigned (Max m n + 1)@@ -469,7 +496,8 @@   mask = 1 `shiftL` sz #endif -{-# NOINLINE times# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE times# #-} {-# ANN times# hasBlackBox #-} times# :: Unsigned m -> Unsigned n -> Unsigned (m + n) times# (U a) (U b) = U (a * b)@@ -490,14 +518,17 @@   toInteger   = toInteger#  quot#,rem# :: Unsigned n -> Unsigned n -> Unsigned n-{-# NOINLINE quot# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE quot# #-} {-# ANN quot# hasBlackBox #-} quot# (U i) (U j) = U (i `quot` j)-{-# NOINLINE rem# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rem# #-} {-# ANN rem# hasBlackBox #-} rem# (U i) (U j) = U (i `rem` j) -{-# NOINLINE toInteger# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE toInteger# #-} {-# ANN toInteger# hasBlackBox #-} toInteger# :: Unsigned n -> Integer toInteger# (U i) = naturalToInteger i@@ -529,29 +560,34 @@   rotateR v i       = rotateR# v i   popCount u        = popCount (pack# u) -{-# NOINLINE and# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE and# #-} {-# ANN and# hasBlackBox #-} and# :: Unsigned n -> Unsigned n -> Unsigned n and# (U v1) (U v2) = U (v1 .&. v2) -{-# NOINLINE or# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE or# #-} {-# ANN or# hasBlackBox #-} or# :: Unsigned n -> Unsigned n -> Unsigned n or# (U v1) (U v2) = U (v1 .|. v2) -{-# NOINLINE xor# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xor# #-} {-# ANN xor# hasBlackBox #-} xor# :: Unsigned n -> Unsigned n -> Unsigned n xor# (U v1) (U v2) = U (v1 `xor` v2) -{-# NOINLINE complement# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE complement# #-} {-# ANN complement# hasBlackBox #-} complement# :: forall n . KnownNat n => Unsigned n -> Unsigned n complement# = \(U i) -> U (complementN i)   where complementN = complementMod (natVal (Proxy @n))  shiftL#, shiftR#, rotateL#, rotateR# :: forall n .KnownNat n => Unsigned n -> Int -> Unsigned n-{-# NOINLINE shiftL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftL# #-} {-# ANN shiftL# hasBlackBox #-} shiftL# = \(U v) i -> #if MIN_VERSION_base(4,15,0)@@ -571,7 +607,8 @@   m  = 1 `shiftL` sz #endif -{-# NOINLINE shiftR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE shiftR# #-} {-# ANN shiftR# hasBlackBox #-} -- shiftR# doesn't need the KnownNat constraint -- But having the same type signature for all shift and rotate functions@@ -581,7 +618,8 @@               $ "'shiftR' undefined for negative number: " ++ show i   | otherwise = U (shiftR v i) -{-# NOINLINE rotateL# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateL# #-} {-# ANN rotateL# hasBlackBox #-} rotateL# =   \(U n) b ->@@ -608,7 +646,8 @@     m  = 1 `shiftL` sz #endif -{-# NOINLINE rotateR# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateR# #-} {-# ANN rotateR# hasBlackBox #-} rotateR# =   \(U n) b ->@@ -646,7 +685,8 @@   zeroExtend = extend   truncateB  = resize# -{-# NOINLINE resize# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE resize# #-} {-# ANN resize# hasBlackBox #-} resize# :: forall n m . KnownNat m => Unsigned n -> Unsigned m resize# = \(U i) -> if i >= m then U (i `mod` m) else U i@@ -697,7 +737,7 @@     let r = minus# a b     in  case msb r of           0 -> resize# r-          _ -> errorX "Unsigned.satSub: underflow"+          _ -> errorX "Unsigned.satSub: overflow"   satSub _ a b =     let r = minus# a b     in  case msb r of@@ -733,7 +773,7 @@   {-# INLINE satSucc #-}    satPred SatError a-    | a == minBound = errorX "Unsigned.satPred: underflow"+    | a == minBound = errorX "Unsigned.satPred: overflow"   satPred satMode a = satSub satMode a 1   {-# INLINE satPred #-} @@ -765,40 +805,53 @@ unsignedToWord (U (NatS# u#)) = W# u# unsignedToWord (U (NatJ# u#)) = W# (bigNatToWord u#) #endif-{-# NOINLINE unsignedToWord #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsignedToWord #-} {-# ANN unsignedToWord hasBlackBox #-}  unsigned8toWord8 :: Unsigned 8 -> Word8-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,16,0)+unsigned8toWord8 (U (NS u#)) = W8# (wordToWord8# u#)+unsigned8toWord8 (U (NB u#)) = W8# (wordToWord8# (bigNatToWord# u#))+#elif MIN_VERSION_base(4,15,0) unsigned8toWord8 (U (NS u#)) = W8# (narrow8Word# u#) unsigned8toWord8 (U (NB u#)) = W8# (narrow8Word# (bigNatToWord# u#)) #else unsigned8toWord8 (U (NatS# u#)) = W8# (narrow8Word# u#) unsigned8toWord8 (U (NatJ# u#)) = W8# (narrow8Word# (bigNatToWord u#)) #endif-{-# NOINLINE unsigned8toWord8 #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsigned8toWord8 #-} {-# ANN unsigned8toWord8 hasBlackBox #-}  unsigned16toWord16 :: Unsigned 16 -> Word16-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,16,0)+unsigned16toWord16 (U (NS u#)) = W16# (wordToWord16# u#)+unsigned16toWord16 (U (NB u#)) = W16# (wordToWord16# (bigNatToWord# u#))+#elif MIN_VERSION_base(4,15,0) unsigned16toWord16 (U (NS u#)) = W16# (narrow16Word# u#) unsigned16toWord16 (U (NB u#)) = W16# (narrow16Word# (bigNatToWord# u#)) #else unsigned16toWord16 (U (NatS# u#)) = W16# (narrow16Word# u#) unsigned16toWord16 (U (NatJ# u#)) = W16# (narrow16Word# (bigNatToWord u#)) #endif-{-# NOINLINE unsigned16toWord16 #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsigned16toWord16 #-} {-# ANN unsigned16toWord16 hasBlackBox #-}  unsigned32toWord32 :: Unsigned 32 -> Word32-#if MIN_VERSION_base(4,15,0)+#if MIN_VERSION_base(4,16,0)+unsigned32toWord32 (U (NS u#)) = W32# (wordToWord32# u#)+unsigned32toWord32 (U (NB u#)) = W32# (wordToWord32# (bigNatToWord# u#))+#elif MIN_VERSION_base(4,15,0) unsigned32toWord32 (U (NS u#)) = W32# (narrow32Word# u#) unsigned32toWord32 (U (NB u#)) = W32# (narrow32Word# (bigNatToWord# u#)) #else unsigned32toWord32 (U (NatS# u#)) = W32# (narrow32Word# u#) unsigned32toWord32 (U (NatJ# u#)) = W32# (narrow32Word# (bigNatToWord u#)) #endif-{-# NOINLINE unsigned32toWord32 #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsigned32toWord32 #-} {-# ANN unsigned32toWord32 hasBlackBox #-}  {-# RULES
src/Clash/Sized/RTree.hs view
@@ -57,7 +57,9 @@   ) where +#if !MIN_VERSION_base(4,18,0) import Control.Applicative         (liftA2)+#endif import Control.DeepSeq             (NFData(..)) import qualified Control.Lens      as Lens import Data.Default.Class          (Default (..))@@ -122,14 +124,20 @@  textract :: RTree 0 a -> a textract (RLeaf x)   = x+#if __GLASGOW_HASKELL__ != 902 textract (RBranch _ _) = error $ "textract: nodes hold no values"-{-# NOINLINE textract #-}+#endif+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE textract #-} {-# ANN textract hasBlackBox #-}  tsplit :: RTree (d+1) a -> (RTree d a,RTree d a) tsplit (RBranch l r) = (l,r)+#if __GLASGOW_HASKELL__ != 902 tsplit (RLeaf _)   = error $ "tsplit: leaf is atomic"-{-# NOINLINE tsplit #-}+#endif+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tsplit #-} {-# ANN tsplit hasBlackBox #-}  -- | RLeaf of a perfect depth tree@@ -373,7 +381,7 @@        -> (forall l . SNat l -> (p @@ l) -> (p @@ l) -> (p @@ (l+1)))        -- ^ Function to fold the branches with.        ---       -- __NB:__ @SNat l@ is the depth of the two sub-branches.+       -- __NB__: @SNat l@ is the depth of the two sub-branches.        -> RTree k a -- ^ Tree to fold over.        -> (p @@ k) tdfold _ f g = go SNat@@ -382,7 +390,8 @@     go _  (RLeaf a)   = f a     go sn (RBranch l r) = let sn' = sn `subSNat` d1                       in  g sn' (go sn' l) (go sn' r)-{-# NOINLINE tdfold #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tdfold #-} {-# ANN tdfold hasBlackBox #-}  data TfoldTree (a :: Type) (f :: TyFun Nat Type) :: Type@@ -411,7 +420,8 @@     go :: UNat n -> RTree n a     go UZero      = LR a     go (USucc un) = BR (go un) (go un)-{-# NOINLINE treplicate #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE treplicate #-} {-# ANN treplicate hasBlackBox #-}  -- | \"'trepeat' @a@\" creates a tree with as many copies of /a/ as demanded by
src/Clash/Sized/Vector.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Myrtle Software Ltd-                  2022     , QBayLogic B.V.+                  2022-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -75,9 +75,9 @@   , foldr, foldl, foldr1, foldl1, fold   , ifoldr, ifoldl     -- ** Specialized folds-  , dfold, dtfold, vfold+  , dfold, dtfold, vfold, maximum, minimum     -- * Prefix sums (scans)-  , scanl, scanr, postscanl, postscanr+  , scanl, scanl1, scanr, scanr1, postscanl, postscanr   , mapAccumL, mapAccumR     -- * Stencil computations   , stencil1d, stencil2d@@ -107,6 +107,9 @@ import Data.Data   (Data (..), Constr, DataType, Fixity (..), Typeable, mkConstr, mkDataType) import Data.Either                (isLeft)+#if MIN_VERSION_base(4,18,0)+import qualified Data.Foldable1   as F1+#endif import Data.Default.Class         (Default (..)) import qualified Data.Foldable    as F import Data.Kind                  (Type)@@ -127,8 +130,9 @@                                           foldl, foldl1, foldr, foldr1, head,                                           init, iterate, last, length, map,                                           repeat, replicate, reverse, scanl,-                                          scanr, splitAt, tail, take, unzip,-                                          unzip3, zip, zip3, zipWith, zipWith3)+                                          scanl1, scanr, scanr1, splitAt, tail,+                                          take, unzip, unzip3, zip, zip3, zipWith,+                                          zipWith3, maximum, minimum) import qualified Data.String.Interpolate as I import qualified Prelude          as P import Test.QuickCheck@@ -136,10 +140,14 @@ import Unsafe.Coerce              (unsafeCoerce)  import Clash.Annotations.Primitive-  (Primitive(InlinePrimitive), HDL(..), dontTranslate, hasBlackBox)+  (Primitive(InlineYamlPrimitive), HDL(..), dontTranslate, hasBlackBox)+import Clash.Magic (clashCompileError) import Clash.Promoted.Nat-  (SNat (..), SNatLE (..), UNat (..), compareSNat, leToPlus, pow2SNat,+  (SNat (..), SNatLE (..), UNat (..), compareSNat, pow2SNat,    snatProxy, snatToInteger, subSNat, withSNat, toUNat, natToInteger)+#if MIN_VERSION_base(4,18,0)+import Clash.Promoted.Nat (leToPlus)+#endif import Clash.Promoted.Nat.Literals (d1) import Clash.Sized.Internal.BitVector (Bit, BitVector (..), split#) import Clash.Sized.Index          (Index)@@ -219,8 +227,8 @@   gfoldl f z xs = case compareSNat (SNat @n) (SNat @0) of     SNatLE -> case leZero @n of                   Sub Dict -> z Nil-    SNatGT -> let (y :> ys) = xs-              in (z @(a -> Vec (n-1) a -> Vec n a) (:>) `f` y `f` ys)+    SNatGT -> case xs of+                  (y :> ys) -> (z @(a -> Vec (n-1) a -> Vec n a) (:>) `f` y `f` ys)  tVec :: DataType tVec = mkDataType "Vec" [cNil, cCons]@@ -316,28 +324,48 @@ "zipWith$map" forall f xs ys. zipWith (\g a -> g a) (map f xs) ys = zipWith f xs ys   #-} -instance (KnownNat n, 1 <= n) => F.Foldable (Vec n) where-  fold      = leToPlus @1 @n $ fold mappend-  foldMap f = leToPlus @1 @n $ fold mappend . map f+instance KnownNat n => F.Foldable (Vec n) where+  fold Nil      = mempty+  fold z@Cons{} = fold mappend z+  foldMap _ Nil      = mempty+  foldMap f z@Cons{} = fold mappend (map f z)   foldr     = foldr   foldl     = foldl-  foldr1 f  = leToPlus @1 @n $ foldr1 f-  foldl1 f  = leToPlus @1 @n $ foldl1 f+  foldr1 _ Nil      = clashCompileError "foldr1: empty Vec"+  foldr1 f z@Cons{} = foldr1 f z+  foldl1 _ Nil      = clashCompileError "foldl1: empty Vec"+  foldl1 f z@Cons{} = foldl1 f z   toList    = toList+  null Nil  = True   null _    = False   length    = length-  maximum   = leToPlus @1 @n $ fold (\x y -> if x >= y then x else y)-  minimum   = leToPlus @1 @n $ fold (\x y -> if x <= y then x else y)-  sum       = leToPlus @1 @n $ fold (+)-  product   = leToPlus @1 @n $ fold (*)+  maximum Nil      = clashCompileError "maximum: empty Vec"+  maximum z@Cons{} = fold (\x y -> if x >= y then x else y) z+  minimum Nil      = clashCompileError "minimum: empty Vec"+  minimum z@Cons{} = fold (\x y -> if x <= y then x else y) z+  sum Nil      = 0+  sum z@Cons{} = fold (+) z+  product Nil      = 1+  product z@Cons{} = fold (*) z +#if MIN_VERSION_base(4,18,0)+instance (KnownNat n, 1 <= n) => F1.Foldable1 (Vec n) where+  fold1         = leToPlus @1 @n $ fold (<>)+  foldMap1 f    = leToPlus @1 @n $ fold (<>) . map f+  maximum       = leToPlus @1 @n maximum+  minimum       = leToPlus @1 @n minimum+  head          = leToPlus @1 @n head+  last          = leToPlus @1 @n last+#endif+ instance Functor (Vec n) where   fmap = map -instance (KnownNat n, 1 <= n) => Traversable (Vec n) where+instance KnownNat n => Traversable (Vec n) where   traverse = traverse# -{-# NOINLINE traverse# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE traverse# #-} {-# ANN traverse# hasBlackBox #-} traverse# :: forall a f b n . Applicative f => (a -> f b) -> Vec n a -> f (Vec n b) traverse# _ Nil           = pure Nil@@ -372,7 +400,8 @@ singleton :: a -> Vec 1 a singleton = (`Cons` Nil) -{-# NOINLINE head #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE head #-} {-# ANN head hasBlackBox #-} {- | Extract the first element of a vector @@ -406,7 +435,8 @@ head :: Vec (n + 1) a -> a head (x `Cons` _) = x -{-# NOINLINE tail #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE tail #-} {-# ANN tail hasBlackBox #-} {- | Extract the elements after the head of a vector @@ -440,7 +470,8 @@ tail :: Vec (n + 1) a -> Vec n a tail (_ `Cons` xs) = xs -{-# NOINLINE last #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE last #-} {-# ANN last hasBlackBox #-} {- | Extract the last element of a vector @@ -475,7 +506,8 @@ last (x `Cons` Nil)         = x last (_ `Cons` y `Cons` ys) = last (y `Cons` ys) -{-# NOINLINE init #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE init #-} {-# ANN init hasBlackBox #-} {- | Extract all the elements of a vector except the last element @@ -643,7 +675,8 @@ (++) :: Vec n a -> Vec m a -> Vec (n + m) a Nil           ++ ys = ys (x `Cons` xs) ++ ys = x `Cons` xs ++ ys-{-# NOINLINE (++) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE (++) #-} {-# ANN (++) hasBlackBox #-}  -- | Split a vector into two vectors at the given point.@@ -654,7 +687,8 @@ -- (1 :> 2 :> 3 :> Nil,7 :> 8 :> Nil) splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a) splitAt n xs = splitAtU (toUNat n) xs-{-# NOINLINE splitAt #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE splitAt #-} {-# ANN splitAt hasBlackBox #-}  splitAtU :: UNat m -> Vec (m + n) a -> (Vec m a, Vec n a)@@ -678,7 +712,8 @@ concat :: Vec n (Vec m a) -> Vec (n * m) a concat Nil           = Nil concat (x `Cons` xs) = x ++ concat xs-{-# NOINLINE concat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE concat #-} {-# ANN concat hasBlackBox #-}  -- | Map a function over all the elements of a vector and concatentate the resulting vectors.@@ -696,7 +731,8 @@ -- (1 :> 2 :> 3 :> 4 :> Nil) :> (5 :> 6 :> 7 :> 8 :> Nil) :> (9 :> 10 :> 11 :> 12 :> Nil) :> Nil unconcat :: KnownNat n => SNat m -> Vec (n * m) a -> Vec n (Vec m a) unconcat n xs = unconcatU (withSNat toUNat) (toUNat n) xs-{-# NOINLINE unconcat #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unconcat #-} {-# ANN unconcat hasBlackBox #-}  unconcatU :: UNat n -> UNat m -> Vec (n * m) a -> Vec n (Vec m a)@@ -728,7 +764,8 @@ reverse :: Vec n a -> Vec n a reverse Nil           = Nil reverse (x `Cons` xs) = reverse xs :< x-{-# NOINLINE reverse #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE reverse #-} {-# ANN reverse hasBlackBox #-}  -- | \"'map' @f xs@\" is the vector obtained by applying /f/ to each element@@ -742,7 +779,8 @@ map :: (a -> b) -> Vec n a -> Vec n b map _ Nil           = Nil map f (x `Cons` xs) = f x `Cons` map f xs-{-# NOINLINE map #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE map #-} {-# ANN map hasBlackBox #-}  -- | Apply a function of every element of a vector and its index.@@ -765,12 +803,13 @@     go :: Index n -> Vec m a -> Vec m b     go _ Nil           = Nil     go n (x `Cons` xs) = f n x `Cons` go (n+1) xs-{-# NOINLINE imap #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE imap #-} {-# ANN imap hasBlackBox #-}  {- | Zip two vectors with a functions that also takes the elements' indices. -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 900 && __GLASGOW_HASKELL__ < 904 >>> izipWith (\i a b -> i + a + b) (2 :> 2 :> Nil)  (3 :> 3:> Nil) *** Exception: X: Clash.Sized.Index: result 2 is out of bounds: [0..1] ...@@ -786,7 +825,7 @@  <<doc/izipWith.svg>> -__NB:__ 'izipWith' is /strict/ in its second argument, and /lazy/ in its+__NB__: 'izipWith' is /strict/ in its second argument, and /lazy/ in its third. This matters when 'izipWith' is used in a recursive setting. See 'lazyV' for more information. -}@@ -880,13 +919,14 @@ -- -- <<doc/zipWith.svg>> ----- __NB:__ 'zipWith' is /strict/ in its second argument, and /lazy/ in its+-- __NB__: 'zipWith' is /strict/ in its second argument, and /lazy/ in its -- third. This matters when 'zipWith' is used in a recursive setting. See -- 'lazyV' for more information. zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c zipWith _ Nil           _  = Nil zipWith f (x `Cons` xs) ys = f x (head ys) `Cons` zipWith f xs (tail ys)-{-# NOINLINE zipWith #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE zipWith #-} {-# ANN zipWith hasBlackBox #-}  -- | 'zipWith3' generalizes 'zip3' by zipping with the function given@@ -898,7 +938,7 @@ -- -- <<doc/zipWith3.svg>> ----- __NB:__ 'zipWith3' is /strict/ in its second argument, and /lazy/ in its+-- __NB__: 'zipWith3' is /strict/ in its second argument, and /lazy/ in its -- third and fourth. This matters when 'zipWith3' is used in a recursive setting. -- See 'lazyV' for more information. zipWith3 :: (a -> b -> c -> d) -> Vec n a -> Vec n b -> Vec n c -> Vec n d@@ -907,7 +947,7 @@  -- 'zipWith4' is analogous to 'zipWith3', but with four vectors. ----- __NB:__ 'zipWith4' is /strict/ in its second argument, and /lazy/ its following+-- __NB__: 'zipWith4' is /strict/ in its second argument, and /lazy/ its following -- arguments. This matters when 'zipWith4' is used in a recursive setting. See -- 'lazyV' for more information. zipWith4@@ -923,7 +963,7 @@  -- 'zipWith5' is analogous to 'zipWith3', but with five vectors. ----- __NB:__ 'zipWith5' is /strict/ in its second argument, and /lazy/ its following+-- __NB__: 'zipWith5' is /strict/ in its second argument, and /lazy/ its following -- arguments. This matters when 'zipWith5' is used in a recursive setting. See -- 'lazyV' for more information. zipWith5@@ -940,7 +980,7 @@  -- 'zipWith6' is analogous to 'zipWith3', but with six vectors. ----- __NB:__ 'zipWith6' is /strict/ in its second argument, and /lazy/ its following+-- __NB__: 'zipWith6' is /strict/ in its second argument, and /lazy/ its following -- arguments. This matters when 'zipWith6' is used in a recursive setting. See -- 'lazyV' for more information. zipWith6@@ -958,7 +998,7 @@  -- 'zipWith7' is analogous to 'zipWith3', but with seven vectors. ----- __NB:__ 'zipWith7' is /strict/ in its second argument, and /lazy/ its following+-- __NB__: 'zipWith7' is /strict/ in its second argument, and /lazy/ its following -- arguments. This matters when 'zipWith7' is used in a recursive setting. See -- 'lazyV' for more information. zipWith7@@ -996,7 +1036,8 @@ foldr :: (a -> b -> b) -> b -> Vec n a -> b foldr _ z Nil           = z foldr f z (x `Cons` xs) = f x (foldr f z xs)-{-# NOINLINE foldr #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE foldr #-} {-# ANN foldr hasBlackBox #-}  -- | 'foldl', applied to a binary operator, a starting value (typically@@ -1090,8 +1131,13 @@     fold' xs  = fold' ys `f` fold' zs       where         (ys,zs) = P.splitAt (P.length xs `div` 2) xs-{-# NOINLINE fold #-}-{-# ANN fold (InlinePrimitive [VHDL,Verilog,SystemVerilog] "[ { \"BlackBoxHaskell\" : { \"name\" : \"Clash.Sized.Vector.fold\", \"templateFunction\" : \"Clash.Primitives.Sized.Vector.foldBBF\"}} ]") #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fold #-}+{-# ANN fold (InlineYamlPrimitive [VHDL,Verilog,SystemVerilog] [I.__i|+  BlackBoxHaskell:+    name: Clash.Sized.Vector.fold+    templateFunction: Clash.Primitives.Sized.Vector.foldBBF+  |]) #-}  -- | 'scanl' is similar to 'foldl', but returns a vector of successive reduced -- values from the left:@@ -1117,6 +1163,22 @@     ws = z `Cons` zipWith (flip f) xs (init ws) {-# INLINE scanl #-} +-- | 'scanl' with no seed value+--+-- >>> scanl1 (-) (1 :> 2 :> 3 :> 4 :> Nil)+-- 1 :> -1 :> -4 :> -8 :> Nil+scanl1 :: KnownNat n => (a -> a -> a) -> Vec (n+1) a -> Vec (n+1) a+scanl1 op (v:>vs) = scanl op v vs+{-# INLINE scanl1 #-}++-- | 'scanr' with no seed value+--+-- >>> scanr1 (-) (1 :> 2 :> 3 :> 4 :> Nil)+-- -2 :> 3 :> -1 :> 4 :> Nil+scanr1 :: KnownNat n => (a -> a -> a) -> Vec (n+1) a -> Vec (n+1) a+scanr1 op vs = scanr op (last vs) (init vs)+{-# INLINE scanr1 #-}+ -- | 'postscanl' is a variant of 'scanl' where the first result is dropped: -- -- > postscanl f z (x1 :> x2 :> ... :> Nil) == (z `f` x1) :> ((z `f` x1) `f` x2) :> ... :> Nil@@ -1352,12 +1414,13 @@     sub (y `Cons` (!ys)) n = if isTrue# (n ==# 0#)                                 then y                                 else sub ys (n -# 1#)-{-# NOINLINE index_int #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE index_int #-} {-# ANN index_int hasBlackBox #-}  -- | \"@xs@ '!!' @n@\" returns the /n/'th element of /xs/. ----- __NB__: vector elements have an __ASCENDING__ subscript starting from 0 and+-- __NB__: Vector elements have an __ASCENDING__ subscript starting from 0 and -- ending at @'length' - 1@. -- -- >>> (1:>2:>3:>4:>5:>Nil) !! 4@@ -1379,7 +1442,8 @@ -- 3 length :: KnownNat n => Vec n a -> Int length = fromInteger . natVal . asNatProxy-{-# NOINLINE length #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE length #-} {-# ANN length hasBlackBox #-}  replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a@@ -1396,13 +1460,14 @@     sub (y `Cons` (!ys)) n b = if isTrue# (n ==# 0#)                                  then b `Cons` ys                                  else y `Cons` sub ys (n -# 1#) b-{-# NOINLINE replace_int #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE replace_int #-} {-# ANN replace_int hasBlackBox #-}  -- | \"'replace' @n a xs@\" returns the vector /xs/ where the /n/'th element is -- replaced by /a/. ----- __NB__: vector elements have an __ASCENDING__ subscript starting from 0 and+-- __NB__: Vector elements have an __ASCENDING__ subscript starting from 0 and -- ending at @'length' - 1@. -- -- >>> replace 3 7 (1:>2:>3:>4:>5:>Nil)@@ -1425,13 +1490,25 @@ >>> take d0               (1:>2:>Nil) Nil -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ == 906 >>> take d4               (1:>2:>Nil) <BLANKLINE> <interactive>:...     • Couldn't match type ‘4 + n0’ with ‘2’       Expected: Vec (4 + n0) a         Actual: Vec (1 + 1) a+        The type variable ‘n0’ is ambiguous+    • In the second argument of ‘take’, namely ‘(1 :> 2 :> Nil)’+      In the expression: take d4 (1 :> 2 :> Nil)+      In an equation for ‘it’: it = take d4 (1 :> 2 :> Nil)++#elif __GLASGOW_HASKELL__ >= 900+>>> take d4               (1:>2:>Nil)+<BLANKLINE>+<interactive>:...+    • Couldn't match type ‘4 + n0’ with ‘2’+      Expected: Vec (4 + n0) a+        Actual: Vec (1 + 1) a       The type variable ‘n0’ is ambiguous     • In the second argument of ‘take’, namely ‘(1 :> 2 :> Nil)’       In the expression: take d4 (1 :> 2 :> Nil)@@ -1463,21 +1540,35 @@ takeI = withSNat take {-# INLINE takeI #-} --- | \"'drop' @n xs@\" returns the suffix of /xs/ after the first /n/ elements.------ >>> drop (SNat :: SNat 3) (1:>2:>3:>4:>5:>Nil)--- 4 :> 5 :> Nil--- >>> drop d3               (1:>2:>3:>4:>5:>Nil)--- 4 :> 5 :> Nil--- >>> drop d0               (1:>2:>Nil)--- 1 :> 2 :> Nil--- >>> drop d4               (1:>2:>Nil)--- <BLANKLINE>--- <interactive>:...: error:---     • Couldn't match...type ‘4 + n0...---       The type variable ‘n0’ is ambiguous---     • In the first argument of ‘print’, namely ‘it’---       In a stmt of an interactive GHCi command: print it+{- | \"'drop' @n xs@\" returns the suffix of /xs/ after the first /n/ elements.++>>> drop (SNat :: SNat 3) (1:>2:>3:>4:>5:>Nil)+4 :> 5 :> Nil+>>> drop d3               (1:>2:>3:>4:>5:>Nil)+4 :> 5 :> Nil+>>> drop d0               (1:>2:>Nil)+1 :> 2 :> Nil++#if __GLASGOW_HASKELL__ == 906+>>> drop d4               (1:>2:>Nil)+<BLANKLINE>+<interactive>:...: error:...+    • Couldn't match...type ‘4 + n0...+        The type variable ‘n0’ is ambiguous+    • In the first argument of ‘print’, namely ‘it’+      In a stmt of an interactive GHCi command: print it++#else+>>> drop d4               (1:>2:>Nil)+<BLANKLINE>+<interactive>:...: error:...+    • Couldn't match...type ‘4 + n0...+      The type variable ‘n0’ is ambiguous+    • In the first argument of ‘print’, namely ‘it’+      In a stmt of an interactive GHCi command: print it++#endif+-} drop :: SNat m -> Vec (m + n) a -> Vec n a drop n = snd . splitAt n {-# INLINE drop #-}@@ -1492,7 +1583,7 @@  -- | \"'at' @n xs@\" returns /n/'th element of /xs/ ----- __NB__: vector elements have an __ASCENDING__ subscript starting from 0 and+-- __NB__: Vector elements have an __ASCENDING__ subscript starting from 0 and -- ending at @'length' - 1@. -- -- >>> at (SNat :: SNat 1) (1:>2:>3:>4:>5:>Nil)@@ -1522,7 +1613,8 @@     select' UZero      _               = Nil     select' (USucc n') vs@(x `Cons` _) = x `Cons`                                          select' n' (drop s (unsafeCoerce vs))-{-# NOINLINE select #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE select #-} {-# ANN select hasBlackBox #-}  -- | \"'selectI' @f s xs@\" selects as many elements as demanded by the context@@ -1546,7 +1638,8 @@ -- 6 :> 6 :> 6 :> Nil replicate :: SNat n -> a -> Vec n a replicate n a = replicateU (toUNat n) a-{-# NOINLINE replicate #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE replicate #-} {-# ANN replicate hasBlackBox #-}  replicateU :: UNat n -> a -> Vec n a@@ -1578,7 +1671,7 @@ iterate SNat = iterateI {-# INLINE iterate #-} --- | \"'iterate' @f x@\" returns a vector starting with @x@ followed by @n@+-- | \"'iterateI' @f x@\" returns a vector starting with @x@ followed by @n@ -- repeated applications of @f@ to @x@, where @n@ is determined by the context. -- -- > iterateI f x :: Vec 3 a == (x :> f x :> f (f x) :> Nil)@@ -1594,12 +1687,13 @@   where     xs = init (a `Cons` ws)     ws = map f (lazyV xs)-{-# NOINLINE iterateI #-}-{-# ANN iterateI (InlinePrimitive [VHDL,Verilog,SystemVerilog] [I.i| [{-    "BlackBoxHaskell": {-        "name": "Clash.Sized.Vector.iterateI"-      , "templateFunction": "Clash.Primitives.Sized.Vector.iterateBBF"-    }}] |]) #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE iterateI #-}+{-# ANN iterateI (InlineYamlPrimitive [VHDL,Verilog,SystemVerilog] [I.__i|+  BlackBoxHaskell:+    name: Clash.Sized.Vector.iterateI+    templateFunction: Clash.Primitives.Sized.Vector.iterateBBF+  |]) #-}  -- | \"'unfoldr' @n f s@\" builds a vector of length @n@ from a seed value @s@, -- where every element @a@ is created by successive calls of @f@ on @s@. Unlike@@ -1671,7 +1765,8 @@ -- (1 :> 3 :> 5 :> Nil) :> (2 :> 4 :> 6 :> Nil) :> Nil transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a) transpose = traverse# id-{-# NOINLINE transpose #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE transpose #-} {-# ANN transpose hasBlackBox #-}  -- | 1-dimensional stencil computations@@ -1695,20 +1790,29 @@ stencil1d stX f xs = map f (windows1d stX xs) {-# INLINE stencil1d #-} --- | 2-dimensional stencil computations------ \"'stencil2d' @stY stX f xss@\", where /xss/ is a matrix of /stY + m/ rows--- of /stX + n/ elements, applies the stencil computation /f/ on:--- /(m + 1) * (n + 1)/ overlapping (2D) windows of /stY/ rows of /stX/ elements,--- drawn from /xss/. The result matrix has /m + 1/ rows of /n + 1/ elements.------ >>> let xss = ((1:>2:>3:>4:>Nil):>(5:>6:>7:>8:>Nil):>(9:>10:>11:>12:>Nil):>(13:>14:>15:>16:>Nil):>Nil)--- >>> :t xss--- xss :: Num a => Vec 4 (Vec 4 a)--- >>> :t stencil2d d2 d2 (sum . map sum) xss--- stencil2d d2 d2 (sum . map sum) xss :: Num b => Vec 3 (Vec 3 b)--- >>> stencil2d d2 d2 (sum . map sum) xss--- (14 :> 18 :> 22 :> Nil) :> (30 :> 34 :> 38 :> Nil) :> (46 :> 50 :> 54 :> Nil) :> Nil+{- | 2-dimensional stencil computations++\"'stencil2d' @stY stX f xss@\", where /xss/ is a matrix of /stY + m/ rows+of /stX + n/ elements, applies the stencil computation /f/ on:+/(m + 1) * (n + 1)/ overlapping (2D) windows of /stY/ rows of /stX/ elements,+drawn from /xss/. The result matrix has /m + 1/ rows of /n + 1/ elements.++>>> let xss = ((1:>2:>3:>4:>Nil):>(5:>6:>7:>8:>Nil):>(9:>10:>11:>12:>Nil):>(13:>14:>15:>16:>Nil):>Nil)+>>> :t xss+xss :: Num a => Vec 4 (Vec 4 a)++#if __GLASGOW_HASKELL__ >= 902+>>> :t stencil2d d2 d2 (sum . map sum) xss+stencil2d d2 d2 (sum . map sum) xss :: Num a => Vec 3 (Vec 3 a)++#else+>>> :t stencil2d d2 d2 (sum . map sum) xss+stencil2d d2 d2 (sum . map sum) xss :: Num b => Vec 3 (Vec 3 b)++#endif+>>> stencil2d d2 d2 (sum . map sum) xss+(14 :> 18 :> 22 :> Nil) :> (30 :> 34 :> 38 :> Nil) :> (46 :> 50 :> 54 :> Nil) :> Nil+-} stencil2d :: (KnownNat n, KnownNat m)           => SNat (stY + 1) -- ^ Window hight /stY/, at least size 1           -> SNat (stX + 1) -- ^ Window width /stX/, at least size 1@@ -1863,7 +1967,7 @@ -- >>> rotateLeft xs (-1) -- 4 :> 1 :> 2 :> 3 :> Nil ----- __NB:__ use `rotateLeftS` if you want to rotate left by a /static/ amount.+-- __NB__: Use `rotateLeftS` if you want to rotate left by a /static/ amount. rotateLeft :: (Enum i, KnownNat n)            => Vec n a            -> i@@ -1884,7 +1988,7 @@ -- >>> rotateRight xs (-1) -- 2 :> 3 :> 4 :> 1 :> Nil ----- __NB:__ use `rotateRightS` if you want to rotate right by a /static/ amount.+-- __NB__: Use `rotateRightS` if you want to rotate right by a /static/ amount. rotateRight :: (Enum i, KnownNat n)             => Vec n a             -> i@@ -1901,7 +2005,7 @@ -- >>> rotateLeftS xs d1 -- 2 :> 3 :> 4 :> 1 :> Nil ----- __NB:__ use `rotateLeft` if you want to rotate left by a /dynamic/ amount.+-- __NB__: Use `rotateLeft` if you want to rotate left by a /dynamic/ amount. rotateLeftS :: KnownNat n             => Vec n a             -> SNat d@@ -1912,7 +2016,8 @@     go _ Nil           = Nil     go 0 ys            = ys     go n (y `Cons` ys) = go (n-1) (ys :< y)-{-# NOINLINE rotateLeftS #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateLeftS #-} {-# ANN rotateLeftS hasBlackBox #-}  -- | /Statically/ rotate a 'Vec'tor to the right:@@ -1921,7 +2026,7 @@ -- >>> rotateRightS xs d1 -- 4 :> 1 :> 2 :> 3 :> Nil ----- __NB:__ use `rotateRight` if you want to rotate right by a /dynamic/ amount.+-- __NB__: Use `rotateRight` if you want to rotate right by a /dynamic/ amount. rotateRightS :: KnownNat n              => Vec n a              -> SNat d@@ -1931,7 +2036,8 @@     go _ Nil            = Nil     go 0 ys             = ys     go n ys@(Cons _ _)  = go (n-1) (last ys :> init ys)-{-# NOINLINE rotateRightS #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE rotateRightS #-} {-# ANN rotateRightS hasBlackBox #-}  -- | Convert a vector to a list.@@ -1939,7 +2045,7 @@ -- >>> toList (1:>2:>3:>Nil) -- [1,2,3] ----- __NB:__ this function is not synthesizable+-- __NB__: This function is not synthesizable toList :: Vec n a -> [a] toList = foldr (:) [] {-# INLINE toList #-}@@ -1956,8 +2062,8 @@ -- >>> Vec.fromList [1,2,3,4,5] :: Maybe (Vec 10 Int) -- Nothing ----- * __NB:__ use `listToVecTH` if you want to make a /statically known/ vector--- * __NB:__ this function is not synthesizable+-- * __NB__: Use `listToVecTH` if you want to make a /statically known/ vector+-- * __NB__: This function is not synthesizable -- fromList :: forall n a. (KnownNat n) => [a] -> Maybe (Vec n a) fromList xs@@ -1967,7 +2073,8 @@   exactLength 0 acc = null acc   exactLength _ []  = False   exactLength i (_:ys) = exactLength (i - 1) ys-{-# NOINLINE fromList #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE fromList #-} {-# ANN fromList dontTranslate #-}  -- | Convert a list to a vector. This function always returns a vector of the@@ -1984,8 +2091,8 @@ -- 1 :> 2 :> 3 :> 4 :> 5 :> *** Exception: Clash.Sized.Vector.unsafeFromList: vector larger than list -- ... ----- * __NB:__ use `listToVecTH` if you want to make a /statically known/ vector--- * __NB:__ this function is not synthesizable+-- * __NB__: Use `listToVecTH` if you want to make a /statically known/ vector+-- * __NB__: This function is not synthesizable -- unsafeFromList :: forall n a. (KnownNat n) => [a] -> Vec n a unsafeFromList = unfoldr SNat go@@ -1995,7 +2102,8 @@   go [] =     let item = error "Clash.Sized.Vector.unsafeFromList: vector larger than list"      in (item, [])-{-# NOINLINE unsafeFromList #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeFromList #-} {-# ANN unsafeFromList dontTranslate #-}  -- | Create a vector literal from a list literal.@@ -2096,7 +2204,8 @@     lazyV' :: Vec n () -> Vec n a -> Vec n a     lazyV' Nil           _  = Nil     lazyV' (_ `Cons` xs) ys = head ys `Cons` lazyV' xs (tail ys)-{-# NOINLINE lazyV #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE lazyV #-} {-# ANN lazyV hasBlackBox #-}  -- | A /dependently/ typed fold.@@ -2200,7 +2309,8 @@     go s (y `Cons` ys) =       let s' = s `subSNat` d1       in  f s' y (go s' ys)-{-# NOINLINE dfold #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE dfold #-} {-# ANN dfold hasBlackBox #-}  {- | A combination of 'dfold' and 'fold': a /dependently/ typed fold that@@ -2363,7 +2473,8 @@           sn'       = sn `subSNat` d1           (xsL,xsR) = splitAt (pow2SNat sn') xs       in  g sn' (go sn' xsL) (go sn' xsR)-{-# NOINLINE dtfold #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE dtfold #-} {-# ANN dtfold hasBlackBox #-}  -- | To be used as the motive /p/ for 'dfold', when the /f/ in \"'dfold' @p f@\"@@ -2407,6 +2518,20 @@ vfold f xs = dfold (Proxy @(VCons b)) f Nil xs {-# INLINE vfold #-} +-- | The largest element of a non-empty vector+maximum ::+  Ord a =>+  Vec (n + 1) a ->+  a+maximum = fold (\x y -> if x >= y then x else y)++-- | The least element of a non-empty vector+minimum ::+  Ord a =>+  Vec (n + 1) a ->+  a+minimum = fold (\x y -> if x <= y then x else y)+ -- | Apply a function to every element of a vector and the element's position -- (as an 'SNat' value) in the vector. --@@ -2440,7 +2565,8 @@   go (BV accMsk accVal) ((BV xMsk xVal) `Cons` xs) =     let sh = fromInteger (natVal (Proxy @m)) :: Int in     go (BV (shiftL accMsk sh .|. xMsk) (shiftL accVal sh .|. xVal)) xs-{-# NOINLINE concatBitVector# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE concatBitVector# #-} {-# ANN concatBitVector# hasBlackBox #-}  unconcatBitVector#@@ -2456,7 +2582,8 @@       let (bv,xs) = go n           (l,x) = (GHC.Magic.noinline split#) bv       in  (l,x :> xs)-{-# NOINLINE unconcatBitVector# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unconcatBitVector# #-} {-# ANN unconcatBitVector# hasBlackBox #-}  -- | Convert a 'BitVector' to a 'Vec' of 'Bit's.@@ -2488,7 +2615,8 @@ seqV v b =   let s () e = seq e () in   foldl s () v `seq` b-{-# NOINLINE seqV #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE seqV #-} {-# ANN seqV hasBlackBox #-} infixr 0 `seqV` @@ -2511,7 +2639,8 @@ seqVX v b =   let s () e = seqX e () in   foldl s () v `seqX` b-{-# NOINLINE seqVX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE seqVX #-} {-# ANN seqVX hasBlackBox #-} infixr 0 `seqVX` 
src/Clash/Sized/Vector.hs-boot view
@@ -9,16 +9,17 @@ {-# LANGUAGE KindSignatures #-} {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} module Clash.Sized.Vector where  import Data.Kind (Type)-import GHC.TypeLits  (KnownNat, Nat, type (<=))+import GHC.TypeLits  (KnownNat, Nat) import {-# SOURCE #-} Clash.Sized.Internal.BitVector (BitVector, Bit)  type role Vec nominal representational data Vec :: Nat -> Type -> Type -instance (KnownNat n, 1 <= n) => Foldable (Vec n)+instance KnownNat n => Foldable (Vec n)  bv2v  :: KnownNat n => BitVector n -> Vec n Bit map   :: (a -> b) -> Vec n a -> Vec n b
src/Clash/Tutorial.hs view
@@ -4,6 +4,7 @@               2017     , QBayLogic, Google Inc.,               2021-2023, QBayLogic B.V.               2022     , LUMI GUIDE FIETSDETECTIE B.V.+              2023     , Alex Mason  Licence   : Creative Commons 4.0 (CC BY 4.0) (https://creativecommons.org/licenses/by/4.0/) Maintainer:  QBayLogic B.V. <devops@qbaylogic.com>@@ -80,6 +81,7 @@ where  import Clash.Prelude+import Clash.Prelude.Mealy import Clash.Explicit.Testbench import Clash.XException (NFDataX) import Control.Monad.ST@@ -96,6 +98,7 @@ >>> :set -XTemplateHaskell -XDataKinds -XConstraintKinds -XTypeApplications >>> :m -Prelude >>> import Clash.Prelude+>>> import Clash.Prelude.Mealy >>> import Clash.Explicit.Testbench >>> :{ let ma :: Num a => a -> (a, a) -> a@@ -336,8 +339,8 @@   * __@ma ::@__, @ma@ is of type.. - * __@Num a@__, there is some type called @a@ that is a @'Num'@. Examples of-   instances of @'Num'@ are @'Int'@, @'Signed' 16@, @'Index' 32@, and @'Float'@.+ * __@Num a@__, there is some type called @a@ that is a 'Num'. Examples of+   instances of 'Num' are 'Int', @'Signed' 16@, @'Index' 32@, and 'Float'.   * __@a@__, @ma@'s first argument is of type @a@ @@ -346,8 +349,8 @@  * __@a@__, @ma@'s result is of type @a@  Note that @ma@ therefore works on multiple types! The only condition we-imposed is that @a@ should be a @'Num'@ber type. In Clash this means it should-support the operations @'Prelude.+'@, @'Prelude.-'@, @'Prelude.*'@, and some+imposed is that @a@ should be a 'Num'ber type. In Clash this means it should+support the operations 'Prelude.+', 'Prelude.-', 'Prelude.*', and some others. Indeed, this is why Clash adds the constraint in the first place: the definition of @ma@ uses @+@ and @*@. Whenever a function works over multiple types, we call it /polymorphic/ ("poly" meaning "many", "morphic" meaning@@ -359,12 +362,12 @@ tutorial: /types/ and /synchronous sequential logic/. Especially how we can always determine, through the types of a specification, if it describes combinational logic or (synchronous) sequential logic. We do this by examining-the definition of one of the sequential primitives, the @'register'@ function:+the definition of one of the sequential primitives, the 'register' function:  @ register-     ( 'HiddenClockResetEnable' dom-     , 'Clash.XException.NFDataX' a )+  :: ( 'HiddenClockResetEnable' dom+     , 'NFDataX' a )   => a   -> 'Signal' dom a   -> 'Signal' dom a@@ -398,10 +401,10 @@ Where we see that the initial value of the signal is the specified 0 value, followed by 8's. You might be surprised to see /two/ zeros instead of just a single zero. What happens is that in Clash you get to see the output of the-circuit /before/ the clock becomes actives. In other words, in Clash you get to+circuit /before/ the clock becomes active. In other words, in Clash you get to describe the powerup values of registers too. Whether this is a defined or unknown value depends on your hardware target, and can be configured by using a-different synthesis @'Domain'@. The default synthesis domain, @'System', assumes+different synthesis 'Domain'. The default synthesis domain, @'System', assumes that registers do have a powerup value - as is true for most FPGA platforms in most contexts. -}@@ -452,7 +455,7 @@  @ mealy-  :: ('HiddenClockResetEnable' dom, 'Clash.XException.NFDataX' s)+  :: ('HiddenClockResetEnable' dom, 'NFDataX' s)   => (s -> i -> (s,o))   -> s   -> ('Signal' dom i -> 'Signal' dom o)@@ -465,7 +468,7 @@ mac inp = 'mealy' macT 0 inp @ -Where the first argument of @'mealy'@ is our @macT@ function, and the second+Where the first argument of 'mealy' is our @macT@ function, and the second argument is the initial state, in this case 0. We can see it is functioning correctly in our interpreter: @@ -512,7 +515,7 @@     acc' = ma acc (x,y)     o    = acc -mac inp = 'mealy' macT 0 inp+mac xy = 'mealy' macT 0 xy  topEntity   :: 'Clock' 'System'@@ -649,8 +652,9 @@     function directly:      @-    macN (x,y) = acc+    macN xy = acc       where+        (x,y) = 'unbundle' xy         acc = 'register' 0 (acc + x * y)     @ @@ -662,52 +666,47 @@     class:      @-    macA (x,y) = acc+    macA xy = acc       where         acc  = 'register' 0 acc'-        acc' = ma '<$>' acc '<*>' 'bundle' (x,y)+        acc' = ma '<$>' acc '<*>' xy     @ -* __'Control.Monad.State.Lazy.State' Monad__+* __t'Control.Monad.State.Strict.State' Monad__ -    We can also implement the original @macT@ function as a-    @'Control.Monad.State.Lazy.State'@-    monadic computation. First we must add an extra import statement, right-    after the import of "Clash.Prelude":+    We can also implement the original @macT@ function as+    a t'Control.Monad.State.Strict.State' monadic computation. First we must add+    an extra import statement, right after the import of "Clash.Prelude":      @-    import Control.Monad.State+    import Control.Monad.State.Strict     @      We can then implement macT as follows:      @     macTS (x,y) = do-      acc <- 'Control.Monad.State.Lazy.get'-      'Control.Monad.State.Lazy.put' (acc + x * y)+      acc <- 'Control.Monad.State.Strict.get'+      'Control.Monad.State.Strict.put' (acc + x * y)       return acc     @ -    We can use the 'mealy' function again, although we will have to change-    position of the arguments and result:+    We can use the 'mealyS' function to run our stateful implementation, this+    can simplify translating algorithms which are described imperatively.      @-    asStateM-      :: ( 'HiddenClockResetEnable' dom-         , 'NFDataX' s )-      => (i -> 'Control.Monad.State.Lazy.State' s o)+    mealyS+      :: ( HiddenClockResetEnable dom, NFDataX s )+      => (i -> State s o)       -> s-      -> ('Signal' dom i -> 'Signal' dom o)-    asStateM f i = 'mealy' g i-      where-        g s x = let (o,s') = 'Control.Monad.State.Lazy.runState' (f x) s-                in  (s',o)+      -> (Signal dom i -> Signal dom o)+    mealyS f initS = ...     @      We can then create the complete @mac@ circuit as:      @-    macS = asStateM macTS 0+    macS xy = 'mealyS' macTS 0 xy     @ -} @@ -913,19 +912,18 @@ import "Clash.Prelude" import "Clash.Intel.ClockGen" -'createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}+'createDomain' vSystem{vName=\"DomInput\", vPeriod=20000, vResetPolarity=ActiveLow} 'createDomain' vSystem{vName=\"Dom100\", vPeriod=10000}  topEntity   :: Clock DomInput-  -> Signal DomInput Bool+  -> Reset DomInput   -> Signal Dom100 Bit   -> Signal Dom100 (BitVector 8) topEntity clk rst =-    'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . Clash.Prelude.isRising 1) pllOut rstSync 'enableGen'+    'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . 'Clash.Prelude.isRising' 1) pllOut pllRst 'enableGen'   where-    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom100 (SSymbol \@\"altpll100\") clk ('Clash.Signal.unsafeFromLowPolarity' rst)-    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeFromLowPolarity' pllStable)+    (pllOut,pllRst) = 'Clash.Intel.ClockGen.altpllSync' clk rst  blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)   where@@ -959,8 +957,9 @@ entity topEntity is   port(-- clock        clk    : in Blinker_topEntity_types.clk_DomInput;-       rst    : in boolean;-       x      : in std_logic;+       -- reset+       rst    : in Blinker_topEntity_types.rst_DomInput;+       eta    : in std_logic;        result : out std_logic_vector(7 downto 0)); end; @@ -994,8 +993,9 @@  entity blinker is   port(-- clock-       CLOCK_50 : in blinker_types.clk_dominput;-       KEY0     : in boolean;+       CLOCK_50 : in blinker_types.clk_DomInput;+       -- reset+       KEY0     : in blinker_types.rst_DomInput;        KEY1     : in std_logic;        LED      : out std_logic_vector(7 downto 0)); end;@@ -1050,7 +1050,7 @@ "Clash.Sized.Internal.Signed" module specifies multiplication as follows:  @-(*#) :: 'GHC.TypeLits.KnownNat' n => 'Signed' n -> 'Signed' n -> 'Signed' n+(*#) :: 'KnownNat' n => 'Signed' n -> 'Signed' n -> 'Signed' n (S a) *# (S b) = fromInteger_INLINE (a * b) {\-\# NOINLINE (*#) \#-\} @@@ -1109,7 +1109,7 @@   :: ( KnownDomain dom      , HasCallStack      , NFDataX a )-  => 'Clock' dom           -- ^ 'Clock' to synchronize to+  => 'Clock' dom           -- ^ Clock to synchronize to   -> 'Enable' dom          -- ^ Global enable   -> 'Vec' n a             -- ^ Initial content of the BRAM, also                            -- determines the size, @n@, of the BRAM.@@ -1262,7 +1262,7 @@   @-fclash-vivado@ flag. To be used with in an @~IF .. ~THEN .. ~ELSE .. ~FI@   statement. * @~CMPLE[\<HOLE1\>][\<HOLE2\>]@: /1/ when @\<HOLE1\> \<= \<HOLE2\>@, otherwise /0/-* @~IW64@: /1/ when Int/Word/Integer types are represented with 64 bits in HDL.+* @~IW64@: /1/ when Int\/Word\/Integer types are represented with 64 bits in HDL.   /0/ when they're represented by 32 bits. * @~TOBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the   expression in @\<HOLE\>@ is converted to a bit vector (@std_logic_vector@).@@ -1289,16 +1289,16 @@ * @~TAG[N]@: Name of given domain. Errors when called on an argument which is not   a 'KnownDomain', 'Reset', or 'Clock'. * @~PERIOD[N]@: Clock period of given domain. Errors when called on an argument-  which is not a 'KnownDomain' or 'KnownConf'.+  which is not a 'Clock', 'Reset', 'KnownDomain' or 'KnownConf'. * @~ISACTIVEENABLE[N]@: Is the @(N+1)@'th argument a an Enable line NOT set to a   constant True. Can be used instead of deprecated (and removed) template tag * @~ISSYNC[N]@: Does synthesis domain at the @(N+1)@'th argument have synchronous resets. Errors-  when called on an argument which is not a 'KnownDomain' or 'KnownConf'.+  when called on an argument which is not a 'Reset', 'Clock', 'Enable', 'KnownDomain' or 'KnownConf'. * @~ISINITDEFINED[N]@: Does synthesis domain at the @(N+1)@'th argument have defined initial-  values. Errors when called on an argument which is not a 'KnownDomain' or 'KnownConf'.+  values. Errors when called on an argument which is not a 'Clock', 'Reset', 'Enable', 'KnownDomain' or 'KnownConf'. * @~ACTIVEEDGE[edge][N]@: Does synthesis domain at the @(N+1)@'th argument respond to   /edge/. /edge/ must be one of 'Falling' or 'Rising'. Errors when called on an-  argument which is not a 'KnownDomain' or 'KnownConf'.+  argument which is not a 'Clock', 'Reset', 'Enable', 'KnownDomain' or 'KnownConf'. * @~AND[\<HOLE1\>,\<HOLE2\>,..]@: Logically /and/ the conditions in the @\<HOLE\>@'s * @~VAR[\<NAME\>][N]@: Like @~ARG[N]@ but binds the argument to a variable named NAME.   The @\<NAME\>@ can be left blank, then clash will come up with a (unique) name.@@ -1563,9 +1563,10 @@      , 'HasCallStack'      , 'KnownDomain' wdom      , 'KnownDomain' rdom+     , 'NFDataX' a      )-  => 'Clock' wdom                     -- ^ 'Clock' to which to synchronize the write port of the RAM-  -> 'Clock' rdom                     -- ^ 'Clock' to which the read address signal, @r@, is synchronized to+  => 'Clock' wdom                     -- ^ Clock to which to synchronize the write port of the RAM+  -> 'Clock' rdom                     -- ^ Clock to which the read address signal, @r@, is synchronized to   -> 'Enable' wdom                    -- ^ Global enable   -> 'SNat' n                         -- ^ Size @n@ of the RAM   -> 'Signal' rdom addr               -- ^ Read address @r@@@ -1664,12 +1665,10 @@   'Clash.Explicit.Signal.register' clk2 rst2 en2 0 . 'Clash.Explicit.Signal.register' clk2 rst2 en2 0 . 'Clash.Explicit.Signal.unsafeSynchronizer' clk1 clk2 @ -It uses the 'Clash.Explicit.Signal.unsafeSynchronizer' primitive, which is needed to go from one clock-domain to the other. All synchronizers are specified in terms of-'Clash.Explicit.Signal.unsafeSynchronizer' (see for example the <src/Clash-Prelude-RAM.html#line-103 source of asyncRam>).-The 'Clash.Explicit.Signal.unsafeSynchronizer' primitive is turned into a (bundle of) wire(s) by the-Clash compiler, so developers must ensure that it is only used as part of a-proper synchronizer.+It uses the 'Clash.Explicit.Signal.unsafeSynchronizer' primitive, which is+needed to go from one clock domain to the other. The 'Clash.Explicit.Signal.unsafeSynchronizer'+primitive is turned into a (bundle of) wire(s) by the Clash compiler, so+developers must ensure that it is only used as part of a proper synchronizer.  Finally we combine all the components in: @@ -1682,9 +1681,9 @@   -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@   -- elements.   -> 'Clock' wdom-  -- ^ 'Clock' to which the write port is synchronized+  -- ^ Clock to which the write port is synchronized   -> 'Clock' rdom-  -- ^ 'Clock' to which the read port is synchronized+  -- ^ Clock to which the read port is synchronized   -> 'Reset' wdom   -> 'Reset' rdom   -> 'Enable' wdom@@ -2200,7 +2199,7 @@             __plusFloat#__ :: 'Float#' -> 'Float#' -> 'Float#'             @ -            which underlie @'Float'@'s 'Num' instance, must be implemented as+            which underlie 'Float'\'s 'Num' instance, must be implemented as             purely combinational circuits according to their type. Remember,             sequential circuits operate on values of type \"@'Signal' a@\". @@ -2301,9 +2300,9 @@ * Automatic synthesis for user-defined ADTs * Synthesis of all choice constructs (pattern matching, guards, etc.) * 'Applicative' instance for the 'Signal' type-* Working with \"normal\" functions permits the use of e.g. the-  'Control.Monad.State.Lazy.State' monad to describe the functionality of a-  circuit.+* Working with \"normal\" functions permits the use of e.g.+  the t'Control.Monad.State.Strict.State' monad to describe the functionality of+  a circuit.  Although there are Lava alternatives to some of the above features (e.g. first-class patterns to replace pattern matching) they are not as \"beautiful\"@@ -2381,7 +2380,7 @@ testBench = done   where     testInput      = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)-    expectedOutput = outputVerifier clk rst (4:>12:>1:>20:>Nil)+    expectedOutput = outputVerifier' clk rst (4:>12:>1:>20:>Nil)     done           = expectedOutput (topEntity clk rst testInput)     clk            = tbSystemClockGen (not \<$\> done)     rst            = systemResetGen@@ -2505,8 +2504,8 @@ topEntity clk rst =     'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . Clash.Prelude.isRising 1) pllOut rstSync 'enableGen'   where-    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom100 (SSymbol \@\"altpll100\") clk ('Clash.Signal.unsafeFromLowPolarity' rst)-    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeFromLowPolarity' pllStable)+    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom100 (SSymbol \@\"altpll100\") clk ('unsafeFromActiveLow' rst)+    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('unsafeFromActiveLow' pllStable)  blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)   where
src/Clash/XException.hs view
@@ -2,7 +2,7 @@ Copyright  :  (C) 2016,      University of Twente,                   2017,      QBayLogic, Google Inc.                   2017-2019, Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -59,6 +59,9 @@ import           Data.Functor.Product (Product) import           Data.Functor.Sum    (Sum) import           Data.Int            (Int8, Int16, Int32, Int64)+import qualified Data.List.Infinite  as Inf+import           Data.List.Infinite  (Infinite (..))+import           Data.List.NonEmpty  (NonEmpty) import           Data.Ord            (Down (Down)) import           Data.Ratio          (Ratio, numerator, denominator) import qualified Data.Semigroup      as SG@@ -124,7 +127,7 @@ -- > {-# LANGUAGE ViewPatterns, BangPatterns #-} -- > f (xToErrorCtx "a is X" -> !a) (xToErrorCtx "b is X" -> !b) = ... ----- __NB:__ Fully synthesizable, so doesn't have to be removed before synthesis+-- __NB__: Fully synthesizable, so doesn't have to be removed before synthesis -- -- === __Example__ --@@ -150,7 +153,8 @@   (catch (evaluate a >> return a)          (\(XException msg) ->            throw (ErrorCall (unlines [ctx,msg]))))-{-# NOINLINE xToErrorCtx #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xToErrorCtx #-}  -- | Convert 'XException' to 'ErrorCall' --@@ -178,7 +182,7 @@ -- > {-# LANGUAGE ViewPatterns, BangPatterns #-} -- > f (xToError -> !a) (xToError -> !b) = ... ----- __NB:__ Fully synthesizable, so doesn't have to be removed before synthesis+-- __NB__: Fully synthesizable, so doesn't have to be removed before synthesis -- -- === __Example__ --@@ -220,7 +224,8 @@ seqX :: a -> b -> b seqX a b = unsafeDupablePerformIO   (catch (evaluate a >> return b) (\(XException _) -> return b))-{-# NOINLINE seqX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE seqX #-} {-# ANN seqX hasBlackBox #-} infixr 0 `seqX` @@ -236,7 +241,8 @@      [ Handler (\(XException _) -> return b)      , Handler (\(ErrorCall _) -> return b)      ])-{-# NOINLINE seqErrorX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE seqErrorX #-} {-# ANN seqErrorX hasBlackBox #-} infixr 0 `seqErrorX` @@ -247,7 +253,7 @@ -- output of such a component (typically a unit) can be passed as the first -- argument to 'hwSeqX' to ensure the ILA ends up in the generated HDL. ----- __NB__: the result of 'hwSeqX' must (indirectly) be used at the very top of+-- __NB__: The result of 'hwSeqX' must (indirectly) be used at the very top of -- a design. If it's not, Clash will remove it like it does for any other unused -- circuit parts. --@@ -255,18 +261,22 @@ -- uses 'Clash.Netlist.BlackBox.Types.RenderVoid' hwSeqX :: a -> b -> b hwSeqX = seqX-{-# NOINLINE hwSeqX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE hwSeqX #-} {-# ANN hwSeqX hasBlackBox #-} infixr 0 `hwSeqX`  -- | Evaluate a value with given function, returning 'Nothing' if it throws--- 'XException'.+-- 'XException'. Note that non-'XException' errors take precedence over 'XException'+-- ones ----- > maybeX hasX 42                  = Just 42--- > maybeX hasX (XException msg)    = Nothing--- > maybeX hasX (3, XException msg) = Nothing--- > maybeX hasX (3, _|_)            = _|_--- > maybeX hasX _|_                 = _|_+-- > maybeX hasX 42                    = Just 42+-- > maybeX hasX (XException msg)      = Nothing+-- > maybeX hasX (3, XException msg)   = Nothing+-- > maybeX hasX (XException msg, _|_) = _|_+-- > maybeX hasX (_|_, XException msg) = _|_+-- > maybeX hasX (3, _|_)              = _|_+-- > maybeX hasX _|_                   = _|_ -- > -- > maybeX isX 42                  = Just 42 -- > maybeX isX (XException msg)    = Nothing@@ -277,15 +287,18 @@ maybeX :: (a -> Either String a) -> a -> Maybe a maybeX f a = either (const Nothing) Just (f a) --- | Fully evaluate a value, returning 'Nothing' if it throws 'XException'.+-- | Fully evaluate a value, returning 'Nothing' if it throws 'XException'. Note+-- that non-'XException' errors take precedence over 'XException' ones. ----- > maybeHasX 42                  = Just 42--- > maybeHasX (XException msg)    = Nothing--- > maybeHasX (3, XException msg) = Nothing--- > maybeHasX (3, _|_)            = _|_--- > maybeHasX _|_                 = _|_+-- > maybeHasX 42                    = Just 42+-- > maybeHasX (XException msg)      = Nothing+-- > maybeHasX (3, XException msg)   = Nothing+-- > maybeHasX (XException msg, _|_) = _|_+-- > maybeHasX (_|_, XException msg) = _|_+-- > maybeHasX (3, _|_)              = _|_+-- > maybeHasX _|_                   = _|_ ---maybeHasX :: NFData a => a -> Maybe a+maybeHasX :: (NFData a, NFDataX a) => a -> Maybe a maybeHasX = maybeX hasX  -- | Evaluate a value to WHNF, returning 'Nothing' if it throws 'XException'.@@ -302,21 +315,28 @@ -- If you want to determine if a value contains undefined parts, use -- 'hasUndefined' instead. ----- > hasX 42                  = Right 42--- > hasX (XException msg)    = Left msg--- > hasX (3, XException msg) = Left msg--- > hasX (3, _|_)            = _|_--- > hasX _|_                 = _|_+-- > hasX 42                    = Right 42+-- > hasX (XException msg)      = Left msg+-- > hasX (3, XException msg)   = Left msg+-- > hasX (XException msg, _|_) = _|_+-- > hasX (_|_, XException msg) = _|_+-- > hasX (3, _|_)              = _|_+-- > hasX _|_                   = _|_ -- -- If a data structure contains multiple 'XException's, the "first" message is--- picked according to the implementation of 'rnf'.-hasX :: NFData a => a -> Either String a+-- picked according to the implementation of 'rnfX'.+hasX :: (NFData a, NFDataX a) => a -> Either String a hasX a =+  -- TODO: Whenever 'a' contains an 'XException', we need to reevaluate the+  --       structure using 'rnfX' to make sure it didn't also contain another+  --       error call. We could prevent the two traversals by making 'hasX' a+  --       type class method. Also see: https://github.com/clash-lang/clash-compiler/issues/2450.   unsafeDupablePerformIO     (catch       (evaluate (rnf a) >> return (Right a))-      (\(XException msg) -> return (Left msg)))-{-# NOINLINE hasX #-}+      (\(XException msg) -> evaluate (rnfX a) >> return (Left msg)))+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE hasX #-}  -- | Evaluate a value to WHNF, returning @'Left' msg@ if is a 'XException'. --@@ -331,7 +351,8 @@     (catch       (evaluate a >> return (Right a))       (\(XException msg) -> return (Left msg)))-{-# NOINLINE isX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE isX #-}  -- | Like the 'Show' class, but values that normally throw an 'XException' are -- converted to @undefined@, instead of error'ing out with an exception.@@ -422,6 +443,8 @@ instance ShowX Natural where   showsPrecX = showsPrecXWith showsPrec +instance ShowX Ordering+ instance ShowX a => ShowX (Seq a) where   showsPrecX _ = showListX . toList @@ -462,7 +485,8 @@ -- second. Does not propagate 'XException's. deepseqX :: NFDataX a => a -> b -> b deepseqX a b = rnfX a `seq` b-{-# NOINLINE deepseqX #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE deepseqX #-} {-# ANN deepseqX hasBlackBox #-} infixr 0 `deepseqX` @@ -540,8 +564,25 @@   hasUndefined d@(~(Down x))= if isLeft (isX d) then True else hasUndefined x   ensureSpine ~(Down x) = Down (ensureSpine x) +instance NFDataX a => NFDataX (Infinite a) where+  deepErrorX msg = Inf.repeat (deepErrorX msg)+  rnfX d@(~(x :< xs)) =+    if isLeft (isX d) then+      ()+    else+      rnfX x `seq` rnfX xs+  hasUndefined d@(~(x :< xs)) =+    if isLeft (isX d) then+      True+    else+      hasUndefined x || hasUndefined xs++  ensureSpine ~(x :< xs) = ensureSpine x :< ensureSpine xs+ instance NFDataX Bool+instance NFDataX Ordering instance NFDataX a => NFDataX [a]+instance NFDataX a => NFDataX (NonEmpty a) instance (NFDataX a, NFDataX b) => NFDataX (Either a b) instance NFDataX a => NFDataX (Maybe a) instance NFDataX a => NFDataX (Identity a)@@ -697,13 +738,13 @@ instance NFDataX a => NFDataX (SG.Option a) #endif --- | __N.B.__: The documentation only shows instances up to /3/-tuples. By+-- | __NB__: The documentation only shows instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version. mkShowXTupleInstances [2..maxTupleSize] --- | __N.B.__: The documentation only shows instances up to /3/-tuples. By+-- | __NB__: The documentation only shows instances up to /3/-tuples. By -- default, instances up to and including /12/-tuples will exist. If the flag -- @large-tuples@ is set instances up to the GHC imposed limit will exist. The -- GHC imposed limit is either 62 or 64 depending on the GHC version.@@ -715,6 +756,6 @@  -- | Same as 'Data.Maybe.fromJust', but returns a bottom/undefined value that -- other Clash constructs are aware of.-fromJustX :: HasCallStack => Maybe a -> a-fromJustX Nothing = errorX "fromJustX: Nothing"+fromJustX :: (HasCallStack, NFDataX a) => Maybe a -> a+fromJustX Nothing = deepErrorX "fromJustX: Nothing" fromJustX (Just a) = a
+ src/Clash/XException/MaybeX.hs view
@@ -0,0 +1,155 @@+{-|+Copyright  :  (C) 2022, QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>++Helpers to make 'Clash.XException.XException' explicit in the type system.+Using these helpers can help programmers account for 'Clash.XException.XException's+properly in blackbox models or tests. Note that none of these operations can be+translated to HDL.++-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}++module Clash.XException.MaybeX+  ( MaybeX(IsX, IsDefined)++    -- * Construction+  , toMaybeX+  , hasXToMaybeX++    -- * Deconstruction+  , fromMaybeX++    -- * Operations+  , andX+  , orX+  , maybeX+  ) where++import Prelude++#if !MIN_VERSION_base(4,18,0)+import Control.Applicative+#endif+import Control.DeepSeq (NFData)+import Control.Exception (throw)++import Clash.XException (XException(..), NFDataX, isX, hasX)++-- | Structure helping programmers to deal with 'Clash.XException.XException'+-- values. For safety reasons it can't be constructed directly, but should be+-- constructed using either 'pure' or 'toMaybeX'. After construction, it can be+-- deconstructed using either 'IsX' or 'IsDefined'.+data MaybeX a+  = IsX_ String+  -- ^ Upon construction, @a@ evaluated to 'Clash.XException.XException'+  | IsDefined_ !a+  -- ^ Upon construction, @a@ evaluated to a non-bottom WHNF++instance Show a => Show (MaybeX a) where+  showsPrec d = \case+    IsX_ msg     -> showParen (d > 10) $ showString "IsX "       . showsPrec 11 msg+    IsDefined_ a -> showParen (d > 10) $ showString "IsDefined " . showsPrec 11 a++-- | Upon construction, @a@ evaluated to 'Clash.XException.XException'+pattern IsX :: forall a. String -> MaybeX a+pattern IsX msg <- IsX_ msg++-- | Upon construction, @a@ evaluated to a non-bottom WHNF+pattern IsDefined :: forall a. a -> MaybeX a+pattern IsDefined a <- IsDefined_ a+{-# COMPLETE IsX, IsDefined #-}++-- | Note that 'fmap' is X-strict in its argument. That is, if its input is 'IsX',+-- its output will be too.+instance Functor MaybeX where+  fmap _f (IsX_ msg) = IsX_ msg+  fmap f  (IsDefined_ a) = pure (f a)++-- | Note that '<*>' and 'liftA2' are X-strict in their arguments. That is, if+-- any of their inputs are 'IsX', their outputs will be too.+instance Applicative MaybeX where+  pure = either IsX_ IsDefined_ . isX++  liftA2 f (IsDefined_ a) (IsDefined_ b) = pure (f a b)+  liftA2 _ (IsX_ msg)     _              = IsX_ msg+  liftA2 _ _              (IsX_ msg)     = IsX_ msg++-- | Construct a 'MaybeX' value. If @a@ evaluates to 'Clash.XException.XException',+-- this function will return 'IsX'. Otherwise, it will return 'IsDefined'.+toMaybeX :: a -> MaybeX a+toMaybeX = pure++-- | Construct a 'MaybeX' value. If 'hasX' evaluates to 'Left', this function+-- will return 'IsX'. Otherwise, it will return 'IsDefined'.+hasXToMaybeX :: (NFDataX a, NFData a) => a -> MaybeX a+hasXToMaybeX = either IsX_ IsDefined_ . hasX++-- | Deconstruct 'MaybeX' into an @a@ - the opposite of 'toMaybeX'. Be careful+-- when using this function, because it might return an 'Clash.XException.XException'+-- if the argument was 'IsX'.+fromMaybeX :: MaybeX a -> a+fromMaybeX = maybeX (throw . XException) id++-- | Map functions over both constructors.+maybeX :: (String -> b) -> (a -> b) -> MaybeX a -> b+maybeX f _ (IsX_ msg)     = f msg+maybeX _ g (IsDefined_ a) = g a++-- | Implements '&&' accounting for X+--+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- |                         | &#x2003;__@X@__&#x2003; | &#x2003;__@1@__&#x2003; | &#x2003;__@0@__&#x2003; |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@X@__&#x2003; | &#x2003;@X@&#x2003;     | &#x2003;@X@&#x2003;     | &#x2003;@0@&#x2003;     |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@1@__&#x2003; | &#x2003;@X@&#x2003;     | &#x2003;@1@&#x2003;     | &#x2003;@0@&#x2003;     |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@0@__&#x2003; | &#x2003;@0@&#x2003;     | &#x2003;@0@&#x2003;     | &#x2003;@0@&#x2003;     |+-- +-------------------------+-------------------------+-------------------------+-------------------------+++-- (This is not part of the Haddock, a more readable version of the table+-- above)+--    | X | 1 | 0+-- ---|---|---|---+--  X | X | X | 0+--  1 | X | 1 | 0+--  0 | 0 | 0 | 0+andX :: MaybeX Bool -> MaybeX Bool -> MaybeX Bool+andX (IsDefined_ False) _                  = IsDefined_ False+andX _                  (IsDefined_ False) = IsDefined_ False+andX (IsDefined_ True)  (IsDefined_ True)  = IsDefined_ True+andX (IsX_ msg)         _                  = IsX_ msg+andX _                  (IsX_ msg)         = IsX_ msg+infixr 3 `andX`++-- | Implements '||' accounting for X+--+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- |                         | &#x2003;__@X@__&#x2003; | &#x2003;__@1@__&#x2003; | &#x2003;__@0@__&#x2003; |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@X@__&#x2003; | &#x2003;X&#x2003;       | &#x2003;1&#x2003;       | &#x2003;X&#x2003;       |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@1@__&#x2003; | &#x2003;1&#x2003;       | &#x2003;1&#x2003;       | &#x2003;1&#x2003;       |+-- +-------------------------+-------------------------+-------------------------+-------------------------++-- | &#x2003;__@0@__&#x2003; | &#x2003;X&#x2003;       | &#x2003;1&#x2003;       | &#x2003;0&#x2003;       |+-- +-------------------------+-------------------------+-------------------------+-------------------------+++-- (This is not part of the Haddock, a more readable version of the table+-- above)+--    | X | 1 | 0+-- ---|---|---|---+--  X | X | 1 | X+--  1 | 1 | 1 | 1+--  0 | X | 1 | 0+orX :: MaybeX Bool -> MaybeX Bool -> MaybeX Bool+orX (IsDefined_ True)  _                  = IsDefined_ True+orX _                  (IsDefined_ True)  = IsDefined_ True+orX (IsDefined_ False) (IsDefined_ False) = IsDefined_ False+orX (IsX_ msg)         _                  = IsX_ msg+orX _                  (IsX_ msg)         = IsX_ msg+infixr 2 `orX`
src/Clash/XException/TH.hs view
@@ -117,10 +117,12 @@         CondE           (VarE 'isLeft `AppE` (VarE isXName `AppE` VarE t))           (TupE [])-          (foldl-            (\e1 e2 -> UInfixE e1 (VarE 'seq) (VarE rnfXName `AppE` e2))-            (VarE rnfXName `AppE` VarE (head names))-            (map VarE (tail names)))+          (case names of+            (nm:nms) -> foldl+              (\e1 e2 -> UInfixE e1 (VarE 'seq) (VarE rnfXName `AppE` e2))+              (VarE rnfXName `AppE` VarE nm)+              (map VarE nms)+            [] -> error ("mkNFDataXTupleInstance, n must be atleast 1: " <> show n))       ))       []     ]
src/Clash/Xilinx/ClockGen.hs view
@@ -1,105 +1,403 @@ {-|-Copyright  :  (C) 2017, Google Inc+Copyright  :  (C) 2017, Google Inc,+                  2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -PLL and other clock-related components for Xilinx FPGAs+This module contains functions for instantiating clock generators on Xilinx+FPGA's.++We suggest you use a clock generator even if your oscillator runs at the+frequency you want to run your circuit at.++A clock generator generates a stable clock signal for your design at a+configurable frequency. A clock generator in an FPGA is frequently referred to+as a PLL (Phase-Locked Loop). However, Xilinx differentiates between several+types of clock generator implementations in their FPGAs and uses the term PLL to+refer to one specific type, so we choose to use the more generic term /clock/+/generator/ here.++For most use cases, you would create two or more synthesis domains describing+the oscillator input and the domains you wish to use in your design, and use+the [regular functions](#g:regular) below to generate the clocks and resets of+the design from the oscillator input. There are use cases not covered by this+simpler approach, and the [unsafe functions](#g:unsafe) are provided as a means+to build advanced reset managers for the output domains. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} -module Clash.Xilinx.ClockGen where+module Clash.Xilinx.ClockGen+  ( -- * Choosing domains+    -- $domains -import Clash.Annotations.Primitive    (hasBlackBox)-import Clash.Promoted.Symbol+    -- ** Caution: actual output frequency+    -- $caution++    -- * Using+    -- $using++    -- ** Example+    -- $example++    -- ** Type checking errors+    -- $error++    -- ** Tcl+    -- $tcl++    -- * Regular functions #regular#+    clockWizard+  , clockWizardDifferential+    -- * Unsafe functions #unsafe#+    -- $unsafe++    -- ** Example+    -- $unsafe_example+  , unsafeClockWizard+  , unsafeClockWizardDifferential+  ) where++import GHC.TypeLits (type (<=))++import Clash.Annotations.Primitive (hasBlackBox)+import Clash.Clocks+  (Clocks(..), ClocksSync(..), ClocksSyncCxt, NumOutClocksSync) import Clash.Signal.Internal-import Unsafe.Coerce+  (Clock, DiffClock(..), Reset, KnownDomain, HasAsynchronousReset) --- | A clock source that corresponds to the Xilinx PLL/MMCM component created--- with the \"Clock Wizard\" with settings to provide a stable 'Clock' from--- a single free-running input------ Only works when configured with:------ * 1 reference clock--- * 1 output clock--- * a reset port--- * a locked port------ You must use type applications to specify the output clock domain, e.g.:------ @--- type Dom100MHz = Dom \"A\" 10000------ -- outputs a clock running at 100 MHz--- clockWizard @@Dom100MHz (SSymbol @@"clkWizard50to100") clk50 rst--- @------ See also the [Clocking Wizard LogiCORE IP Product Guide](https://docs.xilinx.com/r/en-US/pg065-clk-wiz)-clockWizard-  :: forall domIn domOut periodIn periodOut edge init polarity name-   . ( KnownConfiguration domIn  ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity)-     , KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity) )-  => SSymbol name-  -- ^ Name of the component, must correspond to the name entered in the-  -- \"Clock Wizard\" dialog.-  ---  -- For example, when you entered \"clockWizard50\", instantiate as follows:-  ---  -- > SSymbol @ "clockWizard50"-  -> Clock domIn-  -- ^ Free running clock (i.e. a clock pin connected to a crystal)-  -> Reset domIn-  -- ^ Reset for the PLL-  -> (Clock domOut, Enable domOut)-  -- ^ (Stable PLL clock, PLL lock)-clockWizard !_ clk rst =-  (unsafeCoerce clk, unsafeCoerce (toEnable (unsafeToHighPolarity rst)))-{-# NOINLINE clockWizard #-}-{-# ANN clockWizard hasBlackBox #-}+{- $domains+Synthesis domains are denoted by the type-parameter+@dom :: t'Clash.Signal.Domain'@ as occurring in for instance+@t'Clash.Signal.Signal' dom a@; see "Clash.Signal" for more information. For+each domain, there is only a single clock signal which clocks that domain;+mixing clock signals is a design error. Conversely, it is possible to clock+multiple domains using the same clock signal, in complex designs. --- | A clock source that corresponds to the Xilinx PLL/MMCM component created--- with the \"Clock Wizard\", with settings to provide a stable 'Clock'--- from differential free-running inputs.+For the clock generator inputs, create a domain with the correct clock frequency+and reset polarity. For instance, if the clock input is a free-running clock at+a frequency of 50 MHz (a period of 20 ns or 20,000 ps), and the reset input+connected to the clock generator is /active-low/, the following will instantiate+the required input domain:++@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+@++If you haven't determined the frequency you want the design to run at, the+predefined 100 MHz domain t'Clash.Signal.XilinxSystem' can be a good starting+point. The datasheet for your FPGA specifies lower and upper limits, but the+true maximum frequency is determined by your design.++Supposing you need a clock running at 150 MHz for your design, the following+will instantiate a suitable domain:++@+'Clash.Signal.createDomain' 'Clash.Signal.vXilinxSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}+@++@Dom150@ will have 'Clash.Signal.Synchronous' resets on its memory elements+because it was derived from 'Clash.Signal.vXilinxSystem', whereas @DomInput@+will have 'Clash.Signal.Asynchronous' resets because it was derived from+'Clash.Signal.vSystem'. Xilinx recommends synchronous resets for circuits, but+the clock generator reacts asynchronously to its reset input instead, which will+need to be declared correctly in Clash. If you use the /unsafe/ functions below,+Clash does not enforce this.+-}++{- $caution+The clock generator in the FPGA is limited in which clock frequencies it can+generate, especially when one clock generator has multiple outputs. The clock+generator will pick the attainable frequency closest to the requested frequency+(or possibly fail to synthesize). You can check the frequency that the wizard+chose by loading your design into the Vivado GUI. In the /IP sources/ window,+choose the clock wizard and select /Re-customize IP.../. On the /Output Clocks/+tab, the relevant column is /Actual Output Freq (MHz)/. If the actual value+differs, copy the actual value back to the Clash design.+-}++{- $using+The functions in this module will instantiate a Xilinx MMCM clock generator+corresponding to the Xilinx \"Clock Wizard\" with 1 reference clock input and a+reset input, and 1 to 7 output clocks and a @locked@ output.++The [regular functions](#g:regular) incorporate 'Clash.Signal.resetSynchronizer'+to convert the @locked@ output port into a proper 'Reset' signal for the domains+which will keep the circuit in reset while the clock is still stabilizing.++The clock generator will react asynchronously to the incoming reset input. When+the reset input is asserted, the clock generator's @locked@ output will+deassert, in turn causing the 'Reset' output(s) of these functions to assert.++You can use 'Clash.Magic.setName' to give the IP instance a specific name, which+can be useful if you need to refer to the instance in Synopsys Design+Constraints files.++The output of the function for /n/ output clocks is a /2n/-tuple with clock and+reset outputs. The compiler needs to be able to fully determine the types of the+individual tuple elements from the context; the clock generator function itself+will not constrain them. If the types of the tuple elements cannot be inferred,+you can use pattern type signatures to specify the types. Supposing the+referenced domains have been created with 'Clash.Signal.createDomain', an+instance with a single output clock can be instantiated using:++@+(clk150 :: 'Clock' Dom150, rst150 :: 'Reset' Dom150) = 'clockWizard' clkIn rstIn+@++An instance with two clocks can be instantiated using++@+( clk100 :: 'Clock' Dom100+  , rst100 :: 'Reset' Dom100+  , clk150 :: 'Clock' Dom150+  , rst150 :: 'Reset' Dom150) = 'clockWizard' clkIn rstIn+@++and so on up to 7 clocks, following the general pattern @('Clock' dom1, 'Reset'+dom1, 'Clock' dom2, 'Reset' dom2, ..., 'Clock' dom/n/, 'Reset' dom/n/)@.++If you need access to the @locked@ output to build a more advanced reset+manager, you should use the [unsafe functions](#g:unsafe) instead.++See also the [Clocking Wizard LogiCORE IP Product Guide](https://docs.xilinx.com/r/en-US/pg065-clk-wiz)+-}++{- $example++When the oscillator connected to the FPGA runs at 50 MHz and the external reset+signal is /active-low/, this will generate a 150 MHz clock for use by the+circuit:++@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+'Clash.Signal.createDomain' 'Clash.Signal.vXilinxSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}++topEntity+  :: 'Clock' DomInput+  -> 'Reset' DomInput+  -> t'Clash.Signal.Signal' Dom150 Int+  -> t'Clash.Signal.Signal' Dom150 Int+topEntity clkIn rstIn = 'Clash.Signal.exposeClockResetEnable' (register 0) clk rst 'Clash.Signal.enableGen'+ where+  (clk, rst) = 'clockWizard' clkIn rstIn+@+-}++{- $error+When type checking cannot infer the types of the tuple elements, or they have+the wrong type, the GHC compiler will complain about satisfying @NumOutClocks@.+The error message on GHC 9.4 and up is:++@+    • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+                        (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+                           ([...])+                           DomInput) <= 7+    • In the expression: clockWizard clkIn rstIn+@++On older GHC versions, the error message is:++@+    • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+                             (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+                                ([...])+                                DomInput)+                           <=? 7’+                     with ‘'True’+        arising from a use of ‘clockWizard’+    • In the expression: clockWizard clkIn rstIn+@++The above error message is also emitted when trying to instantiate more than 18+output clocks, as it will fail to find an instance. As the wizard supports no+more than 7 clocks, trying to instantiate between 8 and 18 output clocks will+also cause a type checking error. On GHC 9.4 and up, the error for attempting to+instantiate 8 clocks is:++@+    • Cannot satisfy: 8 <= 7+    • In the expression: clockWizard clkIn rstIn+@++On older GHC versions, the error message is less clear:++@+    • Couldn't match type ‘'False’ with ‘'True’+        arising from a use of ‘clockWizard’+    • In the expression: clockWizard clkIn rstIn+@+-}++{- $tcl+When generating HDL, these functions will emit a Tcl script for Vivado that+instantiates the needed IP core for the function. This Tcl script adheres to the+Clash\<-\>Tcl API. The Tcl Connector bundled in @clash-lib:Clash.DataFiles@ will+automatically process these scripts and build your design in Vivado. See+@clash-lib:Clash.DataFiles@ for more information.+-}++{- $unsafe+These functions are provided for the cases where the [regular+functions](#g:regular) cannot provide the desired behavior, like when+implementing certain advanced reset managers. These functions directly expose+the /asynchronous/ @locked@ output of the clock generator, which will assert+when the output clocks are stable. @locked@ is usually connected to reset+circuitry to keep the circuit in reset while the clock is still stabilizing.++The output of the function for /n/ output clocks is an /n+1/-tuple with /n/+clock outputs and a @locked@ signal. The compiler needs to be able to fully+determine the types of the individual tuple elements from the context; the clock+generator function itself will not constrain them. If the types of the tuple+elements cannot be inferred, you can use pattern type signatures to specify the+types. Supposing the referenced domains have been created with+'Clash.Signal.createDomain', an instance with a single output clock can be+instantiated using:++@+(clk150 :: 'Clock' Dom150, locked :: t'Clash.Signal.Signal' Dom150 'Bool') = 'unsafeClockWizard' clkIn rstIn+@++An instance with two clocks can be instantiated using++@+(clk100 :: 'Clock' Dom100+  , clk150 :: 'Clock' Dom150+  , locked :: t'Clash.Signal.Signal' Dom100 'Bool') = 'unsafeClockWizard' clkIn rstIn+@++and so on up to 7 clocks, following the general pattern @('Clock' dom1, 'Clock'+dom2, ..., 'Clock' dom/n/, t'Clash.Signal.Signal' pllLock Bool)@.++Though the @locked@ output is specified as a @t'Clash.Signal.Signal' pllLock+'Bool'@, it is an asynchronous signal and will need to be synchronized before it+can be used as a (reset) signal. While in the examples above the+@locked@ output has been assigned the domain of one of the output clocks, the+domain @pllLock@ is left unrestricted. If the lock signal is to be used in+multiple domains, the @pllLock@ domain should probably be set to @domIn@ (the+domain of the input clock and reset). While in HDL+'Clash.Explicit.Signal.unsafeSynchronizer' is just a wire, in Haskell simulation+it does actually resample the signal, and by setting @pllLock@ to @domIn@, there+is no resampling of the simulated lock signal. The simulated lock signal is+simply the inverse of the reset input: @locked@ is asserted whenever the reset+input is deasserted and vice versa.+-}++{- $unsafe_example+@+'Clash.Signal.createDomain' 'Clash.Signal.vSystem'{vName=\"DomInput\", vPeriod=20000, vResetPolarity='Clash.Signal.ActiveLow'}+'Clash.Signal.createDomain' 'Clash.Signal.vXilinxSystem'{vName=\"Dom150\", vPeriod='Clash.Signal.hzToPeriod' 150e6}++topEntity+  :: 'Clock' DomInput+  -> 'Reset' DomInput+  -> t'Clash.Signal.Signal' Dom150 Int+  -> t'Clash.Signal.Signal' Dom150 Int+topEntity clkIn rstIn = 'Clash.Signal.exposeClockResetEnable' (register 0) clk rst 'Clash.Signal.enableGen'+ where+  (clk, locked) = 'unsafeClockWizard' clkIn rstIn+  rst = 'Clash.Signal.resetSynchronizer' clk ('Clash.Signal.unsafeFromActiveLow' locked)+@++'Clash.Signal.resetSynchronizer' will keep the reset asserted when @locked@ is+'False', hence the use of @'Clash.Signal.unsafeFromActiveLow' locked@.+-}++-- | Instantiate a Xilinx MMCM clock generator corresponding to the Xilinx+-- \"Clock Wizard\" with 1 single-ended reference clock input and a reset input,+-- and 1 to 7 output clocks and a @locked@ output. ----- Only works when configured with:+-- This function incorporates 'Clash.Signal.resetSynchronizer's to convert the+-- @locked@ output port into proper 'Reset' signals for the output domains which+-- will keep the circuit in reset while the clock is still stabilizing.+clockWizard ::+  forall t domIn .+  ( HasAsynchronousReset domIn+  , ClocksSyncCxt t domIn+  , NumOutClocksSync t domIn <= 7+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+clockWizard clkIn rstIn =+  clocksResetSynchronizer (unsafeClockWizard clkIn rstIn) clkIn++-- | Instantiate a Xilinx MMCM clock generator corresponding to the Xilinx+-- \"Clock Wizard\" with 1 single-ended reference clock input and a reset input,+-- and 1 to 7 output clocks and a @locked@ output. ----- * 1 differential reference pair--- * 1 output clock--- * a reset port--- * a locked port+-- __NB__: Because the clock generator reacts asynchronously to the incoming+-- reset input, the signal __must__ be glitch-free.+unsafeClockWizard ::+  forall t domIn .+  ( KnownDomain domIn+  , Clocks t+  , ClocksCxt t+  , NumOutClocks t <= 7+  ) =>+  -- | Free running clock (e.g. a clock pin connected to a crystal oscillator)+  Clock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+unsafeClockWizard = clocks+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeClockWizard #-}+{-# ANN unsafeClockWizard hasBlackBox #-}++-- | Instantiate a Xilinx MMCM clock generator corresponding to the Xilinx+-- \"Clock Wizard\" with 1 differential reference clock input and a reset input,+-- and 1 to 7 output clocks and a @locked@ output. ----- You must use type applications to specify the output clock domain, e.g.:+-- This function incorporates 'Clash.Signal.resetSynchronizer's to convert the+-- @locked@ output port into proper 'Reset' signals for the output domains which+-- will keep the circuit in reset while the clock is still stabilizing. ----- @--- type Dom100MHz = Dom \"A\" 10000+-- To create a differential clock in a test bench, you can use+-- 'Clash.Explicit.Testbench.clockToDiffClock'.+clockWizardDifferential ::+  forall t domIn .+  ( HasAsynchronousReset domIn+  , ClocksSyncCxt t domIn+  , NumOutClocksSync t domIn <= 7+  ) =>+  -- | Free running clock (e.g. a clock pin pair connected to a crystal+  -- oscillator)+  DiffClock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+clockWizardDifferential clkIn@(DiffClock clkInP _) rstIn =+  clocksResetSynchronizer (unsafeClockWizardDifferential clkIn rstIn) clkInP++-- | Instantiate a Xilinx MMCM clock generator corresponding to the Xilinx+-- \"Clock Wizard\" with 1 differential reference clock input and a reset input,+-- and 1 to 7 output clocks and a @locked@ output. ----- -- outputs a clock running at 100 MHz--- clockWizardDifferential @@Dom100MHz (SSymbol @@"clkWizardD50to100") clk50N clk50P rst--- @+-- __NB__: Because the clock generator reacts asynchronously to the incoming+-- reset input, the signal __must__ be glitch-free. ----- See also the [Clocking Wizard LogiCORE IP Product Guide](https://docs.xilinx.com/r/en-US/pg065-clk-wiz)-clockWizardDifferential-  :: forall domIn domOut periodIn periodOut edge init polarity name-   . ( KnownConfiguration domIn ('DomainConfiguration domIn periodIn edge 'Asynchronous init polarity)-     , KnownConfiguration domOut ('DomainConfiguration domOut periodOut edge 'Asynchronous init polarity) )-  => SSymbol name-  -- ^ Name of the component, must correspond to the name entered in the-  -- \"Clock Wizard\" dialog.-  ---  -- For example, when you entered \"clockWizardD50\", instantiate as follows:-  ---  -- > SSymbol @ "clockWizardD50"-  -> Clock domIn-  -- ^ Free running clock, negative phase-  -> Clock domIn-  -- ^ Free running clock, positive phase-  -> Reset domIn-  -- ^ Reset for the PLL-  -> (Clock domOut, Enable domOut)-  -- ^ (Stable PLL clock, PLL lock)-clockWizardDifferential !_name (Clock _) (Clock _) rst =-  (Clock SSymbol, unsafeCoerce (toEnable (unsafeToHighPolarity rst)))-{-# NOINLINE clockWizardDifferential #-}-{-# ANN clockWizardDifferential hasBlackBox #-}+-- To create a differential clock in a test bench, you can use+-- 'Clash.Explicit.Testbench.clockToDiffClock'.+unsafeClockWizardDifferential ::+  forall t domIn .+  ( KnownDomain domIn+  , Clocks t+  , ClocksCxt t+  , NumOutClocks t <= 7+  ) =>+  -- | Free running clock (e.g. a clock pin pair connected to a crystal+  -- oscillator)+  DiffClock domIn ->+  -- | Reset for the clock generator+  Reset domIn ->+  t+unsafeClockWizardDifferential (DiffClock clk _) = clocks clk+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE unsafeClockWizardDifferential #-}+{-# ANN unsafeClockWizardDifferential hasBlackBox #-}
src/Clash/Xilinx/DDR.hs view
@@ -50,7 +50,8 @@   -> Signal slow ((BitVector m),(BitVector m))   -- ^ normal speed output pairs iddr clk rst en = withFrozenCallStack ddrIn# clk rst en 0 0 0-{-# NOINLINE iddr #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE iddr #-} {-# ANN iddr hasBlackBox #-}  -- | Xilinx specific variant of 'ddrOut' implemented using the Xilinx ODDR@@ -84,5 +85,6 @@   -> Signal slow (BitVector m)   -> Signal fast (BitVector m) oddr# clk rst en = ddrOut# clk rst en 0-{-# NOINLINE oddr# #-}+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE oddr# #-} {-# ANN oddr# hasBlackBox #-}
tests/Clash/Tests/AsyncFIFOSynchronizer.hs view
@@ -202,19 +202,21 @@   :: Foldable f   => f (Bool, (Int, Bool))   -> IO ()-printR r = do-  let (first:rest) = P.map show $ sampleR 60 r-  putStrLn $ (P.foldl (\b a -> b <> "  , " <> a <> "\n")-                ("  [ " <> first <> "\n") rest) <> "  ]"+printR r = case P.map show $ sampleR 60 r of+  (first:rest) ->+    putStrLn $ (P.foldl (\b a -> b <> "  , " <> a <> "\n")+                  ("  [ " <> first <> "\n") rest) <> "  ]"+  _ -> error "impossible"  printW   :: (Foldable f, NFDataX a, Show a)   => f a   -> IO ()-printW w = do-  let (first:rest) = P.map show $ sampleN 60 w-  putStrLn $ (P.foldl (\b a -> b <> "  , " <> a <> "\n")-                ("  [ " <> first <> "\n") rest) <> "  ]"+printW w = case P.map show $ sampleN 60 w of+  (first:rest) ->+    putStrLn $ (P.foldl (\b a -> b <> "  , " <> a <> "\n")+                  ("  [ " <> first <> "\n") rest) <> "  ]"+  _ -> error "impossible"  testR   :: Foldable f@@ -277,8 +279,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (False,(Just 1,False))@@ -287,8 +289,8 @@   , (True,(Just 3,False))   , (True,(Just 4,False))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 5,True))+  , (False,(Just 5,True))   , (False,(Just 5,False))   , (False,(Just 5,False))   , (False,(Just 5,False))@@ -362,8 +364,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (False,(Just 1,False))@@ -372,8 +374,8 @@   , (True,(Just 2,False))   , (True,(Just 3,False))   , (True,(Just 4,False))-  , (False,(Nothing,True))   , (False,(Just 5,True))+  , (False,(Just 5,True))   , (False,(Just 5,False))   , (False,(Just 5,False))   , (False,(Just 5,False))@@ -452,8 +454,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (False,(Just 1,False))@@ -462,8 +464,8 @@   , (True,(Just 3,False))   , (True,(Just 4,False))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 5,True))+  , (False,(Just 5,True))   , (False,(Just 5,False))   , (False,(Just 5,False))   , (False,(Just 5,False))@@ -540,8 +542,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (False,(Just 1,False))@@ -550,8 +552,8 @@   , (True,(Just 2,False))   , (True,(Just 3,False))   , (True,(Just 4,False))-  , (False,(Nothing,True))   , (False,(Just 5,True))+  , (False,(Just 5,True))   , (False,(Just 5,False))   , (False,(Just 5,False))   , (False,(Just 5,False))@@ -641,8 +643,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (False,(Just 1,False))@@ -776,16 +778,16 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (False,(Just 1,False))   , (False,(Just 1,False))   , (True,(Just 1,False))   , (True,(Just 2,False))   , (True,(Just 3,False))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 4,True))+  , (False,(Just 4,True))   , (False,(Just 4,False))   , (False,(Just 4,False))   , (False,(Just 4,False))@@ -909,8 +911,8 @@   , (False,(Nothing,True))   , (False,(Nothing,True))   , (False,(Nothing,True))-  , (False,(Nothing,True))   , (False,(Just 1,True))+  , (False,(Just 1,True))   , (True,(Just 1,False))   , (False,(Just 2,True))   , (True,(Just 2,False))@@ -1051,8 +1053,8 @@   wclk = clockGen @wdom   -- Not resetting makes the test easier to interpret and actual proper testing   -- of reset behaviour is a lot more involved.-  noRRst = unsafeFromHighPolarity @rdom (pure False)-  noWRst = unsafeFromHighPolarity @wdom (pure False)+  noRRst = unsafeFromActiveHigh @rdom (pure False)+  noWRst = unsafeFromActiveHigh @wdom (pure False)   (wdone, wact) =     unbundle $ fromList $ P.zip (P.repeat False) wacts <> P.repeat (True, WNoOp)   (rdone, ract) =
tests/Clash/Tests/BitVector.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}@@ -22,8 +23,11 @@ import qualified Test.Tasty.Hedgehog.Extra as H import qualified Test.Tasty.QuickCheck as Q +#if !MIN_VERSION_base(4,18,0)+import Control.Applicative (liftA2)+#endif import Clash.Prelude-  (Bit, high, low, bitPattern, type (<=), type (-), natToInteger, liftA2, msb, bLit)+  (Bit, high, low, bitPattern, type (<=), type (-), natToInteger, msb, bLit, hLit, oLit) import Clash.Sized.Internal.BitVector (BitVector (..))  import Clash.Tests.SizedNum@@ -120,6 +124,15 @@     , testCase "show11" $ show @(BitVector 5) $(bLit "1010.") @?= "0b1_010."     , testCase "show12" $ show @(BitVector 8) $(bLit "0001010.") @?= "0b0001_010."     , testCase "show13" $ show @(BitVector 9) $(bLit "10001010.") @?= "0b1_0001_010."++    , testCase "show14" $ show @(BitVector 16) $(hLit "dead") @?= "0b1101_1110_1010_1101"+    , testCase "show14" $ show @(BitVector 16) $(hLit "de.d") @?= "0b1101_1110_...._1101"+    , testCase "show15" $ show @(BitVector 16) $(hLit "beef") @?= "0b1011_1110_1110_1111"+    , testCase "show15" $ show @(BitVector 16) $(hLit ".eef") @?= "0b...._1110_1110_1111"+    , testCase "show16" $ show @(BitVector 12) $(oLit "7734") @?= "0b1111_1101_1100"+    , testCase "show16" $ show @(BitVector 12) $(oLit "77.4") @?= "0b1111_11.._.100"+    , testCase "show17" $ show @(BitVector 12) $(oLit "5324") @?= "0b1010_1101_0100"+    , testCase "show17" $ show @(BitVector 12) $(oLit ".324") @?= "0b...0_1101_0100"     ]   ] 
tests/Clash/Tests/BlockRam.hs view
@@ -24,7 +24,7 @@ addrNotTooStrict :: Assertion addrNotTooStrict =   let addr = fromList [0..15]-   in List.tail (sampleN @System 15 (readRam addr)) @?=+   in List.drop 1 (sampleN @System 15 (readRam addr)) @?=         [255,0,0,0,0,0,0,0,255,255,255,255,255,255]  primRam
tests/Clash/Tests/Clocks.hs view
@@ -11,7 +11,7 @@ import Test.Tasty.HUnit  import Clash.Explicit.Prelude-import Clash.Intel.ClockGen (altpll)+import Clash.Intel.ClockGen (unsafeAltpll)  -- Ratio of clock periods in 'createDomain' and 'resetLen' are chosen, rest is -- derived from that@@ -29,7 +29,7 @@     Clock ClocksSlow ->     Reset ClocksSlow ->     (Clock System, Signal System Bool)-  pll = altpll (SSymbol @"pll")+  pll = unsafeAltpll    unlockedLenSeen =     P.length . P.takeWhile not .
tests/Clash/Tests/Counter.hs view
@@ -55,25 +55,25 @@ -- | Counting /down/ from 'countMin' should yield 'countMin' at some point predShouldWrapAround :: forall a. (Eq a, Counter a, Show a) => Proxy a -> Assertion predShouldWrapAround Proxy =-  let counter = P.take 100_0000 (P.tail (P.iterate countPred countMin)) in+  let counter = P.take 100_0000 (P.drop 1 (P.iterate countPred countMin)) in   assertBool "Pred should wrap-around" (countMin @a `P.elem` counter)  -- | Counting /up/ from 'countMin' should yield 'countMin' at some point succShouldWrapAround :: forall a. (Eq a, Counter a, Show a) => Proxy a -> Assertion succShouldWrapAround Proxy =-  let counter = P.take 100_000 (P.tail (P.iterate countSucc countMin)) in+  let counter = P.take 100_000 (P.drop 1 (P.iterate countSucc countMin)) in   assertBool "Succ should wrap-around" (countMin @a `P.elem` counter)  -- | Counting /down/ from 'countMax' should yield 'countMin' at some point predShouldSeeCountMin :: forall a. (Eq a, Counter a, Show a) => Proxy a -> Assertion predShouldSeeCountMin Proxy =-  let counter = P.take 100_0000 (P.tail (P.iterate countPred countMax)) in+  let counter = P.take 100_0000 (P.drop 1 (P.iterate countPred countMax)) in   assertBool "Pred should see countMin" (countMin @a `P.elem` counter)  -- | Counting /up/ from 'countMin' should yield 'countMax' at some point succShouldSeeCountMax :: forall a. (Eq a, Counter a, Show a) => Proxy a -> Assertion succShouldSeeCountMax Proxy =-  let counter = P.take 100_000 (P.tail (P.iterate countSucc countMin)) in+  let counter = P.take 100_000 (P.drop 1 (P.iterate countSucc countMin)) in   assertBool "Succ should see countMax" (countMax @a `P.elem` counter)  quadTest :: forall a. (Eq a, Counter a, Typeable a, Show a) => Proxy a -> TestTree
+ tests/Clash/Tests/MaybeX.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TemplateHaskell #-}++module Clash.Tests.MaybeX where++import Clash.XException (errorX)+import Clash.XException.MaybeX (MaybeX(IsX, IsDefined), toMaybeX)++#if !MIN_VERSION_base(4,18,0)+import Control.Applicative (liftA2)+#endif+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.TH++data ABC = A | B Int deriving Show++x :: MaybeX a+x = errorX "X"++isX :: MaybeX a -> Bool+isX = \case+  IsDefined {} -> False+  IsX {} -> True++isDefined :: MaybeX a -> Bool+isDefined = not . isX++case_showNoParens :: Assertion+case_showNoParens = show (toMaybeX A) @?= "IsDefined A"++case_showParens :: Assertion+case_showParens = show (toMaybeX (B 0)) @?= "IsDefined (B 0)"++case_pureDefined :: Assertion+case_pureDefined = assertBool "defined value resolves to IsDefined" (isDefined (pure 'a'))++case_pureX :: Assertion+case_pureX = assertBool "pure catches X" (isX (pure x))++case_Fmap :: Assertion+case_Fmap = assertBool "fmap" (isDefined (const () <$> pure 'a'))++case_strictFmap :: Assertion+case_strictFmap = assertBool "fmap is strict in X" (isX (const () <$> pure x))++case_liftA2 :: Assertion+case_liftA2 = assertBool "liftA2"  (isDefined (liftA2 (\_ _ -> ()) (pure 'a') (pure 'b')))++case_strictLiftA2 :: Assertion+case_strictLiftA2 = do+  assertBool "liftA2 is strict in X (left)"  (isX (liftA2 (\_ _ -> ()) (pure x) (pure 'b')))+  assertBool "liftA2 is strict in X (right)" (isX (liftA2 (\_ _ -> ()) (pure 'a') (pure x)))+  assertBool "liftA2 is strict in X (both)"  (isX (liftA2 (\_ _ -> ()) (pure x) (pure x)))++tests :: TestTree+tests = $(testGroupGenerator)
tests/Clash/Tests/Reset.hs view
@@ -1,54 +1,59 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeInType #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}  {-# OPTIONS_GHC -Wno-orphans #-}  module Clash.Tests.Reset where -import qualified Prelude as P- import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.TH import Clash.Explicit.Prelude +import qualified Prelude as P+ -- Testing with explicit declaration of the Low type alias type Low = ("Low" :: Domain) createDomain vSystem{vName="Low", vResetPolarity=ActiveLow} -createDomain vSystem{vName="NoInit", vInitBehavior=Unknown}- sampleResetN :: KnownDomain dom => Int -> Reset dom -> [Bool]-sampleResetN n = sampleN n . unsafeToHighPolarity+sampleResetN n = sampleN n . unsafeToActiveHigh  resetFromList :: KnownDomain dom => [Bool] -> Reset dom-resetFromList = unsafeFromHighPolarity . fromList+resetFromList = unsafeFromActiveHigh . fromList  onePeriodGlitchReset :: KnownDomain dom => Reset dom onePeriodGlitchReset =-  resetFromList [True,True,False,False,True,False,False,True,True,False,False]+  resetFromList [True,True,False,False,True,False,False,True,True,False,False,False]  -- | Introduce a glitch of one period, and see if it's filtered out+--+-- Note that since 'System' is a domain with asynchronous resets,+-- 'resetGlitchFilter' first synchronizes the incoming reset. This leads to an+-- additional delay of two cycles with respect to the output. case_onePeriodGlitch :: Assertion case_onePeriodGlitch =-      [True,True,True,True,False,False,False,False,False,True,True,False]-  @=? sampleResetN 12 (resetGlitchFilter d2 systemClockGen onePeriodGlitchReset)+      [True,True,True,True,True,True,False,False,False,False,False,True,True,False]+  @=? sampleResetN 14 (resetGlitchFilter d2 systemClockGen onePeriodGlitchReset)  -- | Same as 'case_onePeriodGlitch' but on a domain with active low resets case_onePeriodGlitch_LowPolarity :: Assertion case_onePeriodGlitch_LowPolarity =-      [True,True,True,True,False,False,False,False,False,True,True,False]-  @=? sampleResetN 12 (resetGlitchFilter d2 (clockGen @Low) onePeriodGlitchReset)+      [True,True,True,True,True,True,False,False,False,False,False,True,True,False]+  @=? sampleResetN 14 (resetGlitchFilter d2 (clockGen @Low) onePeriodGlitchReset) --- | Same as 'case_onePeriodGlitch' but on a domain without initial values. This--- tests whether the 'resetGlitchFilter' can recover from an unknown initial--- state.-case_onePeriodGlitch_NoInit :: Assertion-case_onePeriodGlitch_NoInit =-      P.drop 2 [True,True,True,True,False,False,False,False,False,True,True,False]-  @=? P.drop 2 (sampleResetN 12 (resetGlitchFilter d2 (clockGen @NoInit) onePeriodGlitchReset))+-- Check that the meaning of @Reset@ is maintained when converting from+-- active-low to active-high.+case_convertReset_polarity_change :: Assertion+case_convertReset_polarity_change =+      -- In domains with synchronous resets and defined initial values,+      -- @resetSynchronizer@ will start with an asserted reset.+      True : True : P.replicate 8 False+  @=? sampleResetN 10 (convertReset (clockGen @Low) (clockGen @System)+                                    (resetFromList $ P.repeat False))  tests :: TestTree tests = testGroup "Reset"
tests/Clash/Tests/Signal.hs view
@@ -1,22 +1,33 @@ {-| Copyright  :  (C) 2019, Myrtle Software Ltd+                  2022, Google Inc.+                  2023, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}  {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MagicHash #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}  {-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# OPTIONS_GHC -Wno-orphans #-}  module Clash.Tests.Signal where -import           Clash.Signal                   hiding (sample)-import           Clash.Signal.Internal          (sample)+import qualified Prelude as P+import           Prelude hiding (undefined) -import           Control.Applicative            (liftA2)+import qualified Clash.Explicit.Prelude         as E+import           Clash.Prelude                  hiding (sample)++import           Clash.Signal.Internal+  (Femtoseconds(..), dynamicClockGen, sample, head#)+ import           Control.Exception              (evaluate) import           Data.List                      (isInfixOf) import           Test.Tasty@@ -25,6 +36,12 @@ import qualified Language.Haskell.Interpreter   as Hint import           Language.Haskell.Interpreter   (OptionVal((:=))) +createDomain vSystem{vName="H11", vPeriod=hzToPeriod 11}+createDomain vSystem{vName="H77", vPeriod=hzToPeriod 77}++createDomain vSystem{vName="F1", vPeriod=20}+createDomain vSystem{vName="F6", vPeriod=250}+ customTypeMark :: String customTypeMark = "You tried to apply an explicitly routed clock, reset, or enable line" @@ -48,7 +65,7 @@       else         assertFailure $              "Expression failed to typecheck as expected, but did not contain "-          ++ "expected type error. Instead it contained: " ++ show err+          <> "expected type error. Instead it contained: " <> show err     Right () ->       assertFailure "Expression should have failed to typecheck, but succeeded." @@ -97,7 +114,7 @@         "Implicit"         [ -- See: https://github.com/clash-lang/clash-compiler/pull/655           let rst0 = fromList [True, True, False, False, True, True]-              rst1 = unsafeFromHighPolarity rst0+              rst1 = unsafeFromActiveHigh rst0               reg  = register 'a' (pure 'b') #ifdef CLASH_MULTIPLE_HIDDEN               sig = withReset rst1 reg@@ -162,10 +179,17 @@             let               f (_, b) = (b, b)               s = f <$> liftA2 (,) (fst <$> s) (pure 'a')-              ((a,_):_) = sample @(Signal System) s+              a = fst (head# s)             in               evaluate a >> pure ()         ]+    , testGroup "unsafeSynchronizer"+      [ testCase "case_dynamicStaticEq" case_dynamicStaticEq+      , testCase "case_dynamicHasEffect" case_dynamicHasEffect+      , testCase "case_changingDynamicClocks" case_changingDynamicClocks+      , testCase "case_F1_F6" case_F1_F6+      , testCase "case_F6_F1" case_F6_F1+      ]     ]  -- Tests below should survive compilation:@@ -185,3 +209,114 @@  test5ok_0 = withSpecificReset (resetGen @System) (test5 @System @_) #endif++-- | Asserts that static clocks behave the same as dynamic clocks with a static+-- period signal passed into it.+case_dynamicStaticEq :: Assertion+case_dynamicStaticEq = do+  let+    sampleMagicN = P.take 500 . sample++    clk11 = clockGen @H11+    clk77 = clockGen @H77++    -- We construct periods in a roundabout way (i.e., using 'hzToPeriod' instead+    -- of using 'hzToFs'), to prevent rounding errors between periods of the+    -- static clocks and the periods of the dynamic clocks.+    fs11 = Femtoseconds (1000 * hzToPeriod 11)+    fs77 = Femtoseconds (1000 * hzToPeriod 77)++    dclk11 = dynamicClockGen @H11 (pure fs11)+    dclk77 = dynamicClockGen @H77 (pure fs77)++    counter :: forall dom. Signal dom Int+    counter = fromList [0..]++  assertEqual+    "clk11+clk77 == dclk11+dclk77"+    (sampleMagicN (E.unsafeSynchronizer clk11 clk77 counter))+    (sampleMagicN (E.unsafeSynchronizer dclk11 dclk77 counter))++  assertEqual+    "clk11+dclk77 == dclk11+clk77"+    (sampleMagicN (E.unsafeSynchronizer clk11 dclk77 counter))+    (sampleMagicN (E.unsafeSynchronizer dclk11 clk77 counter))++-- | Asserts that "lying" about a clock's frequency has effect.+case_dynamicHasEffect :: Assertion+case_dynamicHasEffect = do+  let+    sampleMagicN = P.take 500 . sample++    -- We construct periods in a roundabout way (i.e., using 'hzToPeriod' instead+    -- of using 'hzToFs'), to prevent rounding errors between periods of the+    -- static clocks and the periods of the dynamic clocks.+    fs11 = Femtoseconds (1000 * hzToPeriod 11)+    fs77lying = Femtoseconds (1000 * hzToPeriod 78)++    clk11 = clockGen @H11+    clk77 = clockGen @H77+    dclk11 = dynamicClockGen @H11 (pure fs11)+    dclk77lying = dynamicClockGen @H77 (pure fs77lying)++    counter :: forall dom. Signal dom Int+    counter = fromList [0..]++  assertBool "clk11+clk77 /= dclk11+dclk77lying" $+       (sampleMagicN (E.unsafeSynchronizer clk11 clk77 counter))+    /= (sampleMagicN (E.unsafeSynchronizer dclk11 dclk77lying counter))++-- | Regression test+case_changingDynamicClocks :: Assertion+case_changingDynamicClocks = do+  let+    dclk11 = dynamicClockGen @H11 $ fromList $ cycle $ fmap Femtoseconds+      [10, 20, 30, 40, 50, 60, 70, 80, 90]+    dclk77 = dynamicClockGen @H77 $ fromList $ cycle $ fmap Femtoseconds+      [90, 80, 70, 60, 50, 40, 30, 20, 10]++    counter = fromList [(0 :: Int)..]+    actual = P.take 70 (sample (E.unsafeSynchronizer dclk11 dclk77 counter))++  assertEqual "unsafeSynchronizer produced hardcoded results" actual+    [ 0, 4, 6, 7, 8, 8, 9, 9, 9, 9, 13, 15, 16, 17, 17, 18, 18, 18, 18, 22, 24+    , 25, 26, 26, 27, 27, 27, 27, 31, 33, 34, 35, 35, 36, 36, 36, 36, 40, 42+    , 43, 44, 44, 45, 45, 45, 45, 49, 51, 52, 53, 53, 54, 54, 54, 54, 58, 60+    , 61, 62, 62, 63, 63, 63, 63, 67, 69, 70, 71, 71, 72+    ]++-- | Regression test+case_F1_F6 :: Assertion+case_F1_F6 = do+  let+    clk1 = clockGen @F1+    clk6 = clockGen @F6++    counter = fromList [(0 :: Int)..]++    actual = P.take 70 (sample (E.unsafeSynchronizer clk1 clk6 counter))++  assertEqual "unsafeSynchronizer produced hardcoded results" actual+    [ 0, 13, 25, 38, 50, 63, 75, 88, 100, 113, 125, 138, 150, 163, 175, 188, 200+    , 213, 225, 238, 250, 263, 275, 288, 300, 313, 325, 338, 350, 363, 375, 388+    , 400, 413, 425, 438, 450, 463, 475, 488, 500, 513, 525, 538, 550, 563, 575+    , 588, 600, 613, 625, 638, 650, 663, 675, 688, 700, 713, 725, 738, 750, 763+    , 775, 788, 800, 813, 825, 838, 850, 863+    ]++-- | Regression test+case_F6_F1 :: Assertion+case_F6_F1 = do+  let+    clk1 = clockGen @F1+    clk6 = clockGen @F6++    counter = fromList [(0 :: Int)..]++    actual = P.take 70 (sample (E.unsafeSynchronizer clk6 clk1 counter))++  assertEqual "unsafeSynchronizer produced hardcoded results" actual+    [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2+    , 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4+    , 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6+    ]
tests/Clash/Tests/Vector.hs view
@@ -37,9 +37,7 @@   "[1 :> 2 :> Nil,3 :> 4 :> Nil]" @=? show [1 :> 2 :> Nil, 3 :> i 4 :> Nil]  tests :: TestTree-tests = testGroup "All"-  [ $(testGroupGenerator)-  ]+tests = $(testGroupGenerator)  -- Run with: --
+ tests/Clash/Tests/XException.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE TemplateHaskell #-}++module Clash.Tests.XException where++import Clash.XException++import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.HUnit.Extra+import Test.Tasty.TH++expectLeft :: HasCallStack => Either a b -> Assertion+expectLeft (Left _) = pure ()+expectLeft (Right _) = assertFailure "Expected Left, got Right"++expectRight :: HasCallStack => Either a b -> Assertion+expectRight (Right _) = pure ()+expectRight (Left _) = assertFailure "Expected Right, got Left"++case_hasX :: Assertion+case_hasX = do+  expectRight        $ hasX @(Int, Int) (1, 2)+  expectLeft         $ hasX @(Int, Int) (x, 2)+  expectLeft         $ hasX @(Int, Int) (1, x)+  expectLeft         $ hasX @(Int, Int) (x, x)+  expectLeft         $ hasX @(Int, Int) x+  expectExceptionNoX $ hasX @(Int, Int) (e, 2)+  expectExceptionNoX $ hasX @(Int, Int) (1, e)+  expectExceptionNoX $ hasX @(Int, Int) (e, e)+  expectExceptionNoX $ hasX @(Int, Int) (x, e)+  expectExceptionNoX $ hasX @(Int, Int) (e, x)+  expectExceptionNoX $ hasX @(Int, Int) e+ where+  x = errorX "X"+  e = error "E"++tests :: TestTree+tests = $(testGroupGenerator)++-- Run with:+--+--    ./repld p:tests -T Clash.Tests.XException.main+--+-- Add -W if you want to run tests in spite of warnings+--+main :: IO ()+main = defaultMain tests
tests/Test/Tasty/HUnit/Extra.hs view
@@ -6,7 +6,6 @@   , expectExceptionNoX   ) where -import Control.DeepSeq (NFData) import Control.Exception (SomeException, try, evaluate) import Test.Tasty.HUnit @@ -20,14 +19,14 @@     Right a -> assertFailure ("Expected Exception, got: " <> show a)  -- | Succeed if evaluating leads to an Exception-expectException :: (Show a, NFData a) => a -> Assertion+expectException :: Show a => a -> Assertion expectException a0 =   try @SomeException (evaluate a0) >>= \case     Left _ -> pure ()     Right a -> assertFailure ("Expected Exception, got: " <> show a)  -- | Succeed if evaluating leads to a non-XException Exception-expectExceptionNoX :: (Show a, NFData a) => a -> Assertion+expectExceptionNoX :: Show a => a -> Assertion expectExceptionNoX a0 =   try @SomeException (try @XException (evaluate a0)) >>= \case     Left _ -> pure ()
tests/unittests.hs view
@@ -13,6 +13,7 @@ import qualified Clash.Tests.DerivingDataRepr import qualified Clash.Tests.Fixed import qualified Clash.Tests.FixedExhaustive+import qualified Clash.Tests.MaybeX import qualified Clash.Tests.NFDataX import qualified Clash.Tests.NumNewtypes import qualified Clash.Tests.Ram@@ -23,6 +24,7 @@ import qualified Clash.Tests.TopEntityGeneration import qualified Clash.Tests.Unsigned import qualified Clash.Tests.Vector+import qualified Clash.Tests.XException  import qualified Clash.Tests.Laws.Enum import qualified Clash.Tests.Laws.SaturatingNum@@ -40,6 +42,7 @@   , Clash.Tests.DerivingDataRepr.tests   , Clash.Tests.Fixed.tests   , Clash.Tests.FixedExhaustive.tests+  , Clash.Tests.MaybeX.tests   , Clash.Tests.NFDataX.tests   , Clash.Tests.NumNewtypes.tests   , Clash.Tests.Ram.tests@@ -50,6 +53,7 @@   , Clash.Tests.TopEntityGeneration.tests   , Clash.Tests.Unsigned.tests   , Clash.Tests.Vector.tests+  , Clash.Tests.XException.tests   , testGroup "Laws"     [ Clash.Tests.Laws.Enum.tests     , Clash.Tests.Laws.SaturatingNum.tests