{-# LANGUAGE NoImplicitPrelude #-}
module Clash.Explicit.Verification
(
Assertion
, Property
, AssertionValue
, RenderAs(..)
, name
, lit
, not
, and
, or
, implies
, next
, nextN
, before
, timplies
, timpliesOverlapping
, always
, never
, assert
, cover
, check
, checkI
, hideAssertion
)
where
import Prelude
(Bool, Word, (.), pure, max, concat)
import Data.Text (Text)
import Data.Maybe (Maybe(Just))
import Clash.Annotations.Primitive
(Primitive(InlinePrimitive), HDL(..))
import Clash.Signal.Internal (KnownDomain, Signal, Clock, Reset)
import Clash.XException (errorX, hwSeqX)
import Clash.Verification.Internal
name :: Text -> Signal dom Bool -> Assertion dom
name :: Text -> Signal dom Bool -> Assertion dom
name Text
nm Signal dom Bool
signal = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsNotTemporal ((Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. a -> Assertion' a
CvPure (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
nm, Signal dom Bool
signal))
{-# INLINE name #-}
lit :: Bool -> Assertion dom
lit :: Bool -> Assertion dom
lit = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsNotTemporal (Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom)
-> (Bool -> Assertion' (Maybe Text, Signal dom Bool))
-> Bool
-> Assertion dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Assertion' (Maybe Text, Signal dom Bool)
forall a. Bool -> Assertion' a
CvLit
{-# INLINE lit #-}
not :: AssertionValue dom a => a -> Assertion dom
not :: a -> Assertion dom
not (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion dom
a) = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion (Assertion dom -> IsTemporal
forall (dom :: Domain). Assertion dom -> IsTemporal
isTemporal Assertion dom
a) (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a
CvNot (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion Assertion dom
a))
{-# INLINE not #-}
and :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom
and :: a -> b -> Assertion dom
and (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion dom
a) (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion dom
b) =
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion
(IsTemporal -> IsTemporal -> IsTemporal
forall a. Ord a => a -> a -> a
max (Assertion dom -> IsTemporal
forall (dom :: Domain). Assertion dom -> IsTemporal
isTemporal Assertion dom
a) (Assertion dom -> IsTemporal
forall (dom :: Domain). Assertion dom -> IsTemporal
isTemporal Assertion dom
b))
(Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a -> Assertion' a
CvAnd (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion Assertion dom
a) (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion Assertion dom
b))
{-# INLINE and #-}
or :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom
or :: a -> b -> Assertion dom
or (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion dom
a) (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion dom
b) =
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion
(IsTemporal -> IsTemporal -> IsTemporal
forall a. Ord a => a -> a -> a
max (Assertion dom -> IsTemporal
forall (dom :: Domain). Assertion dom -> IsTemporal
isTemporal Assertion dom
a) (Assertion dom -> IsTemporal
forall (dom :: Domain). Assertion dom -> IsTemporal
isTemporal Assertion dom
b))
(Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a -> Assertion' a
CvOr (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion Assertion dom
a) (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion Assertion dom
b))
{-# INLINE or #-}
implies :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom
implies :: a -> b -> Assertion dom
implies (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion IsTemporal
aTmp Assertion' (Maybe Text, Signal dom Bool)
a) (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue -> Assertion IsTemporal
bTmp Assertion' (Maybe Text, Signal dom Bool)
b) =
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion (IsTemporal -> IsTemporal -> IsTemporal
forall a. Ord a => a -> a -> a
max IsTemporal
aTmp IsTemporal
bTmp) (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a -> Assertion' a
CvImplies Assertion' (Maybe Text, Signal dom Bool)
a Assertion' (Maybe Text, Signal dom Bool)
b)
{-# INLINE implies #-}
next :: AssertionValue dom a => a -> Assertion dom
next :: a -> Assertion dom
next = Word -> a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
Word -> a -> Assertion dom
nextN Word
1
{-# INLINE next #-}
nextN :: AssertionValue dom a => Word -> a -> Assertion dom
nextN :: Word -> a -> Assertion dom
nextN Word
n = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom)
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Word -> Assertion' a -> Assertion' a
CvNext Word
n (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion dom)
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue
{-# INLINE nextN #-}
before :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom
before :: a -> b -> Assertion dom
before a
a0 b
b0 = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a -> Assertion' a
CvBefore Assertion' (Maybe Text, Signal dom Bool)
a1 Assertion' (Maybe Text, Signal dom Bool)
b1)
where
a1 :: Assertion' (Maybe Text, Signal dom Bool)
a1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue a
a0)
b1 :: Assertion' (Maybe Text, Signal dom Bool)
b1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue b
b0)
{-# INLINE before #-}
timplies :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom
timplies :: a -> b -> Assertion dom
timplies a
a0 b
b0 = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Word
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Word -> Assertion' a -> Assertion' a -> Assertion' a
CvTemporalImplies Word
1 Assertion' (Maybe Text, Signal dom Bool)
a1 Assertion' (Maybe Text, Signal dom Bool)
b1)
where
a1 :: Assertion' (Maybe Text, Signal dom Bool)
a1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
toTemporal (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue a
a0)
b1 :: Assertion' (Maybe Text, Signal dom Bool)
b1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
toTemporal (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue b
b0)
{-# INLINE timplies #-}
timpliesOverlapping
:: (AssertionValue dom a, AssertionValue dom b)
=> a
-> b
-> Assertion dom
timpliesOverlapping :: a -> b -> Assertion dom
timpliesOverlapping a
a0 b
b0 =
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Word
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Word -> Assertion' a -> Assertion' a -> Assertion' a
CvTemporalImplies Word
0 Assertion' (Maybe Text, Signal dom Bool)
a1 Assertion' (Maybe Text, Signal dom Bool)
b1)
where
a1 :: Assertion' (Maybe Text, Signal dom Bool)
a1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
toTemporal (a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue a
a0)
b1 :: Assertion' (Maybe Text, Signal dom Bool)
b1 = Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
toTemporal (b -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue b
b0)
{-# INLINE timpliesOverlapping #-}
always :: AssertionValue dom a => a -> Assertion dom
always :: a -> Assertion dom
always = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom)
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a
CvAlways (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion dom)
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue
{-# INLINE always #-}
never :: AssertionValue dom a => a -> Assertion dom
never :: a -> Assertion dom
never = IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
forall (dom :: Domain).
IsTemporal
-> Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom
Assertion IsTemporal
IsTemporal (Assertion' (Maybe Text, Signal dom Bool) -> Assertion dom)
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Assertion' a
CvNever (Assertion' (Maybe Text, Signal dom Bool)
-> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion dom)
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue
{-# INLINE never #-}
assert :: AssertionValue dom a => a -> Property dom
assert :: a -> Property dom
assert = Property' (Maybe Text, Signal dom Bool) -> Property dom
forall (dom :: Domain).
Property' (Maybe Text, Signal dom Bool) -> Property dom
Property (Property' (Maybe Text, Signal dom Bool) -> Property dom)
-> (a -> Property' (Maybe Text, Signal dom Bool))
-> a
-> Property dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion' (Maybe Text, Signal dom Bool)
-> Property' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Property' a
CvAssert (Assertion' (Maybe Text, Signal dom Bool)
-> Property' (Maybe Text, Signal dom Bool))
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Property' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion dom)
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue
{-# INLINE assert #-}
cover :: AssertionValue dom a => a -> Property dom
cover :: a -> Property dom
cover = Property' (Maybe Text, Signal dom Bool) -> Property dom
forall (dom :: Domain).
Property' (Maybe Text, Signal dom Bool) -> Property dom
Property (Property' (Maybe Text, Signal dom Bool) -> Property dom)
-> (a -> Property' (Maybe Text, Signal dom Bool))
-> a
-> Property dom
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion' (Maybe Text, Signal dom Bool)
-> Property' (Maybe Text, Signal dom Bool)
forall a. Assertion' a -> Property' a
CvCover (Assertion' (Maybe Text, Signal dom Bool)
-> Property' (Maybe Text, Signal dom Bool))
-> (a -> Assertion' (Maybe Text, Signal dom Bool))
-> a
-> Property' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
forall (dom :: Domain).
Assertion dom -> Assertion' (Maybe Text, Signal dom Bool)
assertion (Assertion dom -> Assertion' (Maybe Text, Signal dom Bool))
-> (a -> Assertion dom)
-> a
-> Assertion' (Maybe Text, Signal dom Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Assertion dom
forall (dom :: Domain) a.
AssertionValue dom a =>
a -> Assertion dom
toAssertionValue
{-# INLINE cover #-}
check
:: KnownDomain dom
=> Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom AssertionResult
check :: Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom AssertionResult
check !Clock dom
_clk !Reset dom
_rst !Text
_propName !RenderAs
_renderAs !Property dom
_prop =
AssertionResult -> Signal dom AssertionResult
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (String -> AssertionResult
forall a. HasCallStack => String -> a
errorX ([String] -> String
forall (t :: Type -> Type) a. Foldable t => t [a] -> [a]
concat [
String
"Simulation for Clash.Verification not yet implemented. If you need this,"
, String
" 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\"}} ]") #-}
checkI
:: KnownDomain dom
=> Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom a
-> Signal dom a
checkI :: Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom a
-> Signal dom a
checkI Clock dom
clk Reset dom
rst Text
propName RenderAs
renderAs Property dom
prop =
Signal dom AssertionResult -> Signal dom a -> Signal dom a
forall (dom :: Domain) a.
Signal dom AssertionResult -> Signal dom a -> Signal dom a
hideAssertion (Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom AssertionResult
forall (dom :: Domain).
KnownDomain dom =>
Clock dom
-> Reset dom
-> Text
-> RenderAs
-> Property dom
-> Signal dom AssertionResult
check Clock dom
clk Reset dom
rst Text
propName RenderAs
renderAs Property dom
prop)
hideAssertion :: Signal dom AssertionResult -> Signal dom a -> Signal dom a
hideAssertion :: Signal dom AssertionResult -> Signal dom a -> Signal dom a
hideAssertion = Signal dom AssertionResult -> Signal dom a -> Signal dom a
forall a b. a -> b -> b
hwSeqX