2019-02-18 09:59:17 +01:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Conversion for `typedef`
|
2019-02-24 09:06:40 +01:00
|
|
|
-
|
|
|
|
|
- Aliased types can (probably) appear in all item declarations, including
|
|
|
|
|
- modules, blocks, and function parameters.
|
2019-02-18 09:59:17 +01:00
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.Typedef (convert) where
|
|
|
|
|
|
2019-03-01 02:30:21 +01:00
|
|
|
import Control.Monad.Writer
|
2019-02-18 09:59:17 +01:00
|
|
|
import qualified Data.Map as Map
|
|
|
|
|
|
2019-03-01 02:30:21 +01:00
|
|
|
import Convert.Traverse
|
2019-02-18 09:59:17 +01:00
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
type Types = Map.Map Identifier Type
|
|
|
|
|
|
|
|
|
|
convert :: AST -> AST
|
|
|
|
|
convert descriptions =
|
2019-03-01 02:30:21 +01:00
|
|
|
filter (not . isTypedef) $ traverseDescriptions (convertDescription types) descriptions
|
2019-02-18 09:59:17 +01:00
|
|
|
where
|
2019-03-01 02:30:21 +01:00
|
|
|
types = execWriter $ collectDescriptionsM getTypedef descriptions
|
|
|
|
|
getTypedef :: Description -> Writer Types ()
|
|
|
|
|
getTypedef (Typedef a b) = tell $ Map.singleton b a
|
|
|
|
|
getTypedef _ = return ()
|
2019-02-18 09:59:17 +01:00
|
|
|
|
|
|
|
|
isTypedef :: Description -> Bool
|
|
|
|
|
isTypedef (Typedef _ _) = True
|
|
|
|
|
isTypedef _ = False
|
|
|
|
|
|
|
|
|
|
convertDescription :: Types -> Description -> Description
|
2019-03-01 02:30:21 +01:00
|
|
|
convertDescription types description =
|
2019-03-01 04:44:31 +01:00
|
|
|
traverseModuleItems (traverseTypes $ resolveType types) description
|
2019-02-18 09:59:17 +01:00
|
|
|
|
|
|
|
|
resolveType :: Types -> Type -> Type
|
2019-02-24 09:06:40 +01:00
|
|
|
resolveType _ (Reg rs) = Reg rs
|
|
|
|
|
resolveType _ (Wire rs) = Wire rs
|
|
|
|
|
resolveType _ (Logic rs) = Logic rs
|
|
|
|
|
resolveType _ (Implicit rs) = Implicit rs
|
|
|
|
|
resolveType _ (IntegerT ) = IntegerT
|
2019-02-24 03:24:13 +01:00
|
|
|
resolveType _ (Enum Nothing vals rs) = Enum Nothing vals rs
|
|
|
|
|
resolveType types (Enum (Just t) vals rs) = Enum (Just $ resolveType types t) vals rs
|
2019-03-02 02:26:44 +01:00
|
|
|
resolveType types (Struct p items rs) = Struct p items' rs
|
|
|
|
|
where
|
|
|
|
|
items' = map resolveItem items
|
|
|
|
|
resolveItem (t, x) = (resolveType types t, x)
|
2019-02-20 22:03:04 +01:00
|
|
|
resolveType types (Alias st rs1) =
|
2019-02-18 09:59:17 +01:00
|
|
|
case resolveType types $ types Map.! st of
|
2019-02-24 03:24:13 +01:00
|
|
|
(Reg rs2) -> Reg $ rs2 ++ rs1
|
|
|
|
|
(Wire rs2) -> Wire $ rs2 ++ rs1
|
|
|
|
|
(Logic rs2) -> Logic $ rs2 ++ rs1
|
|
|
|
|
(Enum t v rs2) -> Enum t v $ rs2 ++ rs1
|
2019-03-02 02:26:44 +01:00
|
|
|
(Struct p l rs2) -> Struct p l $ rs2 ++ rs1
|
2019-02-24 09:06:40 +01:00
|
|
|
(Implicit rs2) -> Implicit $ rs2 ++ rs1
|
|
|
|
|
(IntegerT ) -> error $ "resolveType encountered packed `integer` on " ++ st
|
2019-02-24 03:24:13 +01:00
|
|
|
(Alias _ _) -> error $ "resolveType invariant failed on " ++ st
|