{- sv2v - Author: Zachary Snow <zach@zachjs.com> - - Conversion for `.*` in module instantiation -} module Convert.StarPort (convert) where import Control.Monad.Writer import qualified Data.Map.Strict as Map import Convert.Traverse import Language.SystemVerilog.AST type Ports = Map.Map Identifier [Identifier] convert :: [AST] -> [AST] convert = traverseFiles (collectDescriptionsM collectPortsM) (traverseDescriptions . traverseModuleItems . mapInstance) collectPortsM :: Description -> Writer Ports () collectPortsM (Part _ _ _ _ name ports _) = tell $ Map.singleton name ports collectPortsM _ = return () mapInstance :: Ports -> ModuleItem -> ModuleItem mapInstance modulePorts (Instance m p x r bindings) = Instance m p x r $ concatMap expandBinding bindings where alreadyBound :: [Identifier] alreadyBound = map fst bindings expandBinding :: PortBinding -> [PortBinding] expandBinding ("*", Nothing) = case Map.lookup m modulePorts of Just l -> map (\port -> (port, Just $ Ident port)) $ filter (\s -> not $ elem s alreadyBound) $ l -- if we can't find it, just skip :( Nothing -> [("*", Nothing)] expandBinding other = [other] mapInstance _ other = other