mirror of https://github.com/zachjs/sv2v.git
interface conversion supports positional port bindings
- also fixes an issue where system tasks were inadvertently prefixed during the interface conversion
This commit is contained in:
parent
7a00c36a70
commit
8a008c3024
|
|
@ -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
|
||||||
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 =
|
||||||
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
|
||||||
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
|
||||||
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,18 +131,27 @@ 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) ->
|
||||||
Nothing -> error $ "could not find port "
|
if idx < length decls
|
||||||
++ show portName ++ " in module "
|
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 "
|
||||||
|
++ show portName ++ " in module "
|
||||||
|
++ show moduleName
|
||||||
|
Just t -> (portName, t)
|
||||||
|
(_, Nothing) -> error $ "could not find module "
|
||||||
++ show moduleName
|
++ show moduleName
|
||||||
newExpr = Dot (Ident ident) modportName
|
newExpr = Dot (Ident ident) modportName
|
||||||
(_, Just decls) ->
|
(_, Just decls) ->
|
||||||
|
|
@ -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 =
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue