Commit 0f4a60be by Zachary Snow

functions and typedefs can now appear at the top level

parent e8ed885f
...@@ -13,6 +13,6 @@ convert :: AST -> AST ...@@ -13,6 +13,6 @@ convert :: AST -> AST
convert = traverseDescriptions $ traverseModuleItems convertFunction convert = traverseDescriptions $ traverseModuleItems convertFunction
convertFunction :: ModuleItem -> ModuleItem convertFunction :: ModuleItem -> ModuleItem
convertFunction (Function ml (Logic r) f decls stmts) = convertFunction (MIPackageItem (Function ml (Logic r) f decls stmts)) =
Function ml (Implicit r) f decls stmts MIPackageItem $ Function ml (Implicit r) f decls stmts
convertFunction other = other convertFunction other = other
...@@ -161,7 +161,7 @@ lookupType _ expr = error $ "lookupType on fancy expr: " ++ show expr ...@@ -161,7 +161,7 @@ lookupType _ expr = error $ "lookupType on fancy expr: " ++ show expr
-- convert an interface instantiation into a series of equivalent module items -- convert an interface instantiation into a series of equivalent module items
inlineInterface :: Interface -> (Identifier, [PortBinding]) -> [ModuleItem] inlineInterface :: Interface -> (Identifier, [PortBinding]) -> [ModuleItem]
inlineInterface (ports, items) (instanceName, instancePorts) = inlineInterface (ports, items) (instanceName, instancePorts) =
(:) (Comment $ "expanded instance: " ++ instanceName) $ (:) (MIPackageItem $ Comment $ "expanded instance: " ++ instanceName) $
(++) portBindings $ (++) portBindings $
map (traverseNestedModuleItems removeModport) $ map (traverseNestedModuleItems removeModport) $
map (traverseNestedModuleItems removeMIDeclDir) $ map (traverseNestedModuleItems removeMIDeclDir) $
...@@ -186,5 +186,6 @@ inlineInterface (ports, items) (instanceName, instancePorts) = ...@@ -186,5 +186,6 @@ inlineInterface (ports, items) (instanceName, instancePorts) =
MIDecl $ Variable Local t x a me MIDecl $ Variable Local t x a me
removeMIDeclDir other = other removeMIDeclDir other = other
removeModport :: ModuleItem -> ModuleItem removeModport :: ModuleItem -> ModuleItem
removeModport (Modport x _) = Comment $ "removed modport " ++ x removeModport (Modport x _) =
MIPackageItem $ Comment $ "removed modport " ++ x
removeModport other = other removeModport other = other
...@@ -149,7 +149,7 @@ flattenModuleItem _ other = other ...@@ -149,7 +149,7 @@ flattenModuleItem _ other = other
-- flattened, packed array -- flattened, packed array
unflattener :: Bool -> Identifier -> (Type, Range) -> [GenItem] unflattener :: Bool -> Identifier -> (Type, Range) -> [GenItem]
unflattener writeToFlatVariant arr (t, (majorHi, majorLo)) = unflattener writeToFlatVariant arr (t, (majorHi, majorLo)) =
[ GenModuleItem $ Comment $ "sv2v packed-array-flatten unflattener for " ++ arr [ GenModuleItem $ MIPackageItem $ Comment $ "sv2v packed-array-flatten unflattener for " ++ arr
, GenModuleItem $ MIDecl $ Variable Local t arrUnflat [(majorHi, majorLo)] Nothing , GenModuleItem $ MIDecl $ Variable Local t arrUnflat [(majorHi, majorLo)] Nothing
, GenModuleItem $ Genvar index , GenModuleItem $ Genvar index
, GenModuleItem $ MIDecl $ Variable Local IntegerT (arrUnflat ++ "_repeater_index") [] Nothing , GenModuleItem $ MIDecl $ Variable Local IntegerT (arrUnflat ++ "_repeater_index") [] Nothing
......
...@@ -13,8 +13,9 @@ convert :: AST -> AST ...@@ -13,8 +13,9 @@ convert :: AST -> AST
convert = traverseDescriptions $ traverseModuleItems convertFunction convert = traverseDescriptions $ traverseModuleItems convertFunction
convertFunction :: ModuleItem -> ModuleItem convertFunction :: ModuleItem -> ModuleItem
convertFunction (Function ml t f decls stmts) = convertFunction (MIPackageItem (Function ml t f decls stmts)) =
Function ml t f decls (map (traverseNestedStmts convertStmt) stmts) MIPackageItem $ Function ml t f decls $
map (traverseNestedStmts convertStmt) stmts
where where
convertStmt :: Stmt -> Stmt convertStmt :: Stmt -> Stmt
convertStmt (Return e) = AsgnBlk (LHSIdent f) e convertStmt (Return e) = AsgnBlk (LHSIdent f) e
......
...@@ -109,7 +109,7 @@ collectDecl (Localparam t x _) = tell $ Map.singleton x t ...@@ -109,7 +109,7 @@ collectDecl (Localparam t x _) = tell $ Map.singleton x t
-- write down the return type of a function -- write down the return type of a function
collectFunction :: ModuleItem -> Writer Types () collectFunction :: ModuleItem -> Writer Types ()
collectFunction (Function _ t f _ _) = tell $ Map.singleton f t collectFunction (MIPackageItem (Function _ t f _ _)) = tell $ Map.singleton f t
collectFunction _ = return () collectFunction _ = return ()
......
...@@ -89,7 +89,13 @@ traverseModuleItemsM mapper (Part kw name ports items) = ...@@ -89,7 +89,13 @@ traverseModuleItemsM mapper (Part kw name ports items) =
Generate subItems -> GenBlock Nothing subItems Generate subItems -> GenBlock Nothing subItems
_ -> GenModuleItem moduleItem' _ -> GenModuleItem moduleItem'
genItemMapper other = return other genItemMapper other = return other
traverseModuleItemsM _ orig = return orig traverseModuleItemsM mapper (PackageItem packageItem) = do
let item = MIPackageItem packageItem
Part Module "DNE" [] [item'] <-
traverseModuleItemsM mapper (Part Module "DNE" [] [item])
return $ case item' of
MIPackageItem packageItem' -> PackageItem packageItem'
other -> error $ "encountered bad package module item: " ++ show other
traverseModuleItems :: Mapper ModuleItem -> Mapper Description traverseModuleItems :: Mapper ModuleItem -> Mapper Description
traverseModuleItems = unmonad traverseModuleItemsM traverseModuleItems = unmonad traverseModuleItemsM
...@@ -101,9 +107,9 @@ traverseStmtsM mapper = moduleItemMapper ...@@ -101,9 +107,9 @@ traverseStmtsM mapper = moduleItemMapper
where where
moduleItemMapper (AlwaysC kw stmt) = moduleItemMapper (AlwaysC kw stmt) =
fullMapper stmt >>= return . AlwaysC kw fullMapper stmt >>= return . AlwaysC kw
moduleItemMapper (Function lifetime ret name decls stmts) = do moduleItemMapper (MIPackageItem (Function lifetime ret name decls stmts)) = do
stmts' <- mapM fullMapper stmts stmts' <- mapM fullMapper stmts
return $ Function lifetime ret name decls stmts' return $ MIPackageItem $ Function lifetime ret name decls stmts'
moduleItemMapper (Initial stmt) = moduleItemMapper (Initial stmt) =
fullMapper stmt >>= return . Initial fullMapper stmt >>= return . Initial
moduleItemMapper other = return $ other moduleItemMapper other = return $ other
...@@ -288,10 +294,10 @@ traverseExprsM mapper = moduleItemMapper ...@@ -288,10 +294,10 @@ traverseExprsM mapper = moduleItemMapper
stmtMapper stmt >>= return . AlwaysC kw stmtMapper stmt >>= return . AlwaysC kw
moduleItemMapper (Initial stmt) = moduleItemMapper (Initial stmt) =
stmtMapper stmt >>= return . Initial stmtMapper stmt >>= return . Initial
moduleItemMapper (Function lifetime ret f decls stmts) = do moduleItemMapper (MIPackageItem (Function lifetime ret f decls stmts)) = do
decls' <- mapM declMapper decls decls' <- mapM declMapper decls
stmts' <- mapM stmtMapper stmts stmts' <- mapM stmtMapper stmts
return $ Function lifetime ret f decls' stmts' return $ MIPackageItem $ Function lifetime ret f decls' stmts'
moduleItemMapper (Instance m params x ml) = do moduleItemMapper (Instance m params x ml) = do
if ml == Nothing if ml == Nothing
then return $ Instance m params x Nothing then return $ Instance m params x Nothing
...@@ -300,9 +306,12 @@ traverseExprsM mapper = moduleItemMapper ...@@ -300,9 +306,12 @@ traverseExprsM mapper = moduleItemMapper
return $ Instance m params x (Just l) return $ Instance m params x (Just l)
moduleItemMapper (Modport x l) = moduleItemMapper (Modport x l) =
mapM modportDeclMapper l >>= return . Modport x mapM modportDeclMapper l >>= return . Modport x
moduleItemMapper (Comment x) = return $ Comment x
moduleItemMapper (Genvar x) = return $ Genvar x moduleItemMapper (Genvar x) = return $ Genvar x
moduleItemMapper (Generate x) = return $ Generate x moduleItemMapper (Generate x) = return $ Generate x
moduleItemMapper (MIPackageItem (Typedef t x)) =
return $ MIPackageItem $ Typedef t x
moduleItemMapper (MIPackageItem (Comment c)) =
return $ MIPackageItem $ Comment c
modportDeclMapper (dir, ident, Just e) = do modportDeclMapper (dir, ident, Just e) = do
e' <- exprMapper e e' <- exprMapper e
...@@ -345,9 +354,9 @@ traverseDeclsM mapper item = do ...@@ -345,9 +354,9 @@ traverseDeclsM mapper item = do
where where
miMapperA (MIDecl decl) = miMapperA (MIDecl decl) =
mapper decl >>= return . MIDecl mapper decl >>= return . MIDecl
miMapperA (Function l t x decls s) = do miMapperA (MIPackageItem (Function l t x decls s)) = do
decls' <- mapM mapper decls decls' <- mapM mapper decls
return $ Function l t x decls' s return $ MIPackageItem $ Function l t x decls' s
miMapperA other = return other miMapperA other = return other
miMapperB (Block (Just (name, decls)) stmts) = do miMapperB (Block (Just (name, decls)) stmts) = do
decls' <- mapM mapper decls decls' <- mapM mapper decls
...@@ -389,8 +398,8 @@ traverseTypesM mapper item = ...@@ -389,8 +398,8 @@ traverseTypesM mapper item =
fullMapper t >>= \t' -> return $ Localparam t' x e fullMapper t >>= \t' -> return $ Localparam t' x e
declMapper (Variable d t x a me) = declMapper (Variable d t x a me) =
fullMapper t >>= \t' -> return $ Variable d t' x a me fullMapper t >>= \t' -> return $ Variable d t' x a me
miMapper (Function l t x d s) = miMapper (MIPackageItem (Function l t x d s)) =
fullMapper t >>= \t' -> return $ Function l t' x d s fullMapper t >>= \t' -> return $ MIPackageItem $ Function l t' x d s
miMapper other = return other miMapper other = return other
traverseTypes :: Mapper Type -> Mapper ModuleItem traverseTypes :: Mapper Type -> Mapper ModuleItem
......
...@@ -19,20 +19,34 @@ type Types = Map.Map Identifier Type ...@@ -19,20 +19,34 @@ type Types = Map.Map Identifier Type
convert :: AST -> AST convert :: AST -> AST
convert descriptions = convert descriptions =
filter (not . isTypedef) $ traverseDescriptions (convertDescription types) descriptions traverseDescriptions removeTypedef $
traverseDescriptions (convertDescription types) $
descriptions
where where
types = execWriter $ collectDescriptionsM getTypedef descriptions types = execWriter $ collectDescriptionsM getTypedef descriptions
getTypedef :: Description -> Writer Types () getTypedef :: Description -> Writer Types ()
getTypedef (Typedef a b) = tell $ Map.singleton b a getTypedef (PackageItem (Typedef a b)) = tell $ Map.singleton b a
getTypedef _ = return () getTypedef _ = return ()
removeTypedef :: Description -> Description
isTypedef :: Description -> Bool removeTypedef (PackageItem (Typedef _ x)) =
isTypedef (Typedef _ _) = True PackageItem $ Comment $ "removed typedef: " ++ x
isTypedef _ = False removeTypedef other = other
convertDescription :: Types -> Description -> Description convertDescription :: Types -> Description -> Description
convertDescription types description = convertDescription globalTypes description =
traverseModuleItems (traverseTypes $ resolveType types) description traverseModuleItems removeTypedef $
traverseModuleItems (traverseTypes $ resolveType types) $
description
where
types = Map.union globalTypes $
execWriter $ collectModuleItemsM getTypedef description
getTypedef :: ModuleItem -> Writer Types ()
getTypedef (MIPackageItem (Typedef a b)) = tell $ Map.singleton b a
getTypedef _ = return ()
removeTypedef :: ModuleItem -> ModuleItem
removeTypedef (MIPackageItem (Typedef _ x)) =
MIPackageItem $ Comment $ "removed typedef: " ++ x
removeTypedef other = other
resolveType :: Types -> Type -> Type resolveType :: Types -> Type -> Type
resolveType _ (Reg rs) = Reg rs resolveType _ (Reg rs) = Reg rs
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
module Language.SystemVerilog.AST module Language.SystemVerilog.AST
( Identifier ( Identifier
, Description(..) , Description(..)
, PackageItem(..)
, ModuleItem (..) , ModuleItem (..)
, Direction (..) , Direction (..)
, Type (..) , Type (..)
...@@ -49,9 +50,23 @@ type Identifier = String ...@@ -49,9 +50,23 @@ type Identifier = String
type AST = [Description] type AST = [Description]
data PackageItem
= Typedef Type Identifier
| Function (Maybe Lifetime) Type Identifier [Decl] [Stmt]
| Comment String
deriving Eq
instance Show PackageItem where
show (Typedef t x) = printf "typedef %s %s;" (show t) x
show (Function ml t x i b) =
printf "function %s%s%s;\n%s\n%s\nendfunction"
(showLifetime ml) (showPad t) x (indent $ show i)
(indent $ unlines' $ map show b)
show (Comment c) = "// " ++ c
data Description data Description
= Part PartKW Identifier [Identifier] [ModuleItem] = Part PartKW Identifier [Identifier] [ModuleItem]
| Typedef Type Identifier | PackageItem PackageItem
deriving Eq deriving Eq
instance Show Description where instance Show Description where
...@@ -65,7 +80,7 @@ instance Show Description where ...@@ -65,7 +80,7 @@ instance Show Description where
if null ports if null ports
then "" then ""
else indentedParenList ports else indentedParenList ports
show (Typedef t x) = printf "typedef %s %s;" (show t) x show (PackageItem i) = show i
data PartKW data PartKW
= Module = Module
...@@ -154,16 +169,15 @@ instance Show Decl where ...@@ -154,16 +169,15 @@ instance Show Decl where
show (Variable d t x a me) = printf "%s%s %s%s%s;" (showPad d) (show t) x (showRanges a) (showAssignment me) show (Variable d t x a me) = printf "%s%s %s%s%s;" (showPad d) (show t) x (showRanges a) (showAssignment me)
data ModuleItem data ModuleItem
= Comment String = MIDecl Decl
| MIDecl Decl
| AlwaysC AlwaysKW Stmt | AlwaysC AlwaysKW Stmt
| Assign LHS Expr | Assign LHS Expr
| Instance Identifier [PortBinding] Identifier (Maybe [PortBinding]) -- `Nothing` represents `.*` | Instance Identifier [PortBinding] Identifier (Maybe [PortBinding]) -- `Nothing` represents `.*`
| Function (Maybe Lifetime) Type Identifier [Decl] [Stmt]
| Genvar Identifier | Genvar Identifier
| Generate [GenItem] | Generate [GenItem]
| Modport Identifier [ModportDecl] | Modport Identifier [ModportDecl]
| Initial Stmt | Initial Stmt
| MIPackageItem PackageItem
deriving Eq deriving Eq
data AlwaysKW data AlwaysKW
...@@ -184,18 +198,17 @@ type ModportDecl = (Direction, Identifier, Maybe Expr) ...@@ -184,18 +198,17 @@ type ModportDecl = (Direction, Identifier, Maybe Expr)
instance Show ModuleItem where instance Show ModuleItem where
show thing = case thing of show thing = case thing of
Comment c -> "// " ++ c
MIDecl nest -> show nest MIDecl nest -> show nest
AlwaysC k b -> printf "%s %s" (show k) (show b) AlwaysC k b -> printf "%s %s" (show k) (show b)
Assign a b -> printf "assign %s = %s;" (show a) (show b) Assign a b -> printf "assign %s = %s;" (show a) (show b)
Instance m params i ports Instance m params i ports
| null params -> printf "%s %s%s;" m i (showMaybePorts ports) | null params -> printf "%s %s%s;" m i (showMaybePorts ports)
| otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showMaybePorts ports) | otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showMaybePorts ports)
Function ml t x i b -> printf "function %s%s%s;\n%s\n%s\nendfunction" (showLifetime ml) (showPad t) x (indent $ show i) (indent $ unlines' $ map show b)
Genvar x -> printf "genvar %s;" x Genvar x -> printf "genvar %s;" x
Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b) Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b)
Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l) Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l)
Initial s -> printf "initial %s" (show s) Initial s -> printf "initial %s" (show s)
MIPackageItem i -> show i
where where
showMaybePorts = maybe "(.*)" showPorts showMaybePorts = maybe "(.*)" showPorts
showPorts :: [PortBinding] -> String showPorts :: [PortBinding] -> String
......
...@@ -185,14 +185,12 @@ opt(p) :: { Maybe a } ...@@ -185,14 +185,12 @@ opt(p) :: { Maybe a }
Descriptions :: { [Description] } Descriptions :: { [Description] }
: {- empty -} { [] } : {- empty -} { [] }
| Descriptions ";" { $1 }
| Descriptions Description { $1 ++ [$2] } | Descriptions Description { $1 ++ [$2] }
Description :: { Description } Description :: { Description }
: Part opt(";") { $1 } : Part { $1 }
| Typedef opt(";") { $1 } | PackageItem { PackageItem $1 }
Typedef :: { Description }
: "typedef" Type Identifier ";" { Typedef $2 $3 }
Type :: { Type } Type :: { Type }
: PartialType Dimensions { $1 $2 } : PartialType Dimensions { $1 $2 }
...@@ -322,7 +320,11 @@ ModuleItem :: { [ModuleItem] } ...@@ -322,7 +320,11 @@ ModuleItem :: { [ModuleItem] }
| "genvar" Identifiers ";" { map Genvar $2 } | "genvar" Identifiers ";" { map Genvar $2 }
| "generate" GenItems "endgenerate" { [Generate $2] } | "generate" GenItems "endgenerate" { [Generate $2] }
| "modport" ModportItems ";" { map (uncurry Modport) $2 } | "modport" ModportItems ";" { map (uncurry Modport) $2 }
| "function" opt(Lifetime) FuncRetAndName FunctionItems DeclsAndStmts "endfunction" opt(Tag) { [Function $2 (fst $3) (snd $3) (map defaultFuncInput $ $4 ++ fst $5) (snd $5)] } | PackageItem { [MIPackageItem $1] }
PackageItem :: { PackageItem }
: "typedef" Type Identifier ";" { Typedef $2 $3 }
| "function" opt(Lifetime) FuncRetAndName FunctionItems DeclsAndStmts "endfunction" opt(Tag) { Function $2 (fst $3) (snd $3) (map defaultFuncInput $ $4 ++ fst $5) (snd $5) }
FuncRetAndName :: { (Type, Identifier) } FuncRetAndName :: { (Type, Identifier) }
: {- empty -} Identifier { (Implicit [], $1) } : {- empty -} Identifier { (Implicit [], $1) }
......
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