{- 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.Strict 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@Part{} = traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertExpr functions) description' where (description', functions) = runWriter $ traverseModuleItemsM traverseFunctionsM description convertDescription other = other traverseFunctionsM :: ModuleItem -> Writer Idents ModuleItem traverseFunctionsM (MIPackageItem (Function ml t f decls stmts)) = do decls' <- 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 dummyType = IntegerVector TReg Unspecified [] dummyDecl = Variable Input dummyType "_sv2v_unused" [] Nil isInput :: Decl -> Bool isInput (Variable Input _ _ _ _) = True isInput _ = False traverseFunctionsM other = return other convertExpr :: Idents -> Expr -> Expr convertExpr functions (Call (Ident func) (Args [] [])) = Call (Ident func) (Args args []) where args = if Set.member func functions then [RawNum 0] else [] convertExpr _ other = other