mirror of https://github.com/zachjs/sv2v.git
support simple bundle interfaces
- fix position modport-to-modport bindings - inout logics converted to regs become outputs
This commit is contained in:
parent
589261a91b
commit
b6f4f690e7
|
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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
|
|
||||||
(_, 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
|
else case lookup portName decls of
|
||||||
(_, Just decls) ->
|
Nothing -> error $ "could not find port "
|
||||||
|
++ show portName ++ " in module "
|
||||||
|
++ show moduleName
|
||||||
|
Just t -> t
|
||||||
|
modportDecls =
|
||||||
|
case portType of
|
||||||
|
InterfaceT _ (Just modportName) [] ->
|
||||||
|
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
|
||||||
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) =
|
||||||
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 =
|
||||||
|
|
||||||
-- 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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
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(
|
||||||
.response(myResponse)
|
.response(myResponse)
|
||||||
);
|
);
|
||||||
|
|
||||||
CacheSet set(
|
CacheSetWrapper set(
|
||||||
.data(dataInterface.CacheSet),
|
.data(dataInterface.CacheSet),
|
||||||
.clock,
|
.clock,
|
||||||
.clear
|
.clear
|
||||||
|
|
@ -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
|
||||||
|
|
@ -46,4 +54,4 @@ module CacheSet (
|
||||||
else
|
else
|
||||||
data.response <= ~data.request;
|
data.response <= ~data.request;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue