mirror of https://github.com/zachjs/sv2v.git
initial version of enum conversion
This commit is contained in:
parent
816d959fc8
commit
ab91eaafd7
|
|
@ -11,6 +11,7 @@ import Job (Target(..))
|
||||||
|
|
||||||
import qualified Convert.AlwaysKW
|
import qualified Convert.AlwaysKW
|
||||||
import qualified Convert.CaseKW
|
import qualified Convert.CaseKW
|
||||||
|
import qualified Convert.Enum
|
||||||
import qualified Convert.Logic
|
import qualified Convert.Logic
|
||||||
import qualified Convert.Typedef
|
import qualified Convert.Typedef
|
||||||
import qualified Convert.PackedArray
|
import qualified Convert.PackedArray
|
||||||
|
|
@ -21,9 +22,10 @@ type Phase = AST -> AST
|
||||||
|
|
||||||
phases :: Target -> [Phase]
|
phases :: Target -> [Phase]
|
||||||
phases YOSYS =
|
phases YOSYS =
|
||||||
[ Convert.Typedef.convert
|
[ Convert.Enum.convert
|
||||||
, Convert.PackedArray.convert
|
, Convert.PackedArray.convert
|
||||||
, Convert.StarPort.convert
|
, Convert.StarPort.convert
|
||||||
|
, Convert.Typedef.convert
|
||||||
]
|
]
|
||||||
phases VTR =
|
phases VTR =
|
||||||
(phases YOSYS) ++
|
(phases YOSYS) ++
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
{- sv2v
|
||||||
|
- Author: Zachary Snow <zach@zachjs.com>
|
||||||
|
-
|
||||||
|
- Conversion for `enum`
|
||||||
|
-
|
||||||
|
- TODO: We do not yet properly support enums which specify the value for some,
|
||||||
|
- but not all items. My understanding is that they should continue in order
|
||||||
|
- from the previous value.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Convert.Enum (convert) where
|
||||||
|
|
||||||
|
import Text.Read (readMaybe)
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
import Control.Monad.Writer
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
|
import Convert.Traverse
|
||||||
|
import Language.SystemVerilog.AST
|
||||||
|
|
||||||
|
type EnumInfo = (Maybe Type, [(Identifier, Maybe Expr)])
|
||||||
|
type Enums = Set.Set EnumInfo
|
||||||
|
|
||||||
|
convert :: AST -> AST
|
||||||
|
convert = traverseDescriptions convertDescription
|
||||||
|
|
||||||
|
defaultType :: Type
|
||||||
|
defaultType = Logic [(Number "31", Number "0")]
|
||||||
|
|
||||||
|
convertDescription :: Description -> Description
|
||||||
|
convertDescription (description @ (Module _ _ _)) =
|
||||||
|
Module name ports (enumItems ++ items)
|
||||||
|
where
|
||||||
|
enumPairs = concat $ map (uncurry enumVals) $ Set.toList enums
|
||||||
|
enumItems = map (\(x, v) -> MIDecl $ Localparam (Implicit []) x v) enumPairs
|
||||||
|
(Module name ports items, enums) = runWriter $
|
||||||
|
traverseModuleItemsM (traverseTypesM traverseType) description
|
||||||
|
traverseType :: Type -> Writer Enums Type
|
||||||
|
traverseType (Enum t v r) = do
|
||||||
|
() <- tell $ Set.singleton (t, v)
|
||||||
|
let baseType = fromMaybe defaultType t
|
||||||
|
let (tf, rs) = typeRanges baseType
|
||||||
|
return $ tf (rs ++ r)
|
||||||
|
traverseType other = return other
|
||||||
|
convertDescription other = other
|
||||||
|
|
||||||
|
enumVals :: Maybe Type -> [(Identifier, Maybe Expr)] -> [(Identifier, Expr)]
|
||||||
|
enumVals _ l = zip
|
||||||
|
(map fst l)
|
||||||
|
(tail $ scanl step (Number "-1") (map snd l))
|
||||||
|
where
|
||||||
|
step :: Expr -> Maybe Expr -> Expr
|
||||||
|
step _ (Just expr) = expr
|
||||||
|
step (Number n) Nothing =
|
||||||
|
case (readMaybe n) :: Maybe Int of
|
||||||
|
Just value -> Number (show $ value + 1)
|
||||||
|
Nothing -> BinOp Add (Number n) (Number "1")
|
||||||
|
step expr Nothing =
|
||||||
|
BinOp Add expr (Number "1")
|
||||||
|
|
@ -30,6 +30,9 @@ module Convert.Traverse
|
||||||
, traverseDeclsM
|
, traverseDeclsM
|
||||||
, traverseDecls
|
, traverseDecls
|
||||||
, collectDeclsM
|
, collectDeclsM
|
||||||
|
, traverseTypesM
|
||||||
|
, traverseTypes
|
||||||
|
, collectTypesM
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
|
|
@ -300,3 +303,28 @@ traverseDecls :: Mapper Decl -> Mapper ModuleItem
|
||||||
traverseDecls = unmonad traverseDeclsM
|
traverseDecls = unmonad traverseDeclsM
|
||||||
collectDeclsM :: Monad m => CollectorM m Decl -> CollectorM m ModuleItem
|
collectDeclsM :: Monad m => CollectorM m Decl -> CollectorM m ModuleItem
|
||||||
collectDeclsM = collectify traverseDeclsM
|
collectDeclsM = collectify traverseDeclsM
|
||||||
|
|
||||||
|
traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem
|
||||||
|
traverseTypesM mapper item =
|
||||||
|
traverseDeclsM declMapper item >>= traverseExprsM exprMapper
|
||||||
|
where
|
||||||
|
exprMapper (Cast t e) = do
|
||||||
|
t' <- mapper t
|
||||||
|
-- TODO HACK: If the cast type is no longer "simple", we just drop
|
||||||
|
-- the case altogether. This probably doesn't work great in all
|
||||||
|
-- cases.
|
||||||
|
return $ if elem ' ' (show t')
|
||||||
|
then e
|
||||||
|
else Cast t' e
|
||||||
|
exprMapper other = return other
|
||||||
|
declMapper (Parameter t x e) =
|
||||||
|
mapper t >>= \t' -> return $ Parameter t' x e
|
||||||
|
declMapper (Localparam t x e) =
|
||||||
|
mapper t >>= \t' -> return $ Localparam t' x e
|
||||||
|
declMapper (Variable d t x a me) =
|
||||||
|
mapper t >>= \t' -> return $ Variable d t' x a me
|
||||||
|
|
||||||
|
traverseTypes :: Mapper Type -> Mapper ModuleItem
|
||||||
|
traverseTypes = unmonad traverseTypesM
|
||||||
|
collectTypesM :: Monad m => CollectorM m Type -> CollectorM m ModuleItem
|
||||||
|
collectTypesM = collectify traverseTypesM
|
||||||
|
|
|
||||||
|
|
@ -32,19 +32,7 @@ isTypedef _ = False
|
||||||
|
|
||||||
convertDescription :: Types -> Description -> Description
|
convertDescription :: Types -> Description -> Description
|
||||||
convertDescription types description =
|
convertDescription types description =
|
||||||
traverseModuleItems rewriteMI description
|
traverseModuleItems (traverseTypes $ resolveType types) description
|
||||||
where
|
|
||||||
rt :: Type -> Type
|
|
||||||
rt = resolveType types
|
|
||||||
rewriteMI :: ModuleItem -> ModuleItem
|
|
||||||
rewriteMI = traverseDecls rewriteDecl . traverseExprs rewriteExpr
|
|
||||||
rewriteExpr :: Expr -> Expr
|
|
||||||
rewriteExpr (Cast t e) = Cast (rt t) e
|
|
||||||
rewriteExpr other = other
|
|
||||||
rewriteDecl :: Decl -> Decl
|
|
||||||
rewriteDecl (Parameter t x e) = Parameter (rt t) x e
|
|
||||||
rewriteDecl (Localparam t x e) = Localparam (rt t) x e
|
|
||||||
rewriteDecl (Variable d t x a me) = Variable d (rt t) x a me
|
|
||||||
|
|
||||||
resolveType :: Types -> Type -> Type
|
resolveType :: Types -> Type -> Type
|
||||||
resolveType _ (Reg rs) = Reg rs
|
resolveType _ (Reg rs) = Reg rs
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ data Type
|
||||||
| Implicit [Range]
|
| Implicit [Range]
|
||||||
| IntegerT
|
| IntegerT
|
||||||
| Enum (Maybe Type) [(Identifier, Maybe Expr)] [Range]
|
| Enum (Maybe Type) [(Identifier, Maybe Expr)] [Range]
|
||||||
deriving Eq
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
instance Show Type where
|
instance Show Type where
|
||||||
show (Reg r) = "reg" ++ (showRanges r)
|
show (Reg r) = "reg" ++ (showRanges r)
|
||||||
|
|
@ -212,7 +212,7 @@ data Expr
|
||||||
| Mux Expr Expr Expr
|
| Mux Expr Expr Expr
|
||||||
| Bit Expr Int
|
| Bit Expr Int
|
||||||
| Cast Type Expr
|
| Cast Type Expr
|
||||||
deriving Eq
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
data UniOp
|
data UniOp
|
||||||
= Not
|
= Not
|
||||||
|
|
@ -225,7 +225,7 @@ data UniOp
|
||||||
| RedNor
|
| RedNor
|
||||||
| RedXor
|
| RedXor
|
||||||
| RedXnor
|
| RedXnor
|
||||||
deriving Eq
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
instance Show UniOp where
|
instance Show UniOp where
|
||||||
show Not = "!"
|
show Not = "!"
|
||||||
|
|
@ -260,7 +260,7 @@ data BinOp
|
||||||
| Ge
|
| Ge
|
||||||
| ShiftAL
|
| ShiftAL
|
||||||
| ShiftAR
|
| ShiftAR
|
||||||
deriving Eq
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
instance Show BinOp where
|
instance Show BinOp where
|
||||||
show a = case a of
|
show a = case a of
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ executable sv2v
|
||||||
Convert
|
Convert
|
||||||
Convert.AlwaysKW
|
Convert.AlwaysKW
|
||||||
Convert.CaseKW
|
Convert.CaseKW
|
||||||
|
Convert.Enum
|
||||||
Convert.Logic
|
Convert.Logic
|
||||||
Convert.PackedArray
|
Convert.PackedArray
|
||||||
Convert.SplitPortDecl
|
Convert.SplitPortDecl
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue