@@ -10,7 +10,7 @@ module Clash.Testbench.Generate where
1010
1111import Hedgehog
1212import Hedgehog.Gen
13- import Control.Monad.State.Lazy (liftIO )
13+ import Control.Monad.State.Lazy (liftIO , when , modify )
1414import Data.IORef (newIORef , readIORef , writeIORef )
1515
1616import Clash.Prelude (KnownDomain (.. ), BitPack (.. ), NFDataX )
@@ -101,74 +101,85 @@ matchIOGen expectedOutput gen = do
101101 TBDomain {.. } <- tbDomain @ dom
102102
103103 vRef <- liftIO $ newIORef undefined
104- simStepCache <- liftIO (readIORef simStepRef >>= newIORef)
104+ checkForProgress <- progressCheck simStepRef False
105105
106106 mind SomeSignal $ IOInput
107107 { signalId = NoID
108108 , signalCurVal = const $ do
109- global <- readIORef simStepRef
110- local <- readIORef simStepCache
109+ progress <- checkForProgress
111110
112- if local == global
113- then readIORef vRef
114- else do
111+ if progress
112+ then do
115113 (i, o) <- sample gen
116- signalExpect expectedOutput $ Expectation (global + 1 , verify o)
117-
114+ curStep <- readIORef simStepRef
115+ signalExpect expectedOutput $ Expectation (curStep, verify o)
118116 writeIORef vRef i
119- writeIORef simStepCache global
117+
120118 return i
119+ else
120+ readIORef vRef
121121 , signalPrint = Nothing
122122 }
123+
123124 where
124- verify x y
125- | x == y = Nothing
126- | otherwise = Just $ " Expected " <> show x <> " but the output is " <> show y
125+ verify x y = do
126+ when (x /= y)
127+ $ footnote
128+ $ " Expected '" <> show x <> " ' but the output is '" <> show y <> " '"
129+ x === x
127130
128131-- | Extended version of 'matchIOGen', which allows to specify valid
129- -- IO behavior over a finite amount of simulation steps. The generator
130- -- is repeatedly called after all steps of a generation have been
131- -- verified.
132+ -- IO behavior over a finite amount of simulation steps. During native
133+ -- simulation (no property check), the generator is repeatedly called
134+ -- after all the generated simulation steps have been consumed. The
135+ -- generator is only called once if the test bench is converted to a
136+ -- property instead.
132137matchIOGenN ::
133138 forall dom i o .
134139 (NFDataX i , BitPack i , KnownDomain dom , Eq o , Show o , Show i ) =>
135140 TBSignal dom o -> Gen [(i , o )] -> TB (TBSignal dom i )
136141matchIOGenN expectedOutput gen = do
137142 TBDomain {.. } <- tbDomain @ dom
138143
139- vRef <- liftIO $ newIORef []
140- simStepCache <- liftIO (readIORef simStepRef >>= newIORef)
144+ xs <- liftIO $ sample gen
145+ modify $ \ st@ ST {.. } -> st { simSteps = max simSteps $ length xs }
146+
147+ vRef <- liftIO $ newIORef xs
148+ checkForProgress <- progressCheck simStepRef False
141149
142150 mind SomeSignal $ IOInput
143- { signalId = NoID
151+ { signalId = NoID
144152 , signalCurVal = const $ do
145- global <- readIORef simStepRef
146- local <- readIORef simStepCache
153+ progress <- checkForProgress
147154
148- if local == global
149- then readIORef vRef >>= \ case
150- (i, _) : _ -> return i
151- [] -> do
152- (i, o) : xr <- sample gen
153- writeIORef vRef ((i, o) : xr)
154- Prelude. print $ (i, o) : xr
155- return i
156- else do
157- writeIORef simStepCache global
158- readIORef vRef >>= \ case
155+ readIORef vRef >>=
156+ if progress
157+ then \ case
159158 _ : (i, o) : xr -> do
160159 writeIORef vRef ((i, o) : xr)
161- signalExpect expectedOutput $ Expectation (global + 1 , verify o)
160+ curStep <- readIORef simStepRef
161+ signalExpect expectedOutput $ Expectation (curStep, verify o)
162162 return i
163163 _ -> do
164164 (i, o) : xr <- sample gen
165- Prelude. print $ (i, o) : xr
165+
166166 writeIORef vRef ((i, o) : xr)
167- signalExpect expectedOutput $ Expectation (global + 1 , verify o)
167+ curStep <- readIORef simStepRef
168+ signalExpect expectedOutput $ Expectation (curStep, verify o)
168169 return i
169- , signalPrint = Nothing
170+ else \ case
171+ (i, _) : _ -> return i
172+ [] -> do
173+ (i, o) : xr <- sample gen
174+ writeIORef vRef ((i, o) : xr)
175+ Prelude. print $ (i, o) : xr
176+ return i
177+ , signalPrint = Nothing
170178 }
179+
171180 where
172- verify x y
173- | x == y = Nothing
174- | otherwise = Just $ " Expected '" <> show x <> " ' but the output is '" <> show y <> " '"
181+ verify x y = do
182+ when (x /= y)
183+ $ footnote
184+ $ " Expected '" <> show x <> " ' but the output is '" <> show y <> " '"
185+ x === x
0 commit comments