Commit 90bc30d4 by Zachary Snow

add --oneunit, which treats all input files as being part of one compilation unit

parent 376f0d3f
......@@ -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'
}
......
......@@ -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
`define FANCY_SEEING_YOU 1337
package pkg;
function automatic integer width_calc;
input integer a;
......
`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"
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment