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
|
{-|
Module : Test.VeriFuzz.Verilog.Arbitrary
Description : Arbitrary instances for the AST.
Copyright : (c) 2018-2019, Yann Herklotz Grave
License : GPL-3
Maintainer : ymherklotz [at] gmail [dot] com
Stability : experimental
Portability : POSIX
Arbitrary instances for the AST.
-}
module Test.VeriFuzz.Verilog.Arbitrary where
import Control.Monad (replicateM)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Test.QuickCheck as QC
import Test.VeriFuzz.Verilog.AST
-- Generate Arbitrary instances for the AST
positiveArb :: (QC.Arbitrary a, Ord a, Num a) => QC.Gen a
positiveArb = QC.suchThat QC.arbitrary (>0)
expr :: Int -> QC.Gen Expr
expr 0 = QC.oneof
[ Id <$> QC.arbitrary
, Number <$> positiveArb <*> QC.arbitrary
, UnOp <$> QC.arbitrary <*> QC.arbitrary
-- , Str <$> QC.arbitrary
]
expr n
| n > 0 = QC.oneof
[ Id <$> QC.arbitrary
, Number <$> positiveArb <*> QC.arbitrary
, Concat <$> QC.listOf1 (subexpr 4)
, UnOp <$> QC.arbitrary <*> QC.arbitrary
-- , Str <$> QC.arbitrary
, BinOp <$> subexpr 2 <*> QC.arbitrary <*> subexpr 2
, Cond <$> subexpr 3 <*> subexpr 3 <*> subexpr 3
]
| otherwise = expr 0
where
subexpr y = expr (n `div` y)
statement :: Int -> QC.Gen Stmnt
statement 0 = QC.oneof
[ BlockAssign <$> QC.arbitrary
, NonBlockAssign <$> QC.arbitrary
-- , StatCA <$> QC.arbitrary
, TaskEnable <$> QC.arbitrary
, SysTaskEnable <$> QC.arbitrary
]
statement n
| n > 0 = QC.oneof
[ TimeCtrl <$> QC.arbitrary <*> (Just <$> substat 2)
, SeqBlock <$> QC.listOf1 (substat 4)
, BlockAssign <$> QC.arbitrary
, NonBlockAssign <$> QC.arbitrary
-- , StatCA <$> QC.arbitrary
, TaskEnable <$> QC.arbitrary
, SysTaskEnable <$> QC.arbitrary
]
| otherwise = statement 0
where
substat y = statement (n `div` y)
modPortGen :: QC.Gen Port
modPortGen = QC.oneof
[ Port Wire <$> positiveArb <*> QC.arbitrary
, Port <$> (Reg <$> QC.arbitrary) <*> positiveArb <*> QC.arbitrary
]
instance QC.Arbitrary Text where
arbitrary = T.pack <$> QC.arbitrary
instance QC.Arbitrary Identifier where
arbitrary = do
l <- QC.choose (2, 10)
Identifier . T.pack <$> replicateM l (QC.elements ['a'..'z'])
instance QC.Arbitrary BinaryOperator where
arbitrary = QC.elements
[ 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 QC.Arbitrary UnaryOperator where
arbitrary = QC.elements
[ UnPlus
, UnMinus
, UnNot
, UnAnd
, UnNand
, UnOr
, UnNor
, UnXor
, UnNxor
, UnNxorInv
]
instance QC.Arbitrary PortDir where
arbitrary = QC.elements [PortIn, PortOut, PortInOut]
instance QC.Arbitrary PortType where
arbitrary = QC.oneof [pure Wire, Reg <$> QC.arbitrary]
instance QC.Arbitrary Port where
arbitrary = Port <$> QC.arbitrary <*> positiveArb <*> QC.arbitrary
instance QC.Arbitrary Delay where
arbitrary = Delay <$> positiveArb
instance QC.Arbitrary Event where
arbitrary = EId <$> QC.arbitrary
instance QC.Arbitrary ModConn where
arbitrary = ModConn <$> QC.arbitrary
instance QC.Arbitrary ConstExpr where
arbitrary = ConstExpr <$> positiveArb
instance QC.Arbitrary LVal where
arbitrary = QC.oneof [ RegId <$> QC.arbitrary
, RegExpr <$> QC.arbitrary <*> QC.arbitrary
, RegSize <$> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary
]
instance QC.Arbitrary Assign where
arbitrary = Assign <$> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary
instance QC.Arbitrary Expr where
arbitrary = QC.sized expr
instance QC.Arbitrary Stmnt where
arbitrary = QC.sized statement
instance QC.Arbitrary ContAssign where
arbitrary = ContAssign <$> QC.arbitrary <*> QC.arbitrary
instance QC.Arbitrary Task where
arbitrary = Task <$> QC.arbitrary <*> QC.arbitrary
instance QC.Arbitrary ModItem where
arbitrary = QC.oneof [ ModCA <$> QC.arbitrary
, ModInst <$> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary
, Initial <$> QC.arbitrary
, Always <$> (EventCtrl <$> QC.arbitrary <*> QC.arbitrary)
, Decl <$> pure Nothing <*> QC.arbitrary
]
instance QC.Arbitrary ModDecl where
arbitrary = ModDecl <$> QC.arbitrary <*> QC.arbitrary
<*> QC.listOf1 modPortGen <*> QC.arbitrary
instance QC.Arbitrary Description where
arbitrary = Description <$> QC.arbitrary
instance QC.Arbitrary VerilogSrc where
arbitrary = VerilogSrc <$> QC.arbitrary
|