From 2ee5b6e03915a1842fc4989c5158b20726ba4ee1 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Wed, 20 Feb 2019 15:22:26 -0500 Subject: [PATCH] suport for in module instantiations --- Convert.hs | 2 ++ Convert/StarPort.hs | 37 +++++++++++++++++++++++++++ Language/SystemVerilog/AST.hs | 13 ++++++---- Language/SystemVerilog/Parser/Parse.y | 7 ++--- sv2v.cabal | 1 + 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 Convert/StarPort.hs diff --git a/Convert.hs b/Convert.hs index 149c3c6..21651c1 100644 --- a/Convert.hs +++ b/Convert.hs @@ -11,6 +11,7 @@ import Language.SystemVerilog.AST import qualified Convert.AlwaysKW import qualified Convert.Logic import qualified Convert.Typedef +import qualified Convert.StarPort type Phase = AST -> AST @@ -19,6 +20,7 @@ phases = [ Convert.AlwaysKW.convert , Convert.Logic.convert , Convert.Typedef.convert + , Convert.StarPort.convert ] run :: Phase diff --git a/Convert/StarPort.hs b/Convert/StarPort.hs new file mode 100644 index 0000000..29afc79 --- /dev/null +++ b/Convert/StarPort.hs @@ -0,0 +1,37 @@ +{- sv2v + - Author: Zachary Snow + - + - Conversion for `.*` in module instantiation + -} + +module Convert.StarPort (convert) where + +import Data.Maybe +import qualified Data.Map.Strict as Map + +import Language.SystemVerilog.AST + +type ModulePorts = Map.Map String [String] + +convert :: AST -> AST +convert descriptions = map (convertDescription portsInfo) descriptions + where + portsInfo = Map.fromList $ mapMaybe getPorts descriptions + getPorts :: Description -> Maybe (Identifier, [Identifier]) + getPorts (Module name ports _) = Just (name, ports) + getPorts _ = Nothing + +convertDescription :: ModulePorts -> Description -> Description +convertDescription info (Module name ports items) = + Module name ports $ map (convertModuleItem info) items +convertDescription _ other = other + +convertModuleItem :: ModulePorts -> ModuleItem -> ModuleItem +convertModuleItem info (Instance m p x Nothing) = + Instance m p x (Just portBindings) + where + 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 diff --git a/Language/SystemVerilog/AST.hs b/Language/SystemVerilog/AST.hs index 5b7381a..7bf0b26 100644 --- a/Language/SystemVerilog/AST.hs +++ b/Language/SystemVerilog/AST.hs @@ -92,7 +92,7 @@ data ModuleItem | LocalNet Type Identifier RangesOrAssignment | AlwaysC AlwaysKW Stmt | Assign LHS Expr - | Instance Identifier [PortBinding] Identifier [PortBinding] + | Instance Identifier [PortBinding] Identifier (Maybe [PortBinding]) -- `Nothing` represents `.*` | Function (Maybe FuncRet) Identifier [(Bool, BlockItemDeclaration)] Stmt | Genvar Identifier | Generate [GenItem] @@ -139,14 +139,17 @@ instance Show ModuleItem where AlwaysC k b -> printf "%s %s" (show k) (show b) Assign a b -> printf "assign %s = %s;" (show a) (show b) Instance m params i ports - | null params -> printf "%s %s %s;" m i (showPorts show ports) - | otherwise -> printf "%s #%s %s %s;" m (showPorts show params) i (showPorts show ports) + | null params -> printf "%s %s%s;" m i (showMaybePorts ports) + | otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showMaybePorts ports) Function t x i b -> printf "function %s%s;\n%s\n%s\nendfunction" (showFuncRet t) x (indent $ unlines' $ map showFunctionItem i) (indent $ show b) Genvar x -> printf "genvar %s;" x Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b) where - showPorts :: (Expr -> String) -> [(Identifier, Maybe Expr)] -> String - showPorts s ports = indentedParenList [ if i == "" then show (fromJust arg) else printf ".%s(%s)" i (if isJust arg then s $ fromJust arg else "") | (i, arg) <- ports ] + showMaybePorts :: Maybe [(Identifier, Maybe Expr)] -> String + showMaybePorts Nothing = "(.*)" + showMaybePorts (Just ports) = showPorts ports + showPorts :: [(Identifier, Maybe Expr)] -> String + showPorts ports = indentedParenList [ if i == "" then show (fromJust arg) else printf ".%s(%s)" i (if isJust arg then show $ fromJust arg else "") | (i, arg) <- ports ] showFunctionItem :: (Bool, BlockItemDeclaration) -> String showFunctionItem (b, item) = prefix ++ (show item) where prefix = if b then "input " else "" diff --git a/Language/SystemVerilog/Parser/Parse.y b/Language/SystemVerilog/Parser/Parse.y index a5b5672..0cd8bec 100644 --- a/Language/SystemVerilog/Parser/Parse.y +++ b/Language/SystemVerilog/Parser/Parse.y @@ -260,11 +260,12 @@ AlwaysKW :: { AlwaysKW } | "always_ff" { AlwaysFF } | "always_latch" { AlwaysLatch } -ModuleInstantiations :: { [(Identifier, [PortBinding])] } +ModuleInstantiations :: { [(Identifier, Maybe [PortBinding])] } : ModuleInstantiation { [$1] } | ModuleInstantiations "," ModuleInstantiation { $1 ++ [$3] } -ModuleInstantiation :: { (Identifier, [PortBinding]) } - : Identifier "(" Bindings ")" { ($1, $3) } +ModuleInstantiation :: { (Identifier, Maybe [PortBinding]) } + : Identifier "(" Bindings ")" { ($1, Just $3) } + | Identifier "(" ".*" ")" { ($1, Nothing) } FunctionItems :: { [(Bool, BlockItemDeclaration)] } : "(" FunctionPortList ";" BlockItemDeclarations { (map ((,) True) $2) ++ (map ((,) False) $4) } diff --git a/sv2v.cabal b/sv2v.cabal index 058b87a..9acd2aa 100644 --- a/sv2v.cabal +++ b/sv2v.cabal @@ -62,6 +62,7 @@ executable sv2v Convert Convert.AlwaysKW Convert.Logic + Convert.StarPort Convert.Typedef Convert.Template.ModuleItem ghc-options: