@@ -54,8 +54,10 @@ import GHC.Stack (HasCallStack)
5454data WishboneMasterRequest addressWidth dat
5555 = Read (BitVector addressWidth ) (BitVector (BitSize dat `DivRU ` 8 ))
5656 | Write (BitVector addressWidth ) (BitVector (BitSize dat `DivRU ` 8 )) dat
57+ deriving (Generic )
5758
5859deriving instance (KnownNat addressWidth , KnownNat (BitSize a ), Show a ) => (Show (WishboneMasterRequest addressWidth a ))
60+ deriving instance (KnownNat addressWidth , KnownNat (BitSize a ), ShowX a ) => (ShowX (WishboneMasterRequest addressWidth a ))
5961
6062--
6163-- Validation for (lenient) spec compliance
@@ -238,13 +240,13 @@ stallStandard stallsPerCycle =
238240 -- tell the master that the slave has no reply yet
239241 (emptyWishboneS2M :- )
240242 -- tell the slave that the cycle is over
241- (m :- )
243+ (emptyWishboneM2S :- )
242244 (go (st - 1 : stalls) Nothing m2s s2m)
243245 -- done stalling, got a reply last second, pass through
244246 | busCycle m && strobe m && st == 0 && hasTerminateFlag s =
245247 B. bimap
246248 (s :- )
247- (m :- )
249+ (emptyWishboneM2S :- )
248250 (go stalls Nothing m2s s2m)
249251 -- done stalling but no termination signal yet, just pass through to give the slave
250252 -- the chance to reply
@@ -284,15 +286,15 @@ driveStandard ::
284286 C. KnownNat (C. BitSize a )
285287 ) =>
286288 ExpectOptions ->
287- -- | Requests to send out
288- [WishboneMasterRequest addressWidth a ] ->
289+ -- | Requests to send out and maximum cycles a transfer is allowed to take
290+ [( WishboneMasterRequest addressWidth a , Int ) ] ->
289291 Circuit () (Wishbone dom 'Standard addressWidth a )
290292driveStandard ExpectOptions {.. } reqs =
291293 Circuit $
292294 (() ,)
293295 . C. fromList_lazy
294296 . (emptyWishboneM2S : )
295- . go eoResetCycles reqs
297+ . go eoResetCycles 0 reqs
296298 . (\ s -> C. sample_lazy s)
297299 . snd
298300 where
@@ -326,22 +328,25 @@ driveStandard ExpectOptions {..} reqs =
326328
327329 go ::
328330 Int ->
329- [WishboneMasterRequest addressWidth a ] ->
331+ Int -> -- cycles in the current transaction
332+ [(WishboneMasterRequest addressWidth a , Int )] ->
330333 [WishboneS2M a ] ->
331334 [WishboneM2S addressWidth (BitSize a `DivRU ` 8 ) a ]
332- go nResets dat ~ (rep : replies)
333- | nResets > 0 = emptyWishboneM2S : (rep `C.seqX` go (nResets - 1 ) dat replies)
335+ go nResets _ dat ~ (rep : replies)
336+ | nResets > 0 = emptyWishboneM2S : (rep `C.seqX` go (nResets - 1 ) 0 dat replies)
334337 -- no more data to send
335- go _ [] ~ (rep : replies) = emptyWishboneM2S : (rep `C.seqX` go 0 [] replies)
336- go _ (d : dat) ~ (rep : replies)
338+ go _ _ [] ~ (rep : replies) = emptyWishboneM2S : (rep `C.seqX` go 0 0 [] replies)
339+ go _ cycles ((d, timeOut) : dat) ~ (rep : replies)
337340 -- the sent data was acknowledged, end the cycle before continuing
338- | acknowledge rep || err rep = emptyWishboneM2S : (rep `C.seqX` go 0 dat replies)
341+ | acknowledge rep || err rep = emptyWishboneM2S : (rep `C.seqX` go 0 0 dat replies)
339342 -- end cycle, continue but send the previous request again
340- | retry rep = emptyWishboneM2S : (rep `C.seqX` go 0 (d : dat) replies)
341- -- not a termination signal, so keep sending the data
343+ | retry rep = emptyWishboneM2S : (rep `C.seqX` go 0 0 ((d, timeOut) : dat) replies)
344+ -- not a termination signal, the transfer timed out
345+ | cycles == timeOut = emptyWishboneM2S : (rep `C.seqX` go 0 0 dat replies)
346+ -- not a termination signal, no timeout, keep sending request
342347 | otherwise -- trace "D in-cycle wait for ACK" $
343348 =
344- transferToSignals d : (rep `C.seqX` go 0 (d : dat) replies)
349+ transferToSignals d : (rep `C.seqX` go 0 (cycles + 1 ) ((d, timeOut) : dat) replies)
345350
346351-- | Circuit which validates the wishbone communication signals between a
347352-- master and a slave circuit.
@@ -410,7 +415,8 @@ validatorCircuitLenient =
410415-- | Test a wishbone 'Standard' circuit against a pure model.
411416wishbonePropWithModel ::
412417 forall dom a addressWidth st .
413- ( Eq a ,
418+ ( HasCallStack ,
419+ Eq a ,
414420 C. ShowX a ,
415421 Show a ,
416422 C. NFDataX a ,
@@ -436,36 +442,45 @@ wishbonePropWithModel eOpts model circuit0 inputGen st = H.property $ do
436442
437443 let
438444 n = P. length input
439- genStall = Gen. integral (Range. linear 0 10 )
445+ genStall = Gen. integral (Range. linear 0 15 )
446+ genTimeOut = Gen. integral (Range. linear 1 15 )
440447
448+ timeOuts <- H. forAll (Gen. list (Range. singleton n) genTimeOut)
441449 stalls <- H. forAll (Gen. list (Range. singleton n) genStall)
442450
443451 let
444452 resets = 50
445- driver = driveStandard @ dom (defExpectOptions {eoResetCycles = resets}) input
453+ inputs = P. zip input timeOuts
454+ driver = driveStandard @ dom (defExpectOptions {eoResetCycles = resets}) inputs |> validatorCircuit |> stallC
446455 stallC = stallStandard stalls
447- circuit1 = stallC |> validatorCircuit |> circuit0
448- (_, _ : s2m) = observeComposedWishboneCircuit (eoTimeout eOpts) driver circuit1
456+ circuit1 = validatorCircuit |> circuit0
457+ (m2s, s2m) = observeComposedWishboneCircuit (eoTimeout eOpts) driver circuit1
458+
459+ matchModel 0 m2s s2m st === Right ()
449460
450- matchModel 0 s2m input st === Right ()
451461 where
462+ m2sToReq WishboneM2S {.. }
463+ | not (busCycle && strobe) = Nothing
464+ | writeEnable = Just $ Write addr busSelect writeData
465+ | otherwise = Just $ Read addr busSelect
466+
452467 matchModel ::
453468 Int ->
469+ [WishboneM2S addressWidth (BitSize a `DivRU ` 8 ) a ] ->
454470 [WishboneS2M a ] ->
455- [WishboneMasterRequest addressWidth a ] ->
456471 st ->
457472 Either (Int , String ) ()
458- matchModel _ [] _ _ = Right () -- so far everything is good but the sampling stopped
473+ matchModel _ [] _ _ = Right ()
459474 matchModel _ _ [] _ = Right ()
460- matchModel cyc (s : s2m ) (req : reqs0 ) state
461- | not (hasTerminateFlag s) = s `C.seqX` matchModel ( succ cyc) s2m (req : reqs0) state
462- | otherwise = case model req s state of
463- Left err -> Left (cyc, err)
464- Right st1 -> s `C.seqX` matchModel ( succ cyc) s2m reqs1 st1
465- where
466- reqs1
467- | retry s = req : reqs0
468- | otherwise = reqs0
475+ matchModel cyc (m : m2s ) (s : s2m ) state
476+ | Nothing <- m2sToReq m, hasTerminateFlag s =
477+ Left (cyc, " Termination flag outside of bus cycle " )
478+ | Just req <- m2sToReq m, hasTerminateFlag s =
479+ case model req s state of
480+ Left err -> Left (cyc, err)
481+ Right st1 -> s `C.seqX` matchModel ( succ cyc) m2s s2m st1
482+ | otherwise = s `C.seqX` matchModel ( succ cyc) m2s s2m state
483+
469484
470485observeComposedWishboneCircuit ::
471486 (KnownDomain dom ) =>
0 commit comments