aboutsummaryrefslogtreecommitdiffstats
path: root/src/Verismith/OptParser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Verismith/OptParser.hs')
-rw-r--r--src/Verismith/OptParser.hs566
1 files changed, 309 insertions, 257 deletions
diff --git a/src/Verismith/OptParser.hs b/src/Verismith/OptParser.hs
index 592f9e9..108cf01 100644
--- a/src/Verismith/OptParser.hs
+++ b/src/Verismith/OptParser.hs
@@ -1,304 +1,356 @@
module Verismith.OptParser
- ( OptTool (..)
- , Opts (..)
- , opts
- )
+ ( OptTool (..),
+ Opts (..),
+ opts,
+ )
where
-import Control.Applicative ((<|>))
-import Data.Text (Text)
-import qualified Data.Text as T
-import Options.Applicative (Mod (..), OptionFields (..), Parser (..),
- ParserInfo (..), ReadM (..), (<**>))
+import Control.Applicative ((<|>))
+import Data.Text (Text)
+import qualified Data.Text as T
+import Options.Applicative
+ ( (<**>),
+ Mod (..),
+ OptionFields (..),
+ Parser (..),
+ ParserInfo (..),
+ ReadM (..),
+ )
import qualified Options.Applicative as Opt
-import Prelude hiding (FilePath (..))
-import Shelly (FilePath (..), fromText)
-import Verismith.Config (SynthDescription (..), versionInfo)
+import Shelly (FilePath (..), fromText)
+import Verismith.Config (SynthDescription (..), versionInfo)
+import Prelude hiding (FilePath (..))
-data OptTool = TYosys
- | TXST
- | TIcarus
+data OptTool
+ = TYosys
+ | TXST
+ | TIcarus
instance Show OptTool where
- show TYosys = "yosys"
- show TXST = "xst"
+ show TYosys = "yosys"
+ show TXST = "xst"
show TIcarus = "icarus"
-data Opts = Fuzz { fuzzOutput :: Text
- , fuzzConfigFile :: !(Maybe FilePath)
- , fuzzForced :: !Bool
- , fuzzKeepAll :: !Bool
- , fuzzNum :: {-# UNPACK #-} !Int
- , fuzzNoSim :: !Bool
- , fuzzNoEquiv :: !Bool
- , fuzzNoReduction :: !Bool
- , fuzzExistingFile :: !(Maybe FilePath)
- , fuzzExistingFileTop :: !Text
- , fuzzCrossCheck :: !Bool
- , fuzzChecker :: !(Maybe Text)
- }
- | Generate { generateFilename :: !(Maybe FilePath)
- , generateConfigFile :: !(Maybe FilePath)
- }
- | Parse { parseFilename :: !FilePath
- , parseTop :: !Text
- , parseOutput :: !(Maybe FilePath)
- , parseRemoveConstInConcat :: !Bool
- }
- | Reduce { reduceFilename :: !FilePath
- , reduceTop :: !Text
- , reduceScript :: !(Maybe FilePath)
- , reduceSynthesiserDesc :: ![SynthDescription]
- , reduceRerun :: !Bool
- }
- | ConfigOpt { configOptWriteConfig :: !(Maybe FilePath)
- , configOptConfigFile :: !(Maybe FilePath)
- , configOptDoRandomise :: !Bool
- }
+data Opts
+ = Fuzz
+ { fuzzOutput :: Text,
+ fuzzConfigFile :: !(Maybe FilePath),
+ fuzzForced :: !Bool,
+ fuzzKeepAll :: !Bool,
+ fuzzNum :: {-# UNPACK #-} !Int,
+ fuzzNoSim :: !Bool,
+ fuzzNoEquiv :: !Bool,
+ fuzzNoReduction :: !Bool,
+ fuzzExistingFile :: !(Maybe FilePath),
+ fuzzExistingFileTop :: !Text,
+ fuzzCrossCheck :: !Bool,
+ fuzzChecker :: !(Maybe Text)
+ }
+ | Generate
+ { generateFilename :: !(Maybe FilePath),
+ generateConfigFile :: !(Maybe FilePath)
+ }
+ | Parse
+ { parseFilename :: !FilePath,
+ parseTop :: !Text,
+ parseOutput :: !(Maybe FilePath),
+ parseRemoveConstInConcat :: !Bool
+ }
+ | Reduce
+ { reduceFilename :: !FilePath,
+ reduceTop :: !Text,
+ reduceScript :: !(Maybe FilePath),
+ reduceSynthesiserDesc :: ![SynthDescription],
+ reduceRerun :: !Bool
+ }
+ | ConfigOpt
+ { configOptWriteConfig :: !(Maybe FilePath),
+ configOptConfigFile :: !(Maybe FilePath),
+ configOptDoRandomise :: !Bool
+ }
textOption :: Mod OptionFields String -> Parser Text
textOption = fmap T.pack . Opt.strOption
optReader :: (String -> Maybe a) -> ReadM a
optReader f = Opt.eitherReader $ \arg -> case f arg of
- Just a -> Right a
- Nothing -> Left $ "Cannot parse option: " <> arg
+ Just a -> Right a
+ Nothing -> Left $ "Cannot parse option: " <> arg
parseSynth :: String -> Maybe OptTool
-parseSynth val | val == "yosys" = Just TYosys
- | val == "xst" = Just TXST
- | otherwise = Nothing
+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
+ | 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
+parseSim val
+ | val == "icarus" = Just TIcarus
+ | otherwise = Nothing
fuzzOpts :: Parser Opts
fuzzOpts =
- Fuzz
- <$> textOption
- ( Opt.long "output"
- <> Opt.short 'o'
- <> Opt.metavar "DIR"
- <> Opt.help "Output directory that the fuzz run takes place in."
- <> Opt.showDefault
- <> Opt.value "output")
- <*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "config"
- <> Opt.short 'c'
- <> Opt.metavar "FILE"
- <> Opt.help "Config file for the current fuzz run.")
- <*> (Opt.switch $ Opt.long "force" <> Opt.short 'f' <> Opt.help
- "Overwrite the specified directory.")
- <*> (Opt.switch $ Opt.long "keep" <> Opt.short 'k' <> Opt.help
- "Keep all the directories.")
- <*> ( Opt.option Opt.auto
- $ Opt.long "num"
- <> Opt.short 'n'
- <> Opt.help "The number of fuzz runs that should be performed."
- <> Opt.showDefault
- <> Opt.value 1
- <> Opt.metavar "INT")
- <*> (Opt.switch $ Opt.long "no-sim" <> Opt.help
- "Do not run simulation on the output netlist.")
- <*> (Opt.switch $ Opt.long "no-equiv" <> Opt.help
- "Do not run an equivalence check on the output netlist.")
- <*> (Opt.switch $ Opt.long "no-reduction" <> Opt.help
- "Do not run reduction on a failed testcase.")
- <*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "source"
- <> Opt.short 's'
- <> Opt.metavar "FILE"
- <> Opt.help "Name of the top module.")
- <*> textOption
- ( Opt.long "source-top"
- <> Opt.short 't'
- <> Opt.metavar "TOP"
- <> Opt.help "Define the top module for the source file."
- <> Opt.showDefault
- <> Opt.value "top")
- <*> (Opt.switch $ Opt.long "crosscheck" <> Opt.help
- "Do not only compare against the original design, but also against other netlists.")
- <*> (Opt.optional . textOption $
- Opt.long "checker"
- <> Opt.metavar "CHECKER"
- <> Opt.help "Define the checker to use.")
+ Fuzz
+ <$> textOption
+ ( Opt.long "output"
+ <> Opt.short 'o'
+ <> Opt.metavar "DIR"
+ <> Opt.help "Output directory that the fuzz run takes place in."
+ <> Opt.showDefault
+ <> Opt.value "output"
+ )
+ <*> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "config"
+ <> Opt.short 'c'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Config file for the current fuzz run."
+ )
+ <*> ( Opt.switch $
+ Opt.long "force" <> Opt.short 'f'
+ <> Opt.help
+ "Overwrite the specified directory."
+ )
+ <*> ( Opt.switch $
+ Opt.long "keep" <> Opt.short 'k'
+ <> Opt.help
+ "Keep all the directories."
+ )
+ <*> ( Opt.option Opt.auto $
+ Opt.long "num"
+ <> Opt.short 'n'
+ <> Opt.help "The number of fuzz runs that should be performed."
+ <> Opt.showDefault
+ <> Opt.value 1
+ <> Opt.metavar "INT"
+ )
+ <*> ( Opt.switch $
+ Opt.long "no-sim"
+ <> Opt.help
+ "Do not run simulation on the output netlist."
+ )
+ <*> ( Opt.switch $
+ Opt.long "no-equiv"
+ <> Opt.help
+ "Do not run an equivalence check on the output netlist."
+ )
+ <*> ( Opt.switch $
+ Opt.long "no-reduction"
+ <> Opt.help
+ "Do not run reduction on a failed testcase."
+ )
+ <*> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "source"
+ <> Opt.short 's'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Name of the top module."
+ )
+ <*> textOption
+ ( Opt.long "source-top"
+ <> Opt.short 't'
+ <> Opt.metavar "TOP"
+ <> Opt.help "Define the top module for the source file."
+ <> Opt.showDefault
+ <> Opt.value "top"
+ )
+ <*> ( Opt.switch $
+ Opt.long "crosscheck"
+ <> Opt.help
+ "Do not only compare against the original design, but also against other netlists."
+ )
+ <*> ( Opt.optional . textOption $
+ Opt.long "checker"
+ <> Opt.metavar "CHECKER"
+ <> Opt.help "Define the checker to use."
+ )
genOpts :: Parser Opts
genOpts =
- Generate
- <$> ( Opt.optional
- . Opt.strOption
- $ Opt.long "output"
- <> Opt.short 'o'
- <> Opt.metavar "FILE"
- <> Opt.help "Output to a verilog file instead."
- )
- <*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "config"
- <> Opt.short 'c'
- <> Opt.metavar "FILE"
- <> Opt.help "Config file for the generation run."
- )
+ Generate
+ <$> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "output"
+ <> Opt.short 'o'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Output to a verilog file instead."
+ )
+ <*> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "config"
+ <> Opt.short 'c'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Config file for the generation run."
+ )
parseOpts :: Parser Opts
-parseOpts = Parse
- <$> (fromText . T.pack <$> Opt.strArgument
- (Opt.metavar "FILE" <> Opt.help "Verilog input file."))
- <*> textOption ( Opt.short 't'
- <> Opt.long "top"
- <> Opt.metavar "TOP"
- <> Opt.help "Name of top level module."
- <> Opt.showDefault
- <> Opt.value "top"
- )
+parseOpts =
+ Parse
+ <$> ( fromText . T.pack
+ <$> Opt.strArgument
+ (Opt.metavar "FILE" <> Opt.help "Verilog input file.")
+ )
+ <*> textOption
+ ( Opt.short 't'
+ <> Opt.long "top"
+ <> Opt.metavar "TOP"
+ <> Opt.help "Name of top level module."
+ <> Opt.showDefault
+ <> Opt.value "top"
+ )
<*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "output"
- <> Opt.short 'o'
- <> Opt.metavar "FILE"
- <> Opt.help "Output file to write the parsed file to.")
- <*> (Opt.switch $ Opt.long "remove-const-in-concat" <> Opt.help
- "Remove constants in concatenation to simplify the Verilog.")
+ . Opt.strOption
+ $ Opt.long "output"
+ <> Opt.short 'o'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Output file to write the parsed file to."
+ )
+ <*> ( Opt.switch $
+ Opt.long "remove-const-in-concat"
+ <> Opt.help
+ "Remove constants in concatenation to simplify the Verilog."
+ )
reduceOpts :: Parser Opts
reduceOpts =
- Reduce
- . fromText
- . T.pack
- <$> Opt.strArgument (Opt.metavar "FILE" <> Opt.help "Verilog input file.")
- <*> textOption
- ( Opt.short 't'
- <> Opt.long "top"
- <> Opt.metavar "TOP"
- <> Opt.help "Name of top level module."
- <> Opt.showDefault
- <> Opt.value "top"
- )
- <*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "script"
- <> Opt.metavar "SCRIPT"
- <> Opt.help
- "Script that determines if the current file is interesting, which is determined by the script returning 0."
- )
- <*> ( Opt.many
- . Opt.option (optReader parseSynthDesc)
- $ Opt.short 's'
- <> Opt.long "synth"
- <> Opt.metavar "SYNTH"
- <> Opt.help "Specify synthesiser to use."
- )
- <*> ( Opt.switch
- $ Opt.short 'r'
- <> Opt.long "rerun"
- <> Opt.help
- "Only rerun the current synthesis file with all the synthesisers."
- )
+ Reduce
+ . fromText
+ . T.pack
+ <$> Opt.strArgument (Opt.metavar "FILE" <> Opt.help "Verilog input file.")
+ <*> textOption
+ ( Opt.short 't'
+ <> Opt.long "top"
+ <> Opt.metavar "TOP"
+ <> Opt.help "Name of top level module."
+ <> Opt.showDefault
+ <> Opt.value "top"
+ )
+ <*> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "script"
+ <> Opt.metavar "SCRIPT"
+ <> Opt.help
+ "Script that determines if the current file is interesting, which is determined by the script returning 0."
+ )
+ <*> ( Opt.many
+ . Opt.option (optReader parseSynthDesc)
+ $ Opt.short 's'
+ <> Opt.long "synth"
+ <> Opt.metavar "SYNTH"
+ <> Opt.help "Specify synthesiser to use."
+ )
+ <*> ( Opt.switch $
+ Opt.short 'r'
+ <> Opt.long "rerun"
+ <> Opt.help
+ "Only rerun the current synthesis file with all the synthesisers."
+ )
configOpts :: Parser Opts
configOpts =
- ConfigOpt
- <$> ( Opt.optional
- . Opt.strOption
- $ Opt.long "output"
- <> Opt.short 'o'
- <> Opt.metavar "FILE"
- <> Opt.help "Output to a TOML Config file."
- )
- <*> ( Opt.optional
- . Opt.strOption
- $ Opt.long "config"
- <> Opt.short 'c'
- <> Opt.metavar "FILE"
- <> Opt.help "Config file for the current fuzz run."
- )
- <*> ( Opt.switch
- $ Opt.long "randomise"
- <> Opt.short 'r'
- <> Opt.help
- "Randomise the given default config, or the default config by randomly switchin on and off options."
- )
+ ConfigOpt
+ <$> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "output"
+ <> Opt.short 'o'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Output to a TOML Config file."
+ )
+ <*> ( Opt.optional
+ . Opt.strOption
+ $ Opt.long "config"
+ <> Opt.short 'c'
+ <> Opt.metavar "FILE"
+ <> Opt.help "Config file for the current fuzz run."
+ )
+ <*> ( Opt.switch $
+ Opt.long "randomise"
+ <> Opt.short 'r'
+ <> Opt.help
+ "Randomise the given default config, or the default config by randomly switchin on and off options."
+ )
argparse :: Parser Opts
argparse =
- Opt.hsubparser
- ( Opt.command
- "fuzz"
- (Opt.info
- fuzzOpts
- (Opt.progDesc
- "Run fuzzing on the specified simulators and synthesisers."
- )
- )
- <> Opt.metavar "fuzz"
+ Opt.hsubparser
+ ( Opt.command
+ "fuzz"
+ ( Opt.info
+ fuzzOpts
+ ( Opt.progDesc
+ "Run fuzzing on the specified simulators and synthesisers."
)
- <|> Opt.hsubparser
- ( Opt.command
- "generate"
- (Opt.info
- genOpts
- (Opt.progDesc "Generate a random Verilog program.")
- )
- <> Opt.metavar "generate"
- )
- <|> Opt.hsubparser
- ( Opt.command
- "parse"
- (Opt.info
- parseOpts
- (Opt.progDesc
- "Parse a verilog file and output a pretty printed version."
- )
- )
- <> Opt.metavar "parse"
- )
- <|> Opt.hsubparser
- ( Opt.command
- "reduce"
- (Opt.info
- reduceOpts
- (Opt.progDesc
- "Reduce a Verilog file by rerunning the fuzzer on the file."
- )
- )
- <> Opt.metavar "reduce"
- )
- <|> Opt.hsubparser
- ( Opt.command
- "config"
- (Opt.info
- configOpts
- (Opt.progDesc
- "Print the current configuration of the fuzzer."
- )
- )
- <> Opt.metavar "config"
- )
+ )
+ <> Opt.metavar "fuzz"
+ )
+ <|> Opt.hsubparser
+ ( Opt.command
+ "generate"
+ ( Opt.info
+ genOpts
+ (Opt.progDesc "Generate a random Verilog program.")
+ )
+ <> Opt.metavar "generate"
+ )
+ <|> Opt.hsubparser
+ ( Opt.command
+ "parse"
+ ( Opt.info
+ parseOpts
+ ( Opt.progDesc
+ "Parse a verilog file and output a pretty printed version."
+ )
+ )
+ <> Opt.metavar "parse"
+ )
+ <|> Opt.hsubparser
+ ( Opt.command
+ "reduce"
+ ( Opt.info
+ reduceOpts
+ ( Opt.progDesc
+ "Reduce a Verilog file by rerunning the fuzzer on the file."
+ )
+ )
+ <> Opt.metavar "reduce"
+ )
+ <|> Opt.hsubparser
+ ( Opt.command
+ "config"
+ ( Opt.info
+ configOpts
+ ( Opt.progDesc
+ "Print the current configuration of the fuzzer."
+ )
+ )
+ <> Opt.metavar "config"
+ )
version :: Parser (a -> a)
-version = Opt.infoOption versionInfo $ mconcat
- [Opt.long "version", Opt.short 'v', Opt.help "Show version information.", Opt.hidden]
+version =
+ Opt.infoOption versionInfo $
+ mconcat
+ [Opt.long "version", Opt.short 'v', Opt.help "Show version information.", Opt.hidden]
opts :: ParserInfo Opts
-opts = Opt.info
+opts =
+ Opt.info
(argparse <**> Opt.helper <**> version)
- ( Opt.fullDesc
- <> Opt.progDesc "Fuzz different simulators and synthesisers."
- <> Opt.header
- "Verismith - A hardware simulator and synthesiser Verilog fuzzer."
+ ( Opt.fullDesc
+ <> Opt.progDesc "Fuzz different simulators and synthesisers."
+ <> Opt.header
+ "Verismith - A hardware simulator and synthesiser Verilog fuzzer."
)