From 60e28636ef7f102073c3f3366fdede84a8151f48 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Mon, 20 May 2019 17:16:11 +0100 Subject: Fix warning on CI --- src/VeriFuzz/Fuzz.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 4f5c016..77962b5 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -91,8 +91,8 @@ synthesisers = lift $ asks getSynthesisers --simulators :: (Monad m) => Fuzz () m [SimTool] --simulators = lift $ asks getSimulators -combinations :: [a] -> [b] -> [(a, b)] -combinations l1 l2 = [ (x, y) | x <- l1, y <- l2 ] +--combinations :: [a] -> [b] -> [(a, b)] +--combinations l1 l2 = [ (x, y) | x <- l1, y <- l2 ] logT :: MonadSh m => Text -> m () logT = liftSh . logger -- cgit From dc15e7506096064fcb3fd297b15fc89c83ff32d0 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 12:00:11 +0100 Subject: Add only identity --- src/VeriFuzz/Verilog/Gen.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index 96a90f9..f4c49be 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -459,7 +459,7 @@ calcRange ps i (Range l r) = eval l - eval r + 1 moduleDef :: Maybe Identifier -> StateGen ModDecl moduleDef top = do name <- moduleName top - portList <- some $ nextPort Wire + portList <- Hog.list (Hog.linear 4 10) $ nextPort Wire mi <- Hog.list (Hog.linear 4 100) modItem ps <- many parameter context <- get -- cgit From 238ef567f11c0f07f6b9834ef2199117485ba273 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 15:24:45 +0100 Subject: Remove logging from within tools --- src/VeriFuzz/Sim/Icarus.hs | 2 -- src/VeriFuzz/Sim/Quartus.hs | 5 +---- src/VeriFuzz/Sim/Vivado.hs | 2 -- src/VeriFuzz/Sim/XST.hs | 17 ++++++----------- src/VeriFuzz/Sim/Yosys.hs | 10 ++-------- 5 files changed, 9 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs index 423d51b..6c5751a 100644 --- a/src/VeriFuzz/Sim/Icarus.hs +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -117,10 +117,8 @@ runSimIcarusWithFile :: Icarus -> FilePath -> [ByteString] -> ResultSh ByteString runSimIcarusWithFile sim f _ = annotate SimFail . liftSh $ do dir <- pwd - logger "Icarus: Compile" logCommand_ dir "icarus" $ run (icarusPath sim) ["-o", "main", toTextIgnore f] - logger "Icarus: Run" B.take 8 . BA.convert . (hash :: ByteString -> Digest SHA256) <$> logCommand dir "vvp" diff --git a/src/VeriFuzz/Sim/Quartus.hs b/src/VeriFuzz/Sim/Quartus.hs index ece00eb..4007004 100644 --- a/src/VeriFuzz/Sim/Quartus.hs +++ b/src/VeriFuzz/Sim/Quartus.hs @@ -52,9 +52,7 @@ runSynthQuartus :: Quartus -> SourceInfo -> ResultSh () runSynthQuartus sim (SourceInfo top src) = do dir <- liftSh pwd let ex = execute_ SynthFail dir "quartus" - liftSh $ do - writefile inpf $ genSource src - logger "Running Quartus synthesis" + liftSh . writefile inpf $ genSource src ex (exec "quartus_map") [top, "--source=" <> toTextIgnore inpf, "--family=Cyclone V"] ex (exec "quartus_fit") [top, "--part=5CGTFD9E5F35C7N"] @@ -68,7 +66,6 @@ runSynthQuartus sim (SourceInfo top src) = do , "s,^// DATE.*,,; s,^tri1 (.*);,wire \\1 = 1;,; /^\\/\\/ +synopsys/ d;" , toTextIgnore $ synthOutput sim ] - logger "Quartus synthesis done" where inpf = "rtl.v" exec s = maybe (fromText s) ( fromText s) $ quartusBin sim diff --git a/src/VeriFuzz/Sim/Vivado.hs b/src/VeriFuzz/Sim/Vivado.hs index ee67a78..9f48188 100644 --- a/src/VeriFuzz/Sim/Vivado.hs +++ b/src/VeriFuzz/Sim/Vivado.hs @@ -57,12 +57,10 @@ runSynthVivado sim (SourceInfo top src) = do sim writefile "rtl.v" $ genSource src run_ "sed" ["s/^module/(* use_dsp=\"no\" *) module/;", "-i", "rtl.v"] - logger "Vivado: run" let exec_ n = execute_ SynthFail dir "vivado" (maybe (fromText n) ( fromText n) $ vivadoBin sim) exec_ "vivado" ["-mode", "batch", "-source", toTextIgnore vivadoTcl] - liftSh $ logger "Vivado: done" where vivadoTcl = fromText ("vivado_" <> top) <.> "tcl" diff --git a/src/VeriFuzz/Sim/XST.hs b/src/VeriFuzz/Sim/XST.hs index 11be094..71a4e1b 100644 --- a/src/VeriFuzz/Sim/XST.hs +++ b/src/VeriFuzz/Sim/XST.hs @@ -64,9 +64,7 @@ runSynthXST sim (SourceInfo top src) = do writefile xstFile $ xstSynthConfig top writefile prjFile [st|verilog work "rtl.v"|] writefile "rtl.v" $ genSource src - logger "XST: run" exec "xst" ["-ifn", toTextIgnore xstFile] - liftSh $ logger "XST: netgen" exec "netgen" [ "-w" @@ -75,15 +73,12 @@ runSynthXST sim (SourceInfo top src) = do , toTextIgnore $ modFile <.> "ngc" , toTextIgnore $ synthOutput sim ] - liftSh $ do - logger "XST: clean" - noPrint $ run_ - "sed" - [ "-i" - , "/^`ifndef/,/^`endif/ d; s/ *Timestamp: .*//;" - , toTextIgnore $ synthOutput sim - ] - logger "XST: done" + liftSh . noPrint $ run_ + "sed" + [ "-i" + , "/^`ifndef/,/^`endif/ d; s/ *Timestamp: .*//;" + , toTextIgnore $ synthOutput sim + ] where modFile = fromText top xstFile = modFile <.> "xst" diff --git a/src/VeriFuzz/Sim/Yosys.hs b/src/VeriFuzz/Sim/Yosys.hs index 3081a65..472af1f 100644 --- a/src/VeriFuzz/Sim/Yosys.hs +++ b/src/VeriFuzz/Sim/Yosys.hs @@ -65,13 +65,11 @@ runSynthYosys :: Yosys -> SourceInfo -> ResultSh () runSynthYosys sim (SourceInfo _ src) = ( SynthFail) . liftSh $ do dir <- pwd writefile inpf $ genSource src - logger "Yosys: synthesis" logCommand_ dir "yosys" $ timeout (yosysPath sim) [ "-p" , "read -formal " <> inp <> "; synth; write_verilog -noattr " <> out ] - logger "Yosys: synthesis done" where inpf = "rtl.v" inp = toTextIgnore inpf @@ -95,10 +93,7 @@ runEquivYosys yosys sim1 sim2 srcInfo = do writefile checkFile $ yosysSatConfig sim1 sim2 srcInfo runSynth sim1 srcInfo runSynth sim2 srcInfo - liftSh $ do - logger "Yosys: equivalence check" - run_ (yosysPath yosys) [toTextIgnore checkFile] - logger "Yosys: equivalence done" + liftSh $ run_ (yosysPath yosys) [toTextIgnore checkFile] where checkFile = fromText [st|test.#{toText sim1}.#{toText sim2}.ys|] runEquiv @@ -115,12 +110,11 @@ runEquiv sim1 sim2 srcInfo = do replaceMods (synthOutput sim1) "_1" srcInfo replaceMods (synthOutput sim2) "_2" srcInfo writefile "proof.sby" $ sbyConfig sim1 sim2 srcInfo - liftSh $ logger "Running SymbiYosys" e <- liftSh $ do exe dir "symbiyosys" "sby" ["-f", "proof.sby"] lastExitCode case e of - 0 -> liftSh $ logger "SymbiYosys equivalence check passed" + 0 -> ResultT . return $ Pass () 2 -> ResultT . return $ Fail EquivFail 124 -> ResultT . return $ Fail TimeoutError _ -> ResultT . return $ Fail EquivError -- cgit From d8dd3a04fd820fddc12d1ea46818ed1b1167e9ac Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 15:24:58 +0100 Subject: Remove unused function --- src/VeriFuzz/Verilog/Gen.hs | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index f4c49be..bd80c3d 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -231,9 +231,6 @@ someI m f = do amount <- gen $ Hog.int (Hog.linear 1 m) replicateM amount f -some :: StateGen a -> StateGen [a] -some = someI 50 - many :: StateGen a -> StateGen [a] many f = do amount <- gen $ Hog.int (Hog.linear 0 50) -- cgit From 4aaa96066c1b8df14f36db99a2606eb3ddb1506f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 15:25:10 +0100 Subject: Switch meaning of Semigroup --- src/VeriFuzz/Result.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Result.hs b/src/VeriFuzz/Result.hs index 4d1f5b8..77aa5b3 100644 --- a/src/VeriFuzz/Result.hs +++ b/src/VeriFuzz/Result.hs @@ -42,7 +42,7 @@ data Result a b = Fail a deriving (Eq, Show) instance Semigroup (Result a b) where - Fail _ <> b = b + Pass _ <> a = a a <> _ = a instance (Monoid b) => Monoid (Result a b) where -- cgit From 751edc28943ed5e56dc7fce42f63f4bb8728686f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 15:25:22 +0100 Subject: Add more fields to the FuzzReport --- src/VeriFuzz/Report.hs | 179 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 145 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Report.hs b/src/VeriFuzz/Report.hs index 2edd31e..53e77ba 100644 --- a/src/VeriFuzz/Report.hs +++ b/src/VeriFuzz/Report.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE RankNTypes #-} {-| Module : VeriFuzz.Report Description : Generate a report from a fuzz run. @@ -16,12 +17,18 @@ module VeriFuzz.Report ( SynthTool(..) , SynthStatus(..) , SynthResult(..) + , SimResult(..) , SimTool(..) , FuzzReport(..) , printResultReport + , printSummary , synthResults , simResults , synthStatus + , equivTime + , fuzzDir + , reducTime + , synthTime , defaultIcarusSim , defaultVivadoSynth , defaultYosysSynth @@ -34,18 +41,25 @@ module VeriFuzz.Report where import Control.DeepSeq (NFData, rnf) -import Control.Lens hiding (Identity) +import Control.Lens hiding (Identity, (<.>)) +import Data.Bifunctor (bimap) import Data.ByteString (ByteString) import Data.Maybe (fromMaybe) +import Data.Monoid (Endo) import Data.Text (Text) import Data.Text.Lazy (toStrict) +import Data.Time +import Data.Vector (fromList) import Prelude hiding (FilePath) -import Shelly (fromText) +import Shelly (FilePath, fromText, + toTextIgnore, (<.>), ()) +import Statistics.Sample (meanVariance) import Text.Blaze.Html (Html, (!)) import Text.Blaze.Html.Renderer.Text (renderHtml) import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as A import VeriFuzz.Config +import VeriFuzz.Internal import VeriFuzz.Result import VeriFuzz.Sim import VeriFuzz.Sim.Internal @@ -139,46 +153,54 @@ defaultIcarusSim = IcarusSim defaultIcarus -- | The results from running a tool through a simulator. It can either fail or -- return a result, which is most likely a 'ByteString'. -data SimResult = SimResult !SynthTool !SimTool !BResult +data SimResult = SimResult !SynthTool !SimTool !BResult !NominalDiffTime deriving (Eq) instance Show SimResult where - show (SimResult synth sim r) = show synth <> ", " <> show sim <> ": " <> show r + show (SimResult synth sim r d) = show synth <> ", " <> show sim <> ": " <> show r <> " (" <> show d <> ")" + +getSimResult :: SimResult -> UResult +getSimResult (SimResult _ _ (Pass _) _) = Pass () +getSimResult (SimResult _ _ (Fail b) _) = Fail b -- | The results of comparing the synthesised outputs of two files using a -- formal equivalence checker. This will either return a failure or an output -- which is most likely '()'. -data SynthResult = SynthResult !SynthTool !SynthTool !UResult +data SynthResult = SynthResult !SynthTool !SynthTool !UResult !NominalDiffTime deriving (Eq) instance Show SynthResult where - show (SynthResult synth synth2 r) = show synth <> ", " <> show synth2 <> ": " <> show r + show (SynthResult synth synth2 r d) = show synth <> ", " <> show synth2 <> ": " <> show r <> " (" <> show d <> ")" + +getSynthResult :: SynthResult -> UResult +getSynthResult (SynthResult _ _ a _) = a -- | The status of the synthesis using a simulator. This will be checked before -- attempting to run the equivalence checks on the simulator, as that would be -- unnecessary otherwise. -data SynthStatus = SynthStatus !SynthTool !UResult +data SynthStatus = SynthStatus !SynthTool !UResult !NominalDiffTime deriving (Eq) +getSynthStatus :: SynthStatus -> UResult +getSynthStatus (SynthStatus _ a _) = a + instance Show SynthStatus where - show (SynthStatus synth r) = "synthesis " <> show synth <> ": " <> show r + show (SynthStatus synth r d) = "synthesis " <> show synth <> ": " <> show r <> " (" <> show d <> ")" -- | The complete state that will be used during fuzzing, which contains the -- results from all the operations. -data FuzzReport = FuzzReport { _synthResults :: ![SynthResult] +data FuzzReport = FuzzReport { _fuzzDir :: {-# UNPACK #-} !FilePath + , _synthResults :: ![SynthResult] , _simResults :: ![SimResult] , _synthStatus :: ![SynthStatus] + , _synthTime :: {-# UNPACK #-} !NominalDiffTime + , _equivTime :: {-# UNPACK #-} !NominalDiffTime + , _reducTime :: {-# UNPACK #-} !NominalDiffTime } deriving (Eq, Show) $(makeLenses ''FuzzReport) -instance Semigroup FuzzReport where - FuzzReport a1 b1 c1 <> FuzzReport a2 b2 c2 = FuzzReport (a1 <> a2) (b1 <> b2) (c1 <> c2) - -instance Monoid FuzzReport where - mempty = FuzzReport [] [] [] - descriptionToSim :: SimDescription -> SimTool descriptionToSim (SimDescription "icarus") = defaultIcarusSim descriptionToSim s = @@ -201,11 +223,11 @@ descriptionToSynth (SynthDescription "xst" bin desc out) = descriptionToSynth (SynthDescription "quartus" bin desc out) = QuartusSynth . Quartus (fromText <$> bin) - (fromMaybe (quartusDesc defaultQuartus) $ desc) + (fromMaybe (quartusDesc defaultQuartus) desc) $ maybe (quartusOutput defaultQuartus) fromText out descriptionToSynth (SynthDescription "identity" _ desc out) = IdentitySynth - . Identity (fromMaybe (identityDesc defaultIdentity) $ desc) + . Identity (fromMaybe (identityDesc defaultIdentity) desc) $ maybe (identityOutput defaultIdentity) fromText out descriptionToSynth s = error $ "Could not find implementation for synthesiser '" <> show s <> "'" @@ -220,42 +242,46 @@ status (Fail EquivError ) = H.td ! A.class_ "is-danger" $ "Equivalence error" status (Fail TimeoutError) = H.td ! A.class_ "is-warning" $ "Time out" synthStatusHtml :: SynthStatus -> Html -synthStatusHtml (SynthStatus synth res) = H.tr $ do +synthStatusHtml (SynthStatus synth res diff) = H.tr $ do H.td . H.toHtml $ toText synth status res + H.td . H.toHtml $ showT diff synthResultHtml :: SynthResult -> Html -synthResultHtml (SynthResult synth1 synth2 res) = H.tr $ do +synthResultHtml (SynthResult synth1 synth2 res diff) = H.tr $ do H.td . H.toHtml $ toText synth1 H.td . H.toHtml $ toText synth2 status res + H.td . H.toHtml $ showT diff + +resultHead :: Text -> Html +resultHead name = H.head $ do + H.title $ "Fuzz Report - " <> H.toHtml name + H.meta ! A.name "viewport" ! A.content "width=device-width, initial-scale=1" + H.meta ! A.charset "utf8" + H.link + ! A.rel "stylesheet" + ! A.href + "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" resultReport :: Text -> FuzzReport -> Html -resultReport name (FuzzReport synth _ stat) = H.docTypeHtml $ do - H.head $ do - H.title $ "Fuzz Report - " <> H.toHtml name - H.meta ! A.name "viewport" ! A.content - "width=device-width, initial-scale=1" - H.meta ! A.charset "utf8" - H.link - ! A.rel "stylesheet" - ! A.href - "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" +resultReport name (FuzzReport _ synth _ stat _ _ _) = H.docTypeHtml $ do + resultHead name H.body . (H.section ! A.class_ "section") . (H.div ! A.class_ "container") $ do - H.h1 ! A.class_ "title" $ "Fuzz Report - " <> H.toHtml name - H.h2 ! A.class_ "subtitle" $ "Synthesis Failure" + H.h1 ! A.class_ "title is-1" $ "Fuzz Report - " <> H.toHtml name + H.h2 ! A.class_ "title is-2" $ "Synthesis" H.table ! A.class_ "table" $ do H.thead . H.toHtml $ ( H.tr . H.toHtml - $ [H.th "Synthesis tool", H.th "Synthesis Status"] + $ [H.th "Tool", H.th "Status", H.th "Run time"] ) H.tbody . H.toHtml $ fmap synthStatusHtml stat - H.h2 ! A.class_ "subtitle" $ "Equivalence Check Status" + H.h2 ! A.class_ "title is-2" $ "Equivalence Check" H.table ! A.class_ "table" $ do H.thead . H.toHtml @@ -263,10 +289,95 @@ resultReport name (FuzzReport synth _ stat) = H.docTypeHtml $ do . H.toHtml $ [ H.th "First tool" , H.th "Second tool" - , H.th "Equivalence Status" + , H.th "Status" + , H.th "Run time" ] ) H.tbody . H.toHtml $ fmap synthResultHtml synth +resultStatus :: Result a b -> Html +resultStatus (Pass _) = H.td ! A.class_ "is-success" $ "Passed" +resultStatus (Fail _) = H.td ! A.class_ "is-danger" $ "Failed" + +fuzzStats + :: (Real a1, Traversable t) + => ((a1 -> Const (Endo [a1]) a1) -> a2 -> Const (Endo [a1]) a2) + -> t a2 + -> (Double, Double) +fuzzStats sel fr = meanVariance converted + where converted = fromList . fmap realToFrac $ fr ^.. traverse . sel + +fuzzStatus :: Text -> FuzzReport -> Html +fuzzStatus name (FuzzReport dir s1 s2 s3 t1 t2 t3) = H.tr $ do + H.td + . ( H.a + ! A.href + ( H.textValue + $ toTextIgnore (dir fromText "index" <.> "html") + ) + ) + $ H.toHtml name + resultStatus + $ mconcat (fmap getSynthResult s1) + <> mconcat (fmap getSimResult s2) + <> mconcat (fmap getSynthStatus s3) + H.td . H.string $ show t1 + H.td . H.string $ show t2 + H.td . H.string $ show t3 + +summary :: Text -> [FuzzReport] -> Html +summary name fuzz = H.docTypeHtml $ do + resultHead name + H.body + . (H.section ! A.class_ "section") + . (H.div ! A.class_ "container") + $ do + H.h1 ! A.class_ "title is-1" $ "FuzzReport - " <> H.toHtml name + H.table ! A.class_ "table" $ do + H.thead . H.tr $ H.toHtml + [ H.th "Name" + , H.th "Status" + , H.th "Synthesis time" + , H.th "Equivalence check time" + , H.th "Reduction time" + ] + H.tbody + . H.toHtml + . fmap + (\(i, r) -> + fuzzStatus ("Fuzz " <> showT (i :: Int)) r + ) + $ zip [1 ..] fuzz + H.tfoot . H.toHtml $ do + H.tr $ H.toHtml + [ H.td $ H.strong "Total" + , H.td mempty + , sumUp synthTime + , sumUp equivTime + , sumUp reducTime + ] + H.tr $ H.toHtml + [ H.td $ H.strong "Mean" + , H.td mempty + , fst $ meanVar synthTime + , fst $ meanVar equivTime + , fst $ meanVar reducTime + ] + H.tr $ H.toHtml + [ H.td $ H.strong "Variance" + , H.td mempty + , snd $ meanVar synthTime + , snd $ meanVar equivTime + , snd $ meanVar reducTime + ] + where + sumUp s = showHtml . sum $ fuzz ^.. traverse . s + meanVar s = bimap d2T d2T $ fuzzStats s fuzz + showHtml = H.td . H.string . show + d2T = showHtml . (realToFrac :: Double -> NominalDiffTime) + printResultReport :: Text -> FuzzReport -> Text printResultReport t f = toStrict . renderHtml $ resultReport t f + +printSummary :: Text -> [FuzzReport] -> Text +printSummary t f = toStrict . renderHtml $ summary t f -- cgit From b84e5943008023b68e224e63e1b1d1e0ca8c9566 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 15:25:33 +0100 Subject: Add a different State and new FuzzReport output --- src/VeriFuzz/Fuzz.hs | 155 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 112 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 77962b5..f87d81b 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -27,7 +27,7 @@ where import Control.DeepSeq (force) import Control.Exception.Lifted (finally) import Control.Lens hiding ((<.>)) -import Control.Monad (forM, void) +import Control.Monad (forM) import Control.Monad.IO.Class import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Control (MonadBaseControl) @@ -39,6 +39,7 @@ import Data.Maybe (isNothing) import Data.Text (Text) import qualified Data.Text as T import Data.Time +import Data.Tuple (swap) import Hedgehog (Gen) import qualified Hedgehog.Internal.Gen as Hog import Hedgehog.Internal.Seed (Seed) @@ -64,9 +65,17 @@ data FuzzEnv = FuzzEnv { getSynthesisers :: ![SynthTool] } deriving (Eq, Show) +data FuzzState = FuzzState { _fuzzSynthResults :: ![SynthResult] + , _fuzzSimResults :: ![SimResult] + , _fuzzSynthStatus :: ![SynthStatus] + } + deriving (Eq, Show) + +$(makeLenses ''FuzzState) + -- | The main type for the fuzzing, which contains an environment that can be -- read from and the current state of all the results. -type Fuzz m = StateT FuzzReport (ReaderT FuzzEnv m) +type Fuzz m = StateT FuzzState (ReaderT FuzzEnv m) type MonadFuzz m = (MonadBaseControl IO m, MonadIO m, MonadSh m) @@ -75,7 +84,7 @@ runFuzz conf yos m = shelly $ runFuzz' conf yos m runFuzz' :: Monad m => Config -> Yosys -> (Config -> Fuzz m b) -> m b runFuzz' conf yos m = runReaderT - (evalStateT (m conf) (FuzzReport [] [] [])) + (evalStateT (m conf) (FuzzState [] [] [])) (FuzzEnv ( force $ defaultIdentitySynth @@ -106,12 +115,13 @@ timeit a = do synthesis :: (MonadBaseControl IO m, MonadSh m) => SourceInfo -> Fuzz m () synthesis src = do - synth <- synthesisers - results <- liftSh $ mapM exec synth - synthStatus .= zipWith SynthStatus synth results - liftSh $ inspect results + synth <- synthesisers + resTimes <- liftSh $ mapM exec synth + fuzzSynthStatus + .= applyList (uncurry . SynthStatus <$> synth) (fmap swap resTimes) + liftSh $ inspect resTimes where - exec a = runResultT $ do + exec a = toolRun ("synthesisis with " <> toText a) . runResultT $ do liftSh . mkdir_p . fromText $ toText a pop (fromText $ toText a) $ runSynth a src @@ -127,11 +137,11 @@ generateSample seed gen = do return v passedSynthesis :: MonadSh m => Fuzz m [SynthTool] -passedSynthesis = fmap toSynth . filter passed . _synthStatus <$> get +passedSynthesis = fmap toSynth . filter passed . _fuzzSynthStatus <$> get where - passed (SynthStatus _ (Pass _)) = True - passed _ = False - toSynth (SynthStatus s _) = s + passed (SynthStatus _ (Pass _) _) = True + passed _ = False + toSynth (SynthStatus s _ _) = s make :: MonadSh m => FilePath -> m () make f = liftSh $ do @@ -146,8 +156,21 @@ pop f a = do applyList :: [a -> b] -> [a] -> [b] applyList a b = apply' <$> zip a b where apply' (a', b') = a' b' -toSynthResult :: [(SynthTool, SynthTool)] -> [Result Failed ()] -> [SynthResult] -toSynthResult a b = flip applyList b $ uncurry SynthResult <$> a +applyLots :: (a -> b -> c -> d -> e) -> [(a, b)] -> [(c, d)] -> [e] +applyLots func a b = applyList (uncurry . uncurry func <$> a) b + +toSynthResult + :: [(SynthTool, SynthTool)] + -> [(NominalDiffTime, Result Failed ())] + -> [SynthResult] +toSynthResult a b = applyLots SynthResult a $ fmap swap b + +toolRun :: (MonadIO m, MonadSh m) => Text -> m a -> m (NominalDiffTime, a) +toolRun t m = do + logT $ "Running " <> t + (diff, res) <- timeit m + logT $ "Finished " <> t <> " (" <> showT diff <> ")" + return (diff, res) equivalence :: (MonadBaseControl IO m, MonadSh m) => SourceInfo -> Fuzz m () equivalence src = do @@ -159,29 +182,40 @@ equivalence src = do . filter (uncurry (/=)) $ (,) defaultIdentitySynth <$> synth - results <- liftSh $ mapM (uncurry equiv) synthComb - synthResults .= toSynthResult synthComb results - liftSh $ inspect results + resTimes <- liftSh $ mapM (uncurry equiv) synthComb + fuzzSynthResults .= toSynthResult synthComb resTimes + liftSh $ inspect resTimes where tupEq (a, b) (a', b') = (a == a' && b == b') || (a == b' && b == a') - equiv a b = runResultT $ do - make dir - pop dir $ do - liftSh $ do - cp (fromText ".." fromText (toText a) synthOutput a) - $ synthOutput a - cp (fromText ".." fromText (toText b) synthOutput b) - $ synthOutput b - writefile "rtl.v" $ genSource src - runEquiv a b src + equiv a b = + toolRun ("equivalence check for " <> toText a <> " and " <> toText b) + . runResultT + $ do + make dir + pop dir $ do + liftSh $ do + cp + ( fromText ".." + fromText (toText a) + synthOutput a + ) + $ synthOutput a + cp + ( fromText ".." + fromText (toText b) + synthOutput b + ) + $ synthOutput b + writefile "rtl.v" $ genSource src + runEquiv a b src where dir = fromText $ "equiv_" <> toText a <> "_" <> toText b failEquivWithIdentity :: (MonadSh m) => Fuzz m [SynthResult] -failEquivWithIdentity = filter withIdentity . _synthResults <$> get +failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get where - withIdentity (SynthResult (IdentitySynth _) _ (Fail EquivFail)) = True - withIdentity (SynthResult _ (IdentitySynth _) (Fail EquivFail)) = True - withIdentity _ = False + withIdentity (SynthResult (IdentitySynth _) _ (Fail EquivFail) _) = True + withIdentity (SynthResult _ (IdentitySynth _) (Fail EquivFail) _) = True + withIdentity _ = False -- | Always reduces with respect to 'Identity'. reduction :: (MonadSh m) => SourceInfo -> Fuzz m () @@ -190,7 +224,7 @@ reduction src = do _ <- liftSh $ mapM red fails return () where - red (SynthResult a b _) = do + red (SynthResult a b _ _) = do make dir pop dir $ do s <- reduceSynth a b src @@ -198,6 +232,20 @@ reduction src = do return s where dir = fromText $ "reduce_" <> toText a <> "_" <> toText b +titleRun + :: (MonadIO m, MonadSh m) => Text -> Fuzz m a -> Fuzz m (NominalDiffTime, a) +titleRun t f = do + logT $ "--- Starting " <> t <> " ---" + (diff, res) <- timeit f + logT $ "--- Finished " <> t <> " (" <> showT diff <> ") ---" + return (diff, res) + +whenMaybe :: Applicative m => Bool -> m a -> m (Maybe a) +whenMaybe b x = if b then Just <$> x else pure Nothing + +getTime :: (Num n) => Maybe (n, a) -> n +getTime = maybe 0 fst + fuzz :: MonadFuzz m => Gen SourceInfo -> Config -> Fuzz m FuzzReport fuzz gen conf = do (seed', src) <- generateSample seed gen @@ -207,23 +255,39 @@ fuzz gen conf = do $ conf & configProperty . propSeed - .~ Just seed' - synthesis src - equivalence src - reduction src - report <- get + ?~ seed' + (tsynth, _) <- titleRun "Synthesis" $ synthesis src + (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src + fails <- failEquivWithIdentity + redResult <- whenMaybe (not $ null fails) . titleRun "Reduction" $ reduction + src + state_ <- get currdir <- liftSh pwd + let vi = flip view state_ + let report = FuzzReport currdir + (vi fuzzSynthResults) + (vi fuzzSimResults) + (vi fuzzSynthStatus) + tsynth + tequiv + (getTime redResult) liftSh . writefile "index.html" $ printResultReport (bname currdir) report return report where seed = conf ^. configProperty . propSeed bname = T.pack . takeBaseName . T.unpack . toTextIgnore +relativeFuzzReport :: (MonadSh m) => FuzzReport -> m FuzzReport +relativeFuzzReport fr@(FuzzReport dir _ _ _ _ _ _) = liftSh $ do + newPath <- relPath dir + return $ (fuzzDir .~ newPath) fr + fuzzInDir :: MonadFuzz m => FilePath -> Gen SourceInfo -> Config -> Fuzz m FuzzReport fuzzInDir fp src conf = do make fp - pop fp $ fuzz src conf + res <- pop fp $ fuzz src conf + relativeFuzzReport res fuzzMultiple :: MonadFuzz m @@ -231,7 +295,7 @@ fuzzMultiple -> Maybe FilePath -> Gen SourceInfo -> Config - -> Fuzz m FuzzReport + -> Fuzz m [FuzzReport] fuzzMultiple n fp src conf = do x <- case fp of Nothing -> do @@ -243,11 +307,16 @@ fuzzMultiple n fp src conf = do <> formatTime defaultTimeLocale "%Y-%m-%d_%H-%M-%S" ct Just f -> return f make x - when (isNothing seed) . void . pop x . forM [1 .. n] $ fuzzDir - unless (isNothing seed) . void . pop x $ fuzzDir (1 :: Int) - return mempty + pop x $ do + results <- if isNothing seed + then forM [1 .. n] fuzzDir' + else (: []) <$> fuzzDir' (1 :: Int) + liftSh . writefile (fromText "index" <.> "html") $ printSummary + "Fuzz Summary" + results + return results where - fuzzDir n' = fuzzInDir (fromText $ "fuzz_" <> showT n') src conf + fuzzDir' n' = fuzzInDir (fromText $ "fuzz_" <> showT n') src conf seed = conf ^. configProperty . propSeed sampleSeed :: MonadSh m => Maybe Seed -> Gen a -> m (Seed, a) -- cgit From f7bef9d157ae1c8ce3c8ee638d4f7ff25e5ae8f1 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 20:51:02 +0100 Subject: Add hat sampling --- src/VeriFuzz/Fuzz.hs | 58 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index f87d81b..7626968 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -27,14 +27,14 @@ where import Control.DeepSeq (force) import Control.Exception.Lifted (finally) import Control.Lens hiding ((<.>)) -import Control.Monad (forM) +import Control.Monad (forM, replicateM) import Control.Monad.IO.Class import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Maybe (runMaybeT) import Control.Monad.Trans.Reader hiding (local) import Control.Monad.Trans.State.Strict -import Data.List (nubBy) +import Data.List (nubBy, sort) import Data.Maybe (isNothing) import Data.Text (Text) import qualified Data.Text as T @@ -125,17 +125,6 @@ synthesis src = do liftSh . mkdir_p . fromText $ toText a pop (fromText $ toText a) $ runSynth a src -generateSample - :: (MonadIO m, MonadSh m) - => Maybe Seed - -> Gen SourceInfo - -> Fuzz m (Seed, SourceInfo) -generateSample seed gen = do - logT "Sampling Verilog from generator" - (t, v) <- timeit $ sampleSeed seed gen - logT $ "Generated Verilog (" <> showT t <> ")" - return v - passedSynthesis :: MonadSh m => Fuzz m [SynthTool] passedSynthesis = fmap toSynth . filter passed . _fuzzSynthStatus <$> get where @@ -246,9 +235,38 @@ whenMaybe b x = if b then Just <$> x else pure Nothing getTime :: (Num n) => Maybe (n, a) -> n getTime = maybe 0 fst +generateSample + :: (MonadIO m, MonadSh m) + => Fuzz m (Seed, SourceInfo) + -> Fuzz m (Seed, SourceInfo) +generateSample f = do + logT "Sampling Verilog from generator" + (t, v@(s, _)) <- timeit f + logT $ "Chose " <> showT s + logT $ "Generated Verilog (" <> showT t <> ")" + return v + +verilogSize :: (Source a) => a -> Int +verilogSize = length . lines . T.unpack . genSource + +sampleVerilogHat :: (MonadIO m, MonadSh m) => Int -> Maybe Seed -> Gen SourceInfo -> Fuzz m (Seed, SourceInfo) +sampleVerilogHat _ seed@(Just _) gen = sampleSeed seed gen +sampleVerilogHat n Nothing gen = do + res <- replicateM n $ sampleSeed Nothing gen + let sizes = fmap getSize res + let samples = fmap snd . sort $ zip sizes res + liftIO $ Hog.sample . Hog.frequency $ freqs samples + where + getSize (_, s) = verilogSize s + freqs l = zip hat (return <$> l) + where + h = length l `div` 2 + hat = (+ h) . negate . abs . (h - ) <$> [1..length l] + fuzz :: MonadFuzz m => Gen SourceInfo -> Config -> Fuzz m FuzzReport fuzz gen conf = do - (seed', src) <- generateSample seed gen + (seed', src) <- generateSample genMethod + let size = length . lines . T.unpack $ genSource src liftSh . writefile "config.toml" . encodeConfig @@ -268,6 +286,7 @@ fuzz gen conf = do (vi fuzzSynthResults) (vi fuzzSimResults) (vi fuzzSynthStatus) + size tsynth tequiv (getTime redResult) @@ -276,9 +295,14 @@ fuzz gen conf = do where seed = conf ^. configProperty . propSeed bname = T.pack . takeBaseName . T.unpack . toTextIgnore + genMethod = case conf ^. configProperty . propSampleMethod of + "hat" -> + sampleVerilogHat (conf ^. configProperty . propSampleSize) seed gen + _ -> + sampleSeed seed gen relativeFuzzReport :: (MonadSh m) => FuzzReport -> m FuzzReport -relativeFuzzReport fr@(FuzzReport dir _ _ _ _ _ _) = liftSh $ do +relativeFuzzReport fr@(FuzzReport dir _ _ _ _ _ _ _) = liftSh $ do newPath <- relPath dir return $ (fuzzDir .~ newPath) fr @@ -336,7 +360,5 @@ sampleSeed s gen = $ Hog.runGenT 30 seed gen of Nothing -> loop (n - 1) - Just x -> do - liftSh . logT $ showT seed - return (seed, Hog.nodeValue x) + Just x -> return (seed, Hog.nodeValue x) in loop (100 :: Int) -- cgit From e2cb5d2cfe050ff45fba823c88a5fa45d3fb556e Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 20:51:10 +0100 Subject: Add lines of code to report --- src/VeriFuzz/Report.hs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Report.hs b/src/VeriFuzz/Report.hs index 53e77ba..20addfb 100644 --- a/src/VeriFuzz/Report.hs +++ b/src/VeriFuzz/Report.hs @@ -27,6 +27,7 @@ module VeriFuzz.Report , synthStatus , equivTime , fuzzDir + , fileLines , reducTime , synthTime , defaultIcarusSim @@ -189,10 +190,11 @@ instance Show SynthStatus where -- | The complete state that will be used during fuzzing, which contains the -- results from all the operations. -data FuzzReport = FuzzReport { _fuzzDir :: {-# UNPACK #-} !FilePath +data FuzzReport = FuzzReport { _fuzzDir :: !FilePath , _synthResults :: ![SynthResult] , _simResults :: ![SimResult] , _synthStatus :: ![SynthStatus] + , _fileLines :: {-# UNPACK #-} !Int , _synthTime :: {-# UNPACK #-} !NominalDiffTime , _equivTime :: {-# UNPACK #-} !NominalDiffTime , _reducTime :: {-# UNPACK #-} !NominalDiffTime @@ -265,7 +267,7 @@ resultHead name = H.head $ do "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css" resultReport :: Text -> FuzzReport -> Html -resultReport name (FuzzReport _ synth _ stat _ _ _) = H.docTypeHtml $ do +resultReport name (FuzzReport _ synth _ stat _ _ _ _) = H.docTypeHtml $ do resultHead name H.body . (H.section ! A.class_ "section") @@ -308,7 +310,7 @@ fuzzStats sel fr = meanVariance converted where converted = fromList . fmap realToFrac $ fr ^.. traverse . sel fuzzStatus :: Text -> FuzzReport -> Html -fuzzStatus name (FuzzReport dir s1 s2 s3 t1 t2 t3) = H.tr $ do +fuzzStatus name (FuzzReport dir s1 s2 s3 sz t1 t2 t3) = H.tr $ do H.td . ( H.a ! A.href @@ -321,6 +323,7 @@ fuzzStatus name (FuzzReport dir s1 s2 s3 t1 t2 t3) = H.tr $ do $ mconcat (fmap getSynthResult s1) <> mconcat (fmap getSimResult s2) <> mconcat (fmap getSynthStatus s3) + H.td . H.string $ show sz H.td . H.string $ show t1 H.td . H.string $ show t2 H.td . H.string $ show t3 @@ -337,6 +340,7 @@ summary name fuzz = H.docTypeHtml $ do H.thead . H.tr $ H.toHtml [ H.th "Name" , H.th "Status" + , H.th "Size (loc)" , H.th "Synthesis time" , H.th "Equivalence check time" , H.th "Reduction time" @@ -352,6 +356,7 @@ summary name fuzz = H.docTypeHtml $ do H.tr $ H.toHtml [ H.td $ H.strong "Total" , H.td mempty + , H.td . H.string . show . sum $ fuzz ^.. traverse . fileLines , sumUp synthTime , sumUp equivTime , sumUp reducTime @@ -359,6 +364,7 @@ summary name fuzz = H.docTypeHtml $ do H.tr $ H.toHtml [ H.td $ H.strong "Mean" , H.td mempty + , fst $ bimap d2I d2I $ fuzzStats fileLines fuzz , fst $ meanVar synthTime , fst $ meanVar equivTime , fst $ meanVar reducTime @@ -366,6 +372,7 @@ summary name fuzz = H.docTypeHtml $ do H.tr $ H.toHtml [ H.td $ H.strong "Variance" , H.td mempty + , snd $ bimap d2I d2I $ fuzzStats fileLines fuzz , snd $ meanVar synthTime , snd $ meanVar equivTime , snd $ meanVar reducTime @@ -375,6 +382,7 @@ summary name fuzz = H.docTypeHtml $ do meanVar s = bimap d2T d2T $ fuzzStats s fuzz showHtml = H.td . H.string . show d2T = showHtml . (realToFrac :: Double -> NominalDiffTime) + d2I = H.td . H.string . show printResultReport :: Text -> FuzzReport -> Text printResultReport t f = toStrict . renderHtml $ resultReport t f -- cgit From e8915d759c1f6da2a1f3e8328708f40c2d203022 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 20:51:20 +0100 Subject: Add necessary exports to AST and CodeGen --- src/VeriFuzz/Verilog/AST.hs | 2 +- src/VeriFuzz/Verilog/CodeGen.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/AST.hs b/src/VeriFuzz/Verilog/AST.hs index 306366c..7a654fd 100644 --- a/src/VeriFuzz/Verilog/AST.hs +++ b/src/VeriFuzz/Verilog/AST.hs @@ -492,7 +492,7 @@ newtype Verilog = Verilog { getVerilog :: [ModDecl] } data SourceInfo = SourceInfo { _infoTop :: {-# UNPACK #-} !Text , _infoSrc :: !Verilog } - deriving (Eq, Show) + deriving (Eq, Ord, Data, Show) $(makeLenses ''Expr) $(makeLenses ''ConstExpr) diff --git a/src/VeriFuzz/Verilog/CodeGen.hs b/src/VeriFuzz/Verilog/CodeGen.hs index a0ec0cc..6ef1959 100644 --- a/src/VeriFuzz/Verilog/CodeGen.hs +++ b/src/VeriFuzz/Verilog/CodeGen.hs @@ -17,7 +17,7 @@ This module generates the code from the Verilog AST defined in module VeriFuzz.Verilog.CodeGen ( -- * Code Generation GenVerilog(..) - , genSource + , Source(..) , render ) where -- cgit From fca2988da194d41b04321ad46d7dd3b905613c15 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 May 2019 20:51:30 +0100 Subject: Add choice for hat sampling in config --- src/VeriFuzz/Config.hs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Config.hs b/src/VeriFuzz/Config.hs index 9295f71..375c739 100644 --- a/src/VeriFuzz/Config.hs +++ b/src/VeriFuzz/Config.hs @@ -61,6 +61,8 @@ module VeriFuzz.Config , probStmntNonBlock , probStmntCond , probStmntFor + , propSampleSize + , propSampleMethod , propSize , propSeed , propStmntDepth @@ -189,11 +191,13 @@ data Probability = Probability { _probModItem :: {-# UNPACK #-} !ProbModItem } deriving (Eq, Show) -data ConfProperty = ConfProperty { _propSize :: {-# UNPACK #-} !Int - , _propSeed :: !(Maybe Seed) - , _propStmntDepth :: {-# UNPACK #-} !Int - , _propModDepth :: {-# UNPACK #-} !Int - , _propMaxModules :: {-# UNPACK #-} !Int +data ConfProperty = ConfProperty { _propSize :: {-# UNPACK #-} !Int + , _propSeed :: !(Maybe Seed) + , _propStmntDepth :: {-# UNPACK #-} !Int + , _propModDepth :: {-# UNPACK #-} !Int + , _propMaxModules :: {-# UNPACK #-} !Int + , _propSampleMethod :: !Text + , _propSampleSize :: {-# UNPACK #-} !Int } deriving (Eq, Show) @@ -261,7 +265,7 @@ defaultConfig :: Config defaultConfig = Config (Info (pack $(gitHash)) (pack $ showVersion version)) (Probability defModItem defStmnt defExpr) - (ConfProperty 20 Nothing 3 2 5) + (ConfProperty 20 Nothing 3 2 5 "random" 10) [] [fromYosys defaultYosys, fromVivado defaultVivado] where @@ -374,6 +378,10 @@ propCodec = .= _propModDepth <*> defaultValue (defProp propMaxModules) (int "module" "max") .= _propMaxModules + <*> defaultValue (defProp propSampleMethod) (Toml.text (twoKey "sample" "method")) + .= _propSampleMethod + <*> defaultValue (defProp propSampleSize) (int "sample" "size") + .= _propSampleSize where defProp i = defaultConfig ^. configProperty . i simulator :: TomlCodec SimDescription -- cgit From a056ff5ec91f95aab7cb502b20530d935d1774a8 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 22 May 2019 11:05:51 +0100 Subject: Add hat sampling to config --- src/VeriFuzz/Fuzz.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 7626968..b3d76ad 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -296,9 +296,11 @@ fuzz gen conf = do seed = conf ^. configProperty . propSeed bname = T.pack . takeBaseName . T.unpack . toTextIgnore genMethod = case conf ^. configProperty . propSampleMethod of - "hat" -> + "hat" -> do + logT "Using the hat function" sampleVerilogHat (conf ^. configProperty . propSampleSize) seed gen - _ -> + _ -> do + logT "Using first seed" sampleSeed seed gen relativeFuzzReport :: (MonadSh m) => FuzzReport -> m FuzzReport -- cgit From 5df5d613e3aaf5f14368903b5fec5596d848ef44 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 22 May 2019 15:14:30 +0100 Subject: Change parameters of generation --- src/VeriFuzz/Verilog/Gen.hs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index bd80c3d..bc40de5 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -231,11 +231,6 @@ someI m f = do amount <- gen $ Hog.int (Hog.linear 1 m) replicateM amount f -many :: StateGen a -> StateGen [a] -many f = do - amount <- gen $ Hog.int (Hog.linear 0 50) - replicateM amount f - makeIdentifier :: T.Text -> StateGen Identifier makeIdentifier prefix = do context <- get @@ -458,7 +453,7 @@ moduleDef top = do name <- moduleName top portList <- Hog.list (Hog.linear 4 10) $ nextPort Wire mi <- Hog.list (Hog.linear 4 100) modItem - ps <- many parameter + ps <- Hog.list (Hog.linear 0 10) parameter context <- get let local = filter (`notElem` portList) $ _variables context let @@ -473,7 +468,7 @@ moduleDef top = do let comb = combineAssigns_ yport local return . declareMod local - . ModDecl name [yport] (clock : portList) (mi <> [comb]) + . ModDecl name [yport] (clock : portList) (comb : mi) $ ps -- | Procedural generation method for random Verilog. Uses internal 'Reader' and -- cgit From 7e67a69693c4c0964f488d87dd94f64a2efe5409 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Fri, 24 May 2019 15:09:06 +0100 Subject: Reduction throws away path if it finds a passing one --- src/VeriFuzz/Fuzz.hs | 4 ++-- src/VeriFuzz/Reduce.hs | 35 ++++++++++++++++------------------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index b3d76ad..e68fc95 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -224,9 +224,9 @@ reduction src = do titleRun :: (MonadIO m, MonadSh m) => Text -> Fuzz m a -> Fuzz m (NominalDiffTime, a) titleRun t f = do - logT $ "--- Starting " <> t <> " ---" + logT $ "### Starting " <> t <> " ###" (diff, res) <- timeit f - logT $ "--- Finished " <> t <> " (" <> showT diff <> ") ---" + logT $ "### Finished " <> t <> " (" <> showT diff <> ") ###" return (diff, res) whenMaybe :: Applicative m => Bool -> m a -> m (Maybe a) diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 33cb648..4875e7d 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -502,28 +502,25 @@ reduce_ title repl bot eval src = do (src ^.. infoSrc . _Wrapped . traverse . modItems . traverse) ) <> ")" - replAnswer <- sequenceA $ evalIfNotEmpty <$> replacement - case (replacement, replAnswer) of - (Single s, Single True ) -> runIf s - (Dual _ r, Dual False True) -> runIf r - (Dual l _, Dual True False) -> runIf l - (Dual l r, Dual True True ) -> check l r - _ -> return src + case repl src of + Single s -> do + red <- eval s + if red then runIf s else return s + Dual l r -> do + red <- eval l + if red && cond l + then reduce_ title repl bot eval l + else do + red' <- eval r + if red' && cond r + then reduce_ title repl bot eval r + else if l < r then return l else return r + None -> return src where - replacement = repl src - runIf s = if s /= src && not (bot s) + runIf s = if cond s then reduce_ title repl bot eval s else return s - evalIfNotEmpty = eval - check l r - | bot l = return l - | bot r = return r - | otherwise = do - lreduced <- runIf l - rreduced <- runIf r - if _infoSrc lreduced < _infoSrc rreduced - then return lreduced - else return rreduced + cond s = s /= src && not (bot s) -- | Reduce an input to a minimal representation. It follows the reduction -- strategy mentioned above. -- cgit From 14158fc4ef0809adbbf0b7fdd0c0d5e0fafc2435 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Fri, 24 May 2019 15:45:35 +0100 Subject: Fix used wire check for clk --- src/VeriFuzz/Fuzz.hs | 2 +- src/VeriFuzz/Reduce.hs | 35 ++++++++++++++++++++++------------- src/VeriFuzz/Verilog/AST.hs | 3 +++ 3 files changed, 26 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index e68fc95..f85ab1f 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -121,7 +121,7 @@ synthesis src = do .= applyList (uncurry . SynthStatus <$> synth) (fmap swap resTimes) liftSh $ inspect resTimes where - exec a = toolRun ("synthesisis with " <> toText a) . runResultT $ do + exec a = toolRun ("synthesis with " <> toText a) . runResultT $ do liftSh . mkdir_p . fromText $ toText a pop (fromText $ toText a) $ runSynth a src diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 4875e7d..fcc8e51 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -111,7 +111,7 @@ instance Traversable Replacement where -- | Split a list in two halves. halve :: Replace [a] -halve [] = None +halve [] = Single [] halve [_] = Single [] halve l = Dual a b where (a, b) = splitAt (length l `div` 2) l @@ -254,6 +254,12 @@ exprId (VecSelect i _) = Just i exprId (RangeSelect i _) = Just i exprId _ = Nothing +eventId :: Event -> Maybe Identifier +eventId (EId i) = Just i +eventId (EPosEdge i) = Just i +eventId (ENegEdge i) = Just i +eventId _ = Nothing + portToId :: Port -> Identifier portToId (Port _ _ _ i) = i @@ -396,16 +402,19 @@ toIds = nub . mapMaybe exprId . concatMap universe toIdsConst :: [ConstExpr] -> [Identifier] toIdsConst = toIds . fmap constToExpr +toIdsEvent :: [Event] -> [Identifier] +toIdsEvent = nub . mapMaybe eventId . concatMap universe + allStatIds' :: Statement -> [Identifier] -allStatIds' s = nub $ assignIds <> otherExpr +allStatIds' s = nub $ assignIds <> otherExpr <> eventProcessedIds where - assignIds = - toIds + assignIds = toIds $ (s ^.. stmntBA . assignExpr) <> (s ^.. stmntNBA . assignExpr) <> (s ^.. forAssign . assignExpr) <> (s ^.. forIncr . assignExpr) otherExpr = toIds $ (s ^.. forExpr) <> (s ^.. stmntCondExpr) + eventProcessedIds = toIdsEvent $ s ^.. statEvent allStatIds :: Statement -> [Identifier] allStatIds s = nub . concat $ allStatIds' <$> universe s @@ -505,22 +514,22 @@ reduce_ title repl bot eval src = do case repl src of Single s -> do red <- eval s - if red then runIf s else return s + if red + then if cond s then recReduction s else return s + else return src Dual l r -> do red <- eval l - if red && cond l - then reduce_ title repl bot eval l + if red + then if cond l then recReduction l else return l else do red' <- eval r - if red' && cond r - then reduce_ title repl bot eval r - else if l < r then return l else return r + if red' + then if cond r then recReduction r else return r + else return src None -> return src where - runIf s = if cond s - then reduce_ title repl bot eval s - else return s cond s = s /= src && not (bot s) + recReduction = reduce_ title repl bot eval -- | Reduce an input to a minimal representation. It follows the reduction -- strategy mentioned above. diff --git a/src/VeriFuzz/Verilog/AST.hs b/src/VeriFuzz/Verilog/AST.hs index 7a654fd..f201064 100644 --- a/src/VeriFuzz/Verilog/AST.hs +++ b/src/VeriFuzz/Verilog/AST.hs @@ -169,6 +169,9 @@ data Event = EId {-# UNPACK #-} !Identifier | EComb !Event !Event deriving (Eq, Show, Ord, Data) +instance Plated Event where + plate = uniplate + -- | Binary operators that are currently supported in the verilog generation. data BinaryOperator = BinPlus -- ^ @+@ | BinMinus -- ^ @-@ -- cgit From fe9084c9fe731ff8f7d94729a3280357cda6f259 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Fri, 24 May 2019 17:37:02 +0100 Subject: No expression reduction --- src/VeriFuzz/Reduce.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index fcc8e51..bfc9a6e 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -543,7 +543,7 @@ reduce eval src = $ red "Modules" moduleBot halveModules src >>= redAll "Module Items" modItemBot halveModItems >>= redAll "Statements" (const defaultBot) halveStatements - >>= redAll "Expressions" (const defaultBot) halveExpr + -- >>= redAll "Expressions" (const defaultBot) halveExpr where red s bot a = reduce_ s a bot eval red' s bot a t = reduce_ s (a t) (bot t) eval -- cgit From e4181b3f672040c2478d00ce4c9cd9b0c2cde473 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 21:10:45 +0100 Subject: Add timeout error to synthesisers --- src/VeriFuzz/Sim/Internal.hs | 21 ++++++++++++++------- src/VeriFuzz/Sim/Yosys.hs | 11 ++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Sim/Internal.hs b/src/VeriFuzz/Sim/Internal.hs index 5c58e1a..d35ad86 100644 --- a/src/VeriFuzz/Sim/Internal.hs +++ b/src/VeriFuzz/Sim/Internal.hs @@ -188,21 +188,28 @@ logCommand_ :: FilePath -> Text -> Sh a -> Sh () logCommand_ fp name = void . logCommand fp name execute - :: (MonadSh m, Monad m, Monoid a) - => a + :: (MonadSh m, Monad m) + => Failed -> FilePath -> Text -> FilePath -> [Text] - -> ResultT a m Text -execute f dir name e = annotate f . liftSh . logCommand dir name . timeout e + -> ResultT Failed m Text +execute f dir name e cs = do + (res, exitCode) <- liftSh $ do + res <- errExit False . logCommand dir name $ timeout e cs + (,) res <$> lastExitCode + case exitCode of + 0 -> ResultT . return $ Pass res + 124 -> ResultT . return $ Fail TimeoutError + _ -> ResultT . return $ Fail f execute_ - :: (MonadSh m, Monad m, Monoid a) - => a + :: (MonadSh m, Monad m) + => Failed -> FilePath -> Text -> FilePath -> [Text] - -> ResultT a m () + -> ResultT Failed m () execute_ a b c d = void . execute a b c d diff --git a/src/VeriFuzz/Sim/Yosys.hs b/src/VeriFuzz/Sim/Yosys.hs index 472af1f..3729a1e 100644 --- a/src/VeriFuzz/Sim/Yosys.hs +++ b/src/VeriFuzz/Sim/Yosys.hs @@ -62,11 +62,12 @@ yosysPath :: Yosys -> FilePath yosysPath sim = maybe (fromText "yosys") ( fromText "yosys") $ yosysBin sim runSynthYosys :: Yosys -> SourceInfo -> ResultSh () -runSynthYosys sim (SourceInfo _ src) = ( SynthFail) . liftSh $ do - dir <- pwd - writefile inpf $ genSource src - logCommand_ dir "yosys" $ timeout - (yosysPath sim) +runSynthYosys sim (SourceInfo _ src) = do + dir <- liftSh $ do + dir' <- pwd + writefile inpf $ genSource src + return dir' + execute_ SynthFail dir "yosys" (yosysPath sim) [ "-p" , "read -formal " <> inp <> "; synth; write_verilog -noattr " <> out ] -- cgit From 0a45b7d0cfa76e8a543bc2ddffe7d4e56aaae93a Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 21:18:24 +0100 Subject: Add reducesynthesis function --- src/VeriFuzz/Reduce.hs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index bfc9a6e..0ecde3f 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -591,3 +591,16 @@ reduceSynth a b = reduce synth Fail EquivFail -> True Fail _ -> False Pass _ -> False + +reduceSynthesis :: (Synthesiser a, MonadSh m) + => a + -> SourceInfo + -> m SourceInfo +reduceSynthesis a = reduce synth + where + synth src = liftSh $ do + r <- runResultT $ runSynth a src + return $ case r of + Fail SynthFail -> True + Fail _ -> False + Pass _ -> False -- cgit From 4fba97ba3a19c725714b5d55721368657e41daa3 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 21:20:51 +0100 Subject: Add synthesis fails to fuzzer --- src/VeriFuzz/Fuzz.hs | 16 ++++++++++++++++ src/VeriFuzz/Reduce.hs | 1 + 2 files changed, 17 insertions(+) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index f85ab1f..3f6a14b 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -132,6 +132,13 @@ passedSynthesis = fmap toSynth . filter passed . _fuzzSynthStatus <$> get passed _ = False toSynth (SynthStatus s _ _) = s +failedSynthesis :: MonadSh m => Fuzz m [SynthTool] +failedSynthesis = fmap toSynth . filter failed . _fuzzSynthStatus <$> get + where + failed (SynthStatus _ (Fail SynthFail) _) = True + failed _ = False + toSynth (SynthStatus s _ _) = s + make :: MonadSh m => FilePath -> m () make f = liftSh $ do mkdir_p f @@ -210,7 +217,9 @@ failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get reduction :: (MonadSh m) => SourceInfo -> Fuzz m () reduction src = do fails <- failEquivWithIdentity + synthFails <- failedSynthesis _ <- liftSh $ mapM red fails + _ <- liftSh $ mapM redSynth synthFails return () where red (SynthResult a b _ _) = do @@ -220,6 +229,13 @@ reduction src = do writefile (fromText ".." dir <.> "v") $ genSource s return s where dir = fromText $ "reduce_" <> toText a <> "_" <> toText b + redSynth (SynthStatus a _ _) = do + make dir + pop dir $ do + s <- reduceSynthesis a src + writefile (fromText ".." dir <.> "v") $ genSource s + return s + where dir = fromText $ "reduce_" <> toText a titleRun :: (MonadIO m, MonadSh m) => Text -> Fuzz m a -> Fuzz m (NominalDiffTime, a) diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 0ecde3f..b025a42 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -17,6 +17,7 @@ module VeriFuzz.Reduce ( -- $strategy reduceWithScript , reduceSynth + , reduceSynthesis , reduce , reduce_ , Replacement(..) -- cgit From 009f1837fb84d6afc194dd3f82fb1cadd6dc64e9 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 21:21:43 +0100 Subject: Use synthesiser instance --- src/VeriFuzz/Fuzz.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 3f6a14b..8db6c29 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -229,7 +229,7 @@ reduction src = do writefile (fromText ".." dir <.> "v") $ genSource s return s where dir = fromText $ "reduce_" <> toText a <> "_" <> toText b - redSynth (SynthStatus a _ _) = do + redSynth a = do make dir pop dir $ do s <- reduceSynthesis a src -- cgit From 404a828cd1bb7d69d1e879882a6b79f3378cd98d Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 22:37:01 +0100 Subject: Add more command line options for replay --- src/VeriFuzz.hs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz.hs b/src/VeriFuzz.hs index 66c795f..6d4f839 100644 --- a/src/VeriFuzz.hs +++ b/src/VeriFuzz.hs @@ -28,7 +28,7 @@ module VeriFuzz where import Control.Concurrent -import Control.Lens +import Control.Lens hiding ((<.>)) import Control.Monad.IO.Class (liftIO) import qualified Crypto.Random.DRBG as C import Data.ByteString (ByteString) @@ -58,6 +58,7 @@ import VeriFuzz.Result import VeriFuzz.Sim import VeriFuzz.Sim.Internal import VeriFuzz.Verilog +import VeriFuzz.Verilog.Parser (parseSourceInfoFile) data OptTool = TYosys | TXST @@ -79,9 +80,11 @@ data Opts = Fuzz { fuzzOutput :: {-# UNPACK #-} !Text } | Parse { fileName :: {-# UNPACK #-} !FilePath } - | Reduce { fileName :: {-# UNPACK #-} !FilePath - , top :: {-# UNPACK #-} !Text - , reduceScript :: {-# UNPACK #-} !FilePath + | Reduce { fileName :: {-# UNPACK #-} !FilePath + , top :: {-# UNPACK #-} !Text + , reduceScript :: {-# UNPACK #-} !(Maybe FilePath) + , synthesiserDesc :: ![SynthDescription] + , rerun :: Bool } | ConfigOpt { writeConfig :: !(Maybe FilePath) , configFile :: !(Maybe FilePath) @@ -107,6 +110,14 @@ parseSynth val | val == "yosys" = Just TYosys | val == "xst" = Just TXST | otherwise = Nothing +parseSynthDesc :: String -> Maybe SynthDescription +parseSynthDesc val | val == "yosys" = Just $ SynthDescription "yosys" Nothing Nothing Nothing + | val == "vivado" = Just $ SynthDescription "vivado" Nothing Nothing Nothing + | val == "xst" = Just $ SynthDescription "xst" Nothing Nothing Nothing + | val == "quartus" = Just $ SynthDescription "quartus" Nothing Nothing Nothing + | val == "identity" = Just $ SynthDescription "identity" Nothing Nothing Nothing + | otherwise = Nothing + parseSim :: String -> Maybe OptTool parseSim val | val == "icarus" = Just TIcarus | otherwise = Nothing @@ -180,13 +191,22 @@ reduceOpts = <> showDefault <> value "top" ) - <*> ( strOption + <*> ( optional . strOption $ long "script" - <> short 's' <> metavar "SCRIPT" <> help "Script that determines if the current file is interesting, which is determined by the script returning 0." ) + <*> (many . option (optReader parseSynthDesc) $ + short 's' + <> long "synth" + <> metavar "SYNTH" + <> help "Specify synthesiser to use." + ) + <*> (switch $ + short 'r' + <> long "rerun" + <> help "Only rerun the current synthesis file with all the synthesisers.") configOpts :: Parser Opts configOpts = @@ -346,7 +366,49 @@ handleOpts (Parse f) = do Left l -> print l Right v -> print $ GenVerilog v where file = T.unpack . toTextIgnore $ f -handleOpts (Reduce f t s) = shelly $ reduceWithScript t s f +handleOpts (Reduce f t _ ls' False) = do + src <- parseSourceInfoFile t (toTextIgnore f) + case descriptionToSynth <$> ls' of + a : b : _ -> do + putStrLn "Reduce with equivalence check" + shelly $ do + make dir + pop dir $ do + src' <- reduceSynth a b src + writefile (fromText ".." dir <.> "v") $ genSource src' + a : _ -> do + putStrLn "Reduce with synthesis failure" + shelly $ do + make dir + pop dir $ do + src' <- reduceSynthesis a src + writefile (fromText ".." dir <.> "v") $ genSource src' + _ -> do + putStrLn "Not reducing because no synthesiser was specified" + return () + where + dir = fromText "reduce" +handleOpts (Reduce f t _ ls' True) = do + src <- parseSourceInfoFile t (toTextIgnore f) + case descriptionToSynth <$> ls' of + a : b : _ -> do + putStrLn "Starting equivalence check" + res <- shelly . runResultT $ do + make dir + pop dir $ do + runSynth a src + runSynth b src + runEquiv a b src + case res of + Pass _ -> putStrLn "Equivalence check passed" + Fail EquivFail -> error "Equivalence check failed" + Fail _ -> error "Equivalence check errored out" + return () + as -> do + putStrLn "Synthesis check" + _ <- shelly . runResultT $ mapM (flip runSynth src) as + return () + where dir = fromText "equiv" handleOpts (ConfigOpt c conf r) = do config <- if r then getConfig conf >>= randomise else getConfig conf maybe (T.putStrLn . encodeConfig $ config) (`encodeConfigFile` config) -- cgit From 3ad518489f1528941d4d059e594ad9ac1d22fd0d Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 22:37:11 +0100 Subject: Export helpers from Fuzz.hs --- src/VeriFuzz/Fuzz.hs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 8db6c29..81bec49 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -21,6 +21,9 @@ module VeriFuzz.Fuzz , fuzzMultiple , runFuzz , sampleSeed + -- * Helpers + , make + , pop ) where -- cgit From 11bd73faa516cde0af74e5359c36c8f1fa4e816a Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 May 2019 23:26:27 +0100 Subject: Fix reduction for statements --- src/VeriFuzz.hs | 7 ++++--- src/VeriFuzz/Reduce.hs | 26 ++++++++++++++------------ src/VeriFuzz/Verilog.hs | 2 ++ 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz.hs b/src/VeriFuzz.hs index 6d4f839..4b9878d 100644 --- a/src/VeriFuzz.hs +++ b/src/VeriFuzz.hs @@ -400,9 +400,10 @@ handleOpts (Reduce f t _ ls' True) = do runSynth b src runEquiv a b src case res of - Pass _ -> putStrLn "Equivalence check passed" - Fail EquivFail -> error "Equivalence check failed" - Fail _ -> error "Equivalence check errored out" + Pass _ -> putStrLn "Equivalence check passed" + Fail EquivFail -> putStrLn "Equivalence check failed" + Fail TimeoutError -> putStrLn "Equivalence check timed out" + Fail _ -> putStrLn "Equivalence check error" return () as -> do putStrLn "Synthesis check" diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index b025a42..2f44c07 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -35,27 +35,28 @@ module VeriFuzz.Reduce ) where -import Control.Lens hiding ((<.>)) -import Control.Monad (void) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Data.Foldable (foldrM) -import Data.List (nub) -import Data.List.NonEmpty (NonEmpty (..)) -import qualified Data.List.NonEmpty as NonEmpty -import Data.Maybe (mapMaybe) -import Data.Text (Text) -import Shelly ((<.>)) +import Control.Lens hiding ((<.>)) +import Control.Monad (void) +import Control.Monad.IO.Class (MonadIO, liftIO) +import Data.Foldable (foldrM) +import Data.List (nub) +import Data.List.NonEmpty (NonEmpty (..)) +import qualified Data.List.NonEmpty as NonEmpty +import Data.Maybe (mapMaybe) +import Data.Text (Text) +import Shelly ((<.>)) import qualified Shelly -import Shelly.Lifted (MonadSh, liftSh) +import Shelly.Lifted (MonadSh, liftSh) import VeriFuzz.Internal import VeriFuzz.Result import VeriFuzz.Sim import VeriFuzz.Sim.Internal +import VeriFuzz.Verilog import VeriFuzz.Verilog.AST -import VeriFuzz.Verilog.CodeGen import VeriFuzz.Verilog.Mutate import VeriFuzz.Verilog.Parser + -- $strategy -- The reduction strategy has multiple different steps. 'reduce' will run these -- strategies one after another, starting at the most coarse grained one. The @@ -334,6 +335,7 @@ matchesModName :: Identifier -> ModDecl -> Bool matchesModName top (ModDecl i _ _ _ _) = top == i halveStatement :: Replace Statement +halveStatement (SeqBlock [s]) = halveStatement s halveStatement (SeqBlock s) = SeqBlock <$> halve s halveStatement (CondStmnt _ (Just s1) (Just s2)) = Dual s1 s2 halveStatement (CondStmnt _ (Just s1) Nothing) = Single s1 diff --git a/src/VeriFuzz/Verilog.hs b/src/VeriFuzz/Verilog.hs index 3e8d2c7..628b00a 100644 --- a/src/VeriFuzz/Verilog.hs +++ b/src/VeriFuzz/Verilog.hs @@ -10,6 +10,8 @@ Portability : POSIX Verilog implementation with random generation and mutations. -} +{-# LANGUAGE QuasiQuotes #-} + module VeriFuzz.Verilog ( SourceInfo(..) , Verilog(..) -- cgit From 87b0f99853072ad1b17b380726b3807f6f4f91d4 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 26 May 2019 16:25:40 +0100 Subject: Add changes to work with older Vivado --- src/VeriFuzz/Sim/Vivado.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Sim/Vivado.hs b/src/VeriFuzz/Sim/Vivado.hs index 9f48188..90eed2d 100644 --- a/src/VeriFuzz/Sim/Vivado.hs +++ b/src/VeriFuzz/Sim/Vivado.hs @@ -56,7 +56,7 @@ runSynthVivado sim (SourceInfo top src) = do writefile vivadoTcl . vivadoSynthConfig top . toTextIgnore $ synthOutput sim writefile "rtl.v" $ genSource src - run_ "sed" ["s/^module/(* use_dsp=\"no\" *) module/;", "-i", "rtl.v"] + run_ "sed" ["s/^module/(* use_dsp48=\"no\" *) (* use_dsp=\"no\" *) module/;", "-i", "rtl.v"] let exec_ n = execute_ SynthFail dir -- cgit From 085b83342f8c8b8f1e84aae0fd1eb6c62fb3bf6f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Thu, 30 May 2019 12:18:51 +0100 Subject: Add check for synthfails --- src/VeriFuzz/Fuzz.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 81bec49..3a469de 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -296,7 +296,8 @@ fuzz gen conf = do (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src fails <- failEquivWithIdentity - redResult <- whenMaybe (not $ null fails) . titleRun "Reduction" $ reduction + synthFails <- failedSynthesis + redResult <- whenMaybe (not $ null fails && null synthFails) . titleRun "Reduction" $ reduction src state_ <- get currdir <- liftSh pwd -- cgit From 43e074229c4ea859e66035c716d8bb4fcd037c90 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 2 Jun 2019 12:54:15 +0100 Subject: Add check for quicker reduction --- src/VeriFuzz/Reduce.hs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 2f44c07..2a8b489 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -514,24 +514,26 @@ reduce_ title repl bot eval src = do (src ^.. infoSrc . _Wrapped . traverse . modItems . traverse) ) <> ")" - case repl src of - Single s -> do - red <- eval s - if red - then if cond s then recReduction s else return s - else return src - Dual l r -> do - red <- eval l - if red - then if cond l then recReduction l else return l - else do - red' <- eval r - if red' - then if cond r then recReduction r else return r - else return src - None -> return src + if bot src + then return src + else case repl src of + Single s -> do + red <- eval s + if red + then if cond s then recReduction s else return s + else return src + Dual l r -> do + red <- eval l + if red + then if cond l then recReduction l else return l + else do + red' <- eval r + if red' + then if cond r then recReduction r else return r + else return src + None -> return src where - cond s = s /= src && not (bot s) + cond s = s /= src recReduction = reduce_ title repl bot eval -- | Reduce an input to a minimal representation. It follows the reduction -- cgit From 12a74a1841ffb5842af029ffcce77c3e765e00f8 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 2 Jun 2019 12:54:35 +0100 Subject: Add fix to synthesise correctly with Quartus without MAC --- src/VeriFuzz/Sim/Quartus.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Sim/Quartus.hs b/src/VeriFuzz/Sim/Quartus.hs index 4007004..a099495 100644 --- a/src/VeriFuzz/Sim/Quartus.hs +++ b/src/VeriFuzz/Sim/Quartus.hs @@ -53,9 +53,10 @@ runSynthQuartus sim (SourceInfo top src) = do dir <- liftSh pwd let ex = execute_ SynthFail dir "quartus" liftSh . writefile inpf $ genSource src + liftSh . noPrint $ run_ "sed" ["-i", "s/^module/(* multstyle = \"logic\" *) module/;", toTextIgnore inpf] ex (exec "quartus_map") [top, "--source=" <> toTextIgnore inpf, "--family=Cyclone V"] - ex (exec "quartus_fit") [top, "--part=5CGTFD9E5F35C7N"] + ex (exec "quartus_fit") [top, "--part=5CGXFC7D6F31C6"] ex (exec "quartus_eda") [top, "--simulation", "--tool=vcs"] liftSh $ do cp (fromText "simulation/vcs" fromText top <.> "vo") -- cgit From 58eb1aea52fb57666f2f4e620e3ac9a8dd05522c Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 2 Jun 2019 12:55:19 +0100 Subject: Add XOR to the output --- src/VeriFuzz/Verilog/Gen.hs | 2 +- src/VeriFuzz/Verilog/Mutate.hs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index bc40de5..828224f 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -464,7 +464,7 @@ moduleDef top = do ^.. traverse . portSize let clock = Port Wire False 1 "clk" - let yport = Port Wire False size "y" + let yport = Port Wire False 1 "y" let comb = combineAssigns_ yport local return . declareMod local diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs index 66f3c37..8af0182 100644 --- a/src/VeriFuzz/Verilog/Mutate.hs +++ b/src/VeriFuzz/Verilog/Mutate.hs @@ -377,13 +377,14 @@ removeId i = transform trans combineAssigns :: Port -> [ModItem] -> [ModItem] combineAssigns p a = - a <> [ModCA . ContAssign (p ^. portName) . fold $ Id <$> assigns] + a <> [ModCA . ContAssign (p ^. portName) . UnOp UnXor . fold $ Id <$> assigns] where assigns = a ^.. traverse . modContAssign . contAssignNetLVal combineAssigns_ :: Port -> [Port] -> ModItem combineAssigns_ p ps = ModCA . ContAssign (p ^. portName) + . UnOp UnXor . fold $ Id <$> ps -- cgit From f4dbd5a813de78a9241573a498a9bb1cb40c65f3 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 2 Jun 2019 13:25:37 +0100 Subject: Remove dead code --- src/VeriFuzz/Verilog/Gen.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index 828224f..c903e28 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -464,7 +464,7 @@ moduleDef top = do ^.. traverse . portSize let clock = Port Wire False 1 "clk" - let yport = Port Wire False 1 "y" + let yport = if True then Port Wire False 1 "y" else Port Wire False size "y" let comb = combineAssigns_ yport local return . declareMod local -- cgit From e4737c37c9dc358d56dbb7a97d68de2c93053c0c Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sun, 2 Jun 2019 19:21:36 +0100 Subject: Add median and mean sampling --- src/VeriFuzz/Fuzz.hs | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 3a469de..00f1926 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -76,6 +76,8 @@ data FuzzState = FuzzState { _fuzzSynthResults :: ![SynthResult] $(makeLenses ''FuzzState) +type Frequency a = [(Seed, a)] -> [(Int, Gen (Seed, a))] + -- | The main type for the fuzzing, which contains an environment that can be -- read from and the current state of all the results. type Fuzz m = StateT FuzzState (ReaderT FuzzEnv m) @@ -268,19 +270,39 @@ generateSample f = do verilogSize :: (Source a) => a -> Int verilogSize = length . lines . T.unpack . genSource -sampleVerilogHat :: (MonadIO m, MonadSh m) => Int -> Maybe Seed -> Gen SourceInfo -> Fuzz m (Seed, SourceInfo) -sampleVerilogHat _ seed@(Just _) gen = sampleSeed seed gen -sampleVerilogHat n Nothing gen = do +sampleVerilog + :: (MonadSh m, MonadIO m, Source a, Ord a) => + Frequency a -> Int -> Maybe Seed -> Gen a -> m (Seed, a) +sampleVerilog _ _ seed@(Just _) gen = sampleSeed seed gen +sampleVerilog freq n Nothing gen = do res <- replicateM n $ sampleSeed Nothing gen let sizes = fmap getSize res let samples = fmap snd . sort $ zip sizes res - liftIO $ Hog.sample . Hog.frequency $ freqs samples + liftIO $ Hog.sample . Hog.frequency $ freq samples where getSize (_, s) = verilogSize s - freqs l = zip hat (return <$> l) - where - h = length l `div` 2 - hat = (+ h) . negate . abs . (h - ) <$> [1..length l] + +hatFreqs :: Frequency a +hatFreqs l = zip hat (return <$> l) + where + h = length l `div` 2 + hat = (+ h) . negate . abs . (h - ) <$> [1..length l] + +meanFreqs :: Source a => Frequency a +meanFreqs l = zip hat (return <$> l) + where + hat = calc <$> sizes + calc i = if abs (mean - i) == min_ then 1 else 0 + mean = sum sizes `div` length l + min_ = minimum $ abs . (mean -) <$> sizes + sizes = verilogSize . snd <$> l + +medianFreqs :: Frequency a +medianFreqs l = zip hat (return <$> l) + where + h = length l `div` 2 + hat = set_ <$> [1..length l] + set_ n = if n == h then 1 else 0 fuzz :: MonadFuzz m => Gen SourceInfo -> Config -> Fuzz m FuzzReport fuzz gen conf = do @@ -315,13 +337,20 @@ fuzz gen conf = do where seed = conf ^. configProperty . propSeed bname = T.pack . takeBaseName . T.unpack . toTextIgnore - genMethod = case conf ^. configProperty . propSampleMethod of + genMethod = case T.toLower $ conf ^. configProperty . propSampleMethod of "hat" -> do logT "Using the hat function" - sampleVerilogHat (conf ^. configProperty . propSampleSize) seed gen + sv hatFreqs + "mean" -> do + logT "Using the mean function" + sv meanFreqs + "median" -> do + logT "Using the median function" + sv medianFreqs _ -> do logT "Using first seed" sampleSeed seed gen + sv a = sampleVerilog a (conf ^. configProperty . propSampleSize) seed gen relativeFuzzReport :: (MonadSh m) => FuzzReport -> m FuzzReport relativeFuzzReport fr@(FuzzReport dir _ _ _ _ _ _ _) = liftSh $ do -- cgit From c40faa081ae7f31cb1b6125d1c5c3bdf650f3f63 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 5 Jun 2019 12:06:49 +0100 Subject: Add combination option --- src/VeriFuzz/Config.hs | 6 +++++- src/VeriFuzz/Verilog/Gen.hs | 3 ++- src/VeriFuzz/Verilog/Mutate.hs | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Config.hs b/src/VeriFuzz/Config.hs index 375c739..dd61d31 100644 --- a/src/VeriFuzz/Config.hs +++ b/src/VeriFuzz/Config.hs @@ -68,6 +68,7 @@ module VeriFuzz.Config , propStmntDepth , propModDepth , propMaxModules + , propCombine , parseConfigFile , parseConfig , encodeConfig @@ -198,6 +199,7 @@ data ConfProperty = ConfProperty { _propSize :: {-# UNPACK #-} !Int , _propMaxModules :: {-# UNPACK #-} !Int , _propSampleMethod :: !Text , _propSampleSize :: {-# UNPACK #-} !Int + , _propCombine :: {-# UNPACK #-} !Bool } deriving (Eq, Show) @@ -265,7 +267,7 @@ defaultConfig :: Config defaultConfig = Config (Info (pack $(gitHash)) (pack $ showVersion version)) (Probability defModItem defStmnt defExpr) - (ConfProperty 20 Nothing 3 2 5 "random" 10) + (ConfProperty 20 Nothing 3 2 5 "random" 10 False) [] [fromYosys defaultYosys, fromVivado defaultVivado] where @@ -382,6 +384,8 @@ propCodec = .= _propSampleMethod <*> defaultValue (defProp propSampleSize) (int "sample" "size") .= _propSampleSize + <*> defaultValue (defProp propCombine) (Toml.bool (twoKey "output" "combine")) + .= _propCombine where defProp i = defaultConfig ^. configProperty . i simulator :: TomlCodec SimDescription diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index c903e28..cb3a8ad 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -455,6 +455,7 @@ moduleDef top = do mi <- Hog.list (Hog.linear 4 100) modItem ps <- Hog.list (Hog.linear 0 10) parameter context <- get + config <- lift ask let local = filter (`notElem` portList) $ _variables context let size = @@ -465,7 +466,7 @@ moduleDef top = do . portSize let clock = Port Wire False 1 "clk" let yport = if True then Port Wire False 1 "y" else Port Wire False size "y" - let comb = combineAssigns_ yport local + let comb = combineAssigns_ (config ^. configProperty . propCombine) yport local return . declareMod local . ModDecl name [yport] (clock : portList) (comb : mi) diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs index 8af0182..7496935 100644 --- a/src/VeriFuzz/Verilog/Mutate.hs +++ b/src/VeriFuzz/Verilog/Mutate.hs @@ -380,11 +380,11 @@ combineAssigns p a = a <> [ModCA . ContAssign (p ^. portName) . UnOp UnXor . fold $ Id <$> assigns] where assigns = a ^.. traverse . modContAssign . contAssignNetLVal -combineAssigns_ :: Port -> [Port] -> ModItem -combineAssigns_ p ps = +combineAssigns_ :: Bool -> Port -> [Port] -> ModItem +combineAssigns_ comb p ps = ModCA . ContAssign (p ^. portName) - . UnOp UnXor + . (if comb then UnOp UnXor else id) . fold $ Id <$> ps -- cgit From f3268d934a9a2b01633b5f7a3353d1a97c40a9df Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 5 Jun 2019 13:26:47 +0100 Subject: Fix size in output wire --- src/VeriFuzz/Verilog/Gen.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index cb3a8ad..c8860ce 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -464,9 +464,10 @@ moduleDef top = do $ local ^.. traverse . portSize + let combine = config ^. configProperty . propCombine let clock = Port Wire False 1 "clk" - let yport = if True then Port Wire False 1 "y" else Port Wire False size "y" - let comb = combineAssigns_ (config ^. configProperty . propCombine) yport local + let yport = if combine then Port Wire False 1 "y" else Port Wire False size "y" + let comb = combineAssigns_ combine yport local return . declareMod local . ModDecl name [yport] (clock : portList) (comb : mi) -- cgit From 720fa7a822a077458cf0b29e9dcdc754a881e8bd Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 5 Jun 2019 13:52:20 +0100 Subject: Format all files --- src/VeriFuzz.hs | 46 +++++++++++++---------- src/VeriFuzz/Config.hs | 12 +++--- src/VeriFuzz/Fuzz.hs | 85 ++++++++++++++++++++++-------------------- src/VeriFuzz/Reduce.hs | 56 ++++++++++++++-------------- src/VeriFuzz/Report.hs | 10 ++++- src/VeriFuzz/Sim/Quartus.hs | 7 +++- src/VeriFuzz/Sim/Vivado.hs | 7 +++- src/VeriFuzz/Sim/Yosys.hs | 6 ++- src/VeriFuzz/Verilog/Gen.hs | 9 +++-- src/VeriFuzz/Verilog/Mutate.hs | 9 ++++- 10 files changed, 143 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz.hs b/src/VeriFuzz.hs index 4b9878d..7bc562f 100644 --- a/src/VeriFuzz.hs +++ b/src/VeriFuzz.hs @@ -111,12 +111,15 @@ parseSynth val | val == "yosys" = Just TYosys | otherwise = Nothing parseSynthDesc :: String -> Maybe SynthDescription -parseSynthDesc val | val == "yosys" = Just $ SynthDescription "yosys" Nothing Nothing Nothing - | val == "vivado" = Just $ SynthDescription "vivado" Nothing Nothing Nothing - | val == "xst" = Just $ SynthDescription "xst" Nothing Nothing Nothing - | val == "quartus" = Just $ SynthDescription "quartus" Nothing Nothing Nothing - | val == "identity" = Just $ SynthDescription "identity" Nothing Nothing Nothing - | otherwise = Nothing +parseSynthDesc val + | val == "yosys" = Just $ SynthDescription "yosys" Nothing Nothing Nothing + | val == "vivado" = Just $ SynthDescription "vivado" Nothing Nothing Nothing + | val == "xst" = Just $ SynthDescription "xst" Nothing Nothing Nothing + | val == "quartus" = Just + $ SynthDescription "quartus" Nothing Nothing Nothing + | val == "identity" = Just + $ SynthDescription "identity" Nothing Nothing Nothing + | otherwise = Nothing parseSim :: String -> Maybe OptTool parseSim val | val == "icarus" = Just TIcarus @@ -191,22 +194,26 @@ reduceOpts = <> showDefault <> value "top" ) - <*> ( optional . strOption + <*> ( optional + . strOption $ long "script" <> metavar "SCRIPT" <> help "Script that determines if the current file is interesting, which is determined by the script returning 0." ) - <*> (many . option (optReader parseSynthDesc) $ - short 's' - <> long "synth" - <> metavar "SYNTH" - <> help "Specify synthesiser to use." - ) - <*> (switch $ - short 'r' - <> long "rerun" - <> help "Only rerun the current synthesis file with all the synthesisers.") + <*> ( many + . option (optReader parseSynthDesc) + $ short 's' + <> long "synth" + <> metavar "SYNTH" + <> help "Specify synthesiser to use." + ) + <*> ( switch + $ short 'r' + <> long "rerun" + <> help + "Only rerun the current synthesis file with all the synthesisers." + ) configOpts :: Parser Opts configOpts = @@ -386,8 +393,7 @@ handleOpts (Reduce f t _ ls' False) = do _ -> do putStrLn "Not reducing because no synthesiser was specified" return () - where - dir = fromText "reduce" + where dir = fromText "reduce" handleOpts (Reduce f t _ ls' True) = do src <- parseSourceInfoFile t (toTextIgnore f) case descriptionToSynth <$> ls' of @@ -409,7 +415,7 @@ handleOpts (Reduce f t _ ls' True) = do putStrLn "Synthesis check" _ <- shelly . runResultT $ mapM (flip runSynth src) as return () - where dir = fromText "equiv" + where dir = fromText "equiv" handleOpts (ConfigOpt c conf r) = do config <- if r then getConfig conf >>= randomise else getConfig conf maybe (T.putStrLn . encodeConfig $ config) (`encodeConfigFile` config) diff --git a/src/VeriFuzz/Config.hs b/src/VeriFuzz/Config.hs index dd61d31..19cdd68 100644 --- a/src/VeriFuzz/Config.hs +++ b/src/VeriFuzz/Config.hs @@ -380,12 +380,14 @@ propCodec = .= _propModDepth <*> defaultValue (defProp propMaxModules) (int "module" "max") .= _propMaxModules - <*> defaultValue (defProp propSampleMethod) (Toml.text (twoKey "sample" "method")) - .= _propSampleMethod + <*> defaultValue (defProp propSampleMethod) + (Toml.text (twoKey "sample" "method")) + .= _propSampleMethod <*> defaultValue (defProp propSampleSize) (int "sample" "size") - .= _propSampleSize - <*> defaultValue (defProp propCombine) (Toml.bool (twoKey "output" "combine")) - .= _propCombine + .= _propSampleSize + <*> defaultValue (defProp propCombine) + (Toml.bool (twoKey "output" "combine")) + .= _propCombine where defProp i = defaultConfig ^. configProperty . i simulator :: TomlCodec SimDescription diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 00f1926..dadae90 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -221,10 +221,10 @@ failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get -- | Always reduces with respect to 'Identity'. reduction :: (MonadSh m) => SourceInfo -> Fuzz m () reduction src = do - fails <- failEquivWithIdentity + fails <- failEquivWithIdentity synthFails <- failedSynthesis - _ <- liftSh $ mapM red fails - _ <- liftSh $ mapM redSynth synthFails + _ <- liftSh $ mapM red fails + _ <- liftSh $ mapM redSynth synthFails return () where red (SynthResult a b _ _) = do @@ -271,38 +271,41 @@ verilogSize :: (Source a) => a -> Int verilogSize = length . lines . T.unpack . genSource sampleVerilog - :: (MonadSh m, MonadIO m, Source a, Ord a) => - Frequency a -> Int -> Maybe Seed -> Gen a -> m (Seed, a) -sampleVerilog _ _ seed@(Just _) gen = sampleSeed seed gen -sampleVerilog freq n Nothing gen = do + :: (MonadSh m, MonadIO m, Source a, Ord a) + => Frequency a + -> Int + -> Maybe Seed + -> Gen a + -> m (Seed, a) +sampleVerilog _ _ seed@(Just _) gen = sampleSeed seed gen +sampleVerilog freq n Nothing gen = do res <- replicateM n $ sampleSeed Nothing gen - let sizes = fmap getSize res + let sizes = fmap getSize res let samples = fmap snd . sort $ zip sizes res liftIO $ Hog.sample . Hog.frequency $ freq samples - where - getSize (_, s) = verilogSize s + where getSize (_, s) = verilogSize s hatFreqs :: Frequency a hatFreqs l = zip hat (return <$> l) - where - h = length l `div` 2 - hat = (+ h) . negate . abs . (h - ) <$> [1..length l] + where + h = length l `div` 2 + hat = (+ h) . negate . abs . (h -) <$> [1 .. length l] meanFreqs :: Source a => Frequency a meanFreqs l = zip hat (return <$> l) - where - hat = calc <$> sizes - calc i = if abs (mean - i) == min_ then 1 else 0 - mean = sum sizes `div` length l - min_ = minimum $ abs . (mean -) <$> sizes - sizes = verilogSize . snd <$> l + where + hat = calc <$> sizes + calc i = if abs (mean - i) == min_ then 1 else 0 + mean = sum sizes `div` length l + min_ = minimum $ abs . (mean -) <$> sizes + sizes = verilogSize . snd <$> l medianFreqs :: Frequency a medianFreqs l = zip hat (return <$> l) - where - h = length l `div` 2 - hat = set_ <$> [1..length l] - set_ n = if n == h then 1 else 0 + where + h = length l `div` 2 + hat = set_ <$> [1 .. length l] + set_ n = if n == h then 1 else 0 fuzz :: MonadFuzz m => Gen SourceInfo -> Config -> Fuzz m FuzzReport fuzz gen conf = do @@ -318,9 +321,11 @@ fuzz gen conf = do (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src fails <- failEquivWithIdentity - synthFails <- failedSynthesis - redResult <- whenMaybe (not $ null fails && null synthFails) . titleRun "Reduction" $ reduction - src + synthFails <- failedSynthesis + redResult <- + whenMaybe (not $ null fails && null synthFails) + . titleRun "Reduction" + $ reduction src state_ <- get currdir <- liftSh pwd let vi = flip view state_ @@ -335,21 +340,21 @@ fuzz gen conf = do liftSh . writefile "index.html" $ printResultReport (bname currdir) report return report where - seed = conf ^. configProperty . propSeed - bname = T.pack . takeBaseName . T.unpack . toTextIgnore + seed = conf ^. configProperty . propSeed + bname = T.pack . takeBaseName . T.unpack . toTextIgnore genMethod = case T.toLower $ conf ^. configProperty . propSampleMethod of - "hat" -> do - logT "Using the hat function" - sv hatFreqs - "mean" -> do - logT "Using the mean function" - sv meanFreqs - "median" -> do - logT "Using the median function" - sv medianFreqs - _ -> do - logT "Using first seed" - sampleSeed seed gen + "hat" -> do + logT "Using the hat function" + sv hatFreqs + "mean" -> do + logT "Using the mean function" + sv meanFreqs + "median" -> do + logT "Using the median function" + sv medianFreqs + _ -> do + logT "Using first seed" + sampleSeed seed gen sv a = sampleVerilog a (conf ^. configProperty . propSampleSize) seed gen relativeFuzzReport :: (MonadSh m) => FuzzReport -> m FuzzReport diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 2a8b489..7cee31c 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -257,7 +257,7 @@ exprId (RangeSelect i _) = Just i exprId _ = Nothing eventId :: Event -> Maybe Identifier -eventId (EId i) = Just i +eventId (EId i) = Just i eventId (EPosEdge i) = Just i eventId (ENegEdge i) = Just i eventId _ = Nothing @@ -411,12 +411,13 @@ toIdsEvent = nub . mapMaybe eventId . concatMap universe allStatIds' :: Statement -> [Identifier] allStatIds' s = nub $ assignIds <> otherExpr <> eventProcessedIds where - assignIds = toIds + assignIds = + toIds $ (s ^.. stmntBA . assignExpr) <> (s ^.. stmntNBA . assignExpr) <> (s ^.. forAssign . assignExpr) <> (s ^.. forIncr . assignExpr) - otherExpr = toIds $ (s ^.. forExpr) <> (s ^.. stmntCondExpr) + otherExpr = toIds $ (s ^.. forExpr) <> (s ^.. stmntCondExpr) eventProcessedIds = toIdsEvent $ s ^.. statEvent allStatIds :: Statement -> [Identifier] @@ -517,21 +518,21 @@ reduce_ title repl bot eval src = do if bot src then return src else case repl src of - Single s -> do - red <- eval s - if red - then if cond s then recReduction s else return s - else return src - Dual l r -> do - red <- eval l - if red - then if cond l then recReduction l else return l - else do - red' <- eval r - if red' - then if cond r then recReduction r else return r - else return src - None -> return src + Single s -> do + red <- eval s + if red + then if cond s then recReduction s else return s + else return src + Dual l r -> do + red <- eval l + if red + then if cond l then recReduction l else return l + else do + red' <- eval r + if red' + then if cond r then recReduction r else return r + else return src + None -> return src where cond s = s /= src recReduction = reduce_ title repl bot eval @@ -597,15 +598,12 @@ reduceSynth a b = reduce synth Fail _ -> False Pass _ -> False -reduceSynthesis :: (Synthesiser a, MonadSh m) - => a - -> SourceInfo - -> m SourceInfo +reduceSynthesis :: (Synthesiser a, MonadSh m) => a -> SourceInfo -> m SourceInfo reduceSynthesis a = reduce synth - where - synth src = liftSh $ do - r <- runResultT $ runSynth a src - return $ case r of - Fail SynthFail -> True - Fail _ -> False - Pass _ -> False + where + synth src = liftSh $ do + r <- runResultT $ runSynth a src + return $ case r of + Fail SynthFail -> True + Fail _ -> False + Pass _ -> False diff --git a/src/VeriFuzz/Report.hs b/src/VeriFuzz/Report.hs index 20addfb..fb66275 100644 --- a/src/VeriFuzz/Report.hs +++ b/src/VeriFuzz/Report.hs @@ -356,7 +356,13 @@ summary name fuzz = H.docTypeHtml $ do H.tr $ H.toHtml [ H.td $ H.strong "Total" , H.td mempty - , H.td . H.string . show . sum $ fuzz ^.. traverse . fileLines + , H.td + . H.string + . show + . sum + $ fuzz + ^.. traverse + . fileLines , sumUp synthTime , sumUp equivTime , sumUp reducTime @@ -382,7 +388,7 @@ summary name fuzz = H.docTypeHtml $ do meanVar s = bimap d2T d2T $ fuzzStats s fuzz showHtml = H.td . H.string . show d2T = showHtml . (realToFrac :: Double -> NominalDiffTime) - d2I = H.td . H.string . show + d2I = H.td . H.string . show printResultReport :: Text -> FuzzReport -> Text printResultReport t f = toStrict . renderHtml $ resultReport t f diff --git a/src/VeriFuzz/Sim/Quartus.hs b/src/VeriFuzz/Sim/Quartus.hs index a099495..4217abb 100644 --- a/src/VeriFuzz/Sim/Quartus.hs +++ b/src/VeriFuzz/Sim/Quartus.hs @@ -53,7 +53,12 @@ runSynthQuartus sim (SourceInfo top src) = do dir <- liftSh pwd let ex = execute_ SynthFail dir "quartus" liftSh . writefile inpf $ genSource src - liftSh . noPrint $ run_ "sed" ["-i", "s/^module/(* multstyle = \"logic\" *) module/;", toTextIgnore inpf] + liftSh . noPrint $ run_ + "sed" + [ "-i" + , "s/^module/(* multstyle = \"logic\" *) module/;" + , toTextIgnore inpf + ] ex (exec "quartus_map") [top, "--source=" <> toTextIgnore inpf, "--family=Cyclone V"] ex (exec "quartus_fit") [top, "--part=5CGXFC7D6F31C6"] diff --git a/src/VeriFuzz/Sim/Vivado.hs b/src/VeriFuzz/Sim/Vivado.hs index 90eed2d..a4feb07 100644 --- a/src/VeriFuzz/Sim/Vivado.hs +++ b/src/VeriFuzz/Sim/Vivado.hs @@ -56,7 +56,12 @@ runSynthVivado sim (SourceInfo top src) = do writefile vivadoTcl . vivadoSynthConfig top . toTextIgnore $ synthOutput sim writefile "rtl.v" $ genSource src - run_ "sed" ["s/^module/(* use_dsp48=\"no\" *) (* use_dsp=\"no\" *) module/;", "-i", "rtl.v"] + run_ + "sed" + [ "s/^module/(* use_dsp48=\"no\" *) (* use_dsp=\"no\" *) module/;" + , "-i" + , "rtl.v" + ] let exec_ n = execute_ SynthFail dir diff --git a/src/VeriFuzz/Sim/Yosys.hs b/src/VeriFuzz/Sim/Yosys.hs index 3729a1e..02a00d5 100644 --- a/src/VeriFuzz/Sim/Yosys.hs +++ b/src/VeriFuzz/Sim/Yosys.hs @@ -67,7 +67,11 @@ runSynthYosys sim (SourceInfo _ src) = do dir' <- pwd writefile inpf $ genSource src return dir' - execute_ SynthFail dir "yosys" (yosysPath sim) + execute_ + SynthFail + dir + "yosys" + (yosysPath sim) [ "-p" , "read -formal " <> inp <> "; synth; write_verilog -noattr " <> out ] diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index c8860ce..e52a158 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -455,7 +455,7 @@ moduleDef top = do mi <- Hog.list (Hog.linear 4 100) modItem ps <- Hog.list (Hog.linear 0 10) parameter context <- get - config <- lift ask + config <- lift ask let local = filter (`notElem` portList) $ _variables context let size = @@ -465,9 +465,10 @@ moduleDef top = do ^.. traverse . portSize let combine = config ^. configProperty . propCombine - let clock = Port Wire False 1 "clk" - let yport = if combine then Port Wire False 1 "y" else Port Wire False size "y" - let comb = combineAssigns_ combine yport local + let clock = Port Wire False 1 "clk" + let yport = + if combine then Port Wire False 1 "y" else Port Wire False size "y" + let comb = combineAssigns_ combine yport local return . declareMod local . ModDecl name [yport] (clock : portList) (comb : mi) diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs index 7496935..0fb4c49 100644 --- a/src/VeriFuzz/Verilog/Mutate.hs +++ b/src/VeriFuzz/Verilog/Mutate.hs @@ -377,7 +377,14 @@ removeId i = transform trans combineAssigns :: Port -> [ModItem] -> [ModItem] combineAssigns p a = - a <> [ModCA . ContAssign (p ^. portName) . UnOp UnXor . fold $ Id <$> assigns] + a + <> [ ModCA + . ContAssign (p ^. portName) + . UnOp UnXor + . fold + $ Id + <$> assigns + ] where assigns = a ^.. traverse . modContAssign . contAssignNetLVal combineAssigns_ :: Bool -> Port -> [Port] -> ModItem -- cgit From a3cf56b7e2edef87181c534dea099a884ac99306 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Mon, 17 Jun 2019 16:13:00 +0100 Subject: Add part of the simulator implementation --- src/VeriFuzz/Fuzz.hs | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/VeriFuzz/Sim/Icarus.hs | 40 +++++++++++++++++++++++++++++++++++++++ src/VeriFuzz/Sim/Template.hs | 24 ++++++++++++++++++----- 3 files changed, 104 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index dadae90..3aeb0e0 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -211,6 +211,44 @@ equivalence src = do runEquiv a b src where dir = fromText $ "equiv_" <> toText a <> "_" <> toText b +simulation :: (MonadBaseControl IO m, MonadSh m) => SourceInfo -> Fuzz m () +simulation src = do + synth <- passEquiv +-- let synthComb = +-- nubBy tupEq . filter (uncurry (/=)) $ combinations synth synth + let synthComb = + nubBy tupEq + . filter (uncurry (/=)) + $ (,) defaultIdentitySynth + <$> synth + resTimes <- liftSh $ mapM (uncurry equiv) synthComb + fuzzSynthResults .= toSynthResult synthComb resTimes + liftSh $ inspect resTimes + where + tupEq (a, b) (a', b') = (a == a' && b == b') || (a == b' && b == a') + equiv a b = + toolRun ("equivalence check for " <> toText a <> " and " <> toText b) + . runResultT + $ do + make dir + pop dir $ do + liftSh $ do + cp + ( fromText ".." + fromText (toText a) + synthOutput a + ) + $ synthOutput a + cp + ( fromText ".." + fromText (toText b) + synthOutput b + ) + $ synthOutput b + writefile "rtl.v" $ genSource src + runEquiv a b src + where dir = fromText $ "equiv_" <> toText a <> "_" <> toText b + failEquivWithIdentity :: (MonadSh m) => Fuzz m [SynthResult] failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get where @@ -218,6 +256,12 @@ failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get withIdentity (SynthResult _ (IdentitySynth _) (Fail EquivFail) _) = True withIdentity _ = False +passEquiv :: (MonadSh m) => Fuzz m [SynthResult] +passEquiv = filter withIdentity . _fuzzSynthResults <$> get + where + withIdentity (SynthResult _ _ (Pass _) _) = True + withIdentity _ = False + -- | Always reduces with respect to 'Identity'. reduction :: (MonadSh m) => SourceInfo -> Fuzz m () reduction src = do @@ -320,6 +364,7 @@ fuzz gen conf = do ?~ seed' (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src + (tsim, _) <- titleRun "Equivalence Check" $ simulation src fails <- failEquivWithIdentity synthFails <- failedSynthesis redResult <- diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs index 6c5751a..6df2cf7 100644 --- a/src/VeriFuzz/Sim/Icarus.hs +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -123,3 +123,43 @@ runSimIcarusWithFile sim f _ = annotate SimFail . liftSh $ do dir "vvp" (runFoldLines (mempty :: ByteString) callback (vvpPath sim) ["main"]) + +runSimIc + :: (Synthesiser a) => a -> SourceInfo -> [ByteString] -> ResultSh ByteString +runSimIc sim1 srcInfo bss = do + dir <- liftSh pwd + let top = srcInfo ^. mainModule + let inConcat = (RegConcat (Id . fromPort <$> (top ^. modInPorts))) + let tb = ModDecl + "testbench" + [] + [] + [ Initial + $ fold [ BlockAssign (Assign "clk" Nothing 0) + , BlockAssign (Assign inConcat Nothing 0) + ] + <> (SysTaskEnable $ Task "finish" []) + , Always . TimeCtrl 5 $ BlockAssign (Assign "clk" Nothing (UnNot (Id "clk"))) + , Always . EventCtrl (EPosEdge "clk") $ SysTaskEnable $ Task "strobe" ["%b", Id "y"] + ] + [] + liftSh $ do + writefile "top.v" + . genSource + . initMod + . makeTopAssert + $ srcInfo + ^. mainModule + replaceMods (synthOutput sim1) "_1" srcInfo + replaceMods (synthOutput sim2) "_2" srcInfo + writefile "proof.sby" $ sbyConfig sim1 sim2 srcInfo + e <- liftSh $ do + exe dir "symbiyosys" "sby" ["-f", "proof.sby"] + lastExitCode + case e of + 0 -> ResultT . return $ Pass () + 2 -> ResultT . return $ Fail EquivFail + 124 -> ResultT . return $ Fail TimeoutError + _ -> ResultT . return $ Fail EquivError + where + exe dir name e = void . errExit False . logCommand dir name . timeout e diff --git a/src/VeriFuzz/Sim/Template.hs b/src/VeriFuzz/Sim/Template.hs index 4aa07f6..913b220 100644 --- a/src/VeriFuzz/Sim/Template.hs +++ b/src/VeriFuzz/Sim/Template.hs @@ -18,17 +18,19 @@ module VeriFuzz.Sim.Template , xstSynthConfig , vivadoSynthConfig , sbyConfig + , icarusTestbench ) where -import Control.Lens ((^..)) -import Data.Text (Text) -import qualified Data.Text as T -import Prelude hiding (FilePath) +import Control.Lens ((^..)) +import Data.Text (Text) +import qualified Data.Text as T +import Prelude hiding (FilePath) import Shelly -import Text.Shakespeare.Text (st) +import Text.Shakespeare.Text (st) import VeriFuzz.Sim.Internal import VeriFuzz.Verilog.AST +import VeriFuzz.Verilog.CodeGen rename :: Text -> [Text] -> Text rename end entries = @@ -117,3 +119,15 @@ top.v . fromText <$> deps readL = T.intercalate "\n" $ mappend "read -formal " <$> deps + +icarusTestbench :: (Synthesiser a) => Verilog -> a -> Text +icarusTestbench t synth1 = [st| +`include "data/cells_cmos.v" +`include "data/cells_cyclone_v.v" +`include "data/cells_verific.v" +`include "data/cells_xilinx_7.v" +`include "data/cells_yosys.v" +`include "#{synthOutput synth1}" + +#{genSource t} +|] -- cgit From 24cf9ce5bf673615ebe36f5ab5d0ff7685dfada6 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 25 Jun 2019 22:32:21 +0100 Subject: Add back the simulation --- src/VeriFuzz/Fuzz.hs | 49 +++++++++++++++++++++++------------------ src/VeriFuzz/Sim/Icarus.hs | 52 ++++++++++++++++++++++---------------------- src/VeriFuzz/Sim/Template.hs | 2 +- 3 files changed, 55 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 3aeb0e0..181207c 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -37,6 +37,11 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Maybe (runMaybeT) import Control.Monad.Trans.Reader hiding (local) import Control.Monad.Trans.State.Strict +import qualified Crypto.Random.DRBG as C +import Data.ByteString (ByteString) +import Data.ByteString.Builder (byteStringHex, + toLazyByteString) +import qualified Data.ByteString.Lazy as L import Data.List (nubBy, sort) import Data.Maybe (isNothing) import Data.Text (Text) @@ -57,6 +62,7 @@ import VeriFuzz.Internal import VeriFuzz.Reduce import VeriFuzz.Report import VeriFuzz.Result +import VeriFuzz.Sim.Icarus import VeriFuzz.Sim.Internal import VeriFuzz.Sim.Yosys import VeriFuzz.Verilog.AST @@ -211,23 +217,17 @@ equivalence src = do runEquiv a b src where dir = fromText $ "equiv_" <> toText a <> "_" <> toText b -simulation :: (MonadBaseControl IO m, MonadSh m) => SourceInfo -> Fuzz m () +simulation :: (MonadIO m, MonadSh m) => SourceInfo -> Fuzz m () simulation src = do synth <- passEquiv --- let synthComb = --- nubBy tupEq . filter (uncurry (/=)) $ combinations synth synth - let synthComb = - nubBy tupEq - . filter (uncurry (/=)) - $ (,) defaultIdentitySynth - <$> synth - resTimes <- liftSh $ mapM (uncurry equiv) synthComb - fuzzSynthResults .= toSynthResult synthComb resTimes + vals <- liftIO $ generateByteString 20 + resTimes <- liftSh $ mapM (equiv vals) $ conv <$> synth liftSh $ inspect resTimes where tupEq (a, b) (a', b') = (a == a' && b == b') || (a == b' && b == a') - equiv a b = - toolRun ("equivalence check for " <> toText a <> " and " <> toText b) + conv (SynthResult a _ _ _) = a + equiv b a = + toolRun ("simulation for " <> toText a) . runResultT $ do make dir @@ -239,15 +239,22 @@ simulation src = do synthOutput a ) $ synthOutput a - cp - ( fromText ".." - fromText (toText b) - synthOutput b - ) - $ synthOutput b writefile "rtl.v" $ genSource src - runEquiv a b src - where dir = fromText $ "equiv_" <> toText a <> "_" <> toText b + runSimIc defaultIcarus a src b + where dir = fromText $ "simulation_" <> toText a + +-- | Generate a specific number of random bytestrings of size 256. +randomByteString :: C.CtrDRBG -> Int -> [ByteString] -> [ByteString] +randomByteString gen n bytes + | n == 0 = ranBytes : bytes + | otherwise = randomByteString newGen (n - 1) $ ranBytes : bytes + where Right (ranBytes, newGen) = C.genBytes 32 gen + +-- | generates the specific number of bytestring with a random seed. +generateByteString :: Int -> IO [ByteString] +generateByteString n = do + gen <- C.newGenIO :: IO C.CtrDRBG + return $ randomByteString gen n [] failEquivWithIdentity :: (MonadSh m) => Fuzz m [SynthResult] failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get @@ -364,7 +371,7 @@ fuzz gen conf = do ?~ seed' (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src - (tsim, _) <- titleRun "Equivalence Check" $ simulation src + (tsim, _) <- titleRun "Simulation" $ simulation src fails <- failEquivWithIdentity synthFails <- failedSynthesis redResult <- diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs index 6df2cf7..a5a3227 100644 --- a/src/VeriFuzz/Sim/Icarus.hs +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -13,18 +13,21 @@ Icarus verilog module. module VeriFuzz.Sim.Icarus ( Icarus(..) , defaultIcarus + , runSimIc ) where import Control.DeepSeq (NFData, rnf, rwhnf) import Control.Lens +import Control.Monad (void) import Crypto.Hash (Digest, hash) import Crypto.Hash.Algorithms (SHA256) -import Data.Binary (encode) +import Data.Binary (decode, encode) +import Data.Bits import qualified Data.ByteArray as BA (convert) import Data.ByteString (ByteString) import qualified Data.ByteString as B -import Data.ByteString.Lazy (toStrict) +import Data.ByteString.Lazy (fromStrict, toStrict) import qualified Data.ByteString.Lazy as L (ByteString) import Data.Char (digitToInt) import Data.Foldable (fold) @@ -37,6 +40,7 @@ import Prelude hiding (FilePath) import Shelly import Shelly.Lifted (liftSh) import VeriFuzz.Sim.Internal +import VeriFuzz.Sim.Template import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.BitVec import VeriFuzz.Verilog.CodeGen @@ -124,13 +128,18 @@ runSimIcarusWithFile sim f _ = annotate SimFail . liftSh $ do "vvp" (runFoldLines (mempty :: ByteString) callback (vvpPath sim) ["main"]) +fromBytes :: ByteString -> Integer +fromBytes = B.foldl' f 0 + where + f a b = a `shiftL` 8 .|. fromIntegral b + runSimIc - :: (Synthesiser a) => a -> SourceInfo -> [ByteString] -> ResultSh ByteString -runSimIc sim1 srcInfo bss = do + :: (Synthesiser b) => Icarus -> b -> SourceInfo -> [ByteString] -> ResultSh ByteString +runSimIc sim1 synth1 srcInfo bss = do dir <- liftSh pwd let top = srcInfo ^. mainModule let inConcat = (RegConcat (Id . fromPort <$> (top ^. modInPorts))) - let tb = ModDecl + let tb = instantiateMod top $ ModDecl "testbench" [] [] @@ -138,28 +147,19 @@ runSimIc sim1 srcInfo bss = do $ fold [ BlockAssign (Assign "clk" Nothing 0) , BlockAssign (Assign inConcat Nothing 0) ] - <> (SysTaskEnable $ Task "finish" []) - , Always . TimeCtrl 5 $ BlockAssign (Assign "clk" Nothing (UnNot (Id "clk"))) - , Always . EventCtrl (EPosEdge "clk") $ SysTaskEnable $ Task "strobe" ["%b", Id "y"] + <> fold ((\r -> TimeCtrl 10 (Just $ BlockAssign (Assign inConcat Nothing r))) + . fromInteger . fromBytes <$> bss) + <> (SysTaskEnable $ Task "finish" []) + , Always . TimeCtrl 5 . Just $ BlockAssign (Assign "clk" Nothing (UnOp UnNot (Id "clk"))) + , Always . EventCtrl (EPosEdge "clk") . Just . SysTaskEnable $ Task "strobe" ["%b", Id "y"] ] [] - liftSh $ do - writefile "top.v" - . genSource - . initMod - . makeTopAssert - $ srcInfo - ^. mainModule - replaceMods (synthOutput sim1) "_1" srcInfo - replaceMods (synthOutput sim2) "_2" srcInfo - writefile "proof.sby" $ sbyConfig sim1 sim2 srcInfo - e <- liftSh $ do - exe dir "symbiyosys" "sby" ["-f", "proof.sby"] - lastExitCode - case e of - 0 -> ResultT . return $ Pass () - 2 -> ResultT . return $ Fail EquivFail - 124 -> ResultT . return $ Fail TimeoutError - _ -> ResultT . return $ Fail EquivError + + liftSh . writefile "testbench.v" $ icarusTestbench (Verilog [tb]) synth1 + liftSh $ exe dir "icarus" "iverilog" ["-o", "main", "testbench.v"] + liftSh $ B.take 8 . BA.convert . (hash :: ByteString -> Digest SHA256) <$> logCommand + dir + "vvp" + (runFoldLines (mempty :: ByteString) callback (vvpPath sim1) ["main"]) where exe dir name e = void . errExit False . logCommand dir name . timeout e diff --git a/src/VeriFuzz/Sim/Template.hs b/src/VeriFuzz/Sim/Template.hs index 913b220..3be6558 100644 --- a/src/VeriFuzz/Sim/Template.hs +++ b/src/VeriFuzz/Sim/Template.hs @@ -127,7 +127,7 @@ icarusTestbench t synth1 = [st| `include "data/cells_verific.v" `include "data/cells_xilinx_7.v" `include "data/cells_yosys.v" -`include "#{synthOutput synth1}" +`include "#{toTextIgnore $ synthOutput synth1}" #{genSource t} |] -- cgit From bb697f8bc7b593e5aabb43505f686e6503b7726f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 29 Jun 2019 20:21:43 +0100 Subject: Fix pedantic warnings --- src/VeriFuzz/Fuzz.hs | 6 +----- src/VeriFuzz/Internal.hs | 13 +++++++++++-- src/VeriFuzz/Report.hs | 3 ++- src/VeriFuzz/Result.hs | 5 +++++ src/VeriFuzz/Sim/Icarus.hs | 4 ++-- 5 files changed, 21 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index 181207c..fcc96d3 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -39,9 +39,6 @@ import Control.Monad.Trans.Reader hiding (local) import Control.Monad.Trans.State.Strict import qualified Crypto.Random.DRBG as C import Data.ByteString (ByteString) -import Data.ByteString.Builder (byteStringHex, - toLazyByteString) -import qualified Data.ByteString.Lazy as L import Data.List (nubBy, sort) import Data.Maybe (isNothing) import Data.Text (Text) @@ -224,7 +221,6 @@ simulation src = do resTimes <- liftSh $ mapM (equiv vals) $ conv <$> synth liftSh $ inspect resTimes where - tupEq (a, b) (a', b') = (a == a' && b == b') || (a == b' && b == a') conv (SynthResult a _ _ _) = a equiv b a = toolRun ("simulation for " <> toText a) @@ -371,7 +367,7 @@ fuzz gen conf = do ?~ seed' (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src - (tsim, _) <- titleRun "Simulation" $ simulation src + (_, _) <- titleRun "Simulation" $ simulation src fails <- failEquivWithIdentity synthFails <- failedSynthesis redResult <- diff --git a/src/VeriFuzz/Internal.hs b/src/VeriFuzz/Internal.hs index 22efa92..fd9d409 100644 --- a/src/VeriFuzz/Internal.hs +++ b/src/VeriFuzz/Internal.hs @@ -14,13 +14,22 @@ module VeriFuzz.Internal ( -- * Useful functions safe , showT + , showBS , comma , commaNL ) where -import Data.Text (Text) -import qualified Data.Text as T +import Data.ByteString (ByteString) +import Data.ByteString.Builder (byteStringHex, toLazyByteString) +import qualified Data.ByteString.Lazy as L +import Data.Text (Text) +import qualified Data.Text as T +import Data.Text.Encoding (decodeUtf8) + +-- | Function to show a bytestring in a hex format. +showBS :: ByteString -> Text +showBS = decodeUtf8 . L.toStrict . toLazyByteString . byteStringHex -- | Converts unsafe list functions in the Prelude to a safe version. safe :: ([a] -> b) -> [a] -> Maybe b diff --git a/src/VeriFuzz/Report.hs b/src/VeriFuzz/Report.hs index fb66275..a3c4ebd 100644 --- a/src/VeriFuzz/Report.hs +++ b/src/VeriFuzz/Report.hs @@ -48,6 +48,7 @@ import Data.ByteString (ByteString) import Data.Maybe (fromMaybe) import Data.Monoid (Endo) import Data.Text (Text) +import qualified Data.Text as T import Data.Text.Lazy (toStrict) import Data.Time import Data.Vector (fromList) @@ -158,7 +159,7 @@ data SimResult = SimResult !SynthTool !SimTool !BResult !NominalDiffTime deriving (Eq) instance Show SimResult where - show (SimResult synth sim r d) = show synth <> ", " <> show sim <> ": " <> show r <> " (" <> show d <> ")" + show (SimResult synth sim r d) = show synth <> ", " <> show sim <> ": " <> show (bimap show (T.unpack . showBS) r) <> " (" <> show d <> ")" getSimResult :: SimResult -> UResult getSimResult (SimResult _ _ (Pass _) _) = Pass () diff --git a/src/VeriFuzz/Result.hs b/src/VeriFuzz/Result.hs index 77aa5b3..c02690f 100644 --- a/src/VeriFuzz/Result.hs +++ b/src/VeriFuzz/Result.hs @@ -31,6 +31,7 @@ import Control.Monad.Base import Control.Monad.IO.Class import Control.Monad.Trans.Class import Control.Monad.Trans.Control +import Data.Bifunctor (Bifunctor (..)) import Shelly (RunFailed (..), Sh, catch_sh) import Shelly.Lifted (MonadSh, liftSh) @@ -64,6 +65,10 @@ instance Monad (Result a) where instance MonadBase (Result a) (Result a) where liftBase = id +instance Bifunctor Result where + bimap a _ (Fail c) = Fail $ a c + bimap _ b (Pass c) = Pass $ b c + -- | The transformer for the 'Result' type. This newtype ResultT a m b = ResultT { runResultT :: m (Result a b) } diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs index a5a3227..7f90814 100644 --- a/src/VeriFuzz/Sim/Icarus.hs +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -22,12 +22,12 @@ import Control.Lens import Control.Monad (void) import Crypto.Hash (Digest, hash) import Crypto.Hash.Algorithms (SHA256) -import Data.Binary (decode, encode) +import Data.Binary (encode) import Data.Bits import qualified Data.ByteArray as BA (convert) import Data.ByteString (ByteString) import qualified Data.ByteString as B -import Data.ByteString.Lazy (fromStrict, toStrict) +import Data.ByteString.Lazy (toStrict) import qualified Data.ByteString.Lazy as L (ByteString) import Data.Char (digitToInt) import Data.Foldable (fold) -- cgit From d32f4cc45bc8c0670fb788b1fcd4c2f2b15fa094 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 29 Jun 2019 20:33:59 +0100 Subject: Format files --- src/VeriFuzz.hs | 44 ++++++++------- src/VeriFuzz/Circuit.hs | 4 +- src/VeriFuzz/Circuit/Base.hs | 5 +- src/VeriFuzz/Circuit/Gen.hs | 8 ++- src/VeriFuzz/Circuit/Internal.hs | 8 ++- src/VeriFuzz/Circuit/Random.hs | 15 ++--- src/VeriFuzz/Config.hs | 26 +++++---- src/VeriFuzz/Fuzz.hs | 96 ++++++++++++++++---------------- src/VeriFuzz/Internal.hs | 14 +++-- src/VeriFuzz/Reduce.hs | 26 +++++---- src/VeriFuzz/Report.hs | 40 +++++++++----- src/VeriFuzz/Result.hs | 11 +++- src/VeriFuzz/Sim/Icarus.hs | 116 ++++++++++++++++++++++++--------------- src/VeriFuzz/Sim/Identity.hs | 15 +++-- src/VeriFuzz/Sim/Internal.hs | 32 ++++++----- src/VeriFuzz/Sim/Quartus.hs | 13 +++-- src/VeriFuzz/Sim/Vivado.hs | 13 +++-- src/VeriFuzz/Sim/XST.hs | 15 +++-- src/VeriFuzz/Sim/Yosys.hs | 17 ++++-- src/VeriFuzz/Verilog/AST.hs | 16 ++++-- src/VeriFuzz/Verilog/CodeGen.hs | 14 +++-- src/VeriFuzz/Verilog/Eval.hs | 6 +- src/VeriFuzz/Verilog/Gen.hs | 21 +++---- src/VeriFuzz/Verilog/Internal.hs | 2 +- src/VeriFuzz/Verilog/Mutate.hs | 46 ++++++++-------- src/VeriFuzz/Verilog/Parser.hs | 23 ++++---- src/VeriFuzz/Verilog/Quote.hs | 4 +- 27 files changed, 381 insertions(+), 269 deletions(-) (limited to 'src') diff --git a/src/VeriFuzz.hs b/src/VeriFuzz.hs index 7bc562f..0bbdc4f 100644 --- a/src/VeriFuzz.hs +++ b/src/VeriFuzz.hs @@ -28,27 +28,29 @@ module VeriFuzz where import Control.Concurrent -import Control.Lens hiding ((<.>)) -import Control.Monad.IO.Class (liftIO) -import qualified Crypto.Random.DRBG as C -import Data.ByteString (ByteString) -import Data.ByteString.Builder (byteStringHex, toLazyByteString) -import qualified Data.ByteString.Lazy as L -import qualified Data.Graph.Inductive as G -import qualified Data.Graph.Inductive.Dot as G -import Data.Maybe (isNothing) -import Data.Text (Text) -import qualified Data.Text as T -import Data.Text.Encoding (decodeUtf8) -import qualified Data.Text.IO as T -import Hedgehog (Gen) -import qualified Hedgehog.Gen as Hog -import Hedgehog.Internal.Seed (Seed) +import Control.Lens hiding ( (<.>) ) +import Control.Monad.IO.Class ( liftIO ) +import qualified Crypto.Random.DRBG as C +import Data.ByteString ( ByteString ) +import Data.ByteString.Builder ( byteStringHex + , toLazyByteString + ) +import qualified Data.ByteString.Lazy as L +import qualified Data.Graph.Inductive as G +import qualified Data.Graph.Inductive.Dot as G +import Data.Maybe ( isNothing ) +import Data.Text ( Text ) +import qualified Data.Text as T +import Data.Text.Encoding ( decodeUtf8 ) +import qualified Data.Text.IO as T +import Hedgehog ( Gen ) +import qualified Hedgehog.Gen as Hog +import Hedgehog.Internal.Seed ( Seed ) import Options.Applicative -import Prelude hiding (FilePath) -import Shelly hiding (command) -import Shelly.Lifted (liftSh) -import System.Random (randomIO) +import Prelude hiding ( FilePath ) +import Shelly hiding ( command ) +import Shelly.Lifted ( liftSh ) +import System.Random ( randomIO ) import VeriFuzz.Circuit import VeriFuzz.Config import VeriFuzz.Fuzz @@ -58,7 +60,7 @@ import VeriFuzz.Result import VeriFuzz.Sim import VeriFuzz.Sim.Internal import VeriFuzz.Verilog -import VeriFuzz.Verilog.Parser (parseSourceInfoFile) +import VeriFuzz.Verilog.Parser ( parseSourceInfoFile ) data OptTool = TYosys | TXST diff --git a/src/VeriFuzz/Circuit.hs b/src/VeriFuzz/Circuit.hs index 58027b1..9ee601f 100644 --- a/src/VeriFuzz/Circuit.hs +++ b/src/VeriFuzz/Circuit.hs @@ -26,8 +26,8 @@ module VeriFuzz.Circuit where import Control.Lens -import Hedgehog (Gen) -import qualified Hedgehog.Gen as Hog +import Hedgehog ( Gen ) +import qualified Hedgehog.Gen as Hog import VeriFuzz.Circuit.Base import VeriFuzz.Circuit.Gen import VeriFuzz.Circuit.Random diff --git a/src/VeriFuzz/Circuit/Base.hs b/src/VeriFuzz/Circuit/Base.hs index ed63105..adc7d52 100644 --- a/src/VeriFuzz/Circuit/Base.hs +++ b/src/VeriFuzz/Circuit/Base.hs @@ -18,7 +18,10 @@ module VeriFuzz.Circuit.Base ) where -import Data.Graph.Inductive (Gr, LEdge, LNode) +import Data.Graph.Inductive ( Gr + , LEdge + , LNode + ) import System.Random -- | The types for all the gates. diff --git a/src/VeriFuzz/Circuit/Gen.hs b/src/VeriFuzz/Circuit/Gen.hs index 0b13ece..323d8bb 100644 --- a/src/VeriFuzz/Circuit/Gen.hs +++ b/src/VeriFuzz/Circuit/Gen.hs @@ -15,9 +15,11 @@ module VeriFuzz.Circuit.Gen ) where -import Data.Graph.Inductive (LNode, Node) -import qualified Data.Graph.Inductive as G -import Data.Maybe (catMaybes) +import Data.Graph.Inductive ( LNode + , Node + ) +import qualified Data.Graph.Inductive as G +import Data.Maybe ( catMaybes ) import VeriFuzz.Circuit.Base import VeriFuzz.Circuit.Internal import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Circuit/Internal.hs b/src/VeriFuzz/Circuit/Internal.hs index 3a7346f..5220f4d 100644 --- a/src/VeriFuzz/Circuit/Internal.hs +++ b/src/VeriFuzz/Circuit/Internal.hs @@ -19,9 +19,11 @@ module VeriFuzz.Circuit.Internal ) 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 -- | Convert an integer into a label. -- diff --git a/src/VeriFuzz/Circuit/Random.hs b/src/VeriFuzz/Circuit/Random.hs index 58e855c..2750de8 100644 --- a/src/VeriFuzz/Circuit/Random.hs +++ b/src/VeriFuzz/Circuit/Random.hs @@ -18,13 +18,14 @@ module VeriFuzz.Circuit.Random ) where -import Data.Graph.Inductive (Context) -import qualified Data.Graph.Inductive as G -import Data.Graph.Inductive.PatriciaTree (Gr) -import Data.List (nub) -import Hedgehog (Gen) -import qualified Hedgehog.Gen as Hog -import qualified Hedgehog.Range as Hog +import Data.Graph.Inductive ( Context ) +import qualified Data.Graph.Inductive as G +import Data.Graph.Inductive.PatriciaTree + ( Gr ) +import Data.List ( nub ) +import Hedgehog ( Gen ) +import qualified Hedgehog.Gen as Hog +import qualified Hedgehog.Range as Hog import VeriFuzz.Circuit.Base dupFolder :: (Eq a, Eq b) => Context a b -> [Context a b] -> [Context a b] diff --git a/src/VeriFuzz/Config.hs b/src/VeriFuzz/Config.hs index 19cdd68..0fc9435 100644 --- a/src/VeriFuzz/Config.hs +++ b/src/VeriFuzz/Config.hs @@ -77,18 +77,22 @@ module VeriFuzz.Config ) where -import Control.Applicative (Alternative) -import Control.Lens hiding ((.=)) -import Data.List.NonEmpty (NonEmpty (..)) -import Data.Maybe (fromMaybe) -import Data.Text (Text, pack) -import qualified Data.Text.IO as T -import Data.Version (showVersion) +import Control.Applicative ( Alternative ) +import Control.Lens hiding ( (.=) ) +import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.Maybe ( fromMaybe ) +import Data.Text ( Text + , pack + ) +import qualified Data.Text.IO as T +import Data.Version ( showVersion ) import Development.GitRev -import Hedgehog.Internal.Seed (Seed) -import Paths_verifuzz (version) -import Shelly (toTextIgnore) -import Toml (TomlCodec, (.=)) +import Hedgehog.Internal.Seed ( Seed ) +import Paths_verifuzz ( version ) +import Shelly ( toTextIgnore ) +import Toml ( TomlCodec + , (.=) + ) import qualified Toml import VeriFuzz.Sim.Quartus import VeriFuzz.Sim.Vivado diff --git a/src/VeriFuzz/Fuzz.hs b/src/VeriFuzz/Fuzz.hs index fcc96d3..dd7fe7b 100644 --- a/src/VeriFuzz/Fuzz.hs +++ b/src/VeriFuzz/Fuzz.hs @@ -27,33 +27,40 @@ module VeriFuzz.Fuzz ) where -import Control.DeepSeq (force) -import Control.Exception.Lifted (finally) -import Control.Lens hiding ((<.>)) -import Control.Monad (forM, replicateM) +import Control.DeepSeq ( force ) +import Control.Exception.Lifted ( finally ) +import Control.Lens hiding ( (<.>) ) +import Control.Monad ( forM + , replicateM + ) import Control.Monad.IO.Class -import Control.Monad.Trans.Class (lift) -import Control.Monad.Trans.Control (MonadBaseControl) -import Control.Monad.Trans.Maybe (runMaybeT) -import Control.Monad.Trans.Reader hiding (local) +import Control.Monad.Trans.Class ( lift ) +import Control.Monad.Trans.Control ( MonadBaseControl ) +import Control.Monad.Trans.Maybe ( runMaybeT ) +import Control.Monad.Trans.Reader + hiding ( local ) import Control.Monad.Trans.State.Strict -import qualified Crypto.Random.DRBG as C -import Data.ByteString (ByteString) -import Data.List (nubBy, sort) -import Data.Maybe (isNothing) -import Data.Text (Text) -import qualified Data.Text as T +import qualified Crypto.Random.DRBG as C +import Data.ByteString ( ByteString ) +import Data.List ( nubBy + , sort + ) +import Data.Maybe ( isNothing ) +import Data.Text ( Text ) +import qualified Data.Text as T import Data.Time -import Data.Tuple (swap) -import Hedgehog (Gen) -import qualified Hedgehog.Internal.Gen as Hog -import Hedgehog.Internal.Seed (Seed) -import qualified Hedgehog.Internal.Seed as Hog -import qualified Hedgehog.Internal.Tree as Hog -import Prelude hiding (FilePath) -import Shelly hiding (get) -import Shelly.Lifted (MonadSh, liftSh) -import System.FilePath.Posix (takeBaseName) +import Data.Tuple ( swap ) +import Hedgehog ( Gen ) +import qualified Hedgehog.Internal.Gen as Hog +import Hedgehog.Internal.Seed ( Seed ) +import qualified Hedgehog.Internal.Seed as Hog +import qualified Hedgehog.Internal.Tree as Hog +import Prelude hiding ( FilePath ) +import Shelly hiding ( get ) +import Shelly.Lifted ( MonadSh + , liftSh + ) +import System.FilePath.Posix ( takeBaseName ) import VeriFuzz.Config import VeriFuzz.Internal import VeriFuzz.Reduce @@ -144,7 +151,7 @@ failedSynthesis :: MonadSh m => Fuzz m [SynthTool] failedSynthesis = fmap toSynth . filter failed . _fuzzSynthStatus <$> get where failed (SynthStatus _ (Fail SynthFail) _) = True - failed _ = False + failed _ = False toSynth (SynthStatus s _ _) = s make :: MonadSh m => FilePath -> m () @@ -216,27 +223,24 @@ equivalence src = do simulation :: (MonadIO m, MonadSh m) => SourceInfo -> Fuzz m () simulation src = do - synth <- passEquiv - vals <- liftIO $ generateByteString 20 + synth <- passEquiv + vals <- liftIO $ generateByteString 20 + ident <- liftSh $ equiv vals defaultIdentitySynth resTimes <- liftSh $ mapM (equiv vals) $ conv <$> synth - liftSh $ inspect resTimes + liftSh + . inspect + $ (\(_, r) -> bimap show (T.unpack . T.take 10 . showBS) r) + <$> (ident : resTimes) where - conv (SynthResult a _ _ _) = a - equiv b a = - toolRun ("simulation for " <> toText a) - . runResultT - $ do - make dir - pop dir $ do - liftSh $ do - cp - ( fromText ".." - fromText (toText a) - synthOutput a - ) - $ synthOutput a - writefile "rtl.v" $ genSource src - runSimIc defaultIcarus a src b + conv (SynthResult _ a _ _) = a + equiv b a = toolRun ("simulation for " <> toText a) . runResultT $ do + make dir + pop dir $ do + liftSh $ do + cp (fromText ".." fromText (toText a) synthOutput a) + $ synthOutput a + writefile "rtl.v" $ genSource src + runSimIc defaultIcarus a src b where dir = fromText $ "simulation_" <> toText a -- | Generate a specific number of random bytestrings of size 256. @@ -257,7 +261,7 @@ failEquivWithIdentity = filter withIdentity . _fuzzSynthResults <$> get where withIdentity (SynthResult (IdentitySynth _) _ (Fail EquivFail) _) = True withIdentity (SynthResult _ (IdentitySynth _) (Fail EquivFail) _) = True - withIdentity _ = False + withIdentity _ = False passEquiv :: (MonadSh m) => Fuzz m [SynthResult] passEquiv = filter withIdentity . _fuzzSynthResults <$> get @@ -367,7 +371,7 @@ fuzz gen conf = do ?~ seed' (tsynth, _) <- titleRun "Synthesis" $ synthesis src (tequiv, _) <- titleRun "Equivalence Check" $ equivalence src - (_, _) <- titleRun "Simulation" $ simulation src + (_ , _) <- titleRun "Simulation" $ simulation src fails <- failEquivWithIdentity synthFails <- failedSynthesis redResult <- diff --git a/src/VeriFuzz/Internal.hs b/src/VeriFuzz/Internal.hs index fd9d409..b5ce3ba 100644 --- a/src/VeriFuzz/Internal.hs +++ b/src/VeriFuzz/Internal.hs @@ -20,12 +20,14 @@ module VeriFuzz.Internal ) where -import Data.ByteString (ByteString) -import Data.ByteString.Builder (byteStringHex, toLazyByteString) -import qualified Data.ByteString.Lazy as L -import Data.Text (Text) -import qualified Data.Text as T -import Data.Text.Encoding (decodeUtf8) +import Data.ByteString ( ByteString ) +import Data.ByteString.Builder ( byteStringHex + , toLazyByteString + ) +import qualified Data.ByteString.Lazy as L +import Data.Text ( Text ) +import qualified Data.Text as T +import Data.Text.Encoding ( decodeUtf8 ) -- | Function to show a bytestring in a hex format. showBS :: ByteString -> Text diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs index 7cee31c..6bae371 100644 --- a/src/VeriFuzz/Reduce.hs +++ b/src/VeriFuzz/Reduce.hs @@ -35,18 +35,22 @@ module VeriFuzz.Reduce ) where -import Control.Lens hiding ((<.>)) -import Control.Monad (void) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Data.Foldable (foldrM) -import Data.List (nub) -import Data.List.NonEmpty (NonEmpty (..)) -import qualified Data.List.NonEmpty as NonEmpty -import Data.Maybe (mapMaybe) -import Data.Text (Text) -import Shelly ((<.>)) +import Control.Lens hiding ( (<.>) ) +import Control.Monad ( void ) +import Control.Monad.IO.Class ( MonadIO + , liftIO + ) +import Data.Foldable ( foldrM ) +import Data.List ( nub ) +import Data.List.NonEmpty ( NonEmpty(..) ) +import qualified Data.List.NonEmpty as NonEmpty +import Data.Maybe ( mapMaybe ) +import Data.Text ( Text ) +import Shelly ( (<.>) ) import qualified Shelly -import Shelly.Lifted (MonadSh, liftSh) +import Shelly.Lifted ( MonadSh + , liftSh + ) import VeriFuzz.Internal import VeriFuzz.Result import VeriFuzz.Sim diff --git a/src/VeriFuzz/Report.hs b/src/VeriFuzz/Report.hs index a3c4ebd..3037b34 100644 --- a/src/VeriFuzz/Report.hs +++ b/src/VeriFuzz/Report.hs @@ -41,23 +41,33 @@ module VeriFuzz.Report ) where -import Control.DeepSeq (NFData, rnf) -import Control.Lens hiding (Identity, (<.>)) -import Data.Bifunctor (bimap) -import Data.ByteString (ByteString) -import Data.Maybe (fromMaybe) -import Data.Monoid (Endo) -import Data.Text (Text) +import Control.DeepSeq ( NFData + , rnf + ) +import Control.Lens hiding ( Identity + , (<.>) + ) +import Data.Bifunctor ( bimap ) +import Data.ByteString ( ByteString ) +import Data.Maybe ( fromMaybe ) +import Data.Monoid ( Endo ) +import Data.Text ( Text ) import qualified Data.Text as T -import Data.Text.Lazy (toStrict) +import Data.Text.Lazy ( toStrict ) import Data.Time -import Data.Vector (fromList) -import Prelude hiding (FilePath) -import Shelly (FilePath, fromText, - toTextIgnore, (<.>), ()) -import Statistics.Sample (meanVariance) -import Text.Blaze.Html (Html, (!)) -import Text.Blaze.Html.Renderer.Text (renderHtml) +import Data.Vector ( fromList ) +import Prelude hiding ( FilePath ) +import Shelly ( FilePath + , fromText + , toTextIgnore + , (<.>) + , () + ) +import Statistics.Sample ( meanVariance ) +import Text.Blaze.Html ( Html + , (!) + ) +import Text.Blaze.Html.Renderer.Text ( renderHtml ) import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as A import VeriFuzz.Config diff --git a/src/VeriFuzz/Result.hs b/src/VeriFuzz/Result.hs index c02690f..4ea7988 100644 --- a/src/VeriFuzz/Result.hs +++ b/src/VeriFuzz/Result.hs @@ -31,9 +31,14 @@ import Control.Monad.Base import Control.Monad.IO.Class import Control.Monad.Trans.Class import Control.Monad.Trans.Control -import Data.Bifunctor (Bifunctor (..)) -import Shelly (RunFailed (..), Sh, catch_sh) -import Shelly.Lifted (MonadSh, liftSh) +import Data.Bifunctor ( Bifunctor(..) ) +import Shelly ( RunFailed(..) + , Sh + , catch_sh + ) +import Shelly.Lifted ( MonadSh + , liftSh + ) -- | Result type which is equivalent to 'Either' or 'Error'. This is -- reimplemented so that there is full control over the 'Monad' definition and diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs index 7f90814..8e62136 100644 --- a/src/VeriFuzz/Sim/Icarus.hs +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -17,28 +17,35 @@ module VeriFuzz.Sim.Icarus ) where -import Control.DeepSeq (NFData, rnf, rwhnf) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) import Control.Lens -import Control.Monad (void) -import Crypto.Hash (Digest, hash) -import Crypto.Hash.Algorithms (SHA256) -import Data.Binary (encode) +import Control.Monad ( void ) +import Crypto.Hash ( Digest + , hash + ) +import Crypto.Hash.Algorithms ( SHA256 ) +import Data.Binary ( encode ) import Data.Bits -import qualified Data.ByteArray as BA (convert) -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import Data.ByteString.Lazy (toStrict) -import qualified Data.ByteString.Lazy as L (ByteString) -import Data.Char (digitToInt) -import Data.Foldable (fold) -import Data.List (transpose) -import Data.Maybe (listToMaybe) -import Data.Text (Text) -import qualified Data.Text as T -import Numeric (readInt) -import Prelude hiding (FilePath) +import qualified Data.ByteArray as BA + ( convert ) +import Data.ByteString ( ByteString ) +import qualified Data.ByteString as B +import Data.ByteString.Lazy ( toStrict ) +import qualified Data.ByteString.Lazy as L + ( ByteString ) +import Data.Char ( digitToInt ) +import Data.Foldable ( fold ) +import Data.List ( transpose ) +import Data.Maybe ( listToMaybe ) +import Data.Text ( Text ) +import qualified Data.Text as T +import Numeric ( readInt ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (liftSh) +import Shelly.Lifted ( liftSh ) import VeriFuzz.Sim.Internal import VeriFuzz.Sim.Template import VeriFuzz.Verilog.AST @@ -129,37 +136,60 @@ runSimIcarusWithFile sim f _ = annotate SimFail . liftSh $ do (runFoldLines (mempty :: ByteString) callback (vvpPath sim) ["main"]) fromBytes :: ByteString -> Integer -fromBytes = B.foldl' f 0 - where - f a b = a `shiftL` 8 .|. fromIntegral b +fromBytes = B.foldl' f 0 where f a b = a `shiftL` 8 .|. fromIntegral b runSimIc - :: (Synthesiser b) => Icarus -> b -> SourceInfo -> [ByteString] -> ResultSh ByteString + :: (Synthesiser b) + => Icarus + -> b + -> SourceInfo + -> [ByteString] + -> ResultSh ByteString runSimIc sim1 synth1 srcInfo bss = do dir <- liftSh pwd - let top = srcInfo ^. mainModule + let top = srcInfo ^. mainModule let inConcat = (RegConcat (Id . fromPort <$> (top ^. modInPorts))) - let tb = instantiateMod top $ ModDecl - "testbench" - [] - [] - [ Initial - $ fold [ BlockAssign (Assign "clk" Nothing 0) - , BlockAssign (Assign inConcat Nothing 0) - ] - <> fold ((\r -> TimeCtrl 10 (Just $ BlockAssign (Assign inConcat Nothing r))) - . fromInteger . fromBytes <$> bss) - <> (SysTaskEnable $ Task "finish" []) - , Always . TimeCtrl 5 . Just $ BlockAssign (Assign "clk" Nothing (UnOp UnNot (Id "clk"))) - , Always . EventCtrl (EPosEdge "clk") . Just . SysTaskEnable $ Task "strobe" ["%b", Id "y"] - ] - [] + let + tb = instantiateMod top $ ModDecl + "testbench" + [] + [] + [ Initial + $ fold + [ BlockAssign (Assign "clk" Nothing 0) + , BlockAssign (Assign inConcat Nothing 0) + ] + <> fold + ( (\r -> TimeCtrl + 10 + (Just $ BlockAssign (Assign inConcat Nothing r)) + ) + . fromInteger + . fromBytes + <$> bss + ) + <> (SysTaskEnable $ Task "finish" []) + , Always . TimeCtrl 5 . Just $ BlockAssign + (Assign "clk" Nothing (UnOp UnNot (Id "clk"))) + , Always . EventCtrl (EPosEdge "clk") . Just . SysTaskEnable $ Task + "strobe" + ["%b", Id "y"] + ] + [] liftSh . writefile "testbench.v" $ icarusTestbench (Verilog [tb]) synth1 liftSh $ exe dir "icarus" "iverilog" ["-o", "main", "testbench.v"] - liftSh $ B.take 8 . BA.convert . (hash :: ByteString -> Digest SHA256) <$> logCommand - dir - "vvp" - (runFoldLines (mempty :: ByteString) callback (vvpPath sim1) ["main"]) + liftSh + $ B.take 8 + . BA.convert + . (hash :: ByteString -> Digest SHA256) + <$> logCommand + dir + "vvp" + (runFoldLines (mempty :: ByteString) + callback + (vvpPath sim1) + ["main"] + ) where exe dir name e = void . errExit False . logCommand dir name . timeout e diff --git a/src/VeriFuzz/Sim/Identity.hs b/src/VeriFuzz/Sim/Identity.hs index bfded0b..95b4097 100644 --- a/src/VeriFuzz/Sim/Identity.hs +++ b/src/VeriFuzz/Sim/Identity.hs @@ -16,11 +16,16 @@ module VeriFuzz.Sim.Identity ) where -import Control.DeepSeq (NFData, rnf, rwhnf) -import Data.Text (Text, unpack) -import Prelude hiding (FilePath) -import Shelly (FilePath) -import Shelly.Lifted (writefile) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) +import Data.Text ( Text + , unpack + ) +import Prelude hiding ( FilePath ) +import Shelly ( FilePath ) +import Shelly.Lifted ( writefile ) import VeriFuzz.Sim.Internal import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.CodeGen diff --git a/src/VeriFuzz/Sim/Internal.hs b/src/VeriFuzz/Sim/Internal.hs index d35ad86..a05a96f 100644 --- a/src/VeriFuzz/Sim/Internal.hs +++ b/src/VeriFuzz/Sim/Internal.hs @@ -40,20 +40,26 @@ module VeriFuzz.Sim.Internal where import Control.Lens -import Control.Monad (forM, void) -import Control.Monad.Catch (throwM) -import Data.Bits (shiftL) -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import Data.Maybe (catMaybes) -import Data.Text (Text) -import qualified Data.Text as T -import Data.Time.Format (defaultTimeLocale, formatTime) -import Data.Time.LocalTime (getZonedTime) -import Prelude hiding (FilePath) +import Control.Monad ( forM + , void + ) +import Control.Monad.Catch ( throwM ) +import Data.Bits ( shiftL ) +import Data.ByteString ( ByteString ) +import qualified Data.ByteString as B +import Data.Maybe ( catMaybes ) +import Data.Text ( Text ) +import qualified Data.Text as T +import Data.Time.Format ( defaultTimeLocale + , formatTime + ) +import Data.Time.LocalTime ( getZonedTime ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (MonadSh, liftSh) -import System.FilePath.Posix (takeBaseName) +import Shelly.Lifted ( MonadSh + , liftSh + ) +import System.FilePath.Posix ( takeBaseName ) import VeriFuzz.Internal import VeriFuzz.Result import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Sim/Quartus.hs b/src/VeriFuzz/Sim/Quartus.hs index 4217abb..e0fbba5 100644 --- a/src/VeriFuzz/Sim/Quartus.hs +++ b/src/VeriFuzz/Sim/Quartus.hs @@ -16,11 +16,16 @@ module VeriFuzz.Sim.Quartus ) where -import Control.DeepSeq (NFData, rnf, rwhnf) -import Data.Text (Text, unpack) -import Prelude hiding (FilePath) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) +import Data.Text ( Text + , unpack + ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (liftSh) +import Shelly.Lifted ( liftSh ) import VeriFuzz.Sim.Internal import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.CodeGen diff --git a/src/VeriFuzz/Sim/Vivado.hs b/src/VeriFuzz/Sim/Vivado.hs index a4feb07..8697a0f 100644 --- a/src/VeriFuzz/Sim/Vivado.hs +++ b/src/VeriFuzz/Sim/Vivado.hs @@ -16,11 +16,16 @@ module VeriFuzz.Sim.Vivado ) where -import Control.DeepSeq (NFData, rnf, rwhnf) -import Data.Text (Text, unpack) -import Prelude hiding (FilePath) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) +import Data.Text ( Text + , unpack + ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (liftSh) +import Shelly.Lifted ( liftSh ) import VeriFuzz.Sim.Internal import VeriFuzz.Sim.Template import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Sim/XST.hs b/src/VeriFuzz/Sim/XST.hs index 71a4e1b..f5faae5 100644 --- a/src/VeriFuzz/Sim/XST.hs +++ b/src/VeriFuzz/Sim/XST.hs @@ -18,12 +18,17 @@ module VeriFuzz.Sim.XST ) where -import Control.DeepSeq (NFData, rnf, rwhnf) -import Data.Text (Text, unpack) -import Prelude hiding (FilePath) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) +import Data.Text ( Text + , unpack + ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (liftSh) -import Text.Shakespeare.Text (st) +import Shelly.Lifted ( liftSh ) +import Text.Shakespeare.Text ( st ) import VeriFuzz.Sim.Internal import VeriFuzz.Sim.Template import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Sim/Yosys.hs b/src/VeriFuzz/Sim/Yosys.hs index 02a00d5..8f9d4a7 100644 --- a/src/VeriFuzz/Sim/Yosys.hs +++ b/src/VeriFuzz/Sim/Yosys.hs @@ -20,14 +20,19 @@ module VeriFuzz.Sim.Yosys ) where -import Control.DeepSeq (NFData, rnf, rwhnf) +import Control.DeepSeq ( NFData + , rnf + , rwhnf + ) import Control.Lens -import Control.Monad (void) -import Data.Text (Text, unpack) -import Prelude hiding (FilePath) +import Control.Monad ( void ) +import Data.Text ( Text + , unpack + ) +import Prelude hiding ( FilePath ) import Shelly -import Shelly.Lifted (liftSh) -import Text.Shakespeare.Text (st) +import Shelly.Lifted ( liftSh ) +import Text.Shakespeare.Text ( st ) import VeriFuzz.Result import VeriFuzz.Sim.Internal import VeriFuzz.Sim.Template diff --git a/src/VeriFuzz/Verilog/AST.hs b/src/VeriFuzz/Verilog/AST.hs index f201064..43063e6 100644 --- a/src/VeriFuzz/Verilog/AST.hs +++ b/src/VeriFuzz/Verilog/AST.hs @@ -139,14 +139,18 @@ module VeriFuzz.Verilog.AST ) where -import Control.Lens hiding ((<|)) +import Control.Lens hiding ( (<|) ) import Data.Data import Data.Data.Lens -import Data.Functor.Foldable.TH (makeBaseFunctor) -import Data.List.NonEmpty (NonEmpty (..), (<|)) -import Data.String (IsString, fromString) -import Data.Text (Text) -import Data.Traversable (sequenceA) +import Data.Functor.Foldable.TH ( makeBaseFunctor ) +import Data.List.NonEmpty ( NonEmpty(..) + , (<|) + ) +import Data.String ( IsString + , fromString + ) +import Data.Text ( Text ) +import Data.Traversable ( sequenceA ) import VeriFuzz.Verilog.BitVec -- | Identifier in Verilog. This is just a string of characters that can either diff --git a/src/VeriFuzz/Verilog/CodeGen.hs b/src/VeriFuzz/Verilog/CodeGen.hs index 6ef1959..82945aa 100644 --- a/src/VeriFuzz/Verilog/CodeGen.hs +++ b/src/VeriFuzz/Verilog/CodeGen.hs @@ -22,13 +22,15 @@ module VeriFuzz.Verilog.CodeGen ) where -import Data.Data (Data) -import Data.List.NonEmpty (NonEmpty (..), toList) -import Data.Text (Text) -import qualified Data.Text as T +import Data.Data ( Data ) +import Data.List.NonEmpty ( NonEmpty(..) + , toList + ) +import Data.Text ( Text ) +import qualified Data.Text as T import Data.Text.Prettyprint.Doc -import Numeric (showHex) -import VeriFuzz.Internal hiding (comma) +import Numeric ( showHex ) +import VeriFuzz.Internal hiding ( comma ) import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.BitVec diff --git a/src/VeriFuzz/Verilog/Eval.hs b/src/VeriFuzz/Verilog/Eval.hs index 4a43c19..d8840e3 100644 --- a/src/VeriFuzz/Verilog/Eval.hs +++ b/src/VeriFuzz/Verilog/Eval.hs @@ -17,9 +17,9 @@ module VeriFuzz.Verilog.Eval where import Data.Bits -import Data.Foldable (fold) -import Data.Functor.Foldable hiding (fold) -import Data.Maybe (listToMaybe) +import Data.Foldable ( fold ) +import Data.Functor.Foldable hiding ( fold ) +import Data.Maybe ( listToMaybe ) import VeriFuzz.Verilog.AST import VeriFuzz.Verilog.BitVec diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index e52a158..0a6ece5 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -22,17 +22,18 @@ module VeriFuzz.Verilog.Gen ) 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.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.Strict -import Data.Foldable (fold) -import Data.Functor.Foldable (cata) -import qualified Data.Text as T -import Hedgehog (Gen) -import qualified Hedgehog.Gen as Hog -import qualified Hedgehog.Range as Hog +import Data.Foldable ( fold ) +import Data.Functor.Foldable ( cata ) +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.AST diff --git a/src/VeriFuzz/Verilog/Internal.hs b/src/VeriFuzz/Verilog/Internal.hs index 8d19c14..16148cf 100644 --- a/src/VeriFuzz/Verilog/Internal.hs +++ b/src/VeriFuzz/Verilog/Internal.hs @@ -29,7 +29,7 @@ module VeriFuzz.Verilog.Internal where import Control.Lens -import Data.Text (Text) +import Data.Text ( Text ) import VeriFuzz.Verilog.AST regDecl :: Identifier -> ModItem diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs index 0fb4c49..e4a10df 100644 --- a/src/VeriFuzz/Verilog/Mutate.hs +++ b/src/VeriFuzz/Verilog/Mutate.hs @@ -41,10 +41,12 @@ module VeriFuzz.Verilog.Mutate where import Control.Lens -import Data.Foldable (fold) -import Data.Maybe (catMaybes, fromMaybe) -import Data.Text (Text) -import qualified Data.Text as T +import Data.Foldable ( fold ) +import Data.Maybe ( catMaybes + , fromMaybe + ) +import Data.Text ( Text ) +import qualified Data.Text as T import VeriFuzz.Circuit.Internal import VeriFuzz.Internal import VeriFuzz.Verilog.AST @@ -337,30 +339,30 @@ declareMod ports = initMod . (modItems %~ (decl ++)) -- >>> GenVerilog . simplify $ (Id "y") + (Id "x") -- (y + x) simplify :: Expr -> Expr -simplify (BinOp (Number (BitVec _ 1)) BinAnd e) = e -simplify (BinOp e BinAnd (Number (BitVec _ 1))) = e -simplify (BinOp (Number (BitVec _ 0)) BinAnd _) = Number 0 -simplify (BinOp _ BinAnd (Number (BitVec _ 0))) = Number 0 -simplify (BinOp e BinPlus (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinPlus e) = e +simplify (BinOp (Number (BitVec _ 1)) BinAnd e) = e +simplify (BinOp e BinAnd (Number (BitVec _ 1))) = e +simplify (BinOp (Number (BitVec _ 0)) BinAnd _) = Number 0 +simplify (BinOp _ BinAnd (Number (BitVec _ 0))) = Number 0 +simplify (BinOp e BinPlus (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinPlus e) = e simplify (BinOp e BinMinus (Number (BitVec _ 0))) = e simplify (BinOp (Number (BitVec _ 0)) BinMinus e) = e simplify (BinOp e BinTimes (Number (BitVec _ 1))) = e simplify (BinOp (Number (BitVec _ 1)) BinTimes e) = e simplify (BinOp _ BinTimes (Number (BitVec _ 0))) = Number 0 simplify (BinOp (Number (BitVec _ 0)) BinTimes _) = Number 0 -simplify (BinOp e BinOr (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinOr e) = e -simplify (BinOp e BinLSL (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinLSL e) = e -simplify (BinOp e BinLSR (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinLSR e) = e -simplify (BinOp e BinASL (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinASL e) = e -simplify (BinOp e BinASR (Number (BitVec _ 0))) = e -simplify (BinOp (Number (BitVec _ 0)) BinASR e) = e -simplify (UnOp UnPlus e) = e -simplify e = e +simplify (BinOp e BinOr (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinOr e) = e +simplify (BinOp e BinLSL (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinLSL e) = e +simplify (BinOp e BinLSR (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinLSR e) = e +simplify (BinOp e BinASL (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinASL e) = e +simplify (BinOp e BinASR (Number (BitVec _ 0))) = e +simplify (BinOp (Number (BitVec _ 0)) BinASR e) = e +simplify (UnOp UnPlus e) = e +simplify e = e -- | Remove all 'Identifier' that do not appeare in the input list from an -- 'Expr'. The identifier will be replaced by @1'b0@, which can then later be diff --git a/src/VeriFuzz/Verilog/Parser.hs b/src/VeriFuzz/Verilog/Parser.hs index 68d0ef3..0820e48 100644 --- a/src/VeriFuzz/Verilog/Parser.hs +++ b/src/VeriFuzz/Verilog/Parser.hs @@ -26,17 +26,20 @@ module VeriFuzz.Verilog.Parser where import Control.Lens -import Control.Monad (void) -import Data.Bifunctor (bimap) +import Control.Monad ( void ) +import Data.Bifunctor ( bimap ) import Data.Bits -import Data.Functor (($>)) -import Data.Functor.Identity (Identity) -import Data.List (isInfixOf, isPrefixOf, null) -import Data.List.NonEmpty (NonEmpty (..)) -import Data.Text (Text) -import qualified Data.Text as T -import qualified Data.Text.IO as T -import Text.Parsec hiding (satisfy) +import Data.Functor ( ($>) ) +import Data.Functor.Identity ( Identity ) +import Data.List ( isInfixOf + , isPrefixOf + , null + ) +import Data.List.NonEmpty ( NonEmpty(..) ) +import Data.Text ( Text ) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import Text.Parsec hiding ( satisfy ) import Text.Parsec.Expr import VeriFuzz.Internal import VeriFuzz.Verilog.AST diff --git a/src/VeriFuzz/Verilog/Quote.hs b/src/VeriFuzz/Verilog/Quote.hs index 362cf06..f0b7c96 100644 --- a/src/VeriFuzz/Verilog/Quote.hs +++ b/src/VeriFuzz/Verilog/Quote.hs @@ -18,8 +18,8 @@ module VeriFuzz.Verilog.Quote where import Data.Data -import qualified Data.Text as T -import qualified Language.Haskell.TH as TH +import qualified Data.Text as T +import qualified Language.Haskell.TH as TH import Language.Haskell.TH.Quote import Language.Haskell.TH.Syntax import VeriFuzz.Verilog.Parser -- cgit