mirror of https://github.com/zachjs/sv2v.git
enum conversion only produces localparams for enum items that are used
This commit is contained in:
parent
9fcc8e3478
commit
8298e83f1e
|
|
@ -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 @@
|
||||||
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
|
||||||
|
|
||||||
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 _ _ _ _ _ _)) =
|
||||||
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
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue