2019-02-08 06:19:39 +01:00
|
|
|
{- sv2v
|
2019-02-08 07:09:10 +01:00
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- conversion entry point
|
|
|
|
|
-}
|
2019-02-08 06:19:39 +01:00
|
|
|
|
2021-01-29 00:34:55 +01:00
|
|
|
import System.IO (hPrint, hPutStrLn, stderr, stdout)
|
|
|
|
|
import System.Exit (exitFailure, exitSuccess)
|
2023-06-21 14:25:42 +02:00
|
|
|
import System.FilePath (combine, splitExtension)
|
2021-01-29 00:34:55 +01:00
|
|
|
|
2022-03-16 15:34:29 +01:00
|
|
|
import Control.Monad (when, zipWithM_)
|
2021-08-07 06:23:34 +02:00
|
|
|
import Control.Monad.Except (runExceptT)
|
2023-08-20 19:56:03 +02:00
|
|
|
import Data.List (nub)
|
2019-02-08 06:19:39 +01:00
|
|
|
|
2024-06-20 05:06:34 +02:00
|
|
|
import Bugpoint (runBugpoint)
|
2019-02-18 05:39:01 +01:00
|
|
|
import Convert (convert)
|
2021-01-29 00:34:55 +01:00
|
|
|
import Job (readJob, Job(..), Write(..))
|
2020-12-31 01:17:27 +01:00
|
|
|
import Language.SystemVerilog.AST
|
2023-06-14 04:53:36 +02:00
|
|
|
import Language.SystemVerilog.Parser (parseFiles, Config(..))
|
2024-06-16 04:15:30 +02:00
|
|
|
import Split (splitDescriptions)
|
2019-04-02 22:19:59 +02:00
|
|
|
|
2021-02-03 15:53:32 +01:00
|
|
|
isComment :: Description -> Bool
|
|
|
|
|
isComment (PackageItem (Decl CommentDecl{})) = True
|
|
|
|
|
isComment _ = False
|
|
|
|
|
|
2023-08-20 19:56:03 +02:00
|
|
|
droppedKind :: Description -> Identifier
|
|
|
|
|
droppedKind description =
|
|
|
|
|
case description of
|
|
|
|
|
Part _ _ Interface _ _ _ _ -> "interface"
|
|
|
|
|
Package{} -> "package"
|
|
|
|
|
Class{} -> "class"
|
|
|
|
|
PackageItem Function{} -> "function"
|
|
|
|
|
PackageItem Task {} -> "task"
|
|
|
|
|
PackageItem (Decl Param{}) -> "localparam"
|
|
|
|
|
_ -> ""
|
|
|
|
|
|
2021-02-03 15:53:32 +01:00
|
|
|
emptyWarnings :: AST -> AST -> IO ()
|
2020-12-31 01:17:27 +01:00
|
|
|
emptyWarnings before after =
|
2023-08-20 19:56:03 +02:00
|
|
|
if all isComment before || not (all isComment after) || null kinds then
|
2020-12-31 01:17:27 +01:00
|
|
|
return ()
|
2023-08-20 19:56:03 +02:00
|
|
|
else if elem "interface" kinds then
|
|
|
|
|
hPutStrLn stderr $ "Warning: Source includes an interface but the"
|
|
|
|
|
++ " output is empty because there are no modules without any"
|
|
|
|
|
++ " interface ports. Please convert interfaces alongside the"
|
|
|
|
|
++ " modules that instantiate them."
|
2020-12-31 01:17:27 +01:00
|
|
|
else
|
2023-08-20 19:56:03 +02:00
|
|
|
hPutStrLn stderr $ "Warning: Source includes a " ++ kind ++ " but no"
|
|
|
|
|
++ " modules. Such elements are elaborated into the modules that"
|
|
|
|
|
++ " use them. Please convert all sources in one invocation."
|
|
|
|
|
where
|
|
|
|
|
kinds = nub $ filter (not . null) $ map droppedKind before
|
|
|
|
|
kind = head kinds
|
2020-12-31 01:17:27 +01:00
|
|
|
|
2021-01-29 00:34:55 +01:00
|
|
|
rewritePath :: FilePath -> IO FilePath
|
|
|
|
|
rewritePath path = do
|
|
|
|
|
when (end /= ext) $ do
|
|
|
|
|
hPutStrLn stderr $ "Refusing to write adjacent to " ++ show path
|
|
|
|
|
++ " because that path does not end in " ++ show ext
|
|
|
|
|
exitFailure
|
|
|
|
|
return $ base ++ ".v"
|
|
|
|
|
where
|
|
|
|
|
ext = ".sv"
|
2023-06-21 14:25:42 +02:00
|
|
|
(base, end) = splitExtension path
|
|
|
|
|
|
2021-01-29 00:34:55 +01:00
|
|
|
writeOutput :: Write -> [FilePath] -> [AST] -> IO ()
|
2021-03-29 17:16:53 +02:00
|
|
|
writeOutput _ [] [] =
|
|
|
|
|
hPutStrLn stderr "Warning: No input files specified (try `sv2v --help`)"
|
2021-01-29 00:34:55 +01:00
|
|
|
writeOutput Stdout _ asts =
|
|
|
|
|
hPrint stdout $ concat asts
|
2021-06-16 23:05:53 +02:00
|
|
|
writeOutput (File f) _ asts =
|
2021-06-14 21:45:24 +02:00
|
|
|
writeFile f $ show $ concat asts
|
2021-01-29 00:34:55 +01:00
|
|
|
writeOutput Adjacent inPaths asts = do
|
|
|
|
|
outPaths <- mapM rewritePath inPaths
|
|
|
|
|
let results = map (++ "\n") $ map show asts
|
|
|
|
|
zipWithM_ writeFile outPaths results
|
2024-06-16 04:15:30 +02:00
|
|
|
writeOutput (Directory d) _ asts =
|
2023-06-21 14:25:42 +02:00
|
|
|
zipWithM_ writeFile outPaths outputs
|
2024-06-16 04:15:30 +02:00
|
|
|
where
|
|
|
|
|
(outPaths, outputs) =
|
|
|
|
|
unzip $ map prepare $ fst $ splitDescriptions (concat asts) []
|
|
|
|
|
prepare :: (String, AST) -> (FilePath, String)
|
|
|
|
|
prepare (name, ast) = (path, output)
|
|
|
|
|
where
|
|
|
|
|
path = combine d $ name ++ ".v"
|
|
|
|
|
output = concatMap (++ "\n") $ map show ast
|
2021-01-29 00:34:55 +01:00
|
|
|
|
2019-02-08 06:19:39 +01:00
|
|
|
main :: IO ()
|
|
|
|
|
main = do
|
2019-02-28 20:06:35 +01:00
|
|
|
job <- readJob
|
2019-08-06 04:00:04 +02:00
|
|
|
-- parse the input files
|
2021-08-07 06:23:34 +02:00
|
|
|
let config = Config
|
2023-06-14 04:53:36 +02:00
|
|
|
{ cfDefines = define job
|
2021-08-07 06:23:34 +02:00
|
|
|
, cfIncludePaths = incdir job
|
2023-06-14 04:53:36 +02:00
|
|
|
, cfLibraryPaths = libdir job
|
2021-08-07 06:23:34 +02:00
|
|
|
, cfSiloed = siloed job
|
|
|
|
|
, cfSkipPreprocessor = skipPreprocessor job
|
2021-08-10 06:10:29 +02:00
|
|
|
, cfOversizedNumbers = oversizedNumbers job
|
2021-08-07 06:23:34 +02:00
|
|
|
}
|
|
|
|
|
result <- runExceptT $ parseFiles config (files job)
|
2019-09-18 01:34:53 +02:00
|
|
|
case result of
|
|
|
|
|
Left msg -> do
|
2021-01-29 00:34:55 +01:00
|
|
|
hPutStrLn stderr msg
|
2019-09-18 01:34:53 +02:00
|
|
|
exitFailure
|
2023-06-14 04:53:36 +02:00
|
|
|
Right inputs -> do
|
|
|
|
|
let (inPaths, asts) = unzip inputs
|
2021-06-25 19:05:49 +02:00
|
|
|
-- convert the files if requested
|
2023-06-19 04:36:43 +02:00
|
|
|
let converter = convert (top job) (dumpPrefix job) (exclude job)
|
|
|
|
|
asts' <-
|
|
|
|
|
if passThrough job then
|
|
|
|
|
return asts
|
2024-06-20 05:06:34 +02:00
|
|
|
else if bugpoint job /= [] then
|
|
|
|
|
runBugpoint (bugpoint job) converter asts
|
2023-06-19 04:36:43 +02:00
|
|
|
else
|
|
|
|
|
converter asts
|
2021-02-03 15:53:32 +01:00
|
|
|
emptyWarnings (concat asts) (concat asts')
|
2021-01-29 00:34:55 +01:00
|
|
|
-- write the converted files out
|
2023-06-14 04:53:36 +02:00
|
|
|
writeOutput (write job) inPaths asts'
|
2019-09-18 01:34:53 +02:00
|
|
|
exitSuccess
|