From 4ced649a8716ca153a0ab873c30b006de70cbbec Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 11 Mar 2022 11:32:54 +0100 Subject: [PATCH] convert do while loops --- CHANGELOG.md | 1 + src/Convert.hs | 2 ++ src/Convert/DoWhile.hs | 31 +++++++++++++++++++++++++++++++ src/Convert/Jump.hs | 3 --- sv2v.cabal | 1 + test/core/do_while.sv | 11 +++++++++++ test/core/do_while.v | 10 ++++++++++ test/nosim/do_while.sv | 5 ----- 8 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 src/Convert/DoWhile.hs create mode 100644 test/core/do_while.sv create mode 100644 test/core/do_while.v delete mode 100644 test/nosim/do_while.sv diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a4de84..b112a09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Added support for enumerated type ranges (e.g., `enum { X[3:5] }`) * Added support for the SystemVerilog `edge` event * Added support for cycle delay ranges in assertion sequence expressions +* Added conversion for `do` `while` loops * Added support for passing through DPI imports and exports * Added support for passing through functions with output ports diff --git a/src/Convert.hs b/src/Convert.hs index 4629b38..12d2b1a 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -17,6 +17,7 @@ import qualified Convert.Assertion import qualified Convert.BlockDecl import qualified Convert.Cast import qualified Convert.DimensionQuery +import qualified Convert.DoWhile import qualified Convert.DuplicateGenvar import qualified Convert.EmptyArgs import qualified Convert.Enum @@ -105,6 +106,7 @@ initialPhases selectExclude = , Convert.SenseEdge.convert , Convert.LogOp.convert , Convert.EmptyArgs.convert + , Convert.DoWhile.convert , Convert.Foreach.convert , Convert.FuncRoutine.convert , selectExclude Job.Assert Convert.Assertion.convert diff --git a/src/Convert/DoWhile.hs b/src/Convert/DoWhile.hs new file mode 100644 index 0000000..d97f8ce --- /dev/null +++ b/src/Convert/DoWhile.hs @@ -0,0 +1,31 @@ +{- sv2v + - Author: Zachary Snow + - + - Conversion for `do` `while` loops. + - + - These are converted into while loops with an extra condition which is + - initially true and immediately set to false in the body. This strategy is + - preferrable to simply duplicating the loop body as it could contain jumps. + -} + +module Convert.DoWhile (convert) where + +import Convert.Traverse +import Language.SystemVerilog.AST + +convert :: [AST] -> [AST] +convert = + map $ traverseDescriptions $ traverseModuleItems $ + traverseStmts $ traverseNestedStmts convertStmt + +convertStmt :: Stmt -> Stmt +convertStmt (DoWhile cond body) = + Block Seq "" [decl] [While cond' body'] + where + ident = "sv2v_do_while" + typ = IntegerVector TLogic Unspecified [] + decl = Variable Local typ ident [] (RawNum 1) + cond' = BinOp LogOr (Ident ident) cond + asgn = Asgn AsgnOpEq Nothing (LHSIdent ident) (RawNum 0) + body' = Block Seq "" [] [asgn, body] +convertStmt other = other diff --git a/src/Convert/Jump.hs b/src/Convert/Jump.hs index c0dbf3b..bcd8042 100644 --- a/src/Convert/Jump.hs +++ b/src/Convert/Jump.hs @@ -208,9 +208,6 @@ convertStmt (For inits comp incr stmt) = convertStmt (While comp stmt) = convertLoop Nothing loop comp [] stmt where loop c _ s = While c s -convertStmt (DoWhile comp stmt) = - convertLoop Nothing loop comp [] stmt - where loop c _ s = DoWhile c s convertStmt (Continue) = do loopDepth <- gets sLoopDepth diff --git a/sv2v.cabal b/sv2v.cabal index 6e524d8..172286b 100644 --- a/sv2v.cabal +++ b/sv2v.cabal @@ -68,6 +68,7 @@ executable sv2v Convert.BlockDecl Convert.Cast Convert.DimensionQuery + Convert.DoWhile Convert.DuplicateGenvar Convert.EmptyArgs Convert.Enum diff --git a/test/core/do_while.sv b/test/core/do_while.sv new file mode 100644 index 0000000..fa56ef3 --- /dev/null +++ b/test/core/do_while.sv @@ -0,0 +1,11 @@ +module top; + integer x = 0; + initial + do begin + $display("hi %0d", x); + x++; + if (x == 2) + continue; + $display("step"); + end while (0 < x && x < 3); +endmodule diff --git a/test/core/do_while.v b/test/core/do_while.v new file mode 100644 index 0000000..ad52273 --- /dev/null +++ b/test/core/do_while.v @@ -0,0 +1,10 @@ +module top; + integer x = 0; + initial + while (x < 3) begin + $display("hi %0d", x); + x++; + if (x != 2) + $display("step"); + end +endmodule diff --git a/test/nosim/do_while.sv b/test/nosim/do_while.sv deleted file mode 100644 index 0dd5bec..0000000 --- a/test/nosim/do_while.sv +++ /dev/null @@ -1,5 +0,0 @@ -module top; - initial do - $display("hi"); - while (0); -endmodule