mirror of https://github.com/zachjs/sv2v.git
add --oneunit, which treats all input files as being part of one compilation unit
This commit is contained in:
parent
376f0d3f2a
commit
90bc30d4be
|
|
@ -20,6 +20,7 @@ data Job = Job
|
|||
, files :: [FilePath]
|
||||
, incdir :: [FilePath]
|
||||
, define :: [String]
|
||||
, oneunit :: Bool
|
||||
} deriving (Show, Typeable, Data)
|
||||
|
||||
defaultJob :: Job
|
||||
|
|
@ -29,6 +30,7 @@ defaultJob = Job
|
|||
, files = def &= args &= typ "FILES"
|
||||
, incdir = def &= typDir &= help "add directory to include search path"
|
||||
, define = def &= typ "NAME[=VALUE]" &= help "define a macro for preprocessing"
|
||||
, oneunit = False &= help "compile all files in one compilation unit"
|
||||
}
|
||||
&= program "sv2v"
|
||||
&= summary "sv2v v0.0.1, (C) 2019 Zachary Snow, 2011-2015 Tom Hawkins"
|
||||
|
|
|
|||
|
|
@ -2,15 +2,32 @@
|
|||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
-}
|
||||
module Language.SystemVerilog.Parser
|
||||
( parseFile
|
||||
( parseFiles
|
||||
) where
|
||||
|
||||
import qualified Data.Map.Strict as Map
|
||||
import Language.SystemVerilog.AST (AST)
|
||||
import Language.SystemVerilog.Parser.Lex (lexFile)
|
||||
import Language.SystemVerilog.Parser.Lex (lexFile, Env)
|
||||
import Language.SystemVerilog.Parser.Parse (parse)
|
||||
|
||||
-- parses a compilation unit given include search paths and predefined macros
|
||||
parseFiles :: [FilePath] -> [(String, String)] -> [FilePath] -> IO [AST]
|
||||
parseFiles includePaths defines paths = do
|
||||
let env = Map.map (\a -> (a, [])) $ Map.fromList defines
|
||||
parseFiles' includePaths env paths
|
||||
|
||||
-- parses a compilation unit given include search paths and predefined macros
|
||||
parseFiles' :: [FilePath] -> Env -> [FilePath] -> IO [AST]
|
||||
parseFiles' _ _ [] = return []
|
||||
parseFiles' includePaths env (path : paths) = do
|
||||
(ast, env') <- parseFile' includePaths env path
|
||||
asts <- parseFiles' includePaths env' paths
|
||||
return $ ast : asts
|
||||
|
||||
-- parses a file given include search paths, a table of predefined macros, and
|
||||
-- the file path
|
||||
parseFile :: [String] -> [(String, String)] -> FilePath -> IO AST
|
||||
parseFile includePaths defines path =
|
||||
lexFile includePaths defines path >>= return . parse
|
||||
parseFile' :: [String] -> Env -> FilePath -> IO (AST, Env)
|
||||
parseFile' includePaths env path = do
|
||||
(tokens, env') <- lexFile includePaths env path
|
||||
let ast = parse tokens
|
||||
return (ast, env')
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@
|
|||
-- been fixed on their development branch, so this can be removed once they roll
|
||||
-- a new release. (no new release as of 3/29/2018)
|
||||
|
||||
module Language.SystemVerilog.Parser.Lex (lexFile) where
|
||||
module Language.SystemVerilog.Parser.Lex
|
||||
( lexFile
|
||||
, Env
|
||||
) where
|
||||
|
||||
import System.FilePath (dropFileName)
|
||||
import System.Directory (findFile)
|
||||
|
|
@ -322,11 +325,14 @@ data Cond
|
|||
| NeverTrue
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- map from macro to definition, plus arguments
|
||||
type Env = Map.Map String (String, [(String, Maybe String)])
|
||||
|
||||
-- our custom lexer state
|
||||
data AlexUserState = LS
|
||||
{ lsToks :: [Token] -- tokens read so far, *in reverse order* for efficiency
|
||||
, lsCurrFile :: FilePath -- currently active filename
|
||||
, lsEnv :: Map.Map String (String, [(String, Maybe String)]) -- active macro definitions
|
||||
, lsEnv :: Env -- active macro definitions
|
||||
, lsCondStack :: [Cond] -- if-else cascade state
|
||||
, lsIncludePaths :: [FilePath] -- folders to search for includes
|
||||
} deriving (Eq, Show)
|
||||
|
|
@ -338,7 +344,7 @@ alexInitUserState :: AlexUserState
|
|||
alexInitUserState = LS [] "" Map.empty [] []
|
||||
|
||||
-- public-facing lexer entrypoint
|
||||
lexFile :: [String] -> [(String, String)] -> FilePath -> IO [Token]
|
||||
lexFile :: [String] -> Env -> FilePath -> IO ([Token], Env)
|
||||
lexFile includePaths env path = do
|
||||
str <- readFile path
|
||||
let result = runAlex str $ setEnv >> alexMonadScan >> get
|
||||
|
|
@ -346,16 +352,15 @@ lexFile includePaths env path = do
|
|||
Left msg -> error $ "Lexical Error: " ++ msg
|
||||
Right finalState ->
|
||||
if null $ lsCondStack finalState
|
||||
then reverse $ lsToks finalState
|
||||
then (reverse $ lsToks finalState, lsEnv finalState)
|
||||
else error $ "unfinished conditional directives: " ++
|
||||
(show $ length $ lsCondStack finalState)
|
||||
where
|
||||
initialEnv = Map.map (\a -> (a, [])) $ Map.fromList env
|
||||
setEnv = do
|
||||
-- standardize the file path format
|
||||
path' <- includeSearch path
|
||||
modify $ \s -> s
|
||||
{ lsEnv = initialEnv
|
||||
{ lsEnv = env
|
||||
, lsIncludePaths = includePaths
|
||||
, lsCurrFile = path'
|
||||
}
|
||||
|
|
|
|||
17
src/sv2v.hs
17
src/sv2v.hs
|
|
@ -8,9 +8,9 @@ import System.IO
|
|||
import System.Exit
|
||||
|
||||
import Data.List (elemIndex)
|
||||
import Job (readJob, files, exclude, incdir, define)
|
||||
import Job (readJob, files, exclude, incdir, define, oneunit)
|
||||
import Convert (convert)
|
||||
import Language.SystemVerilog.Parser
|
||||
import Language.SystemVerilog.Parser (parseFiles)
|
||||
|
||||
splitDefine :: String -> (String, String)
|
||||
splitDefine str =
|
||||
|
|
@ -21,12 +21,17 @@ splitDefine str =
|
|||
main :: IO ()
|
||||
main = do
|
||||
job <- readJob
|
||||
-- parse the input file
|
||||
-- parse the input files
|
||||
let includePaths = incdir job
|
||||
let defines = map splitDefine $ define job
|
||||
asts <- mapM (parseFile includePaths defines) (files job)
|
||||
-- convert the file
|
||||
let singleton = \x -> [x]
|
||||
let toFileLists = if oneunit job then singleton else map singleton
|
||||
astLists <- mapM
|
||||
(parseFiles includePaths defines)
|
||||
(toFileLists $ files job)
|
||||
let asts = concat astLists
|
||||
-- convert the files
|
||||
let asts' = convert (exclude job) asts
|
||||
-- print the converted file out
|
||||
-- print the converted files out
|
||||
hPrint stdout $ concat asts'
|
||||
exitSuccess
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ module top
|
|||
assign o = i + 1'b1;
|
||||
initial begin
|
||||
$display(width);
|
||||
$display(`FANCY_SEEING_YOU);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
`define FANCY_SEEING_YOU 1337
|
||||
package pkg;
|
||||
function automatic integer width_calc;
|
||||
input integer a;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
`define FANCY_SEEING_YOU 1337
|
||||
module top;
|
||||
parameter width = 5;
|
||||
input [width-1:0] i;
|
||||
|
|
@ -5,5 +6,6 @@ module top;
|
|||
assign o = i + 1'b1;
|
||||
initial begin
|
||||
$display(width);
|
||||
$display(`FANCY_SEEING_YOU);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
test_main() {
|
||||
cv="$SHUNIT_TMPDIR/conv.v"
|
||||
convert "$cv" package.svh module.sv
|
||||
convert "$cv" --oneunit package.svh module.sv
|
||||
simulateAndCompare "reference.v" "$cv" "$SCRIPT_DIR/empty.v"
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue