mirror of https://github.com/zachjs/sv2v.git
46 lines
1.5 KiB
Haskell
46 lines
1.5 KiB
Haskell
{- sv2v
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
-
|
|
- SystemVerilog allows functions to be called without using their result. For
|
|
- example, if `f` is a function, one may write `f();` or `void'(f());`, causing
|
|
- any side effects of `f` to occur in each case. Verilog-2005 does not allow
|
|
- functions to be called as though they were tasks in this way. This conversion
|
|
- creates a dummy variable to store the result of the function.
|
|
-}
|
|
|
|
module Convert.FuncRoutine (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 @ Part{}) =
|
|
traverseModuleItems (traverseStmts $ convertStmt functions) description
|
|
where functions = execWriter $
|
|
collectModuleItemsM collectFunctionsM description
|
|
convertDescription other = other
|
|
|
|
collectFunctionsM :: ModuleItem -> Writer Idents ()
|
|
collectFunctionsM (MIPackageItem (Function _ _ f _ _)) =
|
|
tell $ Set.singleton f
|
|
collectFunctionsM _ = return ()
|
|
|
|
convertStmt :: Idents -> Stmt -> Stmt
|
|
convertStmt functions (Subroutine (Ident func) args) =
|
|
if Set.member func functions
|
|
then Block Seq "" [decl] []
|
|
else Subroutine (Ident func) args
|
|
where
|
|
t = TypeOf e
|
|
e = Call (Ident func) args
|
|
decl = Variable Local t "sv2v_void" [] (Just e)
|
|
convertStmt _ other = other
|