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) [] ->
|
||||
tell (Map.empty, Map.singleton ident modportDecls)
|
||||
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 ()
|
||||
collectInterface (Instance part _ ident Nothing _) =
|
||||
if Map.member part interfaces
|
||||
|
|
@ -81,7 +86,7 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
|||
collectInterface _ = return ()
|
||||
|
||||
mapInterface :: ModuleItem -> ModuleItem
|
||||
mapInterface (orig @ (MIPackageItem (Decl (Variable Local t ident _ _)))) =
|
||||
mapInterface (orig @ (MIPackageItem (Decl (Variable _ t ident _ _)))) =
|
||||
-- expand instantiation of a modport
|
||||
case Map.lookup ident modports of
|
||||
Just modportDecls -> Generate $
|
||||
|
|
@ -89,7 +94,10 @@ convertDescription interfaces modules (Part attrs extern Module lifetime name po
|
|||
modportDecls
|
||||
Nothing -> orig
|
||||
where
|
||||
InterfaceT interfaceName (Just _) [] = t
|
||||
interfaceName = case t of
|
||||
InterfaceT x (Just _) [] -> x
|
||||
Alias Nothing x [] -> x
|
||||
_ -> error $ "unexpected modport type " ++ show t
|
||||
interfaceItems =
|
||||
case Map.lookup interfaceName interfaces of
|
||||
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))) _ =
|
||||
-- expand instance modport bound to a modport
|
||||
if Map.member instanceName instances && modportDecls /= Nothing
|
||||
then map mapper $ fromJust modportDecls
|
||||
then expandPortBinding' portName instanceName $ fromJust modportDecls
|
||||
else [origBinding]
|
||||
where
|
||||
interfaceName = instances Map.! instanceName
|
||||
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 =
|
||||
case (instances Map.!? ident, modports Map.!? ident) of
|
||||
(Nothing, Nothing) -> [origBinding]
|
||||
(Just _, _) ->
|
||||
(Just interfaceName, _) ->
|
||||
-- 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
|
||||
(portName', InterfaceT _ (Just modportName) []) =
|
||||
case (portName, Map.lookup moduleName modules) of
|
||||
("", 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 "
|
||||
++ show portName ++ " in module "
|
||||
++ show moduleName
|
||||
Just t -> (portName, t)
|
||||
(_, Nothing) -> error $ "could not find module "
|
||||
Just decls = Map.lookup moduleName modules
|
||||
portType =
|
||||
if null portName
|
||||
then if idx < length decls
|
||||
then snd $ decls !! idx
|
||||
else error $ "could not infer port "
|
||||
++ show origBinding ++ " in module "
|
||||
++ show moduleName
|
||||
newExpr = Dot (Ident ident) modportName
|
||||
(_, Just decls) ->
|
||||
else case lookup portName decls of
|
||||
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
|
||||
map mapper decls
|
||||
where
|
||||
mapper (_, x, _) =
|
||||
( portName ++ "_" ++ x
|
||||
, Just $ Dot (Ident ident) x )
|
||||
expandPortBinding' portName ident $ map redirect modportDecls
|
||||
where redirect (d, x, _) = (d, x, Just $ Ident x)
|
||||
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 interfaceName =
|
||||
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 _ = 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 its mps (orig @ (Dot (Ident x) y)) =
|
||||
if Map.member x mps || Map.member x its
|
||||
|
|
@ -263,7 +300,7 @@ lookupType items (Ident ident) =
|
|||
ts -> head ts
|
||||
where
|
||||
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
|
||||
findType _ = Nothing
|
||||
lookupType _ expr =
|
||||
|
|
|
|||
|
|
@ -122,11 +122,15 @@ convertDescription ports orig =
|
|||
|
||||
-- rewrite variable declarations to have the correct type
|
||||
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
|
||||
t = if Set.member ident fixedIdents
|
||||
then IntegerVector TReg sg
|
||||
else Net (NetType TWire) sg
|
||||
dir' =
|
||||
if dir == Inout && Set.member ident fixedIdents
|
||||
then Output
|
||||
else dir
|
||||
convertModuleItem other = other
|
||||
-- all other logics (i.e. inside of functions) become regs
|
||||
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)
|
||||
);
|
||||
|
||||
CacheSet set(
|
||||
CacheSetWrapper set(
|
||||
.data(dataInterface.CacheSet),
|
||||
.clock,
|
||||
.clear
|
||||
|
|
@ -35,6 +35,14 @@ module CacheWithInterface(
|
|||
|
||||
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 (
|
||||
CacheSetInterface.CacheSet data,
|
||||
input logic clock, clear
|
||||
|
|
|
|||
Loading…
Reference in New Issue