mirror of https://github.com/zachjs/sv2v.git
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>
This commit is contained in:
parent
485ffffa01
commit
4756f49750
|
|
@ -13,6 +13,8 @@
|
|||
* Fixed unneeded scoping of constant function calls used in type lookups
|
||||
* `/*/` is no longer interpreted as a self-closing block comment, e.g.,
|
||||
`$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"
|
||||
`begin_keywords` version specifiers
|
||||
|
||||
|
|
|
|||
|
|
@ -87,8 +87,9 @@ instance Show Stmt where
|
|||
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)
|
||||
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 ) = printf "%sif (%s)%s\nelse%s" (showPad u) (show c) (showBlockedBranch s1) (showElseBranch s2)
|
||||
show (If u c s1 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 (RepeatL e s) = printf "repeat (%s) %s" (show e) (show s)
|
||||
show (DoWhile e s) = printf "do %s while (%s);" (show s) (show e)
|
||||
|
|
@ -119,28 +120,32 @@ showBranch (Block Seq "" [] stmts@[CommentStmt{}, _]) =
|
|||
showBranch block@Block{} = ' ' : show block
|
||||
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 =
|
||||
showBranch $
|
||||
if isControl stmt
|
||||
if danglingElse stmt
|
||||
then Block Seq "" [] [stmt]
|
||||
else stmt
|
||||
where
|
||||
isControl s = case s of
|
||||
|
||||
danglingElse :: Stmt -> Bool
|
||||
danglingElse s = case s of
|
||||
If{} -> True
|
||||
For{} -> True
|
||||
While{} -> True
|
||||
RepeatL{} -> True
|
||||
DoWhile{} -> True
|
||||
Forever{} -> True
|
||||
Foreach{} -> True
|
||||
Timing _ subStmt -> isControl subStmt
|
||||
Block Seq "" [] [CommentStmt{}, subStmt] -> isControl subStmt
|
||||
For _ _ _ subStmt -> danglingElse subStmt
|
||||
While _ subStmt -> danglingElse subStmt
|
||||
RepeatL _ subStmt -> danglingElse subStmt
|
||||
Forever subStmt -> danglingElse subStmt
|
||||
Foreach _ _ subStmt -> danglingElse subStmt
|
||||
Timing _ subStmt -> danglingElse subStmt
|
||||
StmtAttr _ subStmt -> danglingElse subStmt
|
||||
Block Seq "" [] [CommentStmt{}, subStmt] -> danglingElse subStmt
|
||||
_ -> False
|
||||
|
||||
showElseBranch :: Stmt -> String
|
||||
showElseBranch stmt@If{} = ' ' : show stmt
|
||||
showElseBranch stmt = showBranch stmt
|
||||
showElseBranch Null = ""
|
||||
showElseBranch stmt@If{} = "\nelse " ++ show stmt
|
||||
showElseBranch stmt = "\nelse" ++ showBranch stmt
|
||||
|
||||
showShortBranch :: Stmt -> String
|
||||
showShortBranch stmt@Asgn{} = ' ' : show stmt
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
`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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
`define REF
|
||||
`include "dangling_else.sv"
|
||||
Loading…
Reference in New Issue