From 2ca8a022adda07ad3c63d8355d54b01a42e5932d Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 15 Sep 2019 13:55:40 -0400 Subject: [PATCH] support and conversion for -> and <-> --- src/Convert.hs | 2 ++ src/Convert/LogOp.hs | 28 +++++++++++++++++++++ src/Language/SystemVerilog/AST/Op.hs | 4 +++ src/Language/SystemVerilog/Parser/Lex.x | 1 + src/Language/SystemVerilog/Parser/Parse.y | 4 +++ src/Language/SystemVerilog/Parser/Tokens.hs | 1 + sv2v.cabal | 1 + test/basic/log_op.sv | 16 ++++++++++++ test/basic/log_op.v | 18 +++++++++++++ 9 files changed, 75 insertions(+) create mode 100644 src/Convert/LogOp.hs create mode 100644 test/basic/log_op.sv create mode 100644 test/basic/log_op.v diff --git a/src/Convert.hs b/src/Convert.hs index ea3ee2a..6960514 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -22,6 +22,7 @@ import qualified Convert.Interface import qualified Convert.IntTypes import qualified Convert.KWArgs import qualified Convert.Logic +import qualified Convert.LogOp import qualified Convert.NamedBlock import qualified Convert.NestPI import qualified Convert.Package @@ -52,6 +53,7 @@ phases excludes = , Convert.EmptyArgs.convert , Convert.IntTypes.convert , Convert.KWArgs.convert + , Convert.LogOp.convert , Convert.PackedArray.convert , Convert.DimensionQuery.convert , Convert.ParamType.convert diff --git a/src/Convert/LogOp.hs b/src/Convert/LogOp.hs new file mode 100644 index 0000000..40ffaf7 --- /dev/null +++ b/src/Convert/LogOp.hs @@ -0,0 +1,28 @@ +{- sv2v + - Author: Zachary Snow + - + - Conversion for logical implication (->) and logical equality (<->) operators. + - + - We convert `a -> b` to `!a || b`, as per the definition of implication. + - + - We convert `a <-> b` to `!a = !b`. Note that we can't simply use `a = b` as + - `1 != 2`, but `1 <-> 2`. + -} + +module Convert.LogOp (convert) where + +import Convert.Traverse +import Language.SystemVerilog.AST + +convert :: [AST] -> [AST] +convert = + map $ + traverseDescriptions $ traverseModuleItems $ + traverseExprs $ traverseNestedExprs convertExpr + +convertExpr :: Expr -> Expr +convertExpr (BinOp LogEq a b) = + BinOp Eq (UniOp LogNot a) (UniOp LogNot b) +convertExpr (BinOp LogImp a b) = + BinOp LogOr (UniOp LogNot a) b +convertExpr other = other diff --git a/src/Language/SystemVerilog/AST/Op.hs b/src/Language/SystemVerilog/AST/Op.hs index 2eb12e8..00167a0 100644 --- a/src/Language/SystemVerilog/AST/Op.hs +++ b/src/Language/SystemVerilog/AST/Op.hs @@ -40,6 +40,8 @@ instance Show UniOp where data BinOp = LogAnd | LogOr + | LogImp + | LogEq | BitAnd | BitXor | BitXnor @@ -69,6 +71,8 @@ data BinOp instance Show BinOp where show LogAnd = "&&" show LogOr = "||" + show LogImp = "->" + show LogEq = "<->" show BitAnd = "&" show BitXor = "^" show BitXnor = "~^" diff --git a/src/Language/SystemVerilog/Parser/Lex.x b/src/Language/SystemVerilog/Parser/Lex.x index a429149..a781b0b 100644 --- a/src/Language/SystemVerilog/Parser/Lex.x +++ b/src/Language/SystemVerilog/Parser/Lex.x @@ -458,6 +458,7 @@ tokens :- "<<<" { tok Sym_lt_lt_lt } "<<=" { tok Sym_lt_lt_eq } ">>=" { tok Sym_gt_gt_eq } + "<->" { tok Sym_lt_dash_gt } "|->" { tok Sym_bar_dash_gt } "|=>" { tok Sym_bar_eq_gt } "[->" { tok Sym_brack_l_dash_gt } diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index f42948d..a4e1124 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -366,6 +366,7 @@ time { Token Lit_time _ _ } "<<<" { Token Sym_lt_lt_lt _ _ } "<<=" { Token Sym_lt_lt_eq _ _ } ">>=" { Token Sym_gt_gt_eq _ _ } +"<->" { Token Sym_lt_dash_gt _ _ } "|->" { Token Sym_bar_dash_gt _ _ } "|=>" { Token Sym_bar_eq_gt _ _ } "[->" { Token Sym_brack_l_dash_gt _ _ } @@ -391,6 +392,7 @@ time { Token Lit_time _ _ } %right "throughout" %left "##" %nonassoc "[*]" "[=]" "[->]" +%right "->" "<->" %right "?" ":" %left "||" %left "&&" @@ -1042,6 +1044,8 @@ Expr :: { Expr } -- binary expressions | Expr "||" Expr { BinOp LogOr $1 $3 } | Expr "&&" Expr { BinOp LogAnd $1 $3 } + | Expr "->" Expr { BinOp LogImp $1 $3 } + | Expr "<->" Expr { BinOp LogEq $1 $3 } | Expr "|" Expr { BinOp BitOr $1 $3 } | Expr "^" Expr { BinOp BitXor $1 $3 } | Expr "&" Expr { BinOp BitAnd $1 $3 } diff --git a/src/Language/SystemVerilog/Parser/Tokens.hs b/src/Language/SystemVerilog/Parser/Tokens.hs index f3939c1..3fcb869 100644 --- a/src/Language/SystemVerilog/Parser/Tokens.hs +++ b/src/Language/SystemVerilog/Parser/Tokens.hs @@ -366,6 +366,7 @@ data TokenName | Sym_lt_lt_lt | Sym_lt_lt_eq | Sym_gt_gt_eq + | Sym_lt_dash_gt | Sym_bar_dash_gt | Sym_bar_eq_gt | Sym_pound_dash_pound diff --git a/sv2v.cabal b/sv2v.cabal index 58e5f2d..30cb39b 100644 --- a/sv2v.cabal +++ b/sv2v.cabal @@ -67,6 +67,7 @@ executable sv2v Convert.IntTypes Convert.KWArgs Convert.Logic + Convert.LogOp Convert.NamedBlock Convert.NestPI Convert.Package diff --git a/test/basic/log_op.sv b/test/basic/log_op.sv new file mode 100644 index 0000000..44ef156 --- /dev/null +++ b/test/basic/log_op.sv @@ -0,0 +1,16 @@ +module top; + function log_imp; + input integer a; + input integer b; + return a -> b; + endfunction + function log_eq; + input integer a; + input integer b; + return a <-> b; + endfunction + initial + for (integer a = -2; a <= 2; a++) + for (integer b = -2; b <= 2; b++) + $display(log_imp(a, b), log_eq(a, b)); +endmodule diff --git a/test/basic/log_op.v b/test/basic/log_op.v new file mode 100644 index 0000000..ed8ce04 --- /dev/null +++ b/test/basic/log_op.v @@ -0,0 +1,18 @@ +module top; + function log_imp; + input integer a; + input integer b; + log_imp = !a || b; + endfunction + function log_eq; + input integer a; + input integer b; + log_eq = !a == !b; + endfunction + initial begin : foo + integer a, b; + for (a = -2; a <= 2; a = a + 1) + for (b = -2; b <= 2; b = b + 1) + $display(log_imp(a, b), log_eq(a, b)); + end +endmodule