Commit 5b035613 by Zachary Snow

constant fold || and &&

parent 619bde4b
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
* Fixed certain non-ANSI style port declarations being incorrectly reported as * Fixed certain non-ANSI style port declarations being incorrectly reported as
incompatible incompatible
### Other Enhancements
* Added constant folding for `||` and `&&`
## v0.0.11 ## v0.0.11
### New Features ### New Features
......
...@@ -161,6 +161,9 @@ simplifyBinOp op (Number n) (ConvertedUU sz v k) | isCmpOp op = ...@@ -161,6 +161,9 @@ simplifyBinOp op (Number n) (ConvertedUU sz v k) | isCmpOp op =
simplifyBinOp op (ConvertedUU sz v k) (Number n) | isCmpOp op = simplifyBinOp op (ConvertedUU sz v k) (Number n) | isCmpOp op =
simplifyBinOp op (uuExtend sz v k) (Number n) simplifyBinOp op (uuExtend sz v k) (Number n)
simplifyBinOp op (Number n) e | op == LogAnd || op == LogOr =
simplifyLogAndOr op n e
simplifyBinOp op e1 e2 = simplifyBinOp op e1 e2 =
case (e1, e2) of case (e1, e2) of
(Dec x, Dec y) -> constantFold orig op x y (Dec x, Dec y) -> constantFold orig op x y
...@@ -327,3 +330,22 @@ simplifyRange (e1, e2) = (simplify e1, simplify e2) ...@@ -327,3 +330,22 @@ simplifyRange (e1, e2) = (simplify e1, simplify e2)
simplifyDimensions :: [Range] -> [Range] simplifyDimensions :: [Range] -> [Range]
simplifyDimensions = map simplifyRange simplifyDimensions = map simplifyRange
-- TODO: extend this to other logical binary operators
simplifyLogAndOr :: BinOp -> Number -> Expr -> Expr
simplifyLogAndOr op n1 (Number n2) =
case (numberToInteger n1, numberToInteger n2) of
(Just v, _) | (v /= 0) == isOr -> bool isOr
(_, Just v) | (v /= 0) == isOr -> bool isOr
(Nothing, _) -> boolUnknown
(_, Nothing) -> boolUnknown
_ -> bool $ not isOr
where
isOr = op == LogOr
boolUnknown = Number $ Based 1 False Binary 0 1
simplifyLogAndOr op n e =
case numberToInteger n of
Just v | (v /= 0) == isOr -> bool isOr
Just _ -> UniOp LogNot $ UniOp LogNot e
Nothing -> BinOp op (Number n) e
where isOr = op == LogOr
`define TEST(expr) initial begin : \blk``expr \
localparam X = expr; \
localparam [63:0] Y = X; \
$display(`"expr %b %b %b`", expr, X, Y); \
end
`define TEST_LOGOP(op) \
`TEST(0``op``0) \
`TEST(0``op``1) \
`TEST(0``op``1'bx) \
`TEST(0``op``P) \
`TEST(0``op``Q) \
`TEST(0``op``R) \
`TEST(1``op``0) \
`TEST(1``op``1) \
`TEST(1``op``1'bx) \
`TEST(1``op``P) \
`TEST(1``op``Q) \
`TEST(1``op``R) \
`TEST(1'bx``op``0) \
`TEST(1'bx``op``1) \
`TEST(1'bx``op``1'bx) \
`TEST(1'bx``op``P) \
`TEST(1'bx``op``Q) \
`TEST(1'bx``op``R)
module top; module top;
initial $display("%b", (12'hb03 - 12'hb07) + 12'hb10); `TEST((12'hb03-12'hb07)+12'hb10)
parameter P = 0;
parameter Q = 1;
parameter R = 1'bx;
`TEST_LOGOP(||)
`TEST_LOGOP(&&)
endmodule endmodule
reject || 1
reject && 1
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