From d01df6110bda6576ee339cb12c23297772917df8 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 23 Apr 2019 15:53:51 -0400 Subject: [PATCH] preliminary language support for packages --- src/Convert/Logic.hs | 1 + src/Convert/Traverse.hs | 11 +++++++++++ src/Language/SystemVerilog/AST/Description.hs | 13 +++++++++++++ src/Language/SystemVerilog/AST/Expr.hs | 2 ++ src/Language/SystemVerilog/Parser/Lex.x | 4 ++++ src/Language/SystemVerilog/Parser/Parse.y | 17 +++++++++++++++++ 6 files changed, 48 insertions(+) diff --git a/src/Convert/Logic.hs b/src/Convert/Logic.hs index c5c1fba..a3c4829 100644 --- a/src/Convert/Logic.hs +++ b/src/Convert/Logic.hs @@ -64,6 +64,7 @@ convertDescription ports orig = Part _ Interface _ _ _ _ -> False Part _ Module _ _ _ _ -> True PackageItem _ -> True + Package _ _ _ -> False Directive _ -> False conversion = traverseDecls convertDecl . convertModuleItem idents = execWriter (collectModuleItemsM regIdents orig) diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 47aacd2..0f1be03 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -151,6 +151,14 @@ traverseModuleItemsM mapper (PackageItem packageItem) = do return $ case item' of MIPackageItem packageItem' -> PackageItem packageItem' other -> error $ "encountered bad package module item: " ++ show other +traverseModuleItemsM mapper (Package lifetime name items) = do + converted <- + traverseModuleItemsM mapper (Part False Module Nothing "DNE" [] items) + let items' = case converted of + Part False Module Nothing "DNE" [] newItems -> newItems + _ -> error $ "redirected Package traverse failed: " + ++ show converted + return $ Package lifetime name items' traverseModuleItemsM _ (Directive str) = return $ Directive str traverseModuleItems :: Mapper ModuleItem -> Mapper Description @@ -399,6 +407,7 @@ traverseNestedExprsM mapper = exprMapper em (String s) = return $ String s em (Number s) = return $ Number s em (Ident i) = return $ Ident i + em (PSIdent x y) = return $ PSIdent x y em (Range e m (e1, e2)) = do e' <- exprMapper e e1' <- exprMapper e1 @@ -552,6 +561,8 @@ traverseExprsM' strat exprMapper = moduleItemMapper return $ MIPackageItem $ Typedef t x moduleItemMapper (MIPackageItem (Comment c)) = return $ MIPackageItem $ Comment c + moduleItemMapper (MIPackageItem (Import imports)) = + return $ MIPackageItem $ Import imports moduleItemMapper (AssertionItem (mx, a)) = do a' <- traverseAssertionStmtsM stmtMapper a a'' <- traverseAssertionExprsM exprMapper a' diff --git a/src/Language/SystemVerilog/AST/Description.hs b/src/Language/SystemVerilog/AST/Description.hs index 4103f89..2d95bf4 100644 --- a/src/Language/SystemVerilog/AST/Description.hs +++ b/src/Language/SystemVerilog/AST/Description.hs @@ -12,6 +12,7 @@ module Language.SystemVerilog.AST.Description , Lifetime (..) ) where +import Data.Maybe (fromMaybe) import Data.List (intercalate) import Text.Printf (printf) @@ -25,6 +26,7 @@ import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem) data Description = Part Bool PartKW (Maybe Lifetime) Identifier [Identifier] [ModuleItem] | PackageItem PackageItem + | Package (Maybe Lifetime) Identifier [ModuleItem] | Directive String -- currently unused deriving Eq @@ -42,6 +44,11 @@ instance Show Description where then "" else " " ++ indentedParenList ports bodyStr = indent $ unlines' $ map show items + show (Package lifetime name items) = + printf "package %s%s;\n%s\nendpackage" + (showLifetime lifetime) name bodyStr + where + bodyStr = indent $ unlines' $ map show items show (PackageItem i) = show i show (Directive str) = str @@ -49,6 +56,7 @@ data PackageItem = Typedef Type Identifier | Function (Maybe Lifetime) Type Identifier [Decl] [Stmt] | Task (Maybe Lifetime) Identifier [Decl] [Stmt] + | Import [(Identifier, Maybe Identifier)] | Comment String deriving Eq @@ -62,6 +70,11 @@ instance Show PackageItem where printf "task %s%s;\n%s\n%s\nendtask" (showLifetime ml) x (indent $ show i) (indent $ unlines' $ map show b) + show (Import imports) = + printf "import %s;" + (commas $ map showImport imports) + where + showImport (x, y) = printf "%s::%s" x (fromMaybe "*" y) show (Comment c) = if elem '\n' c then "// " ++ show c diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index 4ff18f9..1f54314 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -34,6 +34,7 @@ data Expr = String String | Number String | Ident Identifier + | PSIdent Identifier Identifier | Range Expr PartSelectMode Range | Bit Expr Expr | Repeat Expr [Expr] @@ -51,6 +52,7 @@ data Expr instance Show Expr where show (Number str ) = str show (Ident str ) = str + show (PSIdent x y) = printf "%s::%s" x y show (String str ) = printf "\"%s\"" str show (Bit e b ) = printf "%s[%s]" (show e) (show b) show (Range e m r) = printf "%s[%s%s%s]" (show e) (show $ fst r) (show m) (show $ snd r) diff --git a/src/Language/SystemVerilog/Parser/Lex.x b/src/Language/SystemVerilog/Parser/Lex.x index fc6edf6..c09272c 100644 --- a/src/Language/SystemVerilog/Parser/Lex.x +++ b/src/Language/SystemVerilog/Parser/Lex.x @@ -134,8 +134,10 @@ tokens :- "endgenerate" { tok KW_endgenerate } "endinterface" { tok KW_endinterface } "endmodule" { tok KW_endmodule } + "endpackage" { tok KW_endpackage } "endtask" { tok KW_endtask } "enum" { tok KW_enum } + "export" { tok KW_export } "extern" { tok KW_extern } "first_match" { tok KW_first_match } "for" { tok KW_for } @@ -145,6 +147,7 @@ tokens :- "genvar" { tok KW_genvar } "if" { tok KW_if } "iff" { tok KW_iff } + "import" { tok KW_import } "initial" { tok KW_initial } "inout" { tok KW_inout } "input" { tok KW_input } @@ -163,6 +166,7 @@ tokens :- "not" { tok KW_not } "or" { tok KW_or } "output" { tok KW_output } + "package" { tok KW_package } "packed" { tok KW_packed } "parameter" { tok KW_parameter } "posedge" { tok KW_posedge } diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 57edff8..454e222 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -55,8 +55,10 @@ import Language.SystemVerilog.Parser.Tokens "endgenerate" { Token KW_endgenerate _ _ } "endinterface" { Token KW_endinterface _ _ } "endmodule" { Token KW_endmodule _ _ } +"endpackage" { Token KW_endpackage _ _ } "endtask" { Token KW_endtask _ _ } "enum" { Token KW_enum _ _ } +"export" { Token KW_export _ _ } "extern" { Token KW_extern _ _ } "first_match" { Token KW_first_match _ _ } "for" { Token KW_for _ _ } @@ -66,6 +68,7 @@ import Language.SystemVerilog.Parser.Tokens "genvar" { Token KW_genvar _ _ } "if" { Token KW_if _ _ } "iff" { Token KW_iff _ _ } +"import" { Token KW_import _ _ } "initial" { Token KW_initial _ _ } "inout" { Token KW_inout _ _ } "input" { Token KW_input _ _ } @@ -84,6 +87,7 @@ import Language.SystemVerilog.Parser.Tokens "not" { Token KW_not _ _ } "or" { Token KW_or _ _ } "output" { Token KW_output _ _ } +"package" { Token KW_package _ _ } "packed" { Token KW_packed _ _ } "parameter" { Token KW_parameter _ _ } "posedge" { Token KW_posedge _ _ } @@ -258,6 +262,7 @@ Description :: { Description } : Part(ModuleKW , "endmodule" ) { $1 } | Part(InterfaceKW, "endinterface") { $1 } | PackageItem { PackageItem $1 } + | PackageDeclaration { $1 } Type :: { Type } : TypeNonIdent { $1 } @@ -338,6 +343,9 @@ ModuleKW :: { PartKW } InterfaceKW :: { PartKW } : "interface" { Interface } +PackageDeclaration :: { Description } + : "package" opt(Lifetime) Identifier ";" ModuleItems "endpackage" opt(Tag) { Package $2 $3 $5 } + Tag :: { Identifier } : ":" Identifier { $2 } @@ -560,6 +568,14 @@ PackageItem :: { PackageItem } : "typedef" Type Identifier ";" { Typedef $2 $3 } | "function" opt(Lifetime) FuncRetAndName TFItems DeclsAndStmts "endfunction" opt(Tag) { Function $2 (fst $3) (snd $3) (map defaultFuncInput $ (map makeInput $4) ++ fst $5) (snd $5) } | "task" opt(Lifetime) Identifier TFItems DeclsAndStmts "endtask" opt(Tag) { Task $2 $3 (map defaultFuncInput $ $4 ++ fst $5) (snd $5) } + | "import" PackageImportItems ";" { Import $2 } + +PackageImportItems :: { [(Identifier, Maybe Identifier)] } + : PackageImportItem { [$1] } + | PackageImportItems "," PackageImportItem { $1 ++ [$3] } +PackageImportItem :: { (Identifier, Maybe Identifier) } + : Identifier "::" Identifier { ($1, Just $3) } + | Identifier "::" "*" { ($1, Nothing) } FuncRetAndName :: { (Type, Identifier) } : Type Identifier { ($1 , $2) } @@ -791,6 +807,7 @@ Expr :: { Expr } | Identifier "(" CallArgs ")" { Call $1 $3 } | "$bits" "(" BitsArg ")" { Bits $3 } | Identifier { Ident $1 } + | Identifier "::" Identifier { PSIdent $1 $3 } | Expr PartSelect { Range $1 (fst $2) (snd $2) } | Expr "[" Expr "]" { Bit $1 $3 } | "{" Expr "{" Exprs "}" "}" { Repeat $2 $4 }