parse and convert empty function arguments (resolves #17)

This commit is contained in:
Zachary Snow 2019-08-28 20:28:56 -04:00
parent 02ba9e95df
commit 1dad3a7502
6 changed files with 70 additions and 0 deletions

View File

@ -13,6 +13,7 @@ import qualified Convert.AlwaysKW
import qualified Convert.AsgnOp import qualified Convert.AsgnOp
import qualified Convert.Assertion import qualified Convert.Assertion
import qualified Convert.Bits import qualified Convert.Bits
import qualified Convert.EmptyArgs
import qualified Convert.Enum import qualified Convert.Enum
import qualified Convert.FuncRet import qualified Convert.FuncRet
import qualified Convert.Interface import qualified Convert.Interface
@ -42,6 +43,7 @@ phases excludes =
, Convert.Bits.convert , Convert.Bits.convert
, selectExclude (Job.Logic , Convert.Logic.convert) , selectExclude (Job.Logic , Convert.Logic.convert)
, Convert.FuncRet.convert , Convert.FuncRet.convert
, Convert.EmptyArgs.convert
, Convert.Enum.convert , Convert.Enum.convert
, Convert.IntTypes.convert , Convert.IntTypes.convert
, Convert.KWArgs.convert , Convert.KWArgs.convert

53
src/Convert/EmptyArgs.hs Normal file
View File

@ -0,0 +1,53 @@
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- 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

View File

@ -615,6 +615,7 @@ ModuleInstantiation :: { [PortBinding] }
TFItems :: { [Decl] } TFItems :: { [Decl] }
: "(" DeclTokens(")") ";" { parseDTsAsDecls $2 } : "(" DeclTokens(")") ";" { parseDTsAsDecls $2 }
| "(" ")" ";" { [] }
| ";" { [] } | ";" { [] }
ParamType :: { Type } ParamType :: { Type }

View File

@ -57,6 +57,7 @@ executable sv2v
Convert.AsgnOp Convert.AsgnOp
Convert.Assertion Convert.Assertion
Convert.Bits Convert.Bits
Convert.EmptyArgs
Convert.Enum Convert.Enum
Convert.FuncRet Convert.FuncRet
Convert.Interface Convert.Interface

6
test/basic/empty_args.sv Normal file
View File

@ -0,0 +1,6 @@
module top;
function automatic logic [31:0] nop();
return 32'h00000013;
endfunction
initial $display(nop());
endmodule

7
test/basic/empty_args.v Normal file
View File

@ -0,0 +1,7 @@
module top;
function automatic [31:0] nop;
input foo;
nop = 32'h00000013;
endfunction
initial $display(nop(0));
endmodule