Commit 9b8a9502 by Zachary Snow

more robust and full-featured interface conversion

parent 0a3e9f4f
...@@ -17,25 +17,33 @@ type Instances = Map.Map Identifier Identifier ...@@ -17,25 +17,33 @@ type Instances = Map.Map Identifier Identifier
type Interface = ([Identifier], [ModuleItem]) type Interface = ([Identifier], [ModuleItem])
type Interfaces = Map.Map Identifier Interface type Interfaces = Map.Map Identifier Interface
type Modports = Map.Map Identifier [ModportDecl] type Modports = Map.Map Identifier [ModportDecl]
type Modules = Map.Map (Identifier, Identifier) Type
convert :: AST -> AST convert :: AST -> AST
convert descriptions = convert descriptions =
filter (not . isInterface) $ filter (not . isInterface) $
traverseDescriptions (convertDescription interfaces) $ traverseDescriptions (convertDescription interfaces modules) $
descriptions descriptions
where where
interfaces = execWriter $ collectDescriptionsM collectDesc descriptions (interfaces, modules) =
execWriter $ collectDescriptionsM collectDesc descriptions
-- we can only collect/map non-extern interfaces -- we can only collect/map non-extern interfaces
collectDesc :: Description -> Writer Interfaces () collectDesc :: Description -> Writer (Interfaces, Modules) ()
collectDesc (Part False Interface _ name ports items) = collectDesc (orig @ (Part False kw _ name ports items)) = do
tell $ Map.singleton name (ports, items) if kw == Interface
then tell (Map.singleton name (ports, items), Map.empty)
else collectModuleItemsM (collectDeclsM $ collectDecl name) orig
collectDesc _ = return () collectDesc _ = return ()
collectDecl :: Identifier -> Decl -> Writer (Interfaces, Modules) ()
collectDecl name (Variable _ t ident _ _) = do
tell (Map.empty, Map.singleton (name, ident) t)
collectDecl _ _ = return ()
isInterface :: Description -> Bool isInterface :: Description -> Bool
isInterface (Part False Interface _ _ _ _) = True isInterface (Part False Interface _ _ _ _) = True
isInterface _ = False isInterface _ = False
convertDescription :: Interfaces -> Description -> Description convertDescription :: Interfaces -> Modules -> Description -> Description
convertDescription interfaces (Part extern Module lifetime name ports items) = convertDescription interfaces modules (Part extern Module lifetime name ports items) =
Part extern Module lifetime name ports' items' Part extern Module lifetime name ports' items'
where where
items' = items' =
...@@ -49,7 +57,7 @@ convertDescription interfaces (Part extern Module lifetime name ports items) = ...@@ -49,7 +57,7 @@ convertDescription interfaces (Part extern Module lifetime name ports items) =
(instances, modports) = execWriter $ mapM (instances, modports) = execWriter $ mapM
(collectNestedModuleItemsM collectInterface) items (collectNestedModuleItemsM collectInterface) items
collectInterface :: ModuleItem -> Writer (Instances, Modports) () collectInterface :: ModuleItem -> Writer (Instances, Modports) ()
collectInterface (MIDecl (Variable Local t ident _ _)) = collectInterface (MIDecl (Variable _ t ident _ _)) =
case t of case t of
InterfaceT interfaceName (Just modportName) [] -> InterfaceT interfaceName (Just modportName) [] ->
tell (Map.empty, Map.singleton ident modportDecls) tell (Map.empty, Map.singleton ident modportDecls)
...@@ -80,13 +88,16 @@ convertDescription interfaces (Part extern Module lifetime name ports items) = ...@@ -80,13 +88,16 @@ convertDescription interfaces (Part extern Module lifetime name ports items) =
Generate $ map GenModuleItem $ Generate $ map GenModuleItem $
inlineInterface interface (ident, expandedPorts) inlineInterface interface (ident, expandedPorts)
Nothing -> Instance part params ident Nothing expandedPorts Nothing -> Instance part params ident Nothing expandedPorts
where expandedPorts = concatMap expandPortBinding instancePorts where expandedPorts = concatMap (expandPortBinding part) instancePorts
mapInterface other = other mapInterface other = other
expandPortBinding :: PortBinding -> [PortBinding] expandPortBinding :: Identifier -> PortBinding -> [PortBinding]
expandPortBinding (origBinding @ (portName, Just (Dot (Ident instanceName) modportName))) = expandPortBinding _ (origBinding @ (portName, Just (Dot (Ident instanceName) modportName))) =
case Map.lookup instanceName instances of case Map.lookup instanceName instances of
Nothing ->
case Map.lookup instanceName modports of
Nothing -> [origBinding] Nothing -> [origBinding]
Just _ -> [(portName, Just $ Ident $ instanceName ++ "_" ++ modportName)]
Just interfaceName -> Just interfaceName ->
case modportDecls of case modportDecls of
Nothing -> [(portName, Just $ Ident $ instanceName ++ "_" ++ modportName)] Nothing -> [(portName, Just $ Ident $ instanceName ++ "_" ++ modportName)]
...@@ -94,7 +105,22 @@ convertDescription interfaces (Part extern Module lifetime name ports items) = ...@@ -94,7 +105,22 @@ convertDescription interfaces (Part extern Module lifetime name ports items) =
where where
modportDecls = lookupModport (Just instanceName) interfaceName modportName modportDecls = lookupModport (Just instanceName) interfaceName modportName
mapper (_, x, me) = (portName ++ "_" ++ x, me) mapper (_, x, me) = (portName ++ "_" ++ x, me)
expandPortBinding other = [other] expandPortBinding moduleName (origBinding @ (portName, Just (Ident instanceName))) =
case (instances Map.!? instanceName, modports Map.!? instanceName) of
(Nothing, Nothing) -> [origBinding]
(Just _, _) ->
map mapper modportDecls
where
InterfaceT interfaceName (Just modportName) [] =
modules Map.! (moduleName, portName)
Just modportDecls = lookupModport (Just instanceName) interfaceName modportName
mapper (_, x, me) = (portName ++ "_" ++ x, me)
(_, Just decls) ->
map mapper decls
where mapper (_, x, _) =
( portName ++ "_" ++ x
, Just $ Ident $ instanceName ++ "_" ++ x )
expandPortBinding _ other = [other]
lookupModport :: Maybe Identifier -> Identifier -> Identifier -> Maybe [ModportDecl] lookupModport :: Maybe Identifier -> Identifier -> Identifier -> Maybe [ModportDecl]
lookupModport instanceName interfaceName = (Map.!?) modportMap lookupModport instanceName interfaceName = (Map.!?) modportMap
...@@ -128,7 +154,7 @@ convertDescription interfaces (Part extern Module lifetime name ports items) = ...@@ -128,7 +154,7 @@ convertDescription interfaces (Part extern Module lifetime name ports items) =
Nothing -> [ident] Nothing -> [ident]
Just decls -> map (\(_, x, _) -> ident ++ "_" ++ x) decls Just decls -> map (\(_, x, _) -> ident ++ "_" ++ x) decls
convertDescription _ other = other convertDescription _ _ other = other
-- add a prefix to all standard identifiers in a module item -- add a prefix to all standard identifiers in a module item
......
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