diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2018-12-28 19:20:53 +0100 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2018-12-28 19:20:53 +0100 |
commit | 5243210a4c16a7349b59a964072c4effb3aea30a (patch) | |
tree | b92ffc4819d2fd5e4c2742770e5b1e6b3fcd8a9b /src/Test/VeriFuzz/Verilog/Mutate.hs | |
parent | e73362e0650b20281ee43a246d97e1bbe9e34b3b (diff) | |
download | verismith-5243210a4c16a7349b59a964072c4effb3aea30a.tar.gz verismith-5243210a4c16a7349b59a964072c4effb3aea30a.zip |
Move verilog files into specific module
Diffstat (limited to 'src/Test/VeriFuzz/Verilog/Mutate.hs')
-rw-r--r-- | src/Test/VeriFuzz/Verilog/Mutate.hs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/Test/VeriFuzz/Verilog/Mutate.hs b/src/Test/VeriFuzz/Verilog/Mutate.hs new file mode 100644 index 0000000..b903ec9 --- /dev/null +++ b/src/Test/VeriFuzz/Verilog/Mutate.hs @@ -0,0 +1,80 @@ +{-| +Module : Test.VeriFuzz.Verilog.Mutation +Description : Functions to mutate the Verilog AST. +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +Functions to mutate the Verilog AST from "Test.VeriFuzz.Verilog.AST" to generate +more random patterns, such as nesting wires instead of creating new ones. +-} + +module Test.VeriFuzz.Verilog.Mutate where + +import Control.Lens +import Data.Maybe (catMaybes, fromMaybe) +import Test.VeriFuzz.Internal.Gen +import Test.VeriFuzz.Internal.Shared +import Test.VeriFuzz.Verilog.AST + +-- | Return if the 'Identifier' is in a 'ModDecl'. +inPort :: Identifier -> ModDecl -> Bool +inPort id mod = any (\a -> a ^. portName == id) $ mod ^. modPorts + +-- | Find the last assignment of a specific wire/reg to an expression, and +-- returns that expression. +findAssign :: Identifier -> [ModItem] -> Maybe Expression +findAssign id items = + safe last . catMaybes $ isAssign <$> items + where + isAssign (ModCA (ContAssign val expr)) + | val == id = Just $ expr + | otherwise = Nothing + isAssign _ = Nothing + +-- | Transforms an expression by replacing an Identifier with an +-- expression. This is used inside 'transformOf' and 'traverseExpr' to replace +-- the 'Identifier' recursively. +idTrans :: Identifier -> Expression -> Expression -> Expression +idTrans i expr (PrimExpr (PrimId id)) + | id == i = expr + | otherwise = (PrimExpr (PrimId id)) +idTrans _ _ e = e + +-- | Replaces the identifier recursively in an expression. +replace :: Identifier -> Expression -> Expression -> Expression +replace = (transformOf traverseExpr .) . idTrans + +-- | Nest expressions for a specific 'Identifier'. If the 'Identifier' is not found, +-- the AST is not changed. +-- +-- This could be improved by instead of only using the last assignment to the +-- wire that one finds, to use the assignment to the wire before the current +-- expression. This would require a different approach though. +nestId :: Identifier -> ModDecl -> ModDecl +nestId id mod + | not $ inPort id mod = + let expr = fromMaybe def . findAssign id $ mod ^. moduleItems + in mod & get %~ replace id expr + | otherwise = mod + where + get = moduleItems . traverse . _ModCA . contAssignExpr + def = PrimExpr $ PrimId id + +-- | Replaces an identifier by a expression in all the module declaration. +nestSource :: Identifier -> VerilogSrc -> VerilogSrc +nestSource id src = + src & getVerilogSrc . traverse . getDescription %~ nestId id + +-- | Nest variables in the format @w[0-9]*@ up to a certain number. +nestUpTo :: Int -> VerilogSrc -> VerilogSrc +nestUpTo i src = + foldl (flip nestSource) src $ Identifier . fromNode <$> [1..i] + +-- | Add a Module Instantiation using 'ModInst' from the first module passed to +-- it to the body of the second module. +instantiateMod :: ModDecl -> ModDecl -> ModDecl +instantiateMod mod main = + main |