Commit 751b3ad3 by Zachary Snow

initial work on Traverse AST transformations

parent 65e288fc
...@@ -6,20 +6,19 @@ ...@@ -6,20 +6,19 @@
module Convert.AlwaysKW (convert) where module Convert.AlwaysKW (convert) where
import Convert.Template.ModuleItem (moduleItemConverter) import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
convert :: AST -> AST convert :: AST -> AST
convert = moduleItemConverter convertModuleItem convert = traverseDescriptions $ traverseModuleItems replaceAlwaysKW
-- Conversions: -- Conversions:
-- `always_comb` -> `always @*` -- `always_comb` -> `always @*`
-- `always_ff` -> `always` -- `always_ff` -> `always`
convertModuleItem :: ModuleItem -> ModuleItem replaceAlwaysKW :: ModuleItem -> ModuleItem
convertModuleItem (AlwaysC AlwaysComb stmt) = replaceAlwaysKW (AlwaysC AlwaysComb stmt) =
AlwaysC Always $ Timing SenseStar stmt AlwaysC Always $ Timing SenseStar stmt
convertModuleItem (AlwaysC AlwaysFF stmt) = replaceAlwaysKW (AlwaysC AlwaysFF stmt) =
AlwaysC Always stmt AlwaysC Always stmt
convertModuleItem other = other replaceAlwaysKW other = other
...@@ -11,17 +11,15 @@ ...@@ -11,17 +11,15 @@
module Convert.CaseKW (convert) where module Convert.CaseKW (convert) where
import Convert.Template.Stmt (stmtConverter) import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
convert :: AST -> AST convert :: AST -> AST
convert = stmtConverter convertStmt convert = traverseDescriptions (traverseModuleItems (traverseStmts convertStmt))
-- Conversions: -- Conversions:
-- `casez` -> `case` with wildcards (?, z) expanded -- `casez` -> `case` with wildcards (?, z) expanded
-- `casex` -> `case` with wildcards (?, z, x) expanded -- `casex` -> `case` with wildcards (?, z, x) expanded
-- to be either 0 or 1 -- to be either 0 or 1
wildcards :: CaseKW -> [Char] wildcards :: CaseKW -> [Char]
......
...@@ -6,32 +6,27 @@ ...@@ -6,32 +6,27 @@
module Convert.StarPort (convert) where module Convert.StarPort (convert) where
import Data.Maybe import Data.Maybe (mapMaybe)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type ModulePorts = Map.Map String [String]
convert :: AST -> AST convert :: AST -> AST
convert descriptions = map (convertDescription portsInfo) descriptions convert descriptions =
traverseDescriptions (traverseModuleItems mapInstance) descriptions
where where
portsInfo = Map.fromList $ mapMaybe getPorts descriptions modulePorts = Map.fromList $ mapMaybe getPorts descriptions
getPorts :: Description -> Maybe (Identifier, [Identifier]) getPorts :: Description -> Maybe (Identifier, [Identifier])
getPorts (Module name ports _) = Just (name, ports) getPorts (Module name ports _) = Just (name, ports)
getPorts _ = Nothing getPorts _ = Nothing
convertDescription :: ModulePorts -> Description -> Description mapInstance :: ModuleItem -> ModuleItem
convertDescription info (Module name ports items) = mapInstance (Instance m p x Nothing) =
Module name ports $ map (convertModuleItem info) items Instance m p x (Just portBindings)
convertDescription _ other = other where
ports = case Map.lookup m modulePorts of
convertModuleItem :: ModulePorts -> ModuleItem -> ModuleItem Nothing -> error $ "could not convert `.*` in instantiation of " ++ m
convertModuleItem info (Instance m p x Nothing) = Just l -> l
Instance m p x (Just portBindings) portBindings = map (\port -> (port, Just $ Ident port)) ports
where mapInstance other = other
ports = case Map.lookup m info of
Nothing -> error $ "could not convert `.*` in instantiation of " ++ m
Just l -> l
portBindings = map (\port -> (port, Just $ Ident port)) ports
convertModuleItem _ other = other
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Template converter for ModuleItem transformations
-
- Also has coverage for ModuleItems inside of generate blocks
-}
module Convert.Template.ModuleItem (moduleItemConverter) where
import Data.Maybe
import Language.SystemVerilog.AST
type Converter = ModuleItem -> ModuleItem
moduleItemConverter :: Converter -> (AST -> AST)
moduleItemConverter f = convert f
convert :: Converter -> AST -> AST
convert f modules = map (convertDescription f) modules
convertDescription :: Converter -> Description -> Description
convertDescription f (Module name ports items) =
Module name ports $ map (convertModuleItem f) items
convertDescription _ (Typedef a b) = Typedef a b
convertModuleItem :: Converter -> ModuleItem -> ModuleItem
convertModuleItem f (Generate items) = f $ Generate $ map (convertGenItem f) items
convertModuleItem f other = f other
convertGenItem :: Converter -> GenItem -> GenItem
convertGenItem f item = convertGenItem' item
where
convertGenItem' :: GenItem -> GenItem
convertGenItem' (GenBlock x items) = GenBlock x $ map convertGenItem' items
convertGenItem' (GenFor a b c d items) = GenFor a b c d $ map convertGenItem' items
convertGenItem' (GenIf e i1 i2) = GenIf e (convertGenItem' i1) (convertGenItem' i2)
convertGenItem' (GenNull) = GenNull
convertGenItem' (GenModuleItem moduleItem) = GenModuleItem $ f moduleItem
convertGenItem' (GenCase e cases def) = GenCase e cases' def'
where
cases' = zip (map fst cases) (map (convertGenItem' . snd) cases)
def' = if def == Nothing
then Nothing
else Just $ convertGenItem' $ fromJust def
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Template converter for Stmt transformations
-}
module Convert.Template.Stmt (stmtConverter) where
import Convert.Template.ModuleItem (moduleItemConverter)
import Language.SystemVerilog.AST
type Converter = Stmt -> Stmt
stmtConverter :: Converter -> (AST -> AST)
stmtConverter = moduleItemConverter . convertModuleItem
convertModuleItem :: Converter -> ModuleItem -> ModuleItem
convertModuleItem f (AlwaysC kw stmt) =
AlwaysC kw (convertStmt f stmt)
convertModuleItem f (Function ret name decls stmt) =
Function ret name decls (convertStmt f stmt)
convertModuleItem _ other = other
convertStmt :: Converter -> (Stmt -> Stmt)
convertStmt f = f . convertStmt'
where
cs :: Stmt -> Stmt
cs = convertStmt f
convertStmt' :: Stmt -> Stmt
convertStmt' (Block decls stmts) = Block decls (map cs stmts)
convertStmt' (Case kw expr cases def) =
Case kw expr cases' def'
where
cases' = map (\(exprs, stmt) -> (exprs, cs stmt)) cases
def' = maybe Nothing (Just . cs) def
convertStmt' (AsgnBlk lhs expr) = AsgnBlk lhs expr
convertStmt' (Asgn lhs expr) = Asgn lhs expr
convertStmt' (For a b c stmt) = For a b c (cs stmt)
convertStmt' (If e s1 s2) = If e (cs s1) (cs s2)
convertStmt' (Timing sense stmt) = Timing sense (cs stmt)
convertStmt' (Null) = Null
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Utilities for traversing AST transformations.
-}
module Convert.Traverse
( MapperM
, Mapper
, unmonad
, traverseDescriptionsM
, traverseDescriptions
, traverseModuleItemsM
, traverseModuleItems
, traverseStmtsM
, traverseStmts
) where
import Control.Monad.State
import Data.Maybe
import Language.SystemVerilog.AST
type MapperM s t = t -> (State s) t
type Mapper t = t -> t
unmonad :: (MapperM () a -> MapperM () b) -> Mapper a -> Mapper b
unmonad traverser mapper thing =
evalState (traverser (return . mapper) thing) ()
traverseDescriptionsM :: MapperM s Description -> MapperM s AST
traverseDescriptionsM mapper descriptions =
mapM mapper descriptions
traverseDescriptions :: Mapper Description -> Mapper AST
traverseDescriptions = unmonad traverseDescriptionsM
traverseModuleItemsM :: MapperM s ModuleItem -> MapperM s Description
traverseModuleItemsM mapper (Module name ports items) =
mapM fullMapper items >>= return . Module name ports
where
fullMapper (Generate genItems) =
mapM genItemMapper genItems >>= mapper . Generate
fullMapper other = mapper other
-- maps all ModuleItems within the given GenItem
genItemMapper (GenBlock x subItems) =
mapM genItemMapper subItems >>= return . GenBlock x
genItemMapper (GenFor a b c d subItems) =
mapM genItemMapper subItems >>= return . GenFor a b c d
genItemMapper (GenIf e i1 i2) = do
i1' <- genItemMapper i1
i2' <- genItemMapper i2
return $ GenIf e i1' i2'
genItemMapper (GenNull) = return GenNull
genItemMapper (GenModuleItem moduleItem) =
fullMapper moduleItem >>= return . GenModuleItem
genItemMapper (GenCase e cases def) = do
caseItems <- mapM (genItemMapper . snd) cases
let cases' = zip (map fst cases) caseItems
def' <- if def == Nothing
then return Nothing
else genItemMapper (fromJust def) >>= \x -> return $ Just x
return $ GenCase e cases' def'
traverseModuleItemsM _ orig = return orig
traverseModuleItems :: Mapper ModuleItem -> Mapper Description
traverseModuleItems = unmonad traverseModuleItemsM
traverseStmtsM :: MapperM s Stmt -> MapperM s ModuleItem
traverseStmtsM mapper = moduleItemMapper
where
moduleItemMapper (AlwaysC kw stmt) =
fullMapper stmt >>= return . AlwaysC kw
moduleItemMapper (Function ret name decls stmt) =
fullMapper stmt >>= return . Function ret name decls
moduleItemMapper other = return $ other
fullMapper stmt = mapper stmt >>= cs
cs (Block decls stmts) = mapM fullMapper stmts >>= return . Block decls
cs (Case kw expr cases def) = do
caseStmts <- mapM fullMapper $ map snd cases
let cases' = zip (map fst cases) caseStmts
def' <- if def == Nothing
then return Nothing
else fullMapper (fromJust def) >>= \x -> return $ Just x
return $ Case kw expr cases' def'
cs (AsgnBlk lhs expr) = return $ AsgnBlk lhs expr
cs (Asgn lhs expr) = return $ Asgn lhs expr
cs (For a b c stmt) = fullMapper stmt >>= return . For a b c
cs (If e s1 s2) = do
s1' <- fullMapper s1
s2' <- fullMapper s2
return $ If e s1' s2'
cs (Timing sense stmt) = fullMapper stmt >>= return . Timing sense
cs (Null) = return Null
traverseStmts :: Mapper Stmt -> Mapper ModuleItem
traverseStmts = unmonad traverseStmtsM
...@@ -50,7 +50,8 @@ executable sv2v ...@@ -50,7 +50,8 @@ executable sv2v
build-depends: build-depends:
array, array,
base, base,
containers containers,
mtl
other-modules: other-modules:
Language.SystemVerilog Language.SystemVerilog
Language.SystemVerilog.AST Language.SystemVerilog.AST
...@@ -66,8 +67,7 @@ executable sv2v ...@@ -66,8 +67,7 @@ executable sv2v
Convert.PackedArrayFlatten Convert.PackedArrayFlatten
Convert.StarPort Convert.StarPort
Convert.Typedef Convert.Typedef
Convert.Template.ModuleItem Convert.Traverse
Convert.Template.Stmt
ghc-options: ghc-options:
-O3 -O3
-threaded -threaded
......
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