From 8dd9e46314c775b92574b67fc0d7207180fbec78 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Mon, 31 Dec 2018 19:13:47 +0100 Subject: Separate arbitrary from types --- src/Test/VeriFuzz/Verilog/Arbitrary.hs | 184 +++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 src/Test/VeriFuzz/Verilog/Arbitrary.hs (limited to 'src') diff --git a/src/Test/VeriFuzz/Verilog/Arbitrary.hs b/src/Test/VeriFuzz/Verilog/Arbitrary.hs new file mode 100644 index 0000000..5f30b73 --- /dev/null +++ b/src/Test/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 RegLVal 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 -- cgit