aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Verilog/Arbitrary.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/VeriFuzz/Verilog/Arbitrary.hs')
-rw-r--r--src/VeriFuzz/Verilog/Arbitrary.hs184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/VeriFuzz/Verilog/Arbitrary.hs b/src/VeriFuzz/Verilog/Arbitrary.hs
new file mode 100644
index 0000000..1bcb727
--- /dev/null
+++ b/src/VeriFuzz/Verilog/Arbitrary.hs
@@ -0,0 +1,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