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.ForDecl
|
||||||
import qualified Convert.Foreach
|
import qualified Convert.Foreach
|
||||||
import qualified Convert.FuncRet
|
import qualified Convert.FuncRet
|
||||||
|
import qualified Convert.FuncRoutine
|
||||||
import qualified Convert.Inside
|
import qualified Convert.Inside
|
||||||
import qualified Convert.Interface
|
import qualified Convert.Interface
|
||||||
import qualified Convert.IntTypes
|
import qualified Convert.IntTypes
|
||||||
|
|
@ -58,6 +59,7 @@ phases excludes =
|
||||||
, selectExclude (Job.Logic , Convert.Logic.convert)
|
, selectExclude (Job.Logic , Convert.Logic.convert)
|
||||||
, Convert.ForDecl.convert
|
, Convert.ForDecl.convert
|
||||||
, Convert.FuncRet.convert
|
, Convert.FuncRet.convert
|
||||||
|
, Convert.FuncRoutine.convert
|
||||||
, Convert.EmptyArgs.convert
|
, Convert.EmptyArgs.convert
|
||||||
, Convert.Inside.convert
|
, Convert.Inside.convert
|
||||||
, Convert.IntTypes.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 }
|
| AttributeInstance Stmt { StmtAttr $1 $2 }
|
||||||
| ProceduralAssertionStatement { Assertion $1 }
|
| ProceduralAssertionStatement { Assertion $1 }
|
||||||
| IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") }
|
| IncOrDecOperator LHS ";" { AsgnBlk (AsgnOp $1) $2 (Number "1") }
|
||||||
|
| "void" "'" "(" Expr CallArgs ")" ";" { Subroutine $4 $5 }
|
||||||
|
|
||||||
BlockKWPar :: { BlockKW }
|
BlockKWPar :: { BlockKW }
|
||||||
: "fork" { Par }
|
: "fork" { Par }
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ executable sv2v
|
||||||
Convert.ForDecl
|
Convert.ForDecl
|
||||||
Convert.Foreach
|
Convert.Foreach
|
||||||
Convert.FuncRet
|
Convert.FuncRet
|
||||||
|
Convert.FuncRoutine
|
||||||
Convert.Inside
|
Convert.Inside
|
||||||
Convert.Interface
|
Convert.Interface
|
||||||
Convert.IntTypes
|
Convert.IntTypes
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ module top;
|
||||||
f = 1'b1 ^ x;
|
f = 1'b1 ^ x;
|
||||||
$display("f(%b) called", x);
|
$display("f(%b) called", x);
|
||||||
endfunction
|
endfunction
|
||||||
|
task t;
|
||||||
|
input x;
|
||||||
|
$display("t(%b) called", x);
|
||||||
|
endtask
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
type(f(0)) x = f(0);
|
type(f(0)) x = f(0);
|
||||||
|
|
@ -11,5 +15,8 @@ module top;
|
||||||
$display("%b", $bits(x));
|
$display("%b", $bits(x));
|
||||||
$display("%b", $bits(type(x)));
|
$display("%b", $bits(type(x)));
|
||||||
$display("%b", $bits(logic [0:1+$bits(type(x))]));
|
$display("%b", $bits(logic [0:1+$bits(type(x))]));
|
||||||
|
f(1);
|
||||||
|
void'(f(0));
|
||||||
|
t(1);
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ module top;
|
||||||
$display("f(%b) called", x);
|
$display("f(%b) called", x);
|
||||||
end
|
end
|
||||||
endfunction
|
endfunction
|
||||||
|
task t;
|
||||||
|
input x;
|
||||||
|
$display("t(%b) called", x);
|
||||||
|
endtask
|
||||||
|
|
||||||
initial begin : block
|
initial begin : block
|
||||||
reg x;
|
reg x;
|
||||||
|
|
@ -14,5 +18,8 @@ module top;
|
||||||
$display("%b", 32'd1);
|
$display("%b", 32'd1);
|
||||||
$display("%b", 32'd1);
|
$display("%b", 32'd1);
|
||||||
$display("%b", 32'd3);
|
$display("%b", 32'd3);
|
||||||
|
x = f(1);
|
||||||
|
x = f(0);
|
||||||
|
t(1);
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue