From 4ba440d842e9a0502b429fbc04e2be41c8037a4c Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 19 Jan 2019 19:20:33 +0000 Subject: Add brittany formatting instead of stylish-haskell --- src/VeriFuzz/Circuit.hs | 4 +- src/VeriFuzz/Graph/ASTGen.hs | 58 ++++++++-------- src/VeriFuzz/Graph/CodeGen.hs | 55 +++++++++------- src/VeriFuzz/Graph/Random.hs | 44 ++++++------- src/VeriFuzz/Graph/RandomAlt.hs | 21 +++--- src/VeriFuzz/Internal/Gen.hs | 21 ++++-- src/VeriFuzz/Simulator.hs | 3 +- src/VeriFuzz/Simulator/General.hs | 10 +-- src/VeriFuzz/Simulator/Icarus.hs | 35 +++++----- src/VeriFuzz/Simulator/Xst.hs | 10 +-- src/VeriFuzz/Simulator/Yosys.hs | 18 +++-- src/VeriFuzz/Verilog.hs | 3 +- src/VeriFuzz/Verilog/AST.hs | 135 +++++++++++++++++++++++++++----------- src/VeriFuzz/Verilog/CodeGen.hs | 128 ++++++++++++++++++------------------ src/VeriFuzz/Verilog/Helpers.hs | 16 ++--- src/VeriFuzz/Verilog/Mutate.hs | 113 +++++++++++++++++-------------- 16 files changed, 385 insertions(+), 289 deletions(-) (limited to 'src/VeriFuzz') diff --git a/src/VeriFuzz/Circuit.hs b/src/VeriFuzz/Circuit.hs index 7958f6a..1891ff9 100644 --- a/src/VeriFuzz/Circuit.hs +++ b/src/VeriFuzz/Circuit.hs @@ -12,7 +12,9 @@ Definition of the circuit graph. module VeriFuzz.Circuit where -import Data.Graph.Inductive (Gr, LNode) +import Data.Graph.Inductive ( Gr + , LNode + ) import System.Random import Test.QuickCheck diff --git a/src/VeriFuzz/Graph/ASTGen.hs b/src/VeriFuzz/Graph/ASTGen.hs index f7bd058..0403f51 100644 --- a/src/VeriFuzz/Graph/ASTGen.hs +++ b/src/VeriFuzz/Graph/ASTGen.hs @@ -12,10 +12,12 @@ Generates the AST from the graph directly. module VeriFuzz.Graph.ASTGen where -import Data.Foldable (fold) -import Data.Graph.Inductive (LNode, Node) -import qualified Data.Graph.Inductive as G -import Data.Maybe (catMaybes) +import Data.Foldable ( fold ) +import Data.Graph.Inductive ( LNode + , Node + ) +import qualified Data.Graph.Inductive as G +import Data.Maybe ( catMaybes ) import VeriFuzz.Circuit import VeriFuzz.Internal.Gen import VeriFuzz.Verilog.AST @@ -33,52 +35,48 @@ fromGate Or = BinOr fromGate Xor = BinXor inputsC :: Circuit -> [Node] -inputsC c = - inputs (getCircuit c) +inputsC c = inputs (getCircuit c) outputsC :: Circuit -> [Node] -outputsC c = - outputs (getCircuit c) +outputsC c = outputs (getCircuit c) genPortsAST :: (Circuit -> [Node]) -> Circuit -> [Port] -genPortsAST f c = - port . frNode <$> f c - where - port = Port Wire 4 +genPortsAST f c = port . frNode <$> f c where port = Port Wire 4 -- | Generates the nested expression AST, so that it can then generate the -- assignment expressions. genAssignExpr :: Gate -> [Node] -> Maybe Expr -genAssignExpr _ [] = Nothing -genAssignExpr _ [n] = Just . Id $ frNode n -genAssignExpr g (n:ns) = BinOp wire op <$> genAssignExpr g ns - where - wire = Id $ frNode n - op = fromGate g +genAssignExpr _ [] = Nothing +genAssignExpr _ [n ] = Just . Id $ frNode n +genAssignExpr g (n : ns) = BinOp wire op <$> genAssignExpr g ns + where + wire = Id $ frNode n + op = fromGate g -- | Generate the continuous assignment AST for a particular node. If it does -- not have any nodes that link to it then return 'Nothing', as that means that -- the assignment will just be empty. genContAssignAST :: Circuit -> LNode Gate -> Maybe ModItem genContAssignAST c (n, g) = ModCA . ContAssign name <$> genAssignExpr g nodes - where - gr = getCircuit c - nodes = G.pre gr n - name = frNode n + where + gr = getCircuit c + nodes = G.pre gr n + name = frNode n genAssignAST :: Circuit -> [ModItem] genAssignAST c = catMaybes $ genContAssignAST c <$> nodes - where - gr = getCircuit c - nodes = G.labNodes gr + where + gr = getCircuit c + nodes = G.labNodes gr genModuleDeclAST :: Circuit -> ModDecl genModuleDeclAST c = ModDecl i output ports items - where - i = Identifier "gen_module" - ports = genPortsAST inputsC c - output = [Port Wire 90 "y"] - items = genAssignAST c ++ [ModCA . ContAssign "y" . fold $ portToExpr <$> ports] + where + i = Identifier "gen_module" + ports = genPortsAST inputsC c + output = [Port Wire 90 "y"] + items = + genAssignAST c ++ [ModCA . ContAssign "y" . fold $ portToExpr <$> ports] generateAST :: Circuit -> VerilogSrc generateAST c = VerilogSrc [Description $ genModuleDeclAST c] diff --git a/src/VeriFuzz/Graph/CodeGen.hs b/src/VeriFuzz/Graph/CodeGen.hs index 57e7b2a..3c45a9c 100644 --- a/src/VeriFuzz/Graph/CodeGen.hs +++ b/src/VeriFuzz/Graph/CodeGen.hs @@ -12,13 +12,19 @@ Define the code generation directly from the random DAG. module VeriFuzz.Graph.CodeGen ( generate - ) where + ) +where -import Data.Foldable (fold) -import Data.Graph.Inductive (Graph, LNode, Node, labNodes, pre) -import Data.Maybe (fromMaybe) -import Data.Text (Text) -import qualified Data.Text as T +import Data.Foldable ( fold ) +import Data.Graph.Inductive ( Graph + , LNode + , Node + , labNodes + , pre + ) +import Data.Maybe ( fromMaybe ) +import Data.Text ( Text ) +import qualified Data.Text as T import VeriFuzz.Circuit import VeriFuzz.Internal.Gen import VeriFuzz.Internal.Shared @@ -30,30 +36,33 @@ toOperator Xor = " ^ " statList :: Gate -> [Node] -> Maybe Text statList g n = toStr <$> safe tail n - where - toStr = fold . fmap ((<> toOperator g) . fromNode) + where toStr = fold . fmap ((<> toOperator g) . fromNode) lastEl :: [Node] -> Maybe Text lastEl n = fromNode <$> safe head n toStmnt :: (Graph gr) => gr Gate e -> LNode Gate -> Text toStmnt graph (n, g) = - fromMaybe T.empty $ Just " assign " <> Just (fromNode n) - <> Just " = " <> statList g nodeL <> lastEl nodeL <> Just ";\n" - where - nodeL = pre graph n + fromMaybe T.empty + $ Just " assign " + <> Just (fromNode n) + <> Just " = " + <> statList g nodeL + <> lastEl nodeL + <> Just ";\n" + where nodeL = pre graph n generate :: (Graph gr) => gr Gate e -> Text generate graph = "module generated_module(\n" - <> fold (imap " input wire " ",\n" inp) - <> T.intercalate ",\n" (imap " output wire " "" out) - <> ");\n" - <> fold (toStmnt graph <$> labNodes graph) - <> "endmodule\n\nmodule main;\n initial\n begin\n " - <> "$display(\"Hello, world\");\n $finish;\n " - <> "end\nendmodule" - where - inp = inputs graph - out = outputs graph - imap b e = fmap ((\s -> b <> s <> e) . fromNode) + <> fold (imap " input wire " ",\n" inp) + <> T.intercalate ",\n" (imap " output wire " "" out) + <> ");\n" + <> fold (toStmnt graph <$> labNodes graph) + <> "endmodule\n\nmodule main;\n initial\n begin\n " + <> "$display(\"Hello, world\");\n $finish;\n " + <> "end\nendmodule" + where + inp = inputs graph + out = outputs graph + imap b e = fmap ((\s -> b <> s <> e) . fromNode) diff --git a/src/VeriFuzz/Graph/Random.hs b/src/VeriFuzz/Graph/Random.hs index ef0a0c5..5b36c48 100644 --- a/src/VeriFuzz/Graph/Random.hs +++ b/src/VeriFuzz/Graph/Random.hs @@ -12,18 +12,21 @@ Define the random generation for the directed acyclic graph. module VeriFuzz.Graph.Random where -import Data.Graph.Inductive (Context, LEdge) -import qualified Data.Graph.Inductive as G -import Data.Graph.Inductive.PatriciaTree (Gr) -import Data.List (nub) -import Test.QuickCheck (Arbitrary, Gen) -import qualified Test.QuickCheck as QC +import Data.Graph.Inductive ( Context + , LEdge + ) +import qualified Data.Graph.Inductive as G +import Data.Graph.Inductive.PatriciaTree + ( Gr ) +import Data.List ( nub ) +import Test.QuickCheck ( Arbitrary + , Gen + ) +import qualified Test.QuickCheck as QC dupFolder :: (Eq a, Eq b) => Context a b -> [Context a b] -> [Context a b] -dupFolder cont ns = - unique cont : ns - where - unique (a, b, c, d) = (nub a, b, c, nub d) +dupFolder cont ns = unique cont : ns + where unique (a, b, c, d) = (nub a, b, c, nub d) -- | Remove duplicates. rDups :: (Eq a, Eq b) => Gr a b -> Gr a b @@ -33,26 +36,23 @@ rDups g = G.buildGr $ G.ufold dupFolder [] g -- `n` that is passed to it. arbitraryEdge :: (Arbitrary e) => Int -> Gen (LEdge e) arbitraryEdge n = do - x <- with $ \a -> a < n && a > 0 && a /= n-1 + x <- with $ \a -> a < n && a > 0 && a /= n - 1 y <- with $ \a -> x < a && a < n && a > 0 z <- QC.arbitrary return (x, y, z) - where - with = QC.suchThat $ QC.resize n QC.arbitrary + where with = QC.suchThat $ QC.resize n QC.arbitrary -- | Gen instance for a random acyclic DAG. -randomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) - => Gen (Gr l e) -- ^ The generated graph. It uses Arbitrary to +randomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) => Gen (Gr l e) -- ^ The generated graph. It uses Arbitrary to -- generate random instances of each node randomDAG = do list <- QC.infiniteListOf QC.arbitrary - l <- QC.infiniteListOf aE - QC.sized (\n -> return . G.mkGraph (nodes list n) $ take (10*n) l) - where - nodes l n = zip [0..n] $ take n l - aE = QC.sized arbitraryEdge + l <- QC.infiniteListOf aE + QC.sized (\n -> return . G.mkGraph (nodes list n) $ take (10 * n) l) + where + nodes l n = zip [0 .. n] $ take n l + aE = QC.sized arbitraryEdge -- | Generate a random acyclic DAG with an IO instance. -genRandomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) - => IO (Gr l e) +genRandomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) => IO (Gr l e) genRandomDAG = QC.generate randomDAG diff --git a/src/VeriFuzz/Graph/RandomAlt.hs b/src/VeriFuzz/Graph/RandomAlt.hs index 21ef678..c5fad9e 100644 --- a/src/VeriFuzz/Graph/RandomAlt.hs +++ b/src/VeriFuzz/Graph/RandomAlt.hs @@ -12,17 +12,18 @@ Define the random generation for the directed acyclic graph. module VeriFuzz.Graph.RandomAlt where -import qualified Data.Graph.Inductive.Arbitrary as G -import Data.Graph.Inductive.PatriciaTree (Gr) -import Test.QuickCheck (Arbitrary, Gen) -import qualified Test.QuickCheck as QC +import qualified Data.Graph.Inductive.Arbitrary + as G +import Data.Graph.Inductive.PatriciaTree + ( Gr ) +import Test.QuickCheck ( Arbitrary + , Gen + ) +import qualified Test.QuickCheck as QC -randomDAG :: (Arbitrary l, Arbitrary e) - => Gen (Gr l e) -randomDAG = - G.looplessGraph <$> QC.arbitrary +randomDAG :: (Arbitrary l, Arbitrary e) => Gen (Gr l e) +randomDAG = G.looplessGraph <$> QC.arbitrary -- | Generate a random acyclic DAG with an IO instance. -genRandomDAG :: (Arbitrary l, Arbitrary e) - => IO (Gr l e) +genRandomDAG :: (Arbitrary l, Arbitrary e) => IO (Gr l e) genRandomDAG = QC.generate randomDAG diff --git a/src/VeriFuzz/Internal/Gen.hs b/src/VeriFuzz/Internal/Gen.hs index be275dd..6e44524 100644 --- a/src/VeriFuzz/Internal/Gen.hs +++ b/src/VeriFuzz/Internal/Gen.hs @@ -12,18 +12,25 @@ Internal helpers for generation. module VeriFuzz.Internal.Gen where -import Data.Graph.Inductive (Graph, Node) -import qualified Data.Graph.Inductive as G -import qualified Data.Text as T +import Data.Graph.Inductive ( Graph + , Node + ) +import qualified Data.Graph.Inductive as G +import qualified Data.Text as T fromNode :: Int -> T.Text fromNode node = T.pack $ "w" <> show node filterGr :: (Graph gr) => gr n e -> (Node -> Bool) -> [Node] -filterGr graph f = - filter f $ G.nodes graph - -only :: (Graph gr) => gr n e -> (gr n e -> Node -> Int) -> (gr n e -> Node -> Int) -> Node -> Bool +filterGr graph f = filter f $ G.nodes graph + +only + :: (Graph gr) + => gr n e + -> (gr n e -> Node -> Int) + -> (gr n e -> Node -> Int) + -> Node + -> Bool only graph fun1 fun2 n = fun1 graph n == 0 && fun2 graph n /= 0 inputs :: (Graph gr) => gr n e -> [Node] diff --git a/src/VeriFuzz/Simulator.hs b/src/VeriFuzz/Simulator.hs index 0a2cf44..0692c31 100644 --- a/src/VeriFuzz/Simulator.hs +++ b/src/VeriFuzz/Simulator.hs @@ -15,7 +15,8 @@ module VeriFuzz.Simulator , module VeriFuzz.Simulator.Yosys , module VeriFuzz.Simulator.Xst , module VeriFuzz.Simulator.Icarus - ) where + ) +where import VeriFuzz.Simulator.General import VeriFuzz.Simulator.Icarus diff --git a/src/VeriFuzz/Simulator/General.hs b/src/VeriFuzz/Simulator/General.hs index 3615d3a..9001bf9 100644 --- a/src/VeriFuzz/Simulator/General.hs +++ b/src/VeriFuzz/Simulator/General.hs @@ -12,11 +12,11 @@ Class of the simulator and the synthesize tool. module VeriFuzz.Simulator.General where -import Data.Bits (shiftL) -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import Data.Text (Text) -import Prelude hiding (FilePath) +import Data.Bits ( shiftL ) +import Data.ByteString ( ByteString ) +import qualified Data.ByteString as B +import Data.Text ( Text ) +import Prelude hiding ( FilePath ) import Shelly import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Simulator/Icarus.hs b/src/VeriFuzz/Simulator/Icarus.hs index 1f5ad38..443f096 100644 --- a/src/VeriFuzz/Simulator/Icarus.hs +++ b/src/VeriFuzz/Simulator/Icarus.hs @@ -13,12 +13,12 @@ Icarus verilog module. module VeriFuzz.Simulator.Icarus where import Control.Lens -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import Data.Foldable (fold) +import Data.ByteString ( ByteString ) +import qualified Data.ByteString as B +import Data.Foldable ( fold ) import Data.Hashable -import Data.List (transpose) -import Prelude hiding (FilePath) +import Data.List ( transpose ) +import Prelude hiding ( FilePath ) import Shelly import VeriFuzz.Simulator.General import VeriFuzz.Verilog @@ -37,26 +37,29 @@ defaultIcarus :: Icarus defaultIcarus = Icarus "iverilog" "vvp" addDisplay :: [Stmnt] -> [Stmnt] -addDisplay s = - concat $ transpose [s, replicate l $ TimeCtrl 1 Nothing - , replicate l . SysTaskEnable $ Task "display" ["%h", Id "y"]] - where - l = length s +addDisplay s = concat $ transpose + [ s + , replicate l $ TimeCtrl 1 Nothing + , replicate l . SysTaskEnable $ Task "display" ["%h", Id "y"] + ] + where l = length s assignFunc :: [Port] -> ByteString -> Stmnt assignFunc inp bs = NonBlockAssign . Assign conc Nothing . Number (B.length bs * 4) $ bsToI bs - where - conc = RegConcat (portToExpr <$> inp) + where conc = RegConcat (portToExpr <$> inp) runSimIcarus :: Icarus -> ModDecl -> [ByteString] -> Sh Int runSimIcarus sim m bss = do - let tb = ModDecl "main" [] [] - [ Initial $ - fold (addDisplay $ assignFunc (m ^. modInPorts) <$> bss) + let tb = ModDecl + "main" + [] + [] + [ Initial + $ fold (addDisplay $ assignFunc (m ^. modInPorts) <$> bss) <> (SysTaskEnable $ Task "finish" []) ] - let newtb = instantiateMod m tb + let newtb = instantiateMod m tb let modWithTb = VerilogSrc $ Description <$> [newtb, m] writefile "main.v" $ genSource modWithTb run_ (icarusPath sim) ["-o", "main", "main.v"] diff --git a/src/VeriFuzz/Simulator/Xst.hs b/src/VeriFuzz/Simulator/Xst.hs index 16e9b97..3209caf 100644 --- a/src/VeriFuzz/Simulator/Xst.hs +++ b/src/VeriFuzz/Simulator/Xst.hs @@ -14,10 +14,10 @@ Xst (ise) simulator implementation. module VeriFuzz.Simulator.Xst where -import Control.Lens hiding ((<.>)) -import Prelude hiding (FilePath) +import Control.Lens hiding ( (<.>) ) +import Prelude hiding ( FilePath ) import Shelly -import Text.Shakespeare.Text (st) +import Text.Shakespeare.Text ( st ) import VeriFuzz.Simulator.General import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.CodeGen @@ -33,8 +33,10 @@ instance Synthesize Xst where runSynth = runSynthXst defaultXst :: Xst -defaultXst = Xst "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xst" "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/netgen" +defaultXst = Xst "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xst" + "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/netgen" +-- brittany-disable-next-binding runSynthXst :: Xst -> ModDecl -> FilePath -> Sh () runSynthXst sim m outf = do writefile xstFile [st|run diff --git a/src/VeriFuzz/Simulator/Yosys.hs b/src/VeriFuzz/Simulator/Yosys.hs index af950f2..028fbb2 100644 --- a/src/VeriFuzz/Simulator/Yosys.hs +++ b/src/VeriFuzz/Simulator/Yosys.hs @@ -15,10 +15,10 @@ Yosys simulator implementation. module VeriFuzz.Simulator.Yosys where import Control.Lens -import Data.Text (Text) -import Prelude hiding (FilePath) +import Data.Text ( Text ) +import Prelude hiding ( FilePath ) import Shelly -import Text.Shakespeare.Text (st) +import Text.Shakespeare.Text ( st ) import VeriFuzz.Simulator.General import VeriFuzz.Verilog @@ -33,6 +33,7 @@ instance Synthesize Yosys where defaultYosys :: Yosys defaultYosys = Yosys "/usr/bin/yosys" +-- brittany-disable-next-binding writeSimFile :: Yosys -- ^ Simulator instance -> ModDecl -- ^ Current module -> FilePath -- ^ Output sim file @@ -47,11 +48,12 @@ runSynthYosys :: Yosys -> ModDecl -> FilePath -> Sh () runSynthYosys sim m outf = do writefile inpf $ genSource m run_ (yosysPath sim) ["-q", "-b", "verilog -noattr", "-o", out, "-S", inp] - where - inpf = "rtl.v" - inp = toTextIgnore inpf - out = toTextIgnore outf + where + inpf = "rtl.v" + inp = toTextIgnore inpf + out = toTextIgnore outf +-- brittany-disable-next-binding writeSatFile :: (Synthesize a, Synthesize b) => Text -> a -> Maybe b -> ModDecl -> Sh () writeSatFile checkFile sim1 sim2 m = writefile (fromText checkFile) [st|read_verilog syn_#{toText sim1}.v @@ -69,10 +71,12 @@ sat -timeout 20 -verify-no-timeout -ignore_div_by_zero -prove y_1 y_2 #{modName} modName = m ^. moduleId . getIdentifier -- ids = T.intercalate "," $ allVars m ^.. traverse . getIdentifier +-- brittany-disable-next-binding runOtherSynth :: (Synthesize a) => Maybe a -> ModDecl -> Sh () runOtherSynth (Just sim) m = runSynth sim m $ fromText [st|syn_#{toText sim}.v|] runOtherSynth Nothing m = writefile "syn_rtl.v" $ genSource m +-- brittany-disable-next-binding runEquiv :: (Synthesize a, Synthesize b) => Yosys -> a -> Maybe b -> ModDecl -> Sh () runEquiv yosys sim1 sim2 m = do writefile "top.v" . genSource . initMod $ makeTop 2 m diff --git a/src/VeriFuzz/Verilog.hs b/src/VeriFuzz/Verilog.hs index 4e8ed22..6b6a13f 100644 --- a/src/VeriFuzz/Verilog.hs +++ b/src/VeriFuzz/Verilog.hs @@ -18,7 +18,8 @@ module VeriFuzz.Verilog -- * Verilog mutations , module VeriFuzz.Verilog.Mutate , module VeriFuzz.Verilog.Helpers - ) where + ) +where import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.CodeGen diff --git a/src/VeriFuzz/Verilog/AST.hs b/src/VeriFuzz/Verilog/AST.hs index 35f678f..dd61f03 100644 --- a/src/VeriFuzz/Verilog/AST.hs +++ b/src/VeriFuzz/Verilog/AST.hs @@ -15,53 +15,112 @@ Defines the types to build a Verilog AST. module VeriFuzz.Verilog.AST ( -- * Top level types - VerilogSrc(..), getVerilogSrc - , Description(..), getDescription + VerilogSrc(..) + , getVerilogSrc + , Description(..) + , getDescription -- * Primitives -- ** Identifier - , Identifier(..), getIdentifier + , Identifier(..) + , getIdentifier -- ** Control - , Delay(..), getDelay + , Delay(..) + , getDelay , Event(..) -- ** Operators , BinaryOperator(..) , UnaryOperator(..) -- ** Task - , Task(..), taskName, taskExpr + , Task(..) + , taskName + , taskExpr -- ** Left hand side value - , LVal(..), regId, regExprId, regExpr, regSizeId, regSizeMSB - , regSizeLSB, regConc + , LVal(..) + , regId + , regExprId + , regExpr + , regSizeId + , regSizeMSB + , regSizeLSB + , regConc -- ** Ports , PortDir(..) - , PortType(..), regSigned - , Port(..), portType, portSize, portName + , PortType(..) + , regSigned + , Port(..) + , portType + , portSize + , portName -- * Expression - , Expr(..), exprSize, exprVal, exprId, exprConcat - , exprUnOp, exprPrim, exprLhs, exprBinOp, exprRhs - , exprCond, exprTrue, exprFalse, exprStr, traverseExpr - , ConstExpr(..), constNum + , Expr(..) + , exprSize + , exprVal + , exprId + , exprConcat + , exprUnOp + , exprPrim + , exprLhs + , exprBinOp + , exprRhs + , exprCond + , exprTrue + , exprFalse + , exprStr + , traverseExpr + , ConstExpr(..) + , constNum -- * Assignment - , Assign(..), assignReg, assignDelay, assignExpr - , ContAssign(..), contAssignNetLVal, contAssignExpr + , Assign(..) + , assignReg + , assignDelay + , assignExpr + , ContAssign(..) + , contAssignNetLVal + , contAssignExpr -- * Statment - , Stmnt(..), statDelay, statDStat, statEvent, statEStat, statements - , stmntBA, stmntNBA, stmntCA, stmntTask, stmntSysTask + , Stmnt(..) + , statDelay + , statDStat + , statEvent + , statEStat + , statements + , stmntBA + , stmntNBA + , stmntCA + , stmntTask + , stmntSysTask -- * Module - , ModDecl(..), moduleId, modOutPorts, modInPorts, modItems - , ModItem(..), _ModCA, modInstId, modInstName, modInstConns, declDir, declPort - , ModConn(..), modConn - ) where - -import Control.Lens (makeLenses, makePrisms) -import Control.Monad (replicateM) -import Data.String (IsString, fromString) -import Data.Text (Text) -import qualified Data.Text as T -import Data.Traversable (sequenceA) -import qualified Test.QuickCheck as QC + , ModDecl(..) + , moduleId + , modOutPorts + , modInPorts + , modItems + , ModItem(..) + , _ModCA + , modInstId + , modInstName + , modInstConns + , declDir + , declPort + , ModConn(..) + , modConn + ) +where + +import Control.Lens ( makeLenses + , makePrisms + ) +import Control.Monad ( replicateM ) +import Data.String ( IsString + , fromString + ) +import Data.Text ( Text ) +import qualified Data.Text as T +import Data.Traversable ( sequenceA ) +import qualified Test.QuickCheck as QC positiveArb :: (QC.Arbitrary a, Ord a, Num a) => QC.Gen a -positiveArb = QC.suchThat QC.arbitrary (>0) +positiveArb = QC.suchThat QC.arbitrary (> 0) -- | Identifier in Verilog. This is just a string of characters that can either -- be lowercase and uppercase for now. This might change in the future though, @@ -232,23 +291,24 @@ expr n [ Id <$> QC.arbitrary , Number <$> positiveArb <*> QC.arbitrary , Concat <$> QC.listOf1 (subexpr 4) - , UnOp <$> QC.arbitrary <*> QC.arbitrary + , 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) + where subexpr y = expr (n `div` y) instance QC.Arbitrary Expr where arbitrary = QC.sized expr traverseExpr :: (Applicative f) => (Expr -> f Expr) -> Expr -> f Expr -traverseExpr f (Concat e) = Concat <$> sequenceA (f <$> e) -traverseExpr f (UnOp un e) = UnOp un <$> f e +traverseExpr f (Concat e ) = Concat <$> sequenceA (f <$> e) +traverseExpr f (UnOp un e ) = UnOp un <$> f e traverseExpr f (BinOp l op r) = BinOp <$> f l <*> pure op <*> f r -traverseExpr f (Cond c l r) = Cond <$> f c <*> f l <*> f r +traverseExpr f (Cond c l r) = Cond <$> f c <*> f l <*> f r traverseExpr _ e = pure e makeLenses ''Expr @@ -409,8 +469,7 @@ statement n , SysTaskEnable <$> QC.arbitrary ] | otherwise = statement 0 - where - substat y = statement (n `div` y) + where substat y = statement (n `div` y) instance QC.Arbitrary Stmnt where arbitrary = QC.sized statement diff --git a/src/VeriFuzz/Verilog/CodeGen.hs b/src/VeriFuzz/Verilog/CodeGen.hs index fbc2fc1..338838f 100644 --- a/src/VeriFuzz/Verilog/CodeGen.hs +++ b/src/VeriFuzz/Verilog/CodeGen.hs @@ -15,12 +15,14 @@ This module generates the code from the Verilog AST defined in module VeriFuzz.Verilog.CodeGen where -import Control.Lens (view, (^.)) -import Data.Foldable (fold) -import Data.Text (Text) -import qualified Data.Text as T -import qualified Data.Text.IO as T -import Numeric (showHex) +import Control.Lens ( view + , (^.) + ) +import Data.Foldable ( fold ) +import Data.Text ( Text ) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import Numeric ( showHex ) import VeriFuzz.Verilog.AST -- | 'Source' class which determines that source code is able to be generated @@ -44,29 +46,30 @@ defMap = maybe ";\n" genStmnt -- | Convert the 'VerilogSrc' type to 'Text' so that it can be rendered. genVerilogSrc :: VerilogSrc -> Text -genVerilogSrc source = - fold $ genDescription <$> source ^. getVerilogSrc +genVerilogSrc source = fold $ genDescription <$> source ^. getVerilogSrc -- | Generate the 'Description' to 'Text'. genDescription :: Description -> Text -genDescription desc = - genModuleDecl $ desc ^. getDescription +genDescription desc = genModuleDecl $ desc ^. getDescription -- | Generate the 'ModDecl' for a module and convert it to 'Text'. genModuleDecl :: ModDecl -> Text genModuleDecl m = - "module " <> m ^. moduleId . getIdentifier - <> ports <> ";\n" - <> modI - <> "endmodule\n" - where - ports - | noIn && noOut = "" - | otherwise = "(" <> comma (genModPort <$> outIn) <> ")" - modI = fold $ genModuleItem <$> m ^. modItems - noOut = null $ m ^. modOutPorts - noIn = null $ m ^. modInPorts - outIn = (m ^. modOutPorts) ++ (m ^. modInPorts) + "module " + <> m + ^. moduleId + . getIdentifier + <> ports + <> ";\n" + <> modI + <> "endmodule\n" + where + ports | noIn && noOut = "" + | otherwise = "(" <> comma (genModPort <$> outIn) <> ")" + modI = fold $ genModuleItem <$> m ^. modItems + noOut = null $ m ^. modOutPorts + noIn = null $ m ^. modInPorts + outIn = (m ^. modOutPorts) ++ (m ^. modInPorts) -- | Conversts 'Port' to 'Text' for the module list, which means it only -- generates a list of identifiers. @@ -75,14 +78,12 @@ genModPort port = port ^. portName . getIdentifier -- | Generate the 'Port' description. genPort :: Port -> Text -genPort port = - t <> size <> name - where - t = (<>" ") . genPortType $ port ^. portType - size - | port ^. portSize > 1 = "[" <> showT (port ^. portSize - 1) <> ":0] " - | otherwise = "" - name = port ^. portName . getIdentifier +genPort port = t <> size <> name + where + t = (<> " ") . genPortType $ port ^. portType + size | port ^. portSize > 1 = "[" <> showT (port ^. portSize - 1) <> ":0] " + | otherwise = "" + name = port ^. portName . getIdentifier -- | Convert the 'PortDir' type to 'Text'. genPortDir :: PortDir -> Text @@ -96,30 +97,26 @@ genModuleItem (ModCA ca) = genContAssign ca genModuleItem (ModInst (Identifier i) (Identifier name) conn) = i <> " " <> name <> "(" <> comma (genExpr . _modConn <$> conn) <> ")" <> ";\n" genModuleItem (Initial stat) = "initial " <> genStmnt stat -genModuleItem (Always stat) = "always " <> genStmnt stat +genModuleItem (Always stat) = "always " <> genStmnt stat genModuleItem (Decl dir port) = (maybe "" makePort dir) <> genPort port <> ";\n" - where - makePort = (<>" ") . genPortDir + where makePort = (<> " ") . genPortDir -- | Generate continuous assignment genContAssign :: ContAssign -> Text -genContAssign (ContAssign val e) = - "assign " <> name <> " = " <> expr <> ";\n" - where - name = val ^. getIdentifier - expr = genExpr e +genContAssign (ContAssign val e) = "assign " <> name <> " = " <> expr <> ";\n" + where + name = val ^. getIdentifier + expr = genExpr e -- | Generate 'Expr' to 'Text'. genExpr :: Expr -> Text genExpr (BinOp eRhs bin eLhs) = "(" <> genExpr eRhs <> genBinaryOperator bin <> genExpr eLhs <> ")" -genExpr (Number s n) = - showT s <> "'h" <> T.pack (showHex n "") -genExpr (Id i) = i ^. getIdentifier -genExpr (Concat c) = "{" <> comma (genExpr <$> c) <> "}" -genExpr (UnOp u e) = - "(" <> genUnaryOperator u <> genExpr e <> ")" +genExpr (Number s n) = showT s <> "'h" <> T.pack (showHex n "") +genExpr (Id i ) = i ^. getIdentifier +genExpr (Concat c ) = "{" <> comma (genExpr <$> c) <> "}" +genExpr (UnOp u e ) = "(" <> genUnaryOperator u <> genExpr e <> ")" genExpr (Cond l t f) = "(" <> genExpr l <> " ? " <> genExpr t <> " : " <> genExpr f <> ")" genExpr (Str t) = "\"" <> t <> "\"" @@ -167,7 +164,7 @@ genUnaryOperator UnNxorInv = "^~" -- | Generate verilog code for an 'Event'. genEvent :: Event -> Text -genEvent (EId i) = "@(" <> i ^. getIdentifier <> ")" +genEvent (EId i ) = "@(" <> i ^. getIdentifier <> ")" genEvent (EExpr expr) = "@(" <> genExpr expr <> ")" genEvent EAll = "@*" @@ -177,44 +174,45 @@ genDelay (Delay i) = "#" <> showT i -- | Generate the verilog code for an 'LVal'. genLVal :: LVal -> Text -genLVal (RegId i) = i ^. getIdentifier -genLVal (RegExpr i expr) = - i ^. getIdentifier <> " [" <> genExpr expr <> "]" +genLVal (RegId i ) = i ^. getIdentifier +genLVal (RegExpr i expr) = i ^. getIdentifier <> " [" <> genExpr expr <> "]" genLVal (RegSize i msb lsb) = - i ^. getIdentifier <> " [" <> genConstExpr msb <> ":" <> genConstExpr lsb <> "]" -genLVal (RegConcat e) = - "{" <> comma (genExpr <$> e) <> "}" + i + ^. getIdentifier + <> " [" + <> genConstExpr msb + <> ":" + <> genConstExpr lsb + <> "]" +genLVal (RegConcat e) = "{" <> comma (genExpr <$> e) <> "}" genConstExpr :: ConstExpr -> Text genConstExpr (ConstExpr num) = showT num genPortType :: PortType -> Text genPortType Wire = "wire" -genPortType (Reg signed) - | signed = "reg signed" - | otherwise = "reg" +genPortType (Reg signed) | signed = "reg signed" + | otherwise = "reg" genAssign :: Text -> Assign -> Text genAssign op (Assign r d e) = genLVal r <> op <> maybe "" genDelay d <> genExpr e genStmnt :: Stmnt -> Text -genStmnt (TimeCtrl d stat) = genDelay d <> " " <> defMap stat -genStmnt (EventCtrl e stat) = genEvent e <> " " <> defMap stat -genStmnt (SeqBlock s) = - "begin\n" <> fold (genStmnt <$> s) <> "end\n" -genStmnt (BlockAssign a) = genAssign " = " a <> ";\n" -genStmnt (NonBlockAssign a) = genAssign " <= " a <> ";\n" -genStmnt (StatCA a) = genContAssign a -genStmnt (TaskEnable task) = genTask task <> ";\n" -genStmnt (SysTaskEnable task) = "$" <> genTask task <> ";\n" +genStmnt (TimeCtrl d stat ) = genDelay d <> " " <> defMap stat +genStmnt (EventCtrl e stat ) = genEvent e <> " " <> defMap stat +genStmnt (SeqBlock s ) = "begin\n" <> fold (genStmnt <$> s) <> "end\n" +genStmnt (BlockAssign a ) = genAssign " = " a <> ";\n" +genStmnt (NonBlockAssign a ) = genAssign " <= " a <> ";\n" +genStmnt (StatCA a ) = genContAssign a +genStmnt (TaskEnable task) = genTask task <> ";\n" +genStmnt (SysTaskEnable task) = "$" <> genTask task <> ";\n" genTask :: Task -> Text genTask (Task name expr) | null expr = i | otherwise = i <> "(" <> comma (genExpr <$> expr) <> ")" - where - i = name ^. getIdentifier + where i = name ^. getIdentifier -- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'. render :: (Source a) => a -> IO () diff --git a/src/VeriFuzz/Verilog/Helpers.hs b/src/VeriFuzz/Verilog/Helpers.hs index 554b8ba..53d219b 100644 --- a/src/VeriFuzz/Verilog/Helpers.hs +++ b/src/VeriFuzz/Verilog/Helpers.hs @@ -13,7 +13,7 @@ Defaults and common functions. module VeriFuzz.Verilog.Helpers where import Control.Lens -import Data.Text (Text) +import Data.Text ( Text ) import VeriFuzz.Verilog.AST regDecl :: Identifier -> ModItem @@ -38,16 +38,16 @@ addDescription :: Description -> VerilogSrc -> VerilogSrc addDescription desc = getVerilogSrc %~ (:) desc testBench :: ModDecl -testBench = - ModDecl "main" [] [] +testBench = ModDecl + "main" + [] + [] [ regDecl "a" , regDecl "b" , wireDecl "c" - , ModInst "and" "and_gate" - [ ModConn $ Id "c" - , ModConn $ Id "a" - , ModConn $ Id "b" - ] + , ModInst "and" + "and_gate" + [ModConn $ Id "c", ModConn $ Id "a", ModConn $ Id "b"] , Initial $ SeqBlock [ BlockAssign . Assign (RegId "a") Nothing $ Number 1 1 , BlockAssign . Assign (RegId "b") Nothing $ Number 1 1 diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs index eddb93a..bca1c39 100644 --- a/src/VeriFuzz/Verilog/Mutate.hs +++ b/src/VeriFuzz/Verilog/Mutate.hs @@ -14,7 +14,9 @@ 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.Maybe ( catMaybes + , fromMaybe + ) import VeriFuzz.Internal.Gen import VeriFuzz.Internal.Shared import VeriFuzz.Verilog.AST @@ -23,27 +25,25 @@ 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 + 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 +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 i expr (Id id') | id' == i = expr + | otherwise = Id id' idTrans _ _ e = e -- | Replaces the identifier recursively in an expression. @@ -58,27 +58,28 @@ replace = (transformOf traverseExpr .) . idTrans -- 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 + | 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 +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] + foldl (flip nestSource) src $ Identifier . fromNode <$> [1 .. i] allVars :: ModDecl -> [Identifier] allVars m = - (m ^.. modOutPorts . traverse . portName) ++ (m ^.. modInPorts . traverse . portName) + (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" [] [] []) @@ -95,14 +96,21 @@ allVars m = -- endmodule -- 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 ^. moduleId) (m ^. moduleId <> (Identifier . showT $ count+1)) conns - count = length . filter (==m ^. moduleId) $ main ^.. modItems . traverse . modInstId - conns = ModConn . Id <$> allVars m +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 ^. moduleId) + (m ^. moduleId <> (Identifier . showT $ count + 1)) + conns + count = + length + . filter (== m ^. moduleId) + $ 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. @@ -111,11 +119,13 @@ instantiateMod m main = -- m m(y, x); -- instantiateMod_ :: ModDecl -> ModItem -instantiateMod_ m = - ModInst (m ^. moduleId) (m ^. moduleId) conns - where - conns = ModConn . Id <$> - (m ^.. modOutPorts . traverse . portName) ++ (m ^.. modInPorts . traverse . portName) +instantiateMod_ m = ModInst (m ^. moduleId) (m ^. moduleId) conns + where + conns = + ModConn + . Id + <$> (m ^.. modOutPorts . traverse . portName) + ++ (m ^.. modInPorts . traverse . portName) -- | Initialise all the inputs and outputs to a module. -- @@ -126,23 +136,24 @@ instantiateMod_ m = -- endmodule -- initMod :: ModDecl -> ModDecl -initMod m = m & modItems %~ ((out ++ inp)++) - where - out = Decl (Just PortOut) <$> (m ^. modOutPorts) - inp = Decl (Just PortIn) <$> (m ^. modInPorts) +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 +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 ^. moduleId) ys (m ^. modInPorts) modIt - where - ys = Port Wire 90 . (flip makeIdFrom) "y" <$> [1..i] - modIt = instantiateMod_ . modN <$> [1..i] - modN n = m - & moduleId %~ makeIdFrom n - & modOutPorts .~ [Port Wire 90 (makeIdFrom n "y")] +makeTop i m = ModDecl (m ^. moduleId) ys (m ^. modInPorts) modIt + where + ys = Port Wire 90 . (flip makeIdFrom) "y" <$> [1 .. i] + modIt = instantiateMod_ . modN <$> [1 .. i] + modN n = + m + & moduleId + %~ makeIdFrom n + & modOutPorts + .~ [Port Wire 90 (makeIdFrom n "y")] -- cgit