aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Verilog/Mutate.hs
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2019-02-01 19:39:52 +0000
committerYann Herklotz <ymherklotz@gmail.com>2019-02-01 19:39:52 +0000
commit1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad (patch)
tree2c9a8d54bf6f9870f0ae62c150803ccec90d46e7 /src/VeriFuzz/Verilog/Mutate.hs
parenta38289ca9d96e97bc4e65b67c50f5805d56a3d86 (diff)
downloadverismith-1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad.tar.gz
verismith-1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad.zip
More restructuring
Diffstat (limited to 'src/VeriFuzz/Verilog/Mutate.hs')
-rw-r--r--src/VeriFuzz/Verilog/Mutate.hs169
1 files changed, 0 insertions, 169 deletions
diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs
deleted file mode 100644
index 3e03a02..0000000
--- a/src/VeriFuzz/Verilog/Mutate.hs
+++ /dev/null
@@ -1,169 +0,0 @@
-{-|
-Module : VeriFuzz.Verilog.Mutation
-Description : Functions to mutate the Verilog AST.
-Copyright : (c) 2018-2019, Yann Herklotz Grave
-License : BSD-3
-Maintainer : ymherklotz [at] gmail [dot] com
-Stability : experimental
-Portability : POSIX
-
-Functions to mutate the Verilog AST from "VeriFuzz.Verilog.AST" to generate more
-random patterns, such as nesting wires instead of creating new ones.
--}
-
-module VeriFuzz.Verilog.Mutate where
-
-import Control.Lens
-import Data.Maybe (catMaybes, fromMaybe)
-import Data.Text (Text)
-import qualified Data.Text as T
-import VeriFuzz.Internal.Gen
-import VeriFuzz.Internal.Shared
-import VeriFuzz.Verilog.AST
-import VeriFuzz.Verilog.CodeGen
-
--- | Return if the 'Identifier' is in a 'ModDecl'.
-inPort :: Identifier -> ModDecl -> Bool
-inPort i m = inInput
- where inInput = any (\a -> a ^. portName == i) $
- m ^. modInPorts ++ m ^. modOutPorts
-
--- | Find the last assignment of a specific wire/reg to an expression, and
--- returns that expression.
-findAssign :: Identifier -> [ModItem] -> Maybe Expr
-findAssign i items = safe last . catMaybes $ isAssign <$> items
- where
- isAssign (ModCA (ContAssign val expr))
- | val == i = 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 -> Expr -> Expr -> Expr
-idTrans i expr (Id id') | id' == i = expr
- | otherwise = Id id'
-idTrans _ _ e = e
-
--- | Replaces the identifier recursively in an expression.
-replace :: Identifier -> Expr -> Expr -> Expr
-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 i m
- | not $ inPort i m
- = let expr = fromMaybe def . findAssign i $ m ^. modItems in m & get %~ replace i expr
- | otherwise
- = m
- where
- get = modItems . traverse . _ModCA . contAssignExpr
- def = Id i
-
--- | Replaces an identifier by a expression in all the module declaration.
-nestSource :: Identifier -> VerilogSrc -> VerilogSrc
-nestSource i src = src & getVerilogSrc . traverse . getDescription %~ nestId i
-
--- | 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]
-
-allVars :: ModDecl -> [Identifier]
-allVars m = (m ^.. modOutPorts . traverse . portName) ++ (m ^.. modInPorts . traverse . portName)
--- $setup
--- >>> let m = (ModDecl (Identifier "m") [Port Wire 5 (Identifier "y")] [Port Wire 5 "x"] [])
--- >>> let main = (ModDecl "main" [] [] [])
-
--- | Add a Module Instantiation using 'ModInst' from the first module passed to
--- it to the body of the second module. It first has to make all the inputs into
--- @reg@.
---
--- >>> render $ instantiateMod m main
--- module main;
--- wire [4:0] y;
--- reg [4:0] x;
--- m m1(y, x);
--- endmodule
--- <BLANKLINE>
-instantiateMod :: ModDecl -> ModDecl -> ModDecl
-instantiateMod m main = main & modItems %~ ((out ++ regIn ++ [inst]) ++)
- where
- out = Decl Nothing <$> m ^. modOutPorts
- regIn = Decl Nothing <$> (m ^. modInPorts & traverse . portType .~ Reg False)
- inst = ModInst (m ^. modId) (m ^. modId <> (Identifier . showT $ count + 1)) conns
- count = length . filter (== m ^. modId) $ main ^.. modItems . traverse . modInstId
- conns = ModConn . Id <$> allVars m
-
--- | Instantiate without adding wire declarations. It also does not count the
--- current instantiations of the same module.
---
--- >>> render $ instantiateMod_ m
--- m m(y, x);
--- <BLANKLINE>
-instantiateMod_ :: ModDecl -> ModItem
-instantiateMod_ m = ModInst (m ^. modId) (m ^. modId) conns
- where
- conns =
- ModConn
- . Id
- <$> (m ^.. modOutPorts . traverse . portName)
- ++ (m ^.. modInPorts . traverse . portName)
-
--- | Instantiate without adding wire declarations. It also does not count the
--- current instantiations of the same module.
---
--- >>> render $ instantiateModSpec_ "_" m
--- m m(.y(y), .x(x));
--- <BLANKLINE>
-instantiateModSpec_ :: Text -> ModDecl -> ModItem
-instantiateModSpec_ outChar m = ModInst (m ^. modId) (m ^. modId) conns
- where
- conns =
- zipWith ModConnNamed ids (Id <$> instIds)
- ids = (filterChar outChar $ name modOutPorts) ++ (name modInPorts)
- instIds = (name modOutPorts) ++ (name modInPorts)
- name v = m ^.. v . traverse . portName
-
-filterChar :: Text -> [Identifier] -> [Identifier]
-filterChar t ids =
- ids & traverse . getIdentifier %~ (\x -> fromMaybe x . safe head $ T.splitOn t x)
-
--- | Initialise all the inputs and outputs to a module.
---
--- >>> render $ initMod m
--- module m(y, x);
--- output wire [4:0] y;
--- input wire [4:0] x;
--- endmodule
--- <BLANKLINE>
-initMod :: ModDecl -> ModDecl
-initMod m = m & modItems %~ ((out ++ inp) ++)
- where
- out = Decl (Just PortOut) <$> (m ^. modOutPorts)
- inp = Decl (Just PortIn) <$> (m ^. modInPorts)
-
-makeIdFrom :: (Show a) => a -> Identifier -> Identifier
-makeIdFrom a i = (i <>) . Identifier . ("_" <>) $ showT a
-
--- | Make top level module for equivalence verification. Also takes in how many
--- modules to instantiate.
-makeTop :: Int -> ModDecl -> ModDecl
-makeTop i m = ModDecl (m ^. modId) ys (m ^. modInPorts) modIt
- where
- ys = Port Wire 90 . flip makeIdFrom "y" <$> [1 .. i]
- modIt = instantiateModSpec_ "_" . modN <$> [1 .. i]
- modN n = m & modId %~ makeIdFrom n & modOutPorts .~ [Port Wire 90 (makeIdFrom n "y")]
-
-makeTopAssert :: ModDecl -> ModDecl
-makeTopAssert = (modItems %~ (++ [assert])) . (modInPorts %~ addClk) . makeTop 2
- where
- assert = Always . EventCtrl e . Just $ SeqBlock
- [TaskEnable $ Task "assert" [BinOp (Id "y_1") BinEq (Id "y_2")]]
- e = EPosEdge "clk"
- addClk = ((Port Wire 1 "clk") :)