EmptyArgs.hs 1.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
{- 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

11
import Control.Monad.Writer.Strict
12 13 14 15 16 17 18 19 20 21 22
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
23
convertDescription description@Part{} =
24 25 26 27 28 29
    traverseModuleItems
        (traverseExprs $ traverseNestedExprs $ convertExpr functions)
        description'
    where
        (description', functions) =
            runWriter $ traverseModuleItemsM traverseFunctionsM description
30
convertDescription other = other
31 32 33

traverseFunctionsM :: ModuleItem -> Writer Idents ModuleItem
traverseFunctionsM (MIPackageItem (Function ml t f decls stmts)) = do
34
    decls' <-
35 36 37 38 39 40 41
        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
42 43
        dummyType = IntegerVector TReg Unspecified []
        dummyDecl = Variable Input dummyType "_sv2v_unused" [] Nil
44 45 46 47 48 49
        isInput :: Decl -> Bool
        isInput (Variable Input _ _ _ _) = True
        isInput _ = False
traverseFunctionsM other = return other

convertExpr :: Idents -> Expr -> Expr
50 51
convertExpr functions (Call (Ident func) (Args [] [])) =
    Call (Ident func) (Args args [])
52
    where args = if Set.member func functions
53
            then [RawNum 0]
54 55
            else []
convertExpr _ other = other