Commit b7a23276 by Zachary Snow

simple for loop elaboration applies in more cases

parent 5e17ef0d
......@@ -16,6 +16,7 @@
* Added conversion for `do` `while` loops
* Added support for passing through DPI imports and exports
* Added support for passing through functions with output ports
* Extended applicability of simplified Yosys-compatible `for` loop elaboration
### Other Enhancements
......
......@@ -121,12 +121,25 @@ convertStmts stmts = do
pattern SimpleLoopInits :: Identifier -> [(LHS, Expr)]
pattern SimpleLoopInits var <- [(LHSIdent var, _)]
pattern SimpleLoopGuard :: Identifier -> Expr
pattern SimpleLoopGuard var <- BinOp _ (Ident var) _
pattern SimpleLoopIncrs :: Identifier -> [(LHS, AsgnOp, Expr)]
pattern SimpleLoopIncrs var <- [(LHSIdent var, _, _)]
-- check if an expression contains a reference to the given identifier
usesIdent :: Identifier -> Expr -> Writer Any ()
usesIdent x (Ident y)
| x == y = tell $ Any True
| otherwise = return ()
usesIdent x expr =
collectSinglyNestedExprsM (usesIdent x) expr
-- identifies loops which could likely be statically unrolled, and so may
-- benefit from avoiding complicating the loop guard with jump state, assuming
-- the guard and incrementation do not have side effects
simpleLoopVar :: [(LHS, Expr)] -> Expr -> [(LHS, AsgnOp, Expr)] -> Identifier
simpleLoopVar (SimpleLoopInits var1) comp (SimpleLoopIncrs var3)
| var1 == var3, getAny $ execWriter $ usesIdent var1 comp = var1
simpleLoopVar _ _ _ = ""
-- rewrites the given statement, and returns the type of any unfinished jump
convertStmt :: Stmt -> State Info Stmt
......@@ -140,20 +153,12 @@ convertStmt (Block Par x decls stmts) = do
convertStmt (Block Seq ""
decls@[CommentDecl{}, Variable Local _ var0 [] Nil]
[ comment@CommentStmt{}
, For
inits@(SimpleLoopInits var1)
comp@(SimpleLoopGuard var2)
incr@(SimpleLoopIncrs var3)
stmt
]) =
convertLoop localInfo loop comp incr stmt
[comment@CommentStmt{}, For inits comp incr stmt])
| var1@(_ : _) <- simpleLoopVar inits comp incr, var0 == var1 =
convertLoop (Just var1) loop comp incr stmt
>>= return . Block Seq "" decls . (comment :) . pure
where
loop c i s = For inits c i s
localInfo = if var0 /= var1 || var1 /= var2 || var2 /= var3
then Nothing
else Just ""
convertStmt (Block Seq x decls stmts) =
step stmts >>= return . Block Seq x decls
......@@ -192,16 +197,11 @@ convertStmt (Case unique kw expr cases) = do
modify $ \s -> s { sHasJump = hasJump }
return $ Case unique kw expr cases'
convertStmt (For
inits@(SimpleLoopInits var1)
comp@(SimpleLoopGuard var2)
incr@(SimpleLoopIncrs var3) stmt) =
convertLoop localInfo loop comp incr stmt
convertStmt (For inits comp incr stmt)
| var@(_ : _) <- simpleLoopVar inits comp incr =
convertLoop (Just var) loop comp incr stmt
where
loop c i s = For inits c i s
localInfo = if var1 /= var2 || var2 /= var3
then Nothing
else Just var1
convertStmt (For inits comp incr stmt) =
convertLoop Nothing loop comp incr stmt
where loop c i s = For inits c i s
......
......@@ -44,6 +44,15 @@ module top;
return k * 3;
k = k * 2 + 1;
endfunction
function automatic integer l;
input integer inp;
l = 1;
for (integer idx = inp; 0 < idx; idx--) begin
if (l == 32)
break;
l = l * 2;
end
endfunction
integer i;
initial
for (i = 0; i < 10; i = i + 1) begin
......@@ -52,5 +61,6 @@ module top;
$display("h(%0d) = %0d", i, h(i));
$display("j(%0d) = %0d", i, j(i));
$display("k(%0d) = %0d", i, k(i));
$display("l(%0d) = %0d", i, l(i));
end
endmodule
......@@ -34,6 +34,13 @@ module top;
else
k = inp * 2 + 1;
endfunction
function automatic integer l;
input integer inp;
if (inp > 5)
l = 32;
else
l = 2 ** inp;
endfunction
integer i;
initial
for (i = 0; i < 10; i = i + 1) begin
......@@ -42,5 +49,6 @@ module top;
$display("h(%0d) = %0d", i, h(i));
$display("j(%0d) = %0d", i, j(i));
$display("k(%0d) = %0d", i, k(i));
$display("l(%0d) = %0d", i, l(i));
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