Simplify.hs 5.48 KB
Newer Older
1 2 3
{- sv2v
 - Author: Zachary Snow <zach@zachjs.com>
 -
4 5
 - Elaboration of size casts, dimension query system functions, and ternary
 - expressions where the condition references a localparam.
6 7 8 9 10 11 12 13 14 15 16
 -
 - 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.
 -}

17
module Convert.Simplify (convert) where
18

19
import Convert.ExprUtils
20
import Convert.Scoper
21 22 23 24 25 26 27 28
import Convert.Traverse
import Language.SystemVerilog.AST

convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription

convertDescription :: Description -> Description
convertDescription =
29
    partScoper traverseDeclM traverseModuleItemM traverseGenItemM traverseStmtM
30

31
traverseDeclM :: Decl -> Scoper Expr Decl
32
traverseDeclM decl = do
33 34 35 36 37 38 39 40 41
    decl' <- traverseDeclExprsM traverseExprM decl
    case decl' of
        Param Localparam UnknownType x e ->
            insertExpr x e
        Param Localparam (Implicit sg rs) x e ->
            insertExpr x $ Cast (Left t) e
            where t = IntegerVector TLogic sg rs
        Param Localparam t x e ->
            insertExpr x $ Cast (Left t) e
42 43
        Variable _ _ x _ _ -> insertElem x Nil
        Net  _ _ _ _ x _ _ -> insertElem x Nil
44
        _ -> return ()
45
    return decl'
46

47 48 49
pattern SimpleVector :: Signing -> Integer -> Integer -> Type
pattern SimpleVector sg l r <- IntegerVector _ sg [(RawNum l, RawNum r)]

50 51 52
insertExpr :: Identifier -> Expr -> Scoper Expr ()
insertExpr ident expr = do
    expr' <- substituteExprM expr
53
    insertElem ident $ case expr' of
54
        Cast (Left (SimpleVector sg l r)) (Number n) ->
55
            Number $ numberCast signed size n
56 57 58
            where
                signed = sg == Signed
                size = fromIntegral $ abs $ l - r + 1
59 60
        _ | isSimpleExpr expr' -> expr'
        _ -> Nil
61

62 63 64
isSimpleExpr :: Expr -> Bool
isSimpleExpr Number{}  = True
isSimpleExpr String{}  = True
65
isSimpleExpr (Cast Left{} e) = isSimpleExpr e
66 67
isSimpleExpr _ = False

68
traverseModuleItemM :: ModuleItem -> Scoper Expr ModuleItem
69 70
traverseModuleItemM (Genvar x) =
    insertElem x Nil >> return (Genvar x)
71
traverseModuleItemM (Instance m p x rs l) = do
72
    p' <- mapM paramBindingMapper p
73
    traverseExprsM traverseExprM $ Instance m p' x rs l
74 75
    where
        paramBindingMapper (param, Left t) = do
76
            t' <- traverseNestedTypesM (traverseTypeExprsM substituteExprM) t
77 78
            return (param, Left t')
        paramBindingMapper (param, Right e) = return (param, Right e)
79 80
traverseModuleItemM item = traverseExprsM traverseExprM item

81 82 83 84
traverseGenItemM :: GenItem -> Scoper Expr GenItem
traverseGenItemM = traverseGenItemExprsM traverseExprM

traverseStmtM :: Stmt -> Scoper Expr Stmt
85
traverseStmtM = traverseStmtExprsM traverseExprM
86

87 88
traverseExprM :: Expr -> Scoper Expr Expr
traverseExprM = embedScopes convertExpr
89

90 91
substituteExprM :: Expr -> Scoper Expr Expr
substituteExprM = embedScopes substitute
92

93
convertExpr :: Scopes Expr -> Expr -> Expr
94 95 96 97 98
convertExpr info (Cast (Left t) e) =
    Cast (Left t') e'
    where
        t' = traverseNestedTypes (traverseTypeExprs $ substitute info) t
        e' = convertExpr info e
99
convertExpr info (Cast (Right c) e) =
100
    Cast (Right c') e'
101
    where
102 103
        c' = convertExpr info $ substitute info c
        e' = convertExpr info e
104 105
convertExpr info (DimFn f v e) =
    DimFn f v e'
106
    where e' = convertExpr info $ substitute info e
Zachary Snow committed
107
convertExpr info (Call (Ident "$clog2") (Args [e] [])) =
108 109 110
    if val' == val
        then val
        else val'
111
    where
112 113 114
        e' = convertExpr info $ substitute info e
        val = Call (Ident "$clog2") (Args [e'] [])
        val' = simplifyStep val
115
convertExpr info (MuxA a cc aa bb) =
116
    if before == after
117 118
        then simplifyStep $ MuxA a cc' aa' bb'
        else simplifyStep $ MuxA a after aa' bb'
119
    where
120 121 122 123 124
        before = substitute info cc'
        after = convertExpr info before
        aa' = convertExpr info aa
        bb' = convertExpr info bb
        cc' = convertExpr info cc
125 126
convertExpr info (BinOpA op a e1 e2) =
    case simplifyStep $ BinOpA op a e1'Sub e2'Sub of
127
        Number n -> Number n
128
        _ -> simplifyStep $ BinOpA op a e1' e2'
129 130 131 132 133
    where
        e1' = convertExpr info e1
        e2' = convertExpr info e2
        e1'Sub = substituteIdent info e1'
        e2'Sub = substituteIdent info e2'
134 135
convertExpr info (UniOpA op a expr) =
    simplifyStep $ UniOpA op a $ convertExpr info expr
136 137 138 139 140 141 142 143
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
144

145 146
substitute :: Scopes Expr -> Expr -> Expr
substitute scopes expr =
147
    substitute' expr
148 149 150
    where
        substitute' :: Expr -> Expr
        substitute' (Ident x) =
151
            case lookupElem scopes x of
152 153
                Just (_, _, e) | e /= Nil -> e
                _ -> Ident x
154 155
        substitute' other =
            traverseSinglyNestedExprs substitute' other
156 157 158 159

substituteIdent :: Scopes Expr -> Expr -> Expr
substituteIdent scopes (Ident x) =
    case lookupElem scopes x of
160
        Just (_, _, n@Number{}) -> n
161 162
        _ -> Ident x
substituteIdent _ other = other