Commit 8298e83f by Zachary Snow

enum conversion only produces localparams for enum items that are used

parent 9fcc8e34
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
- modules in which that enum type appears. This is not necessarily foolproof, - modules in which that enum type appears. This is not necessarily foolproof,
- as some tools do allow the use of an enum item even if the actual enum type - as some tools do allow the use of an enum item even if the actual enum type
- does not appear in that description. The localparams are explicitly sized to - does not appear in that description. The localparams are explicitly sized to
- match the size of the converted enum type. - match the size of the converted enum type. This conversion only includes enum
- items which are actually used within a given description.
- -
- SystemVerilog allows for enums to have any number of the items' values - SystemVerilog allows for enums to have any number of the items' values
- specified or unspecified. If the first one is unspecified, it is 0. All other - specified or unspecified. If the first one is unspecified, it is 0. All other
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
module Convert.Enum (convert) where module Convert.Enum (convert) where
import Control.Monad.Writer import Control.Monad.Writer
import Data.List (elemIndices, sortOn) import Data.List (elemIndices, partition, sortOn)
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.Traverse import Convert.Traverse
...@@ -29,6 +30,8 @@ import Language.SystemVerilog.AST ...@@ -29,6 +30,8 @@ import Language.SystemVerilog.AST
type EnumInfo = (Range, [(Identifier, Maybe Expr)]) type EnumInfo = (Range, [(Identifier, Maybe Expr)])
type Enums = Set.Set EnumInfo type Enums = Set.Set EnumInfo
type Idents = Set.Set Identifier
type EnumItem = ((Range, Identifier), Expr)
convert :: AST -> AST convert :: AST -> AST
convert = traverseDescriptions convertDescription convert = traverseDescriptions convertDescription
...@@ -47,14 +50,34 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = ...@@ -47,14 +50,34 @@ convertDescription (description @ (Part _ _ _ _ _ _)) =
traverseModuleItems (traverseExprs $ traverseNestedExprs traverseExpr) $ traverseModuleItems (traverseExprs $ traverseNestedExprs traverseExpr) $
description description
-- convert the collected enums into their corresponding localparams -- convert the collected enums into their corresponding localparams
itemType r = Implicit Unspecified [r] enumPairs = concatMap enumVals $ Set.toList enums
enumPairs = sortOn snd $ concatMap enumVals $ Set.toList enums enumItems = map toItem $ sortOn snd $ convergeUsage items enumPairs
enumItems = map toItem enumPairs
toItem ((r, x), v) =
MIDecl $ Localparam (itemType r) x v'
where v' = sizedExpr x r (simplify v)
convertDescription other = other convertDescription other = other
-- add only the enums actually used in the given items
convergeUsage :: [ModuleItem] -> [EnumItem] -> [EnumItem]
convergeUsage items enums =
if null usedEnums
then []
else usedEnums ++ convergeUsage (enumItems ++ items) unusedEnums
where
-- determine which of the enum items are actually used here
(usedEnums, unusedEnums) = partition isUsed enums
enumItems = map toItem usedEnums
isUsed ((_, x), _) = Set.member x usedIdents
usedIdents = execWriter $
mapM (collectExprsM $ collectNestedExprsM collectIdent) $ items
collectIdent :: Expr -> Writer Idents ()
collectIdent (Ident x) = tell $ Set.singleton x
collectIdent _ = return ()
toItem :: EnumItem -> ModuleItem
toItem ((r, x), v) =
MIDecl $ Localparam itemType x v'
where
v' = sizedExpr x r (simplify v)
itemType = Implicit Unspecified [r]
toBaseType :: Maybe Type -> Type toBaseType :: Maybe Type -> Type
toBaseType Nothing = defaultType toBaseType Nothing = defaultType
toBaseType (Just (Implicit _ rs)) = toBaseType (Just (Implicit _ rs)) =
...@@ -83,7 +106,7 @@ traverseExpr :: Expr -> Expr ...@@ -83,7 +106,7 @@ traverseExpr :: Expr -> Expr
traverseExpr (Cast (Left (Enum _ _ _)) e) = e traverseExpr (Cast (Left (Enum _ _ _)) e) = e
traverseExpr other = other traverseExpr other = other
enumVals :: (Range, [(Identifier, Maybe Expr)]) -> [((Range, Identifier), Expr)] enumVals :: EnumInfo -> [EnumItem]
enumVals (r, l) = enumVals (r, l) =
-- check for obviously duplicate values -- check for obviously duplicate values
if noDuplicates if noDuplicates
......
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