clash-protocols
Safe HaskellNone
LanguageGHC2021

Protocols.Experimental.Wishbone.Standard.Hedgehog

Description

Types and functions to aid with testing Wishbone circuits.

This module provides two "modes" of Wishbone Specification compliance checks:

  • "lenient" mode
  • "common sense" mode

"lenient" mode

The Wishbone spec mostly specifies the handshake protocols but does not make many assumptions about which signals *should* be valid in response to what. This is presumably done so to allow circuits to be very flexible, however it makes for a relatively weak validation tool.

"common sense" mode

The Wishbone spec itself makes very little assumptions about how interactions should look like outside of basic hand-shaking. This "common sense" compliance checking additionally checks for: - A read request is acked with defined data - response data respects the busSelect signal - A write request must contain valid data according to the busSelect signal

Synopsis

Types

data WishboneMasterRequest (addressBits :: Nat) (dataBytes :: Nat) Source #

Datatype representing a single transaction request sent from a Wishbone Master to a Wishbone Slave

Constructors

Read (BitVector addressBits) (BitVector dataBytes) 
Write (BitVector addressBits) (BitVector dataBytes) (BitVector (dataBytes * 8)) 

Instances

Instances details
(KnownNat dataBytes, KnownNat addressBits) => BitPack (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Associated Types

type BitSize (WishboneMasterRequest addressBits dataBytes) 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

type BitSize (WishboneMasterRequest addressBits dataBytes) = CLog 2 (GConstructorCount (Rep (WishboneMasterRequest addressBits dataBytes))) + GFieldSize (Rep (WishboneMasterRequest addressBits dataBytes))

Methods

pack :: WishboneMasterRequest addressBits dataBytes -> BitVector (BitSize (WishboneMasterRequest addressBits dataBytes)) #

unpack :: BitVector (BitSize (WishboneMasterRequest addressBits dataBytes)) -> WishboneMasterRequest addressBits dataBytes #

(KnownNat addressBits, KnownNat dataBytes) => NFDataX (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Methods

deepErrorX :: String -> WishboneMasterRequest addressBits dataBytes #

hasUndefined :: WishboneMasterRequest addressBits dataBytes -> Bool #

ensureSpine :: WishboneMasterRequest addressBits dataBytes -> WishboneMasterRequest addressBits dataBytes #

rnfX :: WishboneMasterRequest addressBits dataBytes -> () #

(KnownNat addressBits, KnownNat dataBytes) => ShowX (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Methods

showsPrecX :: Int -> WishboneMasterRequest addressBits dataBytes -> ShowS #

showX :: WishboneMasterRequest addressBits dataBytes -> String #

showListX :: [WishboneMasterRequest addressBits dataBytes] -> ShowS #

NFData (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Methods

rnf :: WishboneMasterRequest addressBits dataBytes -> () #

Generic (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Associated Types

type Rep (WishboneMasterRequest addressBits dataBytes) 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

type Rep (WishboneMasterRequest addressBits dataBytes) = D1 ('MetaData "WishboneMasterRequest" "Protocols.Experimental.Wishbone.Standard.Hedgehog" "clash-protocols-0.1-inplace" 'False) (C1 ('MetaCons "Read" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector addressBits)) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector dataBytes))) :+: C1 ('MetaCons "Write" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector addressBits)) :*: (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector dataBytes)) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector (dataBytes * 8))))))

Methods

from :: WishboneMasterRequest addressBits dataBytes -> Rep (WishboneMasterRequest addressBits dataBytes) x #

to :: Rep (WishboneMasterRequest addressBits dataBytes) x -> WishboneMasterRequest addressBits dataBytes #

(KnownNat addressBits, KnownNat dataBytes) => Show (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Methods

showsPrec :: Int -> WishboneMasterRequest addressBits dataBytes -> ShowS #

show :: WishboneMasterRequest addressBits dataBytes -> String #

showList :: [WishboneMasterRequest addressBits dataBytes] -> ShowS #

(KnownNat addressBits, KnownNat dataBytes) => Eq (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

Methods

(==) :: WishboneMasterRequest addressBits dataBytes -> WishboneMasterRequest addressBits dataBytes -> Bool #

(/=) :: WishboneMasterRequest addressBits dataBytes -> WishboneMasterRequest addressBits dataBytes -> Bool #

type BitSize (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

type BitSize (WishboneMasterRequest addressBits dataBytes) = CLog 2 (GConstructorCount (Rep (WishboneMasterRequest addressBits dataBytes))) + GFieldSize (Rep (WishboneMasterRequest addressBits dataBytes))
type Rep (WishboneMasterRequest addressBits dataBytes) Source # 
Instance details

Defined in Protocols.Experimental.Wishbone.Standard.Hedgehog

type Rep (WishboneMasterRequest addressBits dataBytes) = D1 ('MetaData "WishboneMasterRequest" "Protocols.Experimental.Wishbone.Standard.Hedgehog" "clash-protocols-0.1-inplace" 'False) (C1 ('MetaCons "Read" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector addressBits)) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector dataBytes))) :+: C1 ('MetaCons "Write" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector addressBits)) :*: (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector dataBytes)) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (BitVector (dataBytes * 8))))))

Circuits

stallStandard Source #

Arguments

:: forall (dom :: Domain) (addressBits :: Nat) (dataBytes :: Nat). (KnownNat addressBits, KnownDomain dom, KnownNat dataBytes) 
=> [Int]

Number of cycles to stall the master for on each valid bus-cycle

-> Circuit (Wishbone dom 'Standard addressBits dataBytes) (Wishbone dom 'Standard addressBits dataBytes) 

Create a stalling wishbone Standard circuit.

driveStandard Source #

Arguments

:: forall (dom :: Domain) (addressBits :: Nat) (dataBytes :: Nat). (KnownNat addressBits, KnownDomain dom, KnownNat dataBytes) 
=> ExpectOptions 
-> [(WishboneMasterRequest addressBits dataBytes, Int)]

Requests to send out

-> Circuit () (Wishbone dom 'Standard addressBits dataBytes) 

Create a wishbone Standard circuit to drive other circuits.

validatorCircuit :: forall (dom :: Domain) (addressBits :: Nat) (dataBytes :: Nat). (HasCallStack, HiddenClockResetEnable dom, KnownNat addressBits, KnownNat dataBytes) => Circuit (Wishbone dom 'Standard addressBits dataBytes) (Wishbone dom 'Standard addressBits dataBytes) Source #

Circuit which validates the wishbone communication signals between a master and a slave circuit.

Halts execution using error when a "common sense" spec validation occurs.

N.B. Not synthesisable.

validatorCircuitLenient :: forall (dom :: Domain) (addressBits :: Nat) (dataBytes :: Nat). (HasCallStack, HiddenClockResetEnable dom, KnownNat addressBits, KnownNat dataBytes) => Circuit (Wishbone dom 'Standard addressBits dataBytes) (Wishbone dom 'Standard addressBits dataBytes) Source #

Circuit which validates the wishbone communication signals between a master and a slave circuit.

Halts execution using error when a spec validation occurs.

N.B. Not synthesisable.

observeComposedWishboneCircuit :: forall (dom :: Domain) (mode :: WishboneMode) (addressBits :: Nat) (dataBytes :: Nat). KnownDomain dom => Circuit () (Wishbone dom mode addressBits dataBytes) -> Circuit (Wishbone dom mode addressBits dataBytes) () -> ([WishboneM2S addressBits dataBytes], [WishboneS2M dataBytes]) Source #

Given a wishbone manager and wishbone subordinate, connect them and sample their forward and backward channel lazily.

Properties

wishbonePropWithModel Source #

Arguments

:: forall (dom :: Domain) (addressBits :: Nat) (dataBytes :: Nat) st (m :: Type -> Type). (KnownNat addressBits, HiddenClockResetEnable dom, KnownNat dataBytes, Monad m) 
=> ExpectOptions 
-> (WishboneMasterRequest addressBits dataBytes -> WishboneS2M dataBytes -> st -> Either String st)

Check whether a S2M signal for a given request is matching a pure model using st as its state. Return an error message Left or the updated state Right

-> Circuit (Wishbone dom 'Standard addressBits dataBytes) ()

The circuit to run the test against.

-> Gen [WishboneMasterRequest addressBits dataBytes]

Inputs to the circuit and model

-> st

Initial state of the model

-> PropertyT m () 

Test a wishbone Standard circuit against a pure model.

Generators

genWishboneTransfer :: forall (addressBits :: Nat) (dataBytes :: Nat). (KnownNat addressBits, KnownNat dataBytes) => Range (Unsigned addressBits) -> Gen (WishboneMasterRequest addressBits dataBytes) Source #

Generate a random Wishbone transfer based on an address range and a payload generator.

Simulation

sample :: forall (dom :: Domain) (mode :: WishboneMode) (addressBits :: Nat) (dataBytes :: Nat). KnownDomain dom => ExpectOptions -> Circuit () (Wishbone dom mode addressBits dataBytes) -> Circuit (Wishbone dom mode addressBits dataBytes) () -> [(WishboneM2S addressBits dataBytes, WishboneS2M dataBytes)] Source #

Simulates a wishbone manager and subordinate and returns their transactions. The results are filtered to only include transactions that have bus activity, for a version that includes all cycles, see sampleUnfiltered.

sampleUnfiltered :: forall (dom :: Domain) (mode :: WishboneMode) (addressBits :: Nat) (dataBytes :: Nat). KnownDomain dom => ExpectOptions -> Circuit () (Wishbone dom mode addressBits dataBytes) -> Circuit (Wishbone dom mode addressBits dataBytes) () -> [(WishboneM2S addressBits dataBytes, WishboneS2M dataBytes)] Source #

Simulates a wishbone manager and subordinate and the state of the bus for every cycle. For a time independent version that only includes transactions, see sample.

helpers

m2sToRequest :: forall (addressBits :: Nat) (dataBytes :: Nat). (KnownNat addressBits, KnownNat dataBytes) => WishboneM2S addressBits dataBytes -> WishboneMasterRequest addressBits dataBytes Source #

Interpret a WishboneM2S as a WishboneMasterRequest. Only works for valid requests and performs no checks.

eqWishboneS2M Source #

Arguments

:: forall (addressBits :: Natural) (dataBytes :: Natural). KnownNat dataBytes 
=> WishboneMasterRequest addressBits dataBytes

Request that determines which fields to check

-> WishboneS2M dataBytes

Wishbone Subordinate response A

-> WishboneS2M dataBytes

Wishbone Subordinate response B

-> Bool 

Checks equality for relevant parts of a WishboneS2M response based on the corresponding WishboneMasterRequest. For a Write request, the readData field is ignored, for a Read request only the selected bytes are checked.

>>> 
:{
let
  readReqA = Read (0 :: BitVector 32) (0b1111 :: BitVector 4)
  readReqB = Read (0 :: BitVector 32) (0b0001 :: BitVector 4)
  writeReq = Write (0 :: BitVector 32) (0b1111 :: BitVector 4) (0x12345678 :: BitVector 32)
  s2mA = (emptyWishboneS2M @4)
    { readData = 0x00FF
    , acknowledge = True
    , err = False
    , retry = False
    }
  s2mB = (emptyWishboneS2M @4)
    { readData = 0xFFFF
    , acknowledge = True
    , err = False
    , retry = False
    }
  s2mC = (emptyWishboneS2M @4)
    { readData = deepErrorX ""
    , acknowledge = True
    , err = False
    , retry = False
    }
:}
>>> eqWishboneS2M readReqA s2mA s2mB
False
>>> eqWishboneS2M readReqB s2mA s2mB
True
>>> eqWishboneS2M writeReq s2mA s2mB
True
>>> eqWishboneS2M writeReq s2mA s2mC
True