Commit 8a008c30 by Zachary Snow

interface conversion supports positional port bindings

- also fixes an issue where system tasks were inadvertently prefixed
  during the interface conversion
parent 7a00c36a
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
module Convert.Interface (convert) where module Convert.Interface (convert) where
import Data.List (lookup)
import Data.Maybe (fromJust, mapMaybe) import Data.Maybe (fromJust, mapMaybe)
import Control.Monad.Writer import Control.Monad.Writer
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
...@@ -18,7 +19,7 @@ type Instances = Map.Map Identifier Identifier ...@@ -18,7 +19,7 @@ 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 type Modules = Map.Map Identifier [(Identifier, Type)]
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = convert =
...@@ -32,11 +33,13 @@ convert = ...@@ -32,11 +33,13 @@ convert =
collectDesc (orig @ (Part _ False kw _ name ports items)) = do collectDesc (orig @ (Part _ False kw _ name ports items)) = do
if kw == Interface if kw == Interface
then tell (Map.singleton name (ports, items), Map.empty) then tell (Map.singleton name (ports, items), Map.empty)
else collectModuleItemsM (collectDeclsM collectDecl) orig else tell (Map.empty, Map.singleton name decls)
where where
collectDecl :: Decl -> Writer (Interfaces, Modules) () decls = execWriter $
collectModuleItemsM (collectDeclsM collectDecl) orig
collectDecl :: Decl -> Writer [(Identifier, Type)] ()
collectDecl (Variable _ t ident _ _) = collectDecl (Variable _ t ident _ _) =
tell (Map.empty, Map.singleton (name, ident) t) tell [(ident, t)]
collectDecl _ = return () collectDecl _ = return ()
collectDesc _ = return () collectDesc _ = return ()
isInterface :: Description -> Bool isInterface :: Description -> Bool
...@@ -95,7 +98,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -95,7 +98,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
Generate $ map GenModuleItem $ Generate $ map GenModuleItem $
inlineInterface interface (ident, params, expandedPorts) inlineInterface interface (ident, params, expandedPorts)
Nothing -> Instance part params ident Nothing expandedPorts Nothing -> Instance part params ident Nothing expandedPorts
where expandedPorts = concatMap (expandPortBinding part) instancePorts where expandedPorts = concatMap (uncurry $ expandPortBinding part) (zip instancePorts [0..])
mapInterface (orig @ (MIPackageItem (Function _ _ _ decls _))) = mapInterface (orig @ (MIPackageItem (Function _ _ _ decls _))) =
convertTF decls orig convertTF decls orig
mapInterface (orig @ (MIPackageItem (Task _ _ decls _))) = mapInterface (orig @ (MIPackageItem (Task _ _ decls _))) =
...@@ -114,8 +117,8 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -114,8 +117,8 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
declVarIdent (Variable _ _ x _ _) = Just x declVarIdent (Variable _ _ x _ _) = Just x
declVarIdent _ = Nothing declVarIdent _ = Nothing
expandPortBinding :: Identifier -> PortBinding -> [PortBinding] expandPortBinding :: Identifier -> PortBinding -> Int -> [PortBinding]
expandPortBinding _ (origBinding @ (portName, Just (Dot (Ident instanceName) modportName))) = expandPortBinding _ (origBinding @ (portName, Just (Dot (Ident instanceName) modportName))) _ =
-- expand instance modport bound to a modport -- expand instance modport bound to a modport
if Map.member instanceName instances && modportDecls /= Nothing if Map.member instanceName instances && modportDecls /= Nothing
then map mapper $ fromJust modportDecls then map mapper $ fromJust modportDecls
...@@ -128,19 +131,28 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -128,19 +131,28 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
prefixExpr :: Expr -> Expr prefixExpr :: Expr -> Expr
prefixExpr (Ident x) = Ident (instanceName ++ "_" ++ x) prefixExpr (Ident x) = Ident (instanceName ++ "_" ++ x)
prefixExpr other = other prefixExpr other = other
expandPortBinding moduleName (origBinding @ (portName, Just (Ident ident))) = expandPortBinding moduleName (origBinding @ (portName, Just (Ident ident))) idx =
case (instances Map.!? ident, modports Map.!? ident) of case (instances Map.!? ident, modports Map.!? ident) of
(Nothing, Nothing) -> [origBinding] (Nothing, Nothing) -> [origBinding]
(Just _, _) -> (Just _, _) ->
-- given entire interface, but just bound to a modport -- given entire interface, but just bound to a modport
expandPortBinding moduleName (portName, Just newExpr) expandPortBinding moduleName (portName', Just newExpr) idx
where where
InterfaceT _ (Just modportName) [] = (portName', InterfaceT _ (Just modportName) []) =
case Map.lookup (moduleName, portName) modules of case (portName, Map.lookup moduleName modules) of
Just t -> t ("", Just decls) ->
if idx < length decls
then decls !! idx
else error $ "could not infer port "
++ show origBinding ++ " in module "
++ show moduleName
(_, Just decls) -> case lookup portName decls of
Nothing -> error $ "could not find port " Nothing -> error $ "could not find port "
++ show portName ++ " in module " ++ show portName ++ " in module "
++ show moduleName ++ show moduleName
Just t -> (portName, t)
(_, Nothing) -> error $ "could not find module "
++ show moduleName
newExpr = Dot (Ident ident) modportName newExpr = Dot (Ident ident) modportName
(_, Just decls) -> (_, Just decls) ->
-- modport directly bound to a modport -- modport directly bound to a modport
...@@ -149,7 +161,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -149,7 +161,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
mapper (_, x, _) = mapper (_, x, _) =
( portName ++ "_" ++ x ( portName ++ "_" ++ x
, Just $ Dot (Ident ident) x ) , Just $ Dot (Ident ident) x )
expandPortBinding _ other = [other] expandPortBinding _ other _ = [other]
lookupModport :: Identifier -> Identifier -> Maybe [ModportDecl] lookupModport :: Identifier -> Identifier -> Maybe [ModportDecl]
lookupModport interfaceName = lookupModport interfaceName =
...@@ -200,6 +212,7 @@ prefixModuleItems prefix = ...@@ -200,6 +212,7 @@ prefixModuleItems prefix =
prefixDecl (ParamType s x mt) = ParamType s (prefix ++ x) mt prefixDecl (ParamType s x mt) = ParamType s (prefix ++ x) mt
prefixDecl (CommentDecl c) = CommentDecl c prefixDecl (CommentDecl c) = CommentDecl c
prefixExpr :: Expr -> Expr prefixExpr :: Expr -> Expr
prefixExpr (Ident ('$' : x)) = Ident $ '$' : x
prefixExpr (Ident x) = Ident (prefix ++ x) prefixExpr (Ident x) = Ident (prefix ++ x)
prefixExpr other = other prefixExpr other = other
prefixLHS :: LHS -> LHS prefixLHS :: LHS -> LHS
......
interface Interface;
logic x;
modport Modport(
input x
);
initial $display("Interface", x);
endinterface
module Module(Interface.Modport foo);
initial $display("Module", foo.x);
endmodule
module top;
Interface i();
Module m(i);
endmodule
module Module(input wire x);
initial $display("Module", x);
endmodule
module top;
wire i_x;
initial $display("Interface", i_x);
Module m(.x(i_x));
endmodule
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