Commit cda40a13 by Zachary Snow

more fleshed out Traverse module

parent 8f5620da
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
- Note that this conversion does not completely replicate the behavior of - Note that this conversion does not completely replicate the behavior of
- `casex` and `casez` in cases where that case expression itself (rather than - `casex` and `casez` in cases where that case expression itself (rather than
- just the case item patterns) contains wildcard values. This is apparently - just the case item patterns) contains wildcard values. This is apparently
- rarely ever intentially done. - rarely ever intentionally done.
-} -}
module Convert.CaseKW (convert) where module Convert.CaseKW (convert) where
...@@ -33,16 +33,15 @@ possibilities = ['0', '1'] ...@@ -33,16 +33,15 @@ possibilities = ['0', '1']
explodeBy :: [Char] -> String -> [String] explodeBy :: [Char] -> String -> [String]
explodeBy _ "" = [""] explodeBy _ "" = [""]
explodeBy wilds (x : xs) = explodeBy wilds (x : xs) =
[(:)] <*> chars <*> prev (map (:) chars) <*> (explodeBy wilds xs)
where where chars = if elem x wilds then possibilities else [x]
chars = if elem x wilds then possibilities else [x]
prev = explodeBy wilds xs
expandExpr :: [Char] -> Expr -> [Expr] expandExpr :: [Char] -> Expr -> [Expr]
expandExpr wilds (Number s) = map Number $ explodeBy wilds s expandExpr wilds (Number s) = map Number $ explodeBy wilds s
expandExpr [] other = [other] expandExpr [] other = [other]
-- TODO: Hopefully they only give us constant expressions... -- TODO: Hopefully they only give us constant expressions...
expandExpr _ other = error $ "CaseKW conversione encountered case that was not a number, which is dubious..." ++ (show other) -- TODO: We could be given a constant identifier...
expandExpr _ other = error $ "CaseKW conversion encountered case that was not a number, which is dubious..." ++ (show other)
-- Note that we don't have to convert the statements within the cases, as the -- Note that we don't have to convert the statements within the cases, as the
-- conversion template takes care of that for us. -- conversion template takes care of that for us.
......
...@@ -13,65 +13,34 @@ ...@@ -13,65 +13,34 @@
module Convert.Logic (convert) where module Convert.Logic (convert) where
import Control.Monad.Writer
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type RegIdents = Set.Set String type RegIdents = Set.Set String
convert :: AST -> AST convert :: AST -> AST
convert descriptions = map convertDescription descriptions convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (Module name ports items) = convertDescription orig =
Module name ports $ map (convertModuleItem idents) items traverseModuleItems convertModuleItem orig
where where
idents = Set.unions $ map getRegIdents items idents = execWriter (collectModuleItemsM regIdents orig)
convertDescription other = other convertModuleItem :: ModuleItem -> ModuleItem
convertModuleItem (MIDecl (Variable dir (Logic mr) ident a me)) =
getStmtLHSs :: Stmt -> [LHS] MIDecl $ Variable dir (t mr) ident a me
getStmtLHSs (Block _ stmts) = concat $ map getStmtLHSs stmts where t = if Set.member ident idents then Reg else Wire
getStmtLHSs (Case kw e cases (Just stmt)) = (getStmtLHSs stmt) ++ (getStmtLHSs $ Case kw e cases Nothing) convertModuleItem other = other
getStmtLHSs (Case _ _ cases Nothing) = concat $ map getStmtLHSs $ map snd cases
getStmtLHSs (AsgnBlk lhs _) = [lhs] regIdents :: ModuleItem -> Writer RegIdents ()
getStmtLHSs (Asgn lhs _) = [lhs] regIdents (AlwaysC _ stmt) = collectStmtLHSsM idents stmt
getStmtLHSs (For _ _ _ stmt) = getStmtLHSs stmt
getStmtLHSs (If _ s1 s2) = (getStmtLHSs s1) ++ (getStmtLHSs s2)
getStmtLHSs (Timing _ s) = getStmtLHSs s
getStmtLHSs (Null) = []
getLHSIdents :: LHS -> [Identifier]
getLHSIdents (LHS vx ) = [vx]
getLHSIdents (LHSBit vx _) = [vx]
getLHSIdents (LHSRange vx _) = [vx]
getLHSIdents (LHSConcat lhss) = concat $ map getLHSIdents lhss
getRegIdents :: ModuleItem -> RegIdents
getRegIdents (AlwaysC _ stmt) =
Set.fromList idents
where
lhss = getStmtLHSs stmt
idents = concat $ map getLHSIdents lhss
getRegIdents _ = Set.empty
convertModuleItem :: RegIdents -> ModuleItem -> ModuleItem
convertModuleItem idents (MIDecl (Variable dir (Logic mr) ident a me)) =
MIDecl $ Variable dir (t mr) ident a me
where
t = if Set.member ident idents then Reg else Wire
convertModuleItem idents (Generate items) = Generate $ map (convertGenItem $ convertModuleItem idents) items
convertModuleItem _ other = other
convertGenItem :: (ModuleItem -> ModuleItem) -> GenItem -> GenItem
convertGenItem f item = convertGenItem' item
where where
convertGenItem' :: GenItem -> GenItem idents :: LHS -> Writer RegIdents ()
convertGenItem' (GenBlock x items) = GenBlock x $ map convertGenItem' items idents (LHS vx ) = tell $ Set.singleton vx
convertGenItem' (GenFor a b c d items) = GenFor a b c d $ map convertGenItem' items idents (LHSBit vx _) = tell $ Set.singleton vx
convertGenItem' (GenIf e i1 i2) = GenIf e (convertGenItem' i1) (convertGenItem' i2) idents (LHSRange vx _) = tell $ Set.singleton vx
convertGenItem' (GenNull) = GenNull idents (LHSConcat lhss) = mapM idents lhss >>= \_ -> return ()
convertGenItem' (GenModuleItem moduleItem) = GenModuleItem $ f moduleItem regIdents _ = return ()
convertGenItem' (GenCase e cases def) = GenCase e cases' def'
where
cases' = zip (map fst cases) (map (convertGenItem' . snd) cases)
def' = fmap convertGenItem' def
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
module Convert.StarPort (convert) where module Convert.StarPort (convert) where
import Data.Maybe (mapMaybe) import Control.Monad.Writer
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
...@@ -16,10 +16,10 @@ convert :: AST -> AST ...@@ -16,10 +16,10 @@ convert :: AST -> AST
convert descriptions = convert descriptions =
traverseDescriptions (traverseModuleItems mapInstance) descriptions traverseDescriptions (traverseModuleItems mapInstance) descriptions
where where
modulePorts = Map.fromList $ mapMaybe getPorts descriptions modulePorts = execWriter $ collectDescriptionsM getPorts descriptions
getPorts :: Description -> Maybe (Identifier, [Identifier]) getPorts :: Description -> Writer (Map.Map Identifier [Identifier]) ()
getPorts (Module name ports _) = Just (name, ports) getPorts (Module name ports _) = tell $ Map.singleton name ports
getPorts _ = Nothing getPorts _ = return ()
mapInstance :: ModuleItem -> ModuleItem mapInstance :: ModuleItem -> ModuleItem
mapInstance (Instance m p x Nothing) = mapInstance (Instance m p x Nothing) =
......
...@@ -8,36 +8,51 @@ module Convert.Traverse ...@@ -8,36 +8,51 @@ module Convert.Traverse
( MapperM ( MapperM
, Mapper , Mapper
, unmonad , unmonad
, collectify
, traverseDescriptionsM , traverseDescriptionsM
, traverseDescriptions , traverseDescriptions
, collectDescriptionsM
, traverseModuleItemsM , traverseModuleItemsM
, traverseModuleItems , traverseModuleItems
, collectModuleItemsM
, traverseStmtsM , traverseStmtsM
, traverseStmts , traverseStmts
, collectStmtsM
, traverseStmtLHSsM
, traverseStmtLHSs
, collectStmtLHSsM
) where ) where
import Control.Monad.State import Control.Monad.State
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type MapperM s t = t -> (State s) t type MapperM m t = t -> m t
type Mapper t = t -> t type Mapper t = t -> t
type CollectorM m t = t -> m ()
unmonad :: (MapperM () a -> MapperM () b) -> Mapper a -> Mapper b unmonad :: (MapperM (State ()) a -> MapperM (State ()) b) -> Mapper a -> Mapper b
unmonad traverser mapper thing = unmonad traverser mapper thing =
evalState (traverser (return . mapper) thing) () evalState (traverser (return . mapper) thing) ()
traverseDescriptionsM :: MapperM s Description -> MapperM s AST collectify :: Monad m => (MapperM m a -> MapperM m b) -> CollectorM m a -> CollectorM m b
collectify traverser collector thing =
traverser mapper thing >>= \_ -> return ()
where mapper x = collector x >>= \() -> return x
traverseDescriptionsM :: Monad m => MapperM m Description -> MapperM m AST
traverseDescriptionsM mapper descriptions = traverseDescriptionsM mapper descriptions =
mapM mapper descriptions mapM mapper descriptions
traverseDescriptions :: Mapper Description -> Mapper AST traverseDescriptions :: Mapper Description -> Mapper AST
traverseDescriptions = unmonad traverseDescriptionsM traverseDescriptions = unmonad traverseDescriptionsM
collectDescriptionsM :: Monad m => CollectorM m Description -> CollectorM m AST
collectDescriptionsM = collectify traverseDescriptionsM
maybeDo :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b) maybeDo :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
maybeDo _ Nothing = return Nothing maybeDo _ Nothing = return Nothing
maybeDo fun (Just val) = fun val >>= return . Just maybeDo fun (Just val) = fun val >>= return . Just
traverseModuleItemsM :: MapperM s ModuleItem -> MapperM s Description traverseModuleItemsM :: Monad m => MapperM m ModuleItem -> MapperM m Description
traverseModuleItemsM mapper (Module name ports items) = traverseModuleItemsM mapper (Module name ports items) =
mapM fullMapper items >>= return . Module name ports mapM fullMapper items >>= return . Module name ports
where where
...@@ -65,8 +80,10 @@ traverseModuleItemsM _ orig = return orig ...@@ -65,8 +80,10 @@ traverseModuleItemsM _ orig = return orig
traverseModuleItems :: Mapper ModuleItem -> Mapper Description traverseModuleItems :: Mapper ModuleItem -> Mapper Description
traverseModuleItems = unmonad traverseModuleItemsM traverseModuleItems = unmonad traverseModuleItemsM
collectModuleItemsM :: Monad m => CollectorM m ModuleItem -> CollectorM m Description
collectModuleItemsM = collectify traverseModuleItemsM
traverseStmtsM :: MapperM s Stmt -> MapperM s ModuleItem traverseStmtsM :: Monad m => MapperM m Stmt -> MapperM m ModuleItem
traverseStmtsM mapper = moduleItemMapper traverseStmtsM mapper = moduleItemMapper
where where
moduleItemMapper (AlwaysC kw stmt) = moduleItemMapper (AlwaysC kw stmt) =
...@@ -74,6 +91,19 @@ traverseStmtsM mapper = moduleItemMapper ...@@ -74,6 +91,19 @@ traverseStmtsM mapper = moduleItemMapper
moduleItemMapper (Function ret name decls stmt) = moduleItemMapper (Function ret name decls stmt) =
fullMapper stmt >>= return . Function ret name decls fullMapper stmt >>= return . Function ret name decls
moduleItemMapper other = return $ other moduleItemMapper other = return $ other
fullMapper = traverseNestedStmtsM mapper
traverseStmts :: Mapper Stmt -> Mapper ModuleItem
traverseStmts = unmonad traverseStmtsM
collectStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m ModuleItem
collectStmtsM = collectify traverseStmtsM
-- private utility for turning a thing which maps over a single lever of
-- statements into one that maps over the nested statements first, then the
-- higher levels up
traverseNestedStmtsM :: Monad m => MapperM m Stmt -> MapperM m Stmt
traverseNestedStmtsM mapper = fullMapper
where
fullMapper stmt = mapper stmt >>= cs fullMapper stmt = mapper stmt >>= cs
cs (Block decls stmts) = mapM fullMapper stmts >>= return . Block decls cs (Block decls stmts) = mapM fullMapper stmts >>= return . Block decls
cs (Case kw expr cases def) = do cs (Case kw expr cases def) = do
...@@ -91,5 +121,14 @@ traverseStmtsM mapper = moduleItemMapper ...@@ -91,5 +121,14 @@ traverseStmtsM mapper = moduleItemMapper
cs (Timing sense stmt) = fullMapper stmt >>= return . Timing sense cs (Timing sense stmt) = fullMapper stmt >>= return . Timing sense
cs (Null) = return Null cs (Null) = return Null
traverseStmts :: Mapper Stmt -> Mapper ModuleItem traverseStmtLHSsM :: Monad m => MapperM m LHS -> MapperM m Stmt
traverseStmts = unmonad traverseStmtsM traverseStmtLHSsM mapper = traverseNestedStmtsM stmtMapper
where
stmtMapper (AsgnBlk lhs expr) = mapper lhs >>= \lhs' -> return $ AsgnBlk lhs' expr
stmtMapper (Asgn lhs expr) = mapper lhs >>= \lhs' -> return $ Asgn lhs' expr
stmtMapper other = return other
traverseStmtLHSs :: Mapper LHS -> Mapper Stmt
traverseStmtLHSs = unmonad traverseStmtLHSsM
collectStmtLHSsM :: Monad m => CollectorM m LHS -> CollectorM m Stmt
collectStmtLHSsM = collectify traverseStmtLHSsM
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