6
6
Use generators to create signal data.
7
7
-}
8
8
9
+ {-# LANGUAGE RecursiveDo #-}
10
+ {-# LANGUAGE OverloadedStrings #-}
9
11
module Clash.Testbench.Generate where
10
12
11
13
import Hedgehog
@@ -25,27 +27,29 @@ import Clash.Testbench.Internal.Monad
25
27
generate ::
26
28
forall dom a .
27
29
(NFDataX a , BitPack a , KnownDomain dom ) =>
28
- a -> Gen a -> TB (TBSignal dom a )
29
- generate def gen = do
30
+ Gen a -> TB (TBSignal dom a )
31
+ generate gen = do
30
32
TBDomain {.. } <- tbDomain @ dom
31
33
32
- vRef <- liftIO $ newIORef def
33
- simStepCache <- liftIO (readIORef simStepRef >>= newIORef)
34
+ vRef <- liftIO $ newIORef undefined
35
+ checkForProgress <- progressCheck simStepRef True
36
+ signalHistory <- newHistory
34
37
35
38
mind SomeSignal IOInput
36
39
{ signalId = NoID
37
40
, signalCurVal = const $ do
38
- v <- readIORef simStepRef
39
- v' <- readIORef simStepCache
41
+ progress <- checkForProgress
40
42
41
- if v == v'
42
- then readIORef vRef
43
- else do
43
+ if progress
44
+ then do
44
45
x <- sample gen
45
46
writeIORef vRef x
46
- writeIORef simStepCache v
47
+ memorize signalHistory x
47
48
return x
49
+ else
50
+ readIORef vRef
48
51
, signalPrint = Nothing
52
+ ,..
49
53
}
50
54
51
55
-- | Extended version of 'generate', which allows to generate a finite
@@ -60,32 +64,33 @@ generateN def gen = do
60
64
TBDomain {.. } <- tbDomain @ dom
61
65
62
66
vRef <- liftIO $ newIORef [def]
63
- simStepCache <- liftIO (readIORef simStepRef >>= newIORef)
67
+ checkForProgress <- progressCheck simStepRef False
68
+ signalHistory <- newHistory
64
69
65
70
mind SomeSignal IOInput
66
71
{ signalId = NoID
67
72
, signalCurVal = const $ do
68
- v <- readIORef simStepRef
69
- v' <- readIORef simStepCache
70
-
71
- if v == v'
72
- then readIORef vRef >>= \ case
73
- x : _ -> return x
74
- [] -> do
75
- x : xr <- sample gen
76
- writeIORef vRef (x : xr)
77
- return x
73
+ progress <- checkForProgress
78
74
79
- else do
80
- writeIORef simStepCache v
75
+ if progress
76
+ then
81
77
readIORef vRef >>= \ case
82
- _ : x : xr -> do
78
+ h : x : xr -> do
79
+ memorize signalHistory h
83
80
writeIORef vRef (x : xr)
84
81
return x
85
- _ -> do
82
+ [h] -> do
83
+ memorize signalHistory h
86
84
x : xr <- sample gen
87
85
writeIORef vRef (x : xr)
88
86
return x
87
+ _ -> error " unreachable"
88
+ else readIORef vRef >>= \ case
89
+ x : _ -> return x
90
+ [] -> do
91
+ x : xr <- sample gen
92
+ writeIORef vRef (x : xr)
93
+ return x
89
94
, signalPrint = Nothing
90
95
, ..
91
96
}
@@ -102,6 +107,7 @@ matchIOGen expectedOutput gen = do
102
107
103
108
vRef <- liftIO $ newIORef undefined
104
109
checkForProgress <- progressCheck simStepRef False
110
+ signalHistory <- newHistory
105
111
106
112
mind SomeSignal $ IOInput
107
113
{ signalId = NoID
@@ -119,6 +125,7 @@ matchIOGen expectedOutput gen = do
119
125
else
120
126
readIORef vRef
121
127
, signalPrint = Nothing
128
+ , ..
122
129
}
123
130
124
131
where
@@ -138,35 +145,40 @@ matchIOGenN ::
138
145
forall dom i o .
139
146
(NFDataX i , BitPack i , KnownDomain dom , Eq o , Show o , Show i ) =>
140
147
TBSignal dom o -> Gen [(i , o )] -> TB (TBSignal dom i )
141
- matchIOGenN expectedOutput gen = do
148
+ matchIOGenN checkedOutput gen = mdo
142
149
TBDomain {.. } <- tbDomain @ dom
143
150
144
151
xs <- liftIO $ sample gen
145
152
modify $ \ st@ ST {.. } -> st { simSteps = max simSteps $ length xs }
153
+ liftIO $ Prelude. print xs
146
154
147
155
vRef <- liftIO $ newIORef xs
148
156
checkForProgress <- progressCheck simStepRef False
157
+ signalHistory <- newHistory
149
158
150
- mind SomeSignal $ IOInput
159
+ s <- mind SomeSignal $ IOInput
151
160
{ signalId = NoID
152
161
, signalCurVal = const $ do
153
162
progress <- checkForProgress
154
163
155
164
readIORef vRef >>=
156
165
if progress
157
166
then \ case
158
- _ : (i, o) : xr -> do
167
+ (h, _) : (i, o) : xr -> do
168
+ memorize signalHistory h
159
169
writeIORef vRef ((i, o) : xr)
160
170
curStep <- readIORef simStepRef
161
- signalExpect expectedOutput $ Expectation (curStep, verify o)
171
+ signalExpect checkedOutput $ Expectation (curStep, verify s i o)
162
172
return i
163
- _ -> do
173
+ [(h, _)] -> do
174
+ memorize signalHistory h
164
175
(i, o) : xr <- sample gen
165
176
166
177
writeIORef vRef ((i, o) : xr)
167
178
curStep <- readIORef simStepRef
168
- signalExpect expectedOutput $ Expectation (curStep, verify o)
179
+ signalExpect checkedOutput $ Expectation (curStep, verify s i o)
169
180
return i
181
+ _ -> error " unreachable"
170
182
else \ case
171
183
(i, _) : _ -> return i
172
184
[] -> do
@@ -175,11 +187,41 @@ matchIOGenN expectedOutput gen = do
175
187
Prelude. print $ (i, o) : xr
176
188
return i
177
189
, signalPrint = Nothing
190
+ , ..
178
191
}
179
192
193
+ return s
194
+
180
195
where
181
- verify x y = do
182
- when (x /= y)
183
- $ footnote
184
- $ " Expected '" <> show x <> " ' but the output is '" <> show y <> " '"
185
- x === x
196
+ verify generatedInput currentInput expectedOutput observedOutput = do
197
+ when (expectedOutput /= observedOutput) $ do
198
+ xs <-
199
+ (<> [(currentInput, observedOutput)])
200
+ <$> (zip <$> history generatedInput <*> history checkedOutput)
201
+
202
+ let
203
+ cHeading = " Cycle"
204
+ iHeading = " Input"
205
+ oHeading = " Output"
206
+ cLen = length cHeading
207
+ iLen = maximum $ (length iHeading : ) $ fmap (length . show . fst ) xs
208
+ oLen = maximum $ (length oHeading : ) $ fmap (length . show . snd ) xs
209
+
210
+ footnote $ unlines $
211
+ [ " Expected to see the output '" <> show expectedOutput <> " ',"
212
+ , " but the observed output is '" <> show observedOutput <> " '."
213
+ , " "
214
+ , " I/O History:"
215
+ , " "
216
+ , cHeading <>
217
+ replicate (iLen - length iHeading + 2 ) ' ' <> iHeading <>
218
+ replicate (oLen - length oHeading + 2 ) ' ' <> oHeading
219
+ , replicate (cLen + iLen + oLen + 4 ) ' -'
220
+ ] <>
221
+ [ replicate (cLen - length (show c)) ' ' <> show c <>
222
+ replicate (iLen - length (show i) + 2 ) ' ' <> show i <>
223
+ replicate (oLen - length (show o) + 2 ) ' ' <> show o
224
+ | (c, (i, o)) <- zip [0 :: Int ,1 .. ] xs
225
+ ]
226
+
227
+ failure
0 commit comments