mirror of https://github.com/zachjs/sv2v.git
support evaluating functions as statements
This commit is contained in:
parent
2bd24b6086
commit
22d6ba4927
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
{- 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
|
||||
|
|
|
|||
Loading…
Reference in New Issue