Commit 22d6ba49 by Zachary Snow

support evaluating functions as statements

parent 2bd24b60
......@@ -19,6 +19,7 @@ import qualified Convert.Enum
import qualified Convert.ForDecl
import qualified Convert.Foreach
import qualified Convert.FuncRet
import qualified Convert.FuncRoutine
import qualified Convert.Inside
import qualified Convert.Interface
import qualified Convert.IntTypes
......@@ -58,6 +59,7 @@ phases excludes =
, selectExclude (Job.Logic , Convert.Logic.convert)
, Convert.ForDecl.convert
, Convert.FuncRet.convert
, Convert.FuncRoutine.convert
, Convert.EmptyArgs.convert
, Convert.Inside.convert
, Convert.IntTypes.convert
......
{- 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
......@@ -941,6 +941,7 @@ StmtNonBlock :: { Stmt }
| AttributeInstance Stmt { StmtAttr $1 $2 }
| ProceduralAssertionStatement { Assertion $1 }
| IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") }
| "void" "'" "(" Expr CallArgs ")" ";" { Subroutine $4 $5 }
BlockKWPar :: { BlockKW }
: "fork" { Par }
......
......@@ -66,6 +66,7 @@ executable sv2v
Convert.ForDecl
Convert.Foreach
Convert.FuncRet
Convert.FuncRoutine
Convert.Inside
Convert.Interface
Convert.IntTypes
......
......@@ -4,6 +4,10 @@ module top;
f = 1'b1 ^ x;
$display("f(%b) called", x);
endfunction
task t;
input x;
$display("t(%b) called", x);
endtask
initial begin
type(f(0)) x = f(0);
......@@ -11,5 +15,8 @@ module top;
$display("%b", $bits(x));
$display("%b", $bits(type(x)));
$display("%b", $bits(logic [0:1+$bits(type(x))]));
f(1);
void'(f(0));
t(1);
end
endmodule
......@@ -6,6 +6,10 @@ module top;
$display("f(%b) called", x);
end
endfunction
task t;
input x;
$display("t(%b) called", x);
endtask
initial begin : block
reg x;
......@@ -14,5 +18,8 @@ module top;
$display("%b", 32'd1);
$display("%b", 32'd1);
$display("%b", 32'd3);
x = f(1);
x = f(0);
t(1);
end
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment