Commit b6f4f690 by Zachary Snow

support simple bundle interfaces

- fix position modport-to-modport bindings
- inout logics converted to regs become outputs
parent 589261a9
...@@ -73,6 +73,11 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -73,6 +73,11 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
InterfaceT interfaceName (Just modportName) [] -> InterfaceT interfaceName (Just modportName) [] ->
tell (Map.empty, Map.singleton ident modportDecls) tell (Map.empty, Map.singleton ident modportDecls)
where Just modportDecls = lookupModport interfaceName modportName where Just modportDecls = lookupModport interfaceName modportName
Alias Nothing interfaceName [] ->
case impliedModport interfaceName of
Just modportDecls ->
tell (Map.empty, Map.singleton ident modportDecls)
Nothing -> return ()
_ -> return () _ -> return ()
collectInterface (Instance part _ ident Nothing _) = collectInterface (Instance part _ ident Nothing _) =
if Map.member part interfaces if Map.member part interfaces
...@@ -81,7 +86,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -81,7 +86,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
collectInterface _ = return () collectInterface _ = return ()
mapInterface :: ModuleItem -> ModuleItem mapInterface :: ModuleItem -> ModuleItem
mapInterface (orig @ (MIPackageItem (Decl (Variable Local t ident _ _)))) = mapInterface (orig @ (MIPackageItem (Decl (Variable _ t ident _ _)))) =
-- expand instantiation of a modport -- expand instantiation of a modport
case Map.lookup ident modports of case Map.lookup ident modports of
Just modportDecls -> Generate $ Just modportDecls -> Generate $
...@@ -89,7 +94,10 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -89,7 +94,10 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
modportDecls modportDecls
Nothing -> orig Nothing -> orig
where where
InterfaceT interfaceName (Just _) [] = t interfaceName = case t of
InterfaceT x (Just _) [] -> x
Alias Nothing x [] -> x
_ -> error $ "unexpected modport type " ++ show t
interfaceItems = interfaceItems =
case Map.lookup interfaceName interfaces of case Map.lookup interfaceName interfaces of
Just res -> snd res Just res -> snd res
...@@ -128,48 +136,61 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -128,48 +136,61 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
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 expandPortBinding' portName instanceName $ fromJust modportDecls
else [origBinding] else [origBinding]
where where
interfaceName = instances Map.! instanceName interfaceName = instances Map.! instanceName
modportDecls = lookupModport interfaceName modportName modportDecls = lookupModport interfaceName modportName
mapper (_, x, me) = (portName ++ "_" ++ x, me')
where me' = fmap (traverseNestedExprs prefixExpr) me
prefixExpr :: Expr -> Expr
prefixExpr (Ident x) = Ident (instanceName ++ "_" ++ x)
prefixExpr other = other
expandPortBinding moduleName (origBinding @ (portName, Just (Ident ident))) idx = 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 interfaceName, _) ->
-- given entire interface, but just bound to a modport -- given entire interface, but just bound to a modport
expandPortBinding moduleName (portName', Just newExpr) idx if Map.notMember moduleName modules then
error $ "could not find module " ++ show moduleName
else if modportDecls == Nothing then
[origBinding]
else
expandPortBinding' portName ident $ fromJust modportDecls
where where
(portName', InterfaceT _ (Just modportName) []) = Just decls = Map.lookup moduleName modules
case (portName, Map.lookup moduleName modules) of portType =
("", Just decls) -> if null portName
if idx < length decls then if idx < length decls
then decls !! idx then snd $ decls !! idx
else error $ "could not infer port " else error $ "could not infer port "
++ show origBinding ++ " in module " ++ show origBinding ++ " in module "
++ show moduleName ++ show moduleName
(_, Just decls) -> case lookup portName decls of else 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) Just t -> t
(_, Nothing) -> error $ "could not find module " modportDecls =
++ show moduleName case portType of
newExpr = Dot (Ident ident) modportName InterfaceT _ (Just modportName) [] ->
(_, Just decls) -> lookupModport interfaceName modportName
Alias Nothing _ [] ->
impliedModport interfaceName
_ -> Nothing
(_, Just modportDecls) ->
-- modport directly bound to a modport -- modport directly bound to a modport
map mapper decls expandPortBinding' portName ident $ map redirect modportDecls
where where redirect (d, x, _) = (d, x, Just $ Ident x)
mapper (_, x, _) =
( portName ++ "_" ++ x
, Just $ Dot (Ident ident) x )
expandPortBinding _ other _ = [other] expandPortBinding _ other _ = [other]
expandPortBinding' :: Identifier -> Identifier -> [ModportDecl] -> [PortBinding]
expandPortBinding' portName instanceName modportDecls =
map mapper modportDecls
where
mapper (_, x, me) = (x', me')
where
x' = if null portName then "" else portName ++ '_' : x
me' = fmap (traverseNestedExprs prefixExpr) me
prefixExpr :: Expr -> Expr
prefixExpr (Ident x) = Ident (instanceName ++ '_' : x)
prefixExpr other = other
lookupModport :: Identifier -> Identifier -> Maybe [ModportDecl] lookupModport :: Identifier -> Identifier -> Maybe [ModportDecl]
lookupModport interfaceName = lookupModport interfaceName =
if Map.member interfaceName interfaces if Map.member interfaceName interfaces
...@@ -184,6 +205,22 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po ...@@ -184,6 +205,22 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
collectModport (Modport ident l) = tell $ Map.singleton ident l collectModport (Modport ident l) = tell $ Map.singleton ident l
collectModport _ = return () collectModport _ = return ()
impliedModport :: Identifier -> Maybe [ModportDecl]
impliedModport interfaceName =
if Map.member interfaceName interfaces
then Just modport
else Nothing
where
interfaceItems = snd $ interfaces Map.! interfaceName
modport = execWriter $
mapM (collectNestedModuleItemsM collectModportDecls) $
interfaceItems
collectModportDecls :: ModuleItem -> Writer [ModportDecl] ()
collectModportDecls (MIPackageItem (Decl (Variable d _ x _ _))) =
tell [(d', x, Just $ Ident x)]
where d' = if d == Local then Inout else d
collectModportDecls _ = return ()
convertExpr :: Instances -> Modports -> Expr -> Expr convertExpr :: Instances -> Modports -> Expr -> Expr
convertExpr its mps (orig @ (Dot (Ident x) y)) = convertExpr its mps (orig @ (Dot (Ident x) y)) =
if Map.member x mps || Map.member x its if Map.member x mps || Map.member x its
...@@ -263,7 +300,7 @@ lookupType items (Ident ident) = ...@@ -263,7 +300,7 @@ lookupType items (Ident ident) =
ts -> head ts ts -> head ts
where where
findType :: ModuleItem -> Maybe (Type, [Range]) findType :: ModuleItem -> Maybe (Type, [Range])
findType (MIPackageItem (Decl (Variable _ t x rs Nothing))) = findType (MIPackageItem (Decl (Variable _ t x rs _))) =
if x == ident then Just (t, rs) else Nothing if x == ident then Just (t, rs) else Nothing
findType _ = Nothing findType _ = Nothing
lookupType _ expr = lookupType _ expr =
......
...@@ -122,11 +122,15 @@ convertDescription ports orig = ...@@ -122,11 +122,15 @@ convertDescription ports orig =
-- rewrite variable declarations to have the correct type -- rewrite variable declarations to have the correct type
convertModuleItem (MIPackageItem (Decl (Variable dir (IntegerVector _ sg mr) ident a me))) = convertModuleItem (MIPackageItem (Decl (Variable dir (IntegerVector _ sg mr) ident a me))) =
MIPackageItem $ Decl $ Variable dir (t mr) ident a me MIPackageItem $ Decl $ Variable dir' (t mr) ident a me
where where
t = if Set.member ident fixedIdents t = if Set.member ident fixedIdents
then IntegerVector TReg sg then IntegerVector TReg sg
else Net (NetType TWire) sg else Net (NetType TWire) sg
dir' =
if dir == Inout && Set.member ident fixedIdents
then Output
else dir
convertModuleItem other = other convertModuleItem other = other
-- all other logics (i.e. inside of functions) become regs -- all other logics (i.e. inside of functions) become regs
convertDecl :: Decl -> Decl convertDecl :: Decl -> Decl
......
interface bundle;
logic [1:0] index;
logic clock;
logic [3:0] inp;
logic out;
endinterface
module rotator(bundle b);
initial b.index = 0;
always @(posedge b.clock)
b.index <= b.index + 1;
endmodule
module setter(bundle b);
initial b.inp = '1;
always @(posedge b.clock)
b.inp[b.index] <= b.out;
endmodule
module reducer(bundle b);
assign b.out = ^b.inp;
endmodule
module clocker(bundle b);
initial begin
b.clock <= 0;
forever
#5 b.clock <= ~b.clock;
end
endmodule
module top;
bundle b();
rotator rot(b);
setter set(b);
reducer red(b);
clocker clk(b);
initial begin
$monitor("%b %b %b %b", b.index, b.clock, b.inp, b.out);
#100;
$finish;
end
endmodule
module impl(b_index, b_clock, b_inp, b_out);
output reg [1:0] b_index;
output reg b_clock;
output reg [3:0] b_inp;
output wire b_out;
initial b_index = 0;
always @(posedge b_clock)
b_index <= b_index + 1;
initial b_inp = 4'b1111;
always @(posedge b_clock)
b_inp[b_index] <= b_out;
assign b_out = ^b_inp;
initial begin
b_clock <= 0;
forever
#5 b_clock <= ~b_clock;
end
endmodule
module top;
wire [1:0] b_index;
wire b_clock;
wire [3:0] b_inp;
wire b_out;
impl impl(b_index, b_clock, b_inp, b_out);
initial begin
$monitor("%b %b %b %b", b_index, b_clock, b_inp, b_out);
#100;
$finish;
end
endmodule
...@@ -24,7 +24,7 @@ module CacheWithInterface( ...@@ -24,7 +24,7 @@ module CacheWithInterface(
.response(myResponse) .response(myResponse)
); );
CacheSet set( CacheSetWrapper set(
.data(dataInterface.CacheSet), .data(dataInterface.CacheSet),
.clock, .clock,
.clear .clear
...@@ -35,6 +35,14 @@ module CacheWithInterface( ...@@ -35,6 +35,14 @@ module CacheWithInterface(
endmodule endmodule
// to test binding a modport to another modport
module CacheSetWrapper (
CacheSetInterface.CacheSet data,
input logic clock, clear
);
CacheSet set(data, clock, clear);
endmodule
module CacheSet ( module CacheSet (
CacheSetInterface.CacheSet data, CacheSetInterface.CacheSet data,
input logic clock, clear input logic clock, clear
......
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