{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableSuperClasses #-} {-# OPTIONS_HADDOCK hide #-} -- These types should be re-exported from the Protocols.Experimental.Hedgehog module module Protocols.Experimental.Hedgehog.Types where -- deepseq import Control.DeepSeq import Clash.Prelude qualified as C import Data.Maybe (fromMaybe) import Data.Proxy import GHC.Stack (HasCallStack) import Protocols.Experimental.Simulate.Types -- hedgehog import Hedgehog qualified as H -- | Superclass class to reduce syntactical noise. class (NFData a, C.NFDataX a, C.ShowX a, C.Show a, Eq a) => TestType a instance (NFData a, C.NFDataX a, C.ShowX a, C.Show a, Eq a) => TestType a -- | Options for 'expectN' function. See individual fields for more information. data ExpectOptions = ExpectOptions { eoStopAfterEmpty :: Maybe Int {- ^ Explicitly control the number of samples empty samples simulate before we stop the simulation. When set to `Nothing`, this is derived using `expectedEmptyCycles`. -} , eoSampleMax :: Int {- ^ Produce an error if the circuit produces more than /n/ valid samples. This is used to terminate (potentially) infinitely running circuits. -} , eoStallsMax :: Int -- ^ Generate at most /n/ stall moments of zero or more cycles(set by 'eoConsecutiveStalls'). , eoConsecutiveStalls :: Int -- ^ Maximum number of consecutive stalls that are allowed to be inserted. , eoResetCycles :: Int -- ^ Ignore first /n/ cycles , eoDriveEarly :: Bool {- ^ Start driving the circuit with its reset asserted. Circuits should never acknowledge data while this is happening. -} , eoTimeoutMs :: Maybe Int -- ^ Terminate the test after /n/ milliseconds. , eoTrace :: Bool -- ^ Trace data generation for debugging purposes } -- | Default derivation of `eoStopAfterEmpty` when it is set to `Nothing`. expectedEmptyCycles :: ExpectOptions -> Int expectedEmptyCycles eOpts = -- +2 on `eoStallsMax` to account worst case left side stalling + right side stalling -- +1 on `eoConsecutiveStalls` to consume 1 sample after stalling -- +100 arbitrarily chosen to allow the circuit to have some internal latency. fromMaybe (eOpts.eoStallsMax * (eOpts.eoConsecutiveStalls + 1) + eOpts.eoResetCycles + 100) eOpts.eoStopAfterEmpty {- | Provides a way of comparing expected data with data produced by a protocol component. -} class ( Drivable a , TestType (SimulateFwdType a) , TestType (ExpectType a) ) => Test a where {- | Trim each channel to the lengths given as the third argument. See result documentation for failure modes. -} expectN :: (HasCallStack, H.MonadTest m) => Proxy a -> -- | Options, see t'ExpectOptions' ExpectOptions -> -- | Raw sampled data SimulateFwdType a -> {- | Depending on "ExpectOptions", fails the test if: * Circuit produced less data than expected * Circuit produced more data than expected If it does not fail, /SimulateFwdType a/ will contain exactly the number of expected data packets. TODO: Should probably return a 'Vec (SimulateChannels) Failures' in order to produce pretty reports. -} m (ExpectType a)