2019-08-29 05:26:12 +02:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
2019-09-14 22:42:54 +02:00
|
|
|
- Elaboration of size casts, dimension query system functions, and ternary
|
|
|
|
|
- expressions where the condition references a localparam.
|
2019-08-29 05:26:12 +02:00
|
|
|
-
|
|
|
|
|
- Our conversions generate a lot of ternary expressions. This conversion
|
|
|
|
|
- attempts to make the code output a bit cleaner. Note that we can only do this
|
|
|
|
|
- simplification on localparams because parameters can be overridden at
|
|
|
|
|
- instantiation.
|
|
|
|
|
-
|
|
|
|
|
- This conversion applies the heuristic that it will only make substitutions
|
|
|
|
|
- into a ternary condition if making substitutions immediately enables the
|
|
|
|
|
- expression to be simplified further.
|
|
|
|
|
-}
|
|
|
|
|
|
2019-09-12 04:52:01 +02:00
|
|
|
module Convert.Simplify (convert) where
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
import Control.Monad (when)
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-07-12 23:06:27 +02:00
|
|
|
import Convert.ExprUtils
|
2020-07-16 03:14:05 +02:00
|
|
|
import Convert.Scoper
|
2019-08-29 05:26:12 +02:00
|
|
|
import Convert.Traverse
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
convert :: [AST] -> [AST]
|
|
|
|
|
convert = map $ traverseDescriptions convertDescription
|
|
|
|
|
|
|
|
|
|
convertDescription :: Description -> Description
|
|
|
|
|
convertDescription =
|
2020-07-16 03:14:05 +02:00
|
|
|
partScoper traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
traverseDeclM :: Decl -> Scoper Expr Decl
|
2019-08-29 05:26:12 +02:00
|
|
|
traverseDeclM decl = do
|
|
|
|
|
case decl of
|
2020-06-26 02:36:09 +02:00
|
|
|
Param Localparam _ x e ->
|
2020-07-16 03:14:05 +02:00
|
|
|
when (isSimpleExpr e) $ insertElem x e
|
2019-08-29 05:26:12 +02:00
|
|
|
_ -> return ()
|
2020-04-06 04:13:19 +02:00
|
|
|
let mi = MIPackageItem $ Decl decl
|
|
|
|
|
mi' <- traverseModuleItemM mi
|
|
|
|
|
let MIPackageItem (Decl decl') = mi'
|
|
|
|
|
return decl'
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-06-26 02:36:09 +02:00
|
|
|
isSimpleExpr :: Expr -> Bool
|
|
|
|
|
isSimpleExpr Ident{} = True
|
|
|
|
|
isSimpleExpr Number{} = True
|
|
|
|
|
isSimpleExpr String{} = True
|
|
|
|
|
isSimpleExpr (Dot e _ ) = isSimpleExpr e
|
|
|
|
|
isSimpleExpr (Bit e _ ) = isSimpleExpr e
|
|
|
|
|
isSimpleExpr (Range e _ _) = isSimpleExpr e
|
|
|
|
|
isSimpleExpr _ = False
|
|
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
traverseModuleItemM :: ModuleItem -> Scoper Expr ModuleItem
|
2020-06-18 04:01:59 +02:00
|
|
|
traverseModuleItemM (Instance m p x rs l) = do
|
2020-06-01 04:00:33 +02:00
|
|
|
p' <- mapM paramBindingMapper p
|
2020-06-18 04:01:59 +02:00
|
|
|
traverseExprsM traverseExprM $ Instance m p' x rs l
|
2020-06-01 04:00:33 +02:00
|
|
|
where
|
|
|
|
|
paramBindingMapper (param, Left t) = do
|
2020-07-16 02:44:57 +02:00
|
|
|
t' <- traverseNestedTypesM (traverseTypeExprsM substituteExprM) t
|
2020-06-01 04:00:33 +02:00
|
|
|
return (param, Left t')
|
|
|
|
|
paramBindingMapper (param, Right e) = return (param, Right e)
|
2019-08-29 05:26:12 +02:00
|
|
|
traverseModuleItemM item = traverseExprsM traverseExprM item
|
|
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
traverseGenItemM :: GenItem -> Scoper Expr GenItem
|
|
|
|
|
traverseGenItemM = traverseGenItemExprsM traverseExprM
|
|
|
|
|
|
|
|
|
|
traverseStmtM :: Stmt -> Scoper Expr Stmt
|
2019-08-29 05:26:12 +02:00
|
|
|
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
|
|
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
traverseExprM :: Expr -> Scoper Expr Expr
|
|
|
|
|
traverseExprM = embedScopes convertExpr
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
substituteExprM :: Expr -> Scoper Expr Expr
|
|
|
|
|
substituteExprM = embedScopes substitute
|
2020-06-01 04:00:33 +02:00
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
convertExpr :: Scopes Expr -> Expr -> Expr
|
2019-09-12 04:52:01 +02:00
|
|
|
convertExpr info (Cast (Right c) e) =
|
2020-07-12 23:06:27 +02:00
|
|
|
Cast (Right c') e'
|
2019-09-12 04:52:01 +02:00
|
|
|
where
|
2020-07-12 23:06:27 +02:00
|
|
|
c' = convertExpr info $ substitute info c
|
|
|
|
|
e' = convertExpr info e
|
2019-09-14 22:42:54 +02:00
|
|
|
convertExpr info (DimFn f v e) =
|
|
|
|
|
DimFn f v e'
|
2020-07-12 23:06:27 +02:00
|
|
|
where e' = convertExpr info $ substitute info e
|
2020-06-14 21:56:09 +02:00
|
|
|
convertExpr info (Call (Ident "$clog2") (Args [e] [])) =
|
2020-07-12 23:06:27 +02:00
|
|
|
if val' == val
|
|
|
|
|
then val
|
|
|
|
|
else val'
|
2019-10-12 17:40:36 +02:00
|
|
|
where
|
2020-07-12 23:06:27 +02:00
|
|
|
e' = convertExpr info $ substitute info e
|
|
|
|
|
val = Call (Ident "$clog2") (Args [e'] [])
|
|
|
|
|
val' = simplifyStep val
|
2019-08-29 05:26:12 +02:00
|
|
|
convertExpr info (Mux cc aa bb) =
|
|
|
|
|
if before == after
|
2020-07-12 23:06:27 +02:00
|
|
|
then simplifyStep $ Mux cc' aa' bb'
|
|
|
|
|
else simplifyStep $ Mux after aa' bb'
|
2019-08-29 05:26:12 +02:00
|
|
|
where
|
2020-07-12 23:06:27 +02:00
|
|
|
before = substitute info cc'
|
|
|
|
|
after = convertExpr info before
|
|
|
|
|
aa' = convertExpr info aa
|
|
|
|
|
bb' = convertExpr info bb
|
|
|
|
|
cc' = convertExpr info cc
|
|
|
|
|
convertExpr info (BinOp op e1 e2) =
|
|
|
|
|
simplifyStep $ BinOp op
|
|
|
|
|
(convertExpr info e1)
|
|
|
|
|
(convertExpr info e2)
|
|
|
|
|
convertExpr info (UniOp op expr) =
|
|
|
|
|
simplifyStep $ UniOp op $ convertExpr info expr
|
|
|
|
|
convertExpr info (Repeat expr exprs) =
|
|
|
|
|
simplifyStep $ Repeat
|
|
|
|
|
(convertExpr info expr)
|
|
|
|
|
(map (convertExpr info) exprs)
|
|
|
|
|
convertExpr info (Concat exprs) =
|
|
|
|
|
simplifyStep $ Concat (map (convertExpr info) exprs)
|
|
|
|
|
convertExpr info expr =
|
|
|
|
|
traverseSinglyNestedExprs (convertExpr info) expr
|
2019-08-29 05:26:12 +02:00
|
|
|
|
2020-07-16 03:14:05 +02:00
|
|
|
substitute :: Scopes Expr -> Expr -> Expr
|
|
|
|
|
substitute scopes expr =
|
2020-07-12 23:06:27 +02:00
|
|
|
traverseNestedExprs substitute' expr
|
2019-10-12 17:40:36 +02:00
|
|
|
where
|
|
|
|
|
substitute' :: Expr -> Expr
|
|
|
|
|
substitute' (Ident x) =
|
2020-07-16 03:14:05 +02:00
|
|
|
case lookupElem scopes x of
|
2019-10-12 17:40:36 +02:00
|
|
|
Nothing -> Ident x
|
2020-07-16 03:14:05 +02:00
|
|
|
Just (_, _, e) -> e
|
2019-10-12 17:40:36 +02:00
|
|
|
substitute' other = other
|