Unverified Commit 4756f497 by CORRADI Quentin Committed by GitHub

avoid dangling procedural else

* Remove unneeded begin/end when the loop is a do/while
* Dangling else check passes through statement attributes (bug fix)
* Dangling else check passes through most control flow structures to reduce unneeded begin/end
* Add test case and update changelog

---------

Co-authored-by: qcorradi <q.corradi22@imperial.ac.uk>
Co-authored-by: Zachary Snow <zach@zachjs.com>
parent 485ffffa
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
* Fixed unneeded scoping of constant function calls used in type lookups * Fixed unneeded scoping of constant function calls used in type lookups
* `/*/` is no longer interpreted as a self-closing block comment, e.g., * `/*/` is no longer interpreted as a self-closing block comment, e.g.,
`$display("a"/*/,"b"/* */);` previously printed "ab", but now prints "a" `$display("a"/*/,"b"/* */);` previously printed "ab", but now prints "a"
* Fixed missing `begin`/`end` when disambiguating procedural branches tagged
with an attribute
* Fixed keywords included in the "1364-2001" and "1364-2001-noconfig" * Fixed keywords included in the "1364-2001" and "1364-2001-noconfig"
`begin_keywords` version specifiers `begin_keywords` version specifiers
......
...@@ -87,8 +87,9 @@ instance Show Stmt where ...@@ -87,8 +87,9 @@ instance Show Stmt where
where aStr = if a == Args [] [] then "" else show a where aStr = if a == Args [] [] then "" else show a
show (Asgn o t v e) = printf "%s %s %s%s;" (show v) (show o) tStr (show e) show (Asgn o t v e) = printf "%s %s %s%s;" (show v) (show o) tStr (show e)
where tStr = maybe "" showPad t where tStr = maybe "" showPad t
show (If u c s Null) = printf "%sif (%s)%s" (showPad u) (show c) (showBranch s) show (If u c s1 s2) =
show (If u c s1 s2 ) = printf "%sif (%s)%s\nelse%s" (showPad u) (show c) (showBlockedBranch s1) (showElseBranch s2) -- print the then branch inside a block to avoid dangling else issues
printf "%sif (%s)%s%s" (showPad u) (show c) (showBlockedBranch s1) (showElseBranch s2)
show (While e s) = printf "while (%s) %s" (show e) (show s) show (While e s) = printf "while (%s) %s" (show e) (show s)
show (RepeatL e s) = printf "repeat (%s) %s" (show e) (show s) show (RepeatL e s) = printf "repeat (%s) %s" (show e) (show s)
show (DoWhile e s) = printf "do %s while (%s);" (show s) (show e) show (DoWhile e s) = printf "do %s while (%s);" (show s) (show e)
...@@ -119,28 +120,32 @@ showBranch (Block Seq "" [] stmts@[CommentStmt{}, _]) = ...@@ -119,28 +120,32 @@ showBranch (Block Seq "" [] stmts@[CommentStmt{}, _]) =
showBranch block@Block{} = ' ' : show block showBranch block@Block{} = ' ' : show block
showBranch stmt = '\n' : (indent $ show stmt) showBranch stmt = '\n' : (indent $ show stmt)
-- add a block around the true branch of an if statement when a dangling else is
-- possible to avoid any potential ambiguity downstream
showBlockedBranch :: Stmt -> String showBlockedBranch :: Stmt -> String
showBlockedBranch stmt = showBlockedBranch stmt =
showBranch $ showBranch $
if isControl stmt if danglingElse stmt
then Block Seq "" [] [stmt] then Block Seq "" [] [stmt]
else stmt else stmt
where
isControl s = case s of danglingElse :: Stmt -> Bool
danglingElse s = case s of
If{} -> True If{} -> True
For{} -> True For _ _ _ subStmt -> danglingElse subStmt
While{} -> True While _ subStmt -> danglingElse subStmt
RepeatL{} -> True RepeatL _ subStmt -> danglingElse subStmt
DoWhile{} -> True Forever subStmt -> danglingElse subStmt
Forever{} -> True Foreach _ _ subStmt -> danglingElse subStmt
Foreach{} -> True Timing _ subStmt -> danglingElse subStmt
Timing _ subStmt -> isControl subStmt StmtAttr _ subStmt -> danglingElse subStmt
Block Seq "" [] [CommentStmt{}, subStmt] -> isControl subStmt Block Seq "" [] [CommentStmt{}, subStmt] -> danglingElse subStmt
_ -> False _ -> False
showElseBranch :: Stmt -> String showElseBranch :: Stmt -> String
showElseBranch stmt@If{} = ' ' : show stmt showElseBranch Null = ""
showElseBranch stmt = showBranch stmt showElseBranch stmt@If{} = "\nelse " ++ show stmt
showElseBranch stmt = "\nelse" ++ showBranch stmt
showShortBranch :: Stmt -> String showShortBranch :: Stmt -> String
showShortBranch stmt@Asgn{} = ' ' : show stmt showShortBranch stmt@Asgn{} = ' ' : show stmt
......
`define TEST(id, ctrl) \
always @* #(2 * id) \
if (a) \
ctrl if (b) \
$display("%0d A 1", id); \
else \
$display("%0d A 2", id); \
always @* #(2 * id + 1) \
if (a) begin \
ctrl if (b) \
$display("%0d B 1", id); \
end else \
$display("%0d B 2", id);
`define NOTHING
`define ATTRIBUTE (* test *)
`define FOR for (i = 0; i < 1; i = i + 1)
`define WHILE while (i < 1)
`define REPEAT repeat (b)
`define FOREVER forever #10
`define TIMING #10
// The other tested constructs are supported in Verilog-2005.
`ifdef REF
`define FOREACH repeat ($bits(i))
`else
`define FOREACH foreach (i[j])
`endif
module top;
reg a, b;
integer i;
`TEST(0, `NOTHING)
`TEST(1, `ATTRIBUTE)
`TEST(2, `FOR)
`TEST(3, `WHILE)
`TEST(4, `REPEAT)
`TEST(5, `FOREACH)
`TEST(6, `FOREVER)
`TEST(7, `TIMING)
initial begin
repeat (2) begin
#50 a = 0; b = 0;
#50 a = 0; b = 1;
#50 a = 1; b = 0;
#50 a = 1; b = 1;
end
$finish(0);
end
endmodule
`define REF
`include "dangling_else.sv"
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