aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Verilog/Gen.hs
diff options
context:
space:
mode:
authorYann Herklotz <git@ymhg.org>2019-04-09 17:00:35 +0100
committerYann Herklotz <git@ymhg.org>2019-04-09 17:00:35 +0100
commitc1a832419a28ac074cbccbeb7060afd22c36d033 (patch)
treed051d9d22c985219f063aa5d17aa20f9c6931c08 /src/VeriFuzz/Verilog/Gen.hs
parentd18b11d671c8562c148515347aaf096bc942418f (diff)
downloadverismith-c1a832419a28ac074cbccbeb7060afd22c36d033.tar.gz
verismith-c1a832419a28ac074cbccbeb7060afd22c36d033.zip
Add generation of parameters and constant expressions
Diffstat (limited to 'src/VeriFuzz/Verilog/Gen.hs')
-rw-r--r--src/VeriFuzz/Verilog/Gen.hs54
1 files changed, 47 insertions, 7 deletions
diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs
index 6f50f19..ae72b9f 100644
--- a/src/VeriFuzz/Verilog/Gen.hs
+++ b/src/VeriFuzz/Verilog/Gen.hs
@@ -28,6 +28,7 @@ import Data.Foldable (fold)
import qualified Data.Text as T
import Hedgehog (Gen)
import qualified Hedgehog.Gen as Hog
+import qualified Hedgehog.Range as Hog
import VeriFuzz.Config
import VeriFuzz.Internal
import VeriFuzz.Verilog.Arbitrary
@@ -36,6 +37,7 @@ import VeriFuzz.Verilog.Internal
import VeriFuzz.Verilog.Mutate
data Context = Context { _variables :: [Port]
+ , _parameters :: [Parameter]
, _nameCounter :: Int
, _stmntDepth :: Int
}
@@ -89,6 +91,11 @@ some f = do
amount <- gen genPositive
replicateM amount f
+many :: StateGen a -> StateGen [a]
+many f = do
+ amount <- gen $ Hog.int (Hog.linear 0 10)
+ replicateM amount f
+
makeIdentifier :: T.Text -> StateGen Identifier
makeIdentifier prefix = do
context <- get
@@ -151,10 +158,11 @@ statement :: StateGen Statement
statement = do
prob <- askProbability
cont <- get
+ let defProb i = prob ^. probStmnt . i
Hog.frequency
- [ (prob ^. probBlock , BlockAssign <$> assignment)
- , (prob ^. probNonBlock , NonBlockAssign <$> assignment)
- , (onDepth cont (prob ^. probCond), conditional)
+ [ (defProb probStmntBlock , BlockAssign <$> assignment)
+ , (defProb probStmntNonBlock , NonBlockAssign <$> assignment)
+ , (onDepth cont (defProb probStmntCond), conditional)
]
where onDepth c n = if c ^. stmntDepth > 0 then n else 0
@@ -167,9 +175,10 @@ always = do
modItem :: StateGen ModItem
modItem = do
prob <- askProbability
+ let defProb i = prob ^. probModItem . i
Hog.frequency
- [ (prob ^. probAssign, ModCA <$> contAssign)
- , (prob ^. probAlways, always)
+ [ (defProb probModItemAssign, ModCA <$> contAssign)
+ , (defProb probModItemAlways, always)
]
moduleName :: Maybe Identifier -> StateGen Identifier
@@ -184,6 +193,37 @@ initialBlock = do
where
makeAssign p = NonBlockAssign $ Assign (lvalFromPort p) Nothing 0
+constExprWithContext :: [Parameter] -> ProbExpr -> Hog.Size -> Gen ConstExpr
+constExprWithContext ps prob size
+ | size == 0 = Hog.frequency
+ [ (prob ^. probExprNum, ConstNum <$> genPositive <*> arb)
+ , (if null ps then 0 else prob ^. probExprId, ParamId . view paramIdent <$> Hog.element ps)
+ ]
+ | size > 0 = Hog.frequency
+ [ (prob ^. probExprNum, ConstNum <$> genPositive <*> arb)
+ , (if null ps then 0 else prob ^. probExprId, ParamId . view paramIdent <$> Hog.element ps)
+ , (prob ^. probExprUnOp, ConstUnOp <$> arb <*> subexpr 2)
+ , (prob ^. probExprBinOp, ConstBinOp <$> subexpr 2 <*> arb <*> subexpr 2)
+ , (prob ^. probExprCond, ConstCond <$> subexpr 3 <*> subexpr 3 <*> subexpr 3)
+ , (prob ^. probExprConcat, ConstConcat <$> listOf1 (subexpr 8))
+ ]
+ | otherwise = constExprWithContext ps prob 0
+ where subexpr y = constExprWithContext ps prob $ size `div` y
+
+constExpr :: StateGen ConstExpr
+constExpr = do
+ prob <- askProbability
+ context <- get
+ gen . Hog.sized $ constExprWithContext (context ^. parameters) (prob ^. probExpr)
+
+parameter :: StateGen Parameter
+parameter = do
+ ident <- makeIdentifier "param"
+ cexpr <- constExpr
+ let param = Parameter ident cexpr
+ parameters %= (param :)
+ return $ param
+
-- | Generates a module definition randomly. It always has one output port which
-- is set to @y@. The size of @y@ is the total combination of all the locally
-- defined wires, so that it correctly reflects the internal state of the
@@ -200,7 +240,7 @@ moduleDef top = do
let clock = Port Wire False 1 "clk"
let yport = Port Wire False size "y"
let comb = combineAssigns_ yport local
- return . declareMod local $ ModDecl name [yport] (clock:portList) (initBlock : mi <> [comb]) []
+ declareMod local . ModDecl name [yport] (clock:portList) (initBlock : mi <> [comb]) <$> many parameter
-- | Procedural generation method for random Verilog. Uses internal 'Reader' and
-- 'State' to keep track of the current Verilog code structure.
@@ -209,5 +249,5 @@ procedural config = Verilog . (: []) <$> Hog.resize
num
(runReaderT (evalStateT (moduleDef (Just "top")) context) config)
where
- context = Context [] 0 $ config ^. configProperty . propDepth
+ context = Context [] [] 0 $ config ^. configProperty . propDepth
num = fromIntegral $ config ^. configProperty . propSize