initial version of enum conversion

This commit is contained in:
Zachary Snow 2019-02-28 22:44:31 -05:00
parent 816d959fc8
commit ab91eaafd7
6 changed files with 96 additions and 18 deletions

View File

@ -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) ++

59
src/Convert/Enum.hs Normal file
View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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