From 1dad3a7502f43c032830e7ba99c29aa07fe8fcad Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 28 Aug 2019 20:28:56 -0400 Subject: [PATCH] parse and convert empty function arguments (resolves #17) --- src/Convert.hs | 2 + src/Convert/EmptyArgs.hs | 53 +++++++++++++++++++++++ src/Language/SystemVerilog/Parser/Parse.y | 1 + sv2v.cabal | 1 + test/basic/empty_args.sv | 6 +++ test/basic/empty_args.v | 7 +++ 6 files changed, 70 insertions(+) create mode 100644 src/Convert/EmptyArgs.hs create mode 100644 test/basic/empty_args.sv create mode 100644 test/basic/empty_args.v diff --git a/src/Convert.hs b/src/Convert.hs index a693914..81f6713 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -13,6 +13,7 @@ import qualified Convert.AlwaysKW import qualified Convert.AsgnOp import qualified Convert.Assertion import qualified Convert.Bits +import qualified Convert.EmptyArgs import qualified Convert.Enum import qualified Convert.FuncRet import qualified Convert.Interface @@ -42,6 +43,7 @@ phases excludes = , Convert.Bits.convert , selectExclude (Job.Logic , Convert.Logic.convert) , Convert.FuncRet.convert + , Convert.EmptyArgs.convert , Convert.Enum.convert , Convert.IntTypes.convert , Convert.KWArgs.convert diff --git a/src/Convert/EmptyArgs.hs b/src/Convert/EmptyArgs.hs new file mode 100644 index 0000000..06f8d46 --- /dev/null +++ b/src/Convert/EmptyArgs.hs @@ -0,0 +1,53 @@ +{- sv2v + - Author: Zachary Snow + - + - Verilog-2005 requires that all functions have at least one input port. + - SystemVerilog allows functions to have no arguments. This conversion adds a + - dummy argument to such functions. + -} + +module Convert.EmptyArgs (convert) where + +import Control.Monad.Writer +import qualified Data.Set as Set + +import Convert.Traverse +import Language.SystemVerilog.AST + +type Idents = Set.Set Identifier + +convert :: [AST] -> [AST] +convert = map $ traverseDescriptions convertDescription + +convertDescription :: Description -> Description +convertDescription description = + traverseModuleItems + (traverseExprs $ traverseNestedExprs $ convertExpr functions) + description' + where + (description', functions) = + runWriter $ traverseModuleItemsM traverseFunctionsM description + +traverseFunctionsM :: ModuleItem -> Writer Idents ModuleItem +traverseFunctionsM (MIPackageItem (Function ml t f decls stmts)) = do + let dummyDecl = Variable Input (Implicit Unspecified []) "_sv2v_unused" [] Nothing + decls' <- do + if any isInput decls + then return decls + else do + tell $ Set.singleton f + return $ dummyDecl : decls + return $ MIPackageItem $ Function ml t f decls' stmts + where + isInput :: Decl -> Bool + isInput (Variable Input _ _ _ _) = True + isInput _ = False +traverseFunctionsM other = return other + +convertExpr :: Idents -> Expr -> Expr +convertExpr functions (Call Nothing func (Args [] [])) = + Call Nothing func (Args args []) + where args = if Set.member func functions + then [Just $ Number "0"] + else [] +convertExpr _ other = other diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 0175db4..b6894e6 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -615,6 +615,7 @@ ModuleInstantiation :: { [PortBinding] } TFItems :: { [Decl] } : "(" DeclTokens(")") ";" { parseDTsAsDecls $2 } + | "(" ")" ";" { [] } | ";" { [] } ParamType :: { Type } diff --git a/sv2v.cabal b/sv2v.cabal index 9f15850..2ecf0e8 100644 --- a/sv2v.cabal +++ b/sv2v.cabal @@ -57,6 +57,7 @@ executable sv2v Convert.AsgnOp Convert.Assertion Convert.Bits + Convert.EmptyArgs Convert.Enum Convert.FuncRet Convert.Interface diff --git a/test/basic/empty_args.sv b/test/basic/empty_args.sv new file mode 100644 index 0000000..35bc3e1 --- /dev/null +++ b/test/basic/empty_args.sv @@ -0,0 +1,6 @@ +module top; + function automatic logic [31:0] nop(); + return 32'h00000013; + endfunction + initial $display(nop()); +endmodule diff --git a/test/basic/empty_args.v b/test/basic/empty_args.v new file mode 100644 index 0000000..b7a22e0 --- /dev/null +++ b/test/basic/empty_args.v @@ -0,0 +1,7 @@ +module top; + function automatic [31:0] nop; + input foo; + nop = 32'h00000013; + endfunction + initial $display(nop(0)); +endmodule