From 8f0f8b4afd90b263d329165e684aba6c7023942b Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 11 Jul 2021 16:57:33 -0400 Subject: [PATCH] explicit decl type and expr traversals - fix int type conversion not visiting function return type expressions - add node-based traversal for decls visiting top level types and exprs - explicit expr and type recursion in package ident resolution - expose mapBothM traversal helper - avoid double-visiting of decl types in certain conversions --- src/Convert/IntTypes.hs | 23 ++++++++++++++--- src/Convert/Package.hs | 44 ++++++++++++++++++++++---------- src/Convert/ParamType.hs | 3 +-- src/Convert/Traverse.hs | 36 ++++++++++++++------------ src/Convert/TypeOf.hs | 3 +-- src/Convert/Typedef.hs | 8 ++---- test/core/function_range_cast.sv | 9 +++++++ test/core/function_range_cast.v | 3 +++ 8 files changed, 86 insertions(+), 43 deletions(-) create mode 100644 test/core/function_range_cast.sv create mode 100644 test/core/function_range_cast.v diff --git a/src/Convert/IntTypes.hs b/src/Convert/IntTypes.hs index 06bf33d..370b568 100644 --- a/src/Convert/IntTypes.hs +++ b/src/Convert/IntTypes.hs @@ -13,9 +13,26 @@ convert :: [AST] -> [AST] convert = map $ traverseDescriptions $ traverseModuleItems convertModuleItem convertModuleItem :: ModuleItem -> ModuleItem -convertModuleItem = - traverseTypes (traverseNestedTypes convertType) . - traverseExprs (traverseNestedExprs convertExpr) +convertModuleItem = traverseNodes + traverseExpr traverseDecl traverseType traverseLHS traverseStmt + where + traverseDecl = traverseDeclNodes traverseType traverseExpr + traverseLHS = traverseNestedLHSs $ traverseLHSExprs traverseExpr + traverseStmt = traverseNestedStmts $ + traverseStmtDecls (traverseDeclNodes traverseType id) . + traverseStmtExprs traverseExpr + +traverseType :: Type -> Type +traverseType = + traverseSinglyNestedTypes traverseType . + traverseTypeExprs traverseExpr . + convertType + +traverseExpr :: Expr -> Expr +traverseExpr = + traverseSinglyNestedExprs traverseExpr . + traverseExprTypes traverseType . + convertExpr convertType :: Type -> Type convertType (Struct pk fields rs) = diff --git a/src/Convert/Package.hs b/src/Convert/Package.hs index f7ad77c..420708c 100644 --- a/src/Convert/Package.hs +++ b/src/Convert/Package.hs @@ -310,8 +310,7 @@ processItems topName packageName moduleItems = do traverseDeclM :: Decl -> Scope Decl traverseDeclM decl = do - decl' <- traverseDeclTypesM traverseTypeM decl - >>= traverseDeclExprsM traverseExprM + decl' <- traverseDeclNodesM traverseTypeM traverseExprM decl case decl' of Variable d t x a e -> declHelp x $ \x' -> Variable d t x' a e Net d n s t x a e -> declHelp x $ \x' -> Net d n s t x' a e @@ -320,21 +319,36 @@ processItems topName packageName moduleItems = do CommentDecl c -> return $ CommentDecl c where declHelp x f = prefixIdent x >>= return . f + traverseRangeM :: Range -> Scope Range + traverseRangeM = mapBothM traverseExprM + + traverseEnumItemM :: (Identifier, Expr) -> Scope (Identifier, Expr) + traverseEnumItemM (x, e) = do + x' <- prefixIdent x + e' <- traverseExprM e + return (x', e') + traverseTypeM :: Type -> Scope Type traverseTypeM (CSAlias p b x rs) = do x' <- resolveCSIdent' p b x - return $ Alias x' rs + rs' <- mapM traverseRangeM rs + return $ Alias x' rs' traverseTypeM (PSAlias p x rs) = do x' <- resolvePSIdent' p x - return $ Alias x' rs - traverseTypeM (Alias x rs) = - resolveIdent x >>= \x' -> return $ Alias x' rs + rs' <- mapM traverseRangeM rs + return $ Alias x' rs' + traverseTypeM (Alias x rs) = do + rs' <- mapM traverseRangeM rs + x' <- resolveIdent x + return $ Alias x' rs' traverseTypeM (Enum t enumItems rs) = do t' <- traverseTypeM t - enumItems' <- mapM prefixEnumItem enumItems - return $ Enum t' enumItems' rs - where prefixEnumItem (x, e) = prefixIdent x >>= \x' -> return (x', e) - traverseTypeM other = traverseSinglyNestedTypesM traverseTypeM other + enumItems' <- mapM traverseEnumItemM enumItems + rs' <- mapM traverseRangeM rs + return $ Enum t' enumItems' rs' + traverseTypeM other = + traverseSinglyNestedTypesM traverseTypeM other + >>= traverseTypeExprsM traverseExprM traverseExprM :: Expr -> Scope Expr traverseExprM (CSIdent p b x) = do @@ -344,7 +358,9 @@ processItems topName packageName moduleItems = do x' <- resolvePSIdent' p x return $ Ident x' traverseExprM (Ident x) = resolveIdent x >>= return . Ident - traverseExprM other = traverseSinglyNestedExprsM traverseExprM other + traverseExprM other = + traverseSinglyNestedExprsM traverseExprM other + >>= traverseExprTypesM traverseTypeM traverseLHSM :: LHS -> Scope LHS traverseLHSM (LHSIdent x) = resolveIdent x >>= return . LHSIdent @@ -735,9 +751,9 @@ traverseStmtIdentsM identMapper = fullMapper -- visits all identifiers in a declaration traverseDeclIdentsM :: Monad m => MapperM m Identifier -> MapperM m Decl -traverseDeclIdentsM identMapper = - traverseDeclExprsM (traverseExprIdentsM identMapper) >=> - traverseDeclTypesM (traverseTypeIdentsM identMapper) +traverseDeclIdentsM identMapper = traverseDeclNodesM + (traverseTypeIdentsM identMapper) + (traverseExprIdentsM identMapper) -- returns any names defined by a package item piNames :: PackageItem -> [Identifier] diff --git a/src/Convert/ParamType.hs b/src/Convert/ParamType.hs index 68b384e..c512d95 100644 --- a/src/Convert/ParamType.hs +++ b/src/Convert/ParamType.hs @@ -142,8 +142,7 @@ convert files = then Parameter else Localparam rewriteDecl other = - traverseDeclTypes rewriteType $ - traverseDeclExprs rewriteExpr other + traverseDeclNodes rewriteType rewriteExpr other additionalParamItems = concatMap makeAddedParams $ Map.toList $ Map.map snd inst rewriteExpr :: Expr -> Expr diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index d46ae64..d1f24f2 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -10,6 +10,7 @@ module Convert.Traverse , CollectorM , unmonad , collectify +, mapBothM , traverseDescriptionsM , traverseDescriptions , collectDescriptionsM @@ -54,6 +55,8 @@ module Convert.Traverse , traverseGenItemExprsM , traverseGenItemExprs , collectGenItemExprsM +, traverseDeclNodesM +, traverseDeclNodes , traverseDeclExprsM , traverseDeclExprs , collectDeclExprsM @@ -531,7 +534,7 @@ traverseExprsM :: Monad m => MapperM m Expr -> MapperM m ModuleItem traverseExprsM exprMapper = traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper where - declMapper = traverseDeclExprsM exprMapper + declMapper = traverseDeclNodesM typeMapper exprMapper typeMapper = traverseNestedTypesM (traverseTypeExprsM exprMapper) lhsMapper = traverseNestedLHSsM (traverseLHSExprsM exprMapper) stmtMapper = traverseNestedStmtsM (traverseStmtExprsM exprMapper) @@ -935,12 +938,11 @@ traverseGenItemExprs = unmonad traverseGenItemExprsM collectGenItemExprsM :: Monad m => CollectorM m Expr -> CollectorM m GenItem collectGenItemExprsM = collectify traverseGenItemExprsM -traverseDeclExprsM :: Monad m => MapperM m Expr -> MapperM m Decl -traverseDeclExprsM exprMapper = +traverseDeclNodesM + :: Monad m => MapperM m Type -> MapperM m Expr -> MapperM m Decl +traverseDeclNodesM typeMapper exprMapper = declMapper where - typeMapper = traverseNestedTypesM (traverseTypeExprsM exprMapper) - declMapper (Param s t x e) = do t' <- typeMapper t e' <- exprMapper e @@ -961,21 +963,24 @@ traverseDeclExprsM exprMapper = declMapper (CommentDecl c) = return $ CommentDecl c +traverseDeclNodes :: Mapper Type -> Mapper Expr -> Mapper Decl +traverseDeclNodes typeMapper exprMapper = + runIdentity . traverseDeclNodesM + (return . typeMapper) + (return . exprMapper) + +traverseDeclExprsM :: Monad m => MapperM m Expr -> MapperM m Decl +traverseDeclExprsM exprMapper = traverseDeclNodesM typeMapper exprMapper + where typeMapper = traverseNestedTypesM (traverseTypeExprsM exprMapper) + traverseDeclExprs :: Mapper Expr -> Mapper Decl traverseDeclExprs = unmonad traverseDeclExprsM collectDeclExprsM :: Monad m => CollectorM m Expr -> CollectorM m Decl collectDeclExprsM = collectify traverseDeclExprsM traverseDeclTypesM :: Monad m => MapperM m Type -> MapperM m Decl -traverseDeclTypesM mapper (Param s t x e) = - mapper t >>= \t' -> return $ Param s t' x e -traverseDeclTypesM mapper (ParamType s x t) = - mapper t >>= \t' -> return $ ParamType s x t' -traverseDeclTypesM mapper (Variable d t x a e) = - mapper t >>= \t' -> return $ Variable d t' x a e -traverseDeclTypesM mapper (Net d n s t x a e) = - mapper t >>= \t' -> return $ Net d n s t' x a e -traverseDeclTypesM _ (CommentDecl c) = return $ CommentDecl c +traverseDeclTypesM typeMapper = traverseDeclNodesM typeMapper exprMapper + where exprMapper = traverseNestedExprsM (traverseExprTypesM typeMapper) traverseDeclTypes :: Mapper Type -> Mapper Decl traverseDeclTypes = unmonad traverseDeclTypesM @@ -990,8 +995,7 @@ traverseTypesM typeMapper = lhsMapper = traverseNestedLHSsM (traverseLHSExprsM exprMapper) stmtMapper = traverseNestedStmtsM $ traverseStmtDeclsM declMapper >=> traverseStmtExprsM exprMapper - declMapper = - traverseDeclExprsM exprMapper >=> traverseDeclTypesM typeMapper + declMapper = traverseDeclNodesM typeMapper exprMapper traverseTypes :: Mapper Type -> Mapper ModuleItem traverseTypes = unmonad traverseTypesM diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index 366a5d8..cd5c0c9 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -44,8 +44,7 @@ traverseDeclM :: Decl -> ST Decl traverseDeclM decl @ Net{} = traverseNetAsVarM traverseDeclM decl traverseDeclM decl = do - decl' <- traverseDeclExprsM traverseExprM decl - >>= traverseDeclTypesM traverseTypeM + decl' <- traverseDeclNodesM traverseTypeM traverseExprM decl case decl' of Variable _ (Implicit sg rs) ident a _ -> -- implicit types, which are commonly found in function return diff --git a/src/Convert/Typedef.hs b/src/Convert/Typedef.hs index 799df7d..b073e09 100644 --- a/src/Convert/Typedef.hs +++ b/src/Convert/Typedef.hs @@ -72,8 +72,7 @@ traverseGenItemM = traverseGenItemExprsM traverseExprM traverseDeclM :: Decl -> Scoper Type Decl traverseDeclM decl = do - decl' <- traverseDeclExprsM traverseExprM decl - >>= traverseDeclTypesM traverseTypeM + decl' <- traverseDeclNodesM traverseTypeM traverseExprM decl case decl' of Variable{} -> return decl' Net{} -> return decl' @@ -110,7 +109,4 @@ traverseTypeM other = >>= traverseTypeExprsM traverseExprM traverseRangeM :: Range -> Scoper Type Range -traverseRangeM (a, b) = do - a' <- traverseExprM a - b' <- traverseExprM b - return (a', b') +traverseRangeM = mapBothM traverseExprM diff --git a/test/core/function_range_cast.sv b/test/core/function_range_cast.sv new file mode 100644 index 0000000..06fc494 --- /dev/null +++ b/test/core/function_range_cast.sv @@ -0,0 +1,9 @@ +module top; + localparam type T = int unsigned; + wire [T'(32'sd32) - 1:0] x; + function automatic [T'(32'sd32) - 1:0] foo; + input reg [T'(32'sd32) - 1:0] inp; + foo = inp; + endfunction + assign x = foo(1'sb1); +endmodule diff --git a/test/core/function_range_cast.v b/test/core/function_range_cast.v new file mode 100644 index 0000000..7648c79 --- /dev/null +++ b/test/core/function_range_cast.v @@ -0,0 +1,3 @@ +module top; + wire [31:0] x = 1'sb1; +endmodule