mirror of https://github.com/zachjs/sv2v.git
support case inside with basic side effects
This commit is contained in:
parent
e471d37e5c
commit
2e499dbd03
|
|
@ -19,6 +19,7 @@ module Convert.Inside (convert) where
|
||||||
import Convert.Traverse
|
import Convert.Traverse
|
||||||
import Language.SystemVerilog.AST
|
import Language.SystemVerilog.AST
|
||||||
|
|
||||||
|
import Control.Monad.Writer
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
convert :: [AST] -> [AST]
|
convert :: [AST] -> [AST]
|
||||||
|
|
@ -54,12 +55,19 @@ convertStmt (Case u kw expr items) =
|
||||||
Case u kw expr items
|
Case u kw expr items
|
||||||
else if kw /= CaseN then
|
else if kw /= CaseN then
|
||||||
error $ "cannot use inside with " ++ show kw
|
error $ "cannot use inside with " ++ show kw
|
||||||
|
else if hasSideEffects expr then
|
||||||
|
Block Seq "" [decl] [stmt]
|
||||||
else
|
else
|
||||||
foldr ($) defaultStmt $
|
foldr ($) defaultStmt $
|
||||||
map (uncurry $ If NoCheck) $
|
map (uncurry $ If NoCheck) $
|
||||||
zip comps stmts
|
zip comps stmts
|
||||||
where
|
where
|
||||||
exprs = map fst items
|
exprs = map fst items
|
||||||
|
-- evaluate expressions with side effects once
|
||||||
|
tmp = "sv2v_temp_" ++ shortHash expr
|
||||||
|
decl = Variable Local (TypeOf expr) tmp [] expr
|
||||||
|
stmt = convertStmt (Case u kw (Ident tmp) items)
|
||||||
|
-- underlying inside case elaboration
|
||||||
itemsNonDefault = filter (not . null . fst) items
|
itemsNonDefault = filter (not . null . fst) items
|
||||||
isSpecialInside :: [Expr] -> Bool
|
isSpecialInside :: [Expr] -> Bool
|
||||||
isSpecialInside [Inside Nil _] = True
|
isSpecialInside [Inside Nil _] = True
|
||||||
|
|
@ -71,3 +79,11 @@ convertStmt (Case u kw expr items) =
|
||||||
stmts = map snd itemsNonDefault
|
stmts = map snd itemsNonDefault
|
||||||
defaultStmt = fromMaybe Null (lookup [] items)
|
defaultStmt = fromMaybe Null (lookup [] items)
|
||||||
convertStmt other = other
|
convertStmt other = other
|
||||||
|
|
||||||
|
hasSideEffects :: Expr -> Bool
|
||||||
|
hasSideEffects expr =
|
||||||
|
getAny $ execWriter $ collectNestedExprsM write expr
|
||||||
|
where
|
||||||
|
write :: Expr -> Writer Any ()
|
||||||
|
write Call{} = tell $ Any True
|
||||||
|
write _ = return ()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
module top;
|
module top;
|
||||||
|
|
||||||
|
function integer sideEffect;
|
||||||
|
input integer inp;
|
||||||
|
$display("sideEffect(%b)", inp);
|
||||||
|
sideEffect = inp;
|
||||||
|
endfunction
|
||||||
|
|
||||||
initial
|
initial
|
||||||
for (logic [1:0] a = 0; a < 3; a++) begin
|
for (logic [1:0] a = 0; a < 3; a++) begin
|
||||||
if (a inside {2'b01, 2'b00})
|
if (a inside {2'b01, 2'b00})
|
||||||
|
|
@ -13,6 +19,9 @@ module top;
|
||||||
initial $display("C", 3'bz11 inside {3'b011});
|
initial $display("C", 3'bz11 inside {3'b011});
|
||||||
initial $display("D", 3'bz11 inside {3'b1?1, 3'b011});
|
initial $display("D", 3'bz11 inside {3'b1?1, 3'b011});
|
||||||
initial $display("E", 3'bz11 inside {3'b?01, 3'b011});
|
initial $display("E", 3'bz11 inside {3'b?01, 3'b011});
|
||||||
|
// TODO: Add support for inside expressions with side effects.
|
||||||
|
// initial $display("F", sideEffect(3'bz11) inside {3'b?11});
|
||||||
|
// initial $display("G", 3'bz11 inside {sideEffect(3'b?11)});
|
||||||
|
|
||||||
generate
|
generate
|
||||||
begin : patterns
|
begin : patterns
|
||||||
|
|
@ -53,7 +62,7 @@ module top;
|
||||||
|
|
||||||
function integer test3;
|
function integer test3;
|
||||||
input integer inp;
|
input integer inp;
|
||||||
case (inp) inside
|
case (1 + sideEffect(inp)) inside
|
||||||
[16:23]: return 1;
|
[16:23]: return 1;
|
||||||
[32:47]: return 2;
|
[32:47]: return 2;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
module top;
|
module top;
|
||||||
|
|
||||||
|
function integer sideEffect;
|
||||||
|
input integer inp;
|
||||||
|
begin
|
||||||
|
$display("sideEffect(%b)", inp);
|
||||||
|
sideEffect = inp;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
initial begin : foo
|
initial begin : foo
|
||||||
reg [1:0] a;
|
reg [1:0] a;
|
||||||
for (a = 0; a < 3; a++) begin
|
for (a = 0; a < 3; a++) begin
|
||||||
|
|
@ -15,6 +23,14 @@ module top;
|
||||||
initial $display("C", 1'bx);
|
initial $display("C", 1'bx);
|
||||||
initial $display("D", 1'bx);
|
initial $display("D", 1'bx);
|
||||||
initial $display("E", 1'bx);
|
initial $display("E", 1'bx);
|
||||||
|
// TODO: Add support for inside expressions with side effects.
|
||||||
|
// initial begin : bar
|
||||||
|
// integer tmp;
|
||||||
|
// tmp = sideEffect(3'bz11);
|
||||||
|
// $display("F", 1'b1);
|
||||||
|
// tmp = sideEffect(3'b?11);
|
||||||
|
// $display("G", 1'b1);
|
||||||
|
// end
|
||||||
|
|
||||||
function test1;
|
function test1;
|
||||||
input [2:0] inp;
|
input [2:0] inp;
|
||||||
|
|
@ -54,6 +70,7 @@ module top;
|
||||||
function [0:31] test3;
|
function [0:31] test3;
|
||||||
input integer inp;
|
input integer inp;
|
||||||
begin
|
begin
|
||||||
|
inp = 1 + sideEffect(inp);
|
||||||
if (16 <= inp && inp <= 23) test3 = 1;
|
if (16 <= inp && inp <= 23) test3 = 1;
|
||||||
else if (32 <= inp && inp <= 47) test3 = 2;
|
else if (32 <= inp && inp <= 47) test3 = 2;
|
||||||
else if (inp == 0 || (60 <= inp && inp <= 61) || inp == 4) test3 = 3;
|
else if (inp == 0 || (60 <= inp && inp <= 61) || inp == 4) test3 = 3;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue