1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
{-|
Module : VeriFuzz.Verilog.Arbitrary
Description : Arb instance for all the types.
Copyright : (c) 2019, Yann Herklotz Grave
License : GPL-3
Maintainer : ymherklotz [at] gmail [dot] com
Stability : experimental
Portability : POSIX
Arb instance for all the types.
-}
module VeriFuzz.Verilog.Arbitrary
(
-- * Arbitrary
Arb
, arb
, genPositive
, listOf1
, listOf
)
where
import Control.Monad (replicateM)
import Data.List.NonEmpty (toList)
import qualified Data.Text as T
import Hedgehog (Gen)
import qualified Hedgehog.Gen as Hog
import qualified Hedgehog.Range as Hog
import VeriFuzz.Verilog.AST
listOf1 :: Gen a -> Gen [a]
listOf1 a = toList <$> Hog.nonEmpty (Hog.linear 0 100) a
listOf :: Gen a -> Gen [a]
listOf = Hog.list (Hog.linear 0 100)
genPositive :: Gen Int
genPositive = Hog.filter (>= 0) $ Hog.int (Hog.linear 1 99)
integral :: Gen Integer
integral = Hog.integral (Hog.linear 0 100)
class Arb a where
arb :: Gen a
instance Arb Identifier where
arb = do
l <- genPositive
Identifier . T.pack <$> replicateM (l + 1) (Hog.element ['a'..'z'])
instance Arb Int where
arb = Hog.int (Hog.linear 0 100)
instance Arb Integer where
arb = integral
instance Arb Delay where
arb = Delay <$> genPositive
instance Arb Event where
arb = EId <$> arb
instance Arb BinaryOperator where
arb = Hog.element
[ BinPlus
, BinMinus
, BinTimes
-- , BinDiv
-- , BinMod
, BinEq
, BinNEq
-- , BinCEq
-- , BinCNEq
, BinLAnd
, BinLOr
, BinLT
, BinLEq
, BinGT
, BinGEq
, BinAnd
, BinOr
, BinXor
, BinXNor
, BinXNorInv
-- , BinPower
, BinLSL
, BinLSR
, BinASL
, BinASR
]
instance Arb UnaryOperator where
arb = Hog.element
[ UnPlus
, UnMinus
, UnNot
, UnLNot
, UnAnd
, UnNand
, UnOr
, UnNor
, UnXor
, UnNxor
, UnNxorInv
]
instance Arb Function where
arb = Hog.element
[ SignedFunc
, UnsignedFunc
]
instance Arb Expr where
arb = Hog.sized expr
exprSafeList :: [Gen Expr]
exprSafeList = [Number <$> genPositive <*> integral]
exprRecList :: (Hog.Size -> Gen Expr) -> [Gen Expr]
exprRecList subexpr =
[ Number <$> genPositive <*> integral
, Concat <$> listOf1 (subexpr 8)
, UnOp
<$> arb
<*> subexpr 2
-- , Str <$> arb
, BinOp <$> subexpr 2 <*> arb <*> subexpr 2
, Cond <$> subexpr 3 <*> subexpr 3 <*> subexpr 3
, Func <$> arb <*> subexpr 2
]
expr :: Hog.Size -> Gen Expr
expr n | n == 0 = Hog.choice $ (Id <$> arb) : exprSafeList
| n > 0 = Hog.choice $ (Id <$> arb) : exprRecList subexpr
| otherwise = expr 0
where subexpr y = expr (n `div` y)
constExpr :: Gen ConstExpr
constExpr = Hog.recursive Hog.choice
[ ConstNum <$> genPositive <*> arb
, ParamId <$> arb
]
[ Hog.subtermM constExpr (\e -> ConstUnOp <$> arb <*> pure e)
, Hog.subtermM2 constExpr constExpr (\a b -> ConstBinOp <$> pure a <*> arb <*> pure b)
, Hog.subterm3 constExpr constExpr constExpr ConstCond
]
instance Arb ConstExpr where
arb = constExpr
instance Arb Task where
arb = Task <$> arb <*> listOf arb
instance Arb LVal where
arb = Hog.choice [ RegId <$> arb
, RegExpr <$> arb <*> arb
, RegSize <$> arb <*> arb <*> arb
]
instance Arb PortDir where
arb = Hog.element [PortIn, PortOut, PortInOut]
instance Arb PortType where
arb = Hog.element [Wire, Reg]
instance Arb Port where
arb = Port <$> arb <*> arb <*> genPositive <*> arb
instance Arb ModConn where
arb = ModConn <$> arb
instance Arb Assign where
arb = Assign <$> arb <*> Hog.maybe arb <*> arb
instance Arb ContAssign where
arb = ContAssign <$> arb <*> arb
instance Arb Statement where
arb = Hog.sized statement
statement :: Hog.Size -> Gen Statement
statement n
| n == 0 = Hog.choice
[ BlockAssign <$> arb
, NonBlockAssign <$> arb
, TaskEnable <$> arb
, SysTaskEnable <$> arb
]
| n > 0 = Hog.choice
[ TimeCtrl <$> arb <*> (Just <$> substat 2)
, SeqBlock <$> listOf1 (substat 4)
, BlockAssign <$> arb
, NonBlockAssign <$> arb
, TaskEnable <$> arb
, SysTaskEnable <$> arb
]
| otherwise = statement 0
where substat y = statement (n `div` y)
instance Arb ModItem where
arb = Hog.choice [ ModCA <$> arb
, ModInst <$> arb <*> arb <*> listOf arb
, Initial <$> arb
, Always <$> (EventCtrl <$> arb <*> Hog.maybe arb)
, Decl <$> pure Nothing <*> arb
]
modPortGen :: Gen Port
modPortGen = Port <$> arb <*> arb <*> arb <*> arb
instance Arb Parameter where
arb = Parameter <$> arb <*> arb
instance Arb LocalParam where
arb = LocalParam <$> arb <*> arb
instance Arb ModDecl where
arb = ModDecl <$> arb <*> listOf arb <*> listOf1 modPortGen <*> listOf arb <*> listOf arb
instance Arb Verilog where
arb = Verilog <$> listOf1 arb
instance Arb Bool where
arb = Hog.element [True, False]
|