aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Gen.hs
diff options
context:
space:
mode:
authorYann Herklotz <git@ymhg.org>2019-04-02 19:47:32 +0100
committerYann Herklotz <git@ymhg.org>2019-04-02 19:47:32 +0100
commitfd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0 (patch)
tree673439d49fa095bf3ae9b7bbbca5f30d7ff20838 /src/VeriFuzz/Gen.hs
parentc0c799ab3f79c370e4c33b8f824489ce8b1c96ec (diff)
downloadverismith-fd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0.tar.gz
verismith-fd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0.zip
Large refactor with passing tests
Diffstat (limited to 'src/VeriFuzz/Gen.hs')
-rw-r--r--src/VeriFuzz/Gen.hs215
1 files changed, 0 insertions, 215 deletions
diff --git a/src/VeriFuzz/Gen.hs b/src/VeriFuzz/Gen.hs
deleted file mode 100644
index 6bc01c9..0000000
--- a/src/VeriFuzz/Gen.hs
+++ /dev/null
@@ -1,215 +0,0 @@
-{-|
-Module : VeriFuzz.Gen
-Description : Various useful generators.
-Copyright : (c) 2019, Yann Herklotz
-License : GPL-3
-Maintainer : ymherklotz [at] gmail [dot] com
-Stability : experimental
-Portability : POSIX
-
-Various useful generators.
--}
-
-{-# LANGUAGE TemplateHaskell #-}
-
-module VeriFuzz.Gen
- ( -- * Generation methods
- procedural
- , fromGraph
- , randomMod
- )
-where
-
-import Control.Lens hiding (Context)
-import Control.Monad (replicateM)
-import Control.Monad.Trans.Class (lift)
-import Control.Monad.Trans.Reader hiding (local)
-import Control.Monad.Trans.State.Lazy
-import Data.Foldable (fold)
-import qualified Data.Text as T
-import Hedgehog (Gen)
-import qualified Hedgehog.Gen as Hog
-import VeriFuzz.AST
-import VeriFuzz.ASTGen
-import VeriFuzz.Config
-import VeriFuzz.Internal
-import VeriFuzz.Mutate
-import VeriFuzz.Random
-
-data Context = Context { _variables :: [Port]
- , _nameCounter :: Int
- , _stmntDepth :: Int
- }
-
-makeLenses ''Context
-
-type StateGen = StateT Context (ReaderT Config Gen)
-
-toId :: Int -> Identifier
-toId = Identifier . ("w" <>) . T.pack . show
-
-toPort :: Identifier -> Gen Port
-toPort ident = do
- i <- genPositive
- return $ wire i ident
-
-sumSize :: [Port] -> Int
-sumSize ps = sum $ ps ^.. traverse . portSize
-
-random :: [Identifier] -> (Expr -> ContAssign) -> Gen ModItem
-random ctx fun = do
- expr <- Hog.sized (exprWithContext ctx)
- return . ModCA $ fun expr
-
---randomAssigns :: [Identifier] -> [Gen ModItem]
---randomAssigns ids = random ids . ContAssign <$> ids
-
-randomOrdAssigns :: [Identifier] -> [Identifier] -> [Gen ModItem]
-randomOrdAssigns inp ids = snd $ foldr generate (inp, []) ids
- where generate cid (i, o) = (cid : i, random i (ContAssign cid) : o)
-
-fromGraph :: Gen ModDecl
-fromGraph = do
- gr <- rDupsCirc <$> Hog.resize 100 randomDAG
- return
- $ initMod
- . head
- $ nestUpTo 5 (generateAST gr)
- ^.. getVerilog
- . traverse
- . getDescription
-
-randomMod :: Int -> Int -> Gen ModDecl
-randomMod inps total = do
- x <- sequence $ randomOrdAssigns start end
- ident <- sequence $ toPort <$> ids
- let inputs_ = take inps ident
- let other = drop inps ident
- let y = ModCA . ContAssign "y" . fold $ Id <$> drop inps ids
- let yport = [wire (sumSize other) "y"]
- return . declareMod other . ModDecl "test_module" yport inputs_ $ x ++ [y]
- where
- ids = toId <$> [1 .. total]
- end = drop inps ids
- start = take inps ids
-
-gen :: Gen a -> StateGen a
-gen = lift . lift
-
-some :: StateGen a -> StateGen [a]
-some f = do
- amount <- gen genPositive
- replicateM amount f
-
-makeIdentifier :: T.Text -> StateGen Identifier
-makeIdentifier prefix = do
- context <- get
- let ident = Identifier $ prefix <> showT (context ^. nameCounter)
- nameCounter += 1
- return ident
-
-newPort :: PortType -> StateGen Port
-newPort pt = do
- ident <- makeIdentifier . T.toLower $ showT pt
- p <- gen $ Port pt <$> arb <*> genPositive <*> pure ident
- variables %= (p :)
- return p
-
-select :: PortType -> StateGen Port
-select ptype = do
- context <- get
- case filter chooseReg $ context ^.. variables . traverse of
- [] -> newPort ptype
- l -> gen $ Hog.element l
- where chooseReg (Port a _ _ _) = ptype == a
-
-scopedExpr :: StateGen Expr
-scopedExpr = do
- context <- get
- gen
- . Hog.sized
- . exprWithContext
- $ context
- ^.. variables
- . traverse
- . portName
-
-contAssign :: StateGen ContAssign
-contAssign = do
- p <- newPort Wire
- ContAssign (p ^. portName) <$> scopedExpr
-
-lvalFromPort :: Port -> LVal
-lvalFromPort (Port _ _ _ i) = RegId i
-
-probability :: Config -> Probability
-probability c = c ^. configProbability
-
-askProbability :: StateGen Probability
-askProbability = lift $ asks probability
-
-assignment :: StateGen Assign
-assignment = do
- expr <- scopedExpr
- lval <- lvalFromPort <$> newPort Reg
- return $ Assign lval Nothing expr
-
-conditional :: StateGen Statement
-conditional = do
- expr <- scopedExpr
- stmntDepth -= 1
- tstat <- SeqBlock <$> some statement
- stmntDepth += 1
- return $ CondStmnt expr (Just tstat) Nothing
-
-statement :: StateGen Statement
-statement = do
- prob <- askProbability
- cont <- get
- Hog.frequency
- [ (prob ^. probBlock , BlockAssign <$> assignment)
- , (prob ^. probNonBlock , NonBlockAssign <$> assignment)
- , (onDepth cont (prob ^. probCond), conditional)
- ]
- where onDepth c n = if c ^. stmntDepth > 0 then n else 0
-
--- | Generate a random module item.
-modItem :: StateGen ModItem
-modItem = do
- prob <- askProbability
- stat <- fold <$> some statement
- eventReg <- select Reg
- modCA <- ModCA <$> contAssign
- gen $ Hog.frequency
- [ (prob ^. probAssign, return modCA)
- , ( prob ^. probAlways
- , return $ Always (EventCtrl (EId (eventReg ^. portName)) (Just stat))
- )
- ]
-
--- | 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
--- module.
-moduleDef :: Bool -> StateGen ModDecl
-moduleDef top = do
- name <- if top then return "top" else gen arb
- portList <- some $ newPort Wire
- mi <- some modItem
- context <- get
- let local = filter (`notElem` portList) $ context ^. variables
- let size = sum $ local ^.. traverse . portSize
- let yport = Port Wire False size "y"
- return . declareMod local . ModDecl name [yport] portList $ combineAssigns
- yport
- mi
-
--- | Procedural generation method for random Verilog. Uses internal 'Reader' and
--- 'State' to keep track of the current Verilog code structure.
-procedural :: Config -> Gen Verilog
-procedural config = Verilog . (: []) . Description <$> Hog.resize
- num
- (runReaderT (evalStateT (moduleDef True) context) config)
- where
- context = Context [] 0 $ config ^. configProperty . propDepth
- num = fromIntegral $ config ^. configProperty . propSize