mirror of https://github.com/zachjs/sv2v.git
support function calls within type parameters
This commit is contained in:
parent
5a8801a45f
commit
e6263d6caa
|
|
@ -289,19 +289,22 @@ typeIsUnresolved =
|
|||
collectUnresolvedExprM Dot {} = tell $ Any True
|
||||
collectUnresolvedExprM _ = return ()
|
||||
|
||||
prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet)
|
||||
prepareTypeIdents prefix =
|
||||
prepareTypeExprs :: Identifier -> Identifier -> Type -> (Type, (IdentSet, [Decl]))
|
||||
prepareTypeExprs instanceName paramName =
|
||||
runWriter . traverseNestedTypesM
|
||||
(traverseTypeExprsM $ traverseNestedExprsM prepareExprIdents)
|
||||
(traverseTypeExprsM $ traverseNestedExprsM prepareExpr)
|
||||
where
|
||||
prepareExprIdents :: Expr -> Writer IdentSet Expr
|
||||
prepareExprIdents (e @ (Ident "$unsigned")) = return e
|
||||
prepareExprIdents (e @ (Ident "$signed" )) = return e
|
||||
prepareExprIdents (e @ (Ident "$clog2" )) = return e
|
||||
prepareExprIdents (Ident x) = do
|
||||
tell $ Set.singleton x
|
||||
return $ Ident $ prefix ++ '_' : x
|
||||
prepareExprIdents other = return other
|
||||
prepareExpr :: Expr -> Writer (IdentSet, [Decl]) Expr
|
||||
prepareExpr (e @ Call{}) = do
|
||||
tell (Set.empty, [decl])
|
||||
prepareExpr $ Ident x
|
||||
where
|
||||
decl = Param Localparam (TypeOf e) x e
|
||||
x = instanceName ++ "_sv2v_pfunc_" ++ shortHash e
|
||||
prepareExpr (Ident x) = do
|
||||
tell (Set.singleton x, [])
|
||||
return $ Ident $ paramName ++ '_' : x
|
||||
prepareExpr other = return other
|
||||
|
||||
addedParamName :: Identifier -> Identifier -> Identifier
|
||||
addedParamName paramName var = paramName ++ '_' : var
|
||||
|
|
@ -328,7 +331,9 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
|
|||
else do
|
||||
tell $ Set.singleton (m, resolvedTypes)
|
||||
let m' = moduleInstanceName m resolvedTypes
|
||||
return $ Instance m' (additionalBindings ++ bindings') x r p
|
||||
return $ Generate $ map GenModuleItem $
|
||||
map (MIPackageItem . Decl) addedDecls ++
|
||||
[Instance m' (additionalBindings ++ bindings') x r p]
|
||||
where
|
||||
(paramNames, maybeTypeMap) = info Map.! m
|
||||
-- attach names to unnamed parameters
|
||||
|
|
@ -341,20 +346,23 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
|
|||
else bindings
|
||||
-- determine the types corresponding to each type parameter
|
||||
bindingsMap = Map.fromList bindingsNamed
|
||||
resolvedTypes = Map.mapWithKey resolveType maybeTypeMap
|
||||
resolveType :: Identifier -> Maybe Type -> (Type, IdentSet)
|
||||
resolvedTypesWithDecls = Map.mapWithKey resolveType maybeTypeMap
|
||||
resolvedTypes = Map.map (\(a, (b, _)) -> (a, b)) resolvedTypesWithDecls
|
||||
addedDecls = concatMap (snd . snd . snd) $
|
||||
Map.toList resolvedTypesWithDecls
|
||||
resolveType :: Identifier -> Maybe Type -> (Type, (IdentSet, [Decl]))
|
||||
resolveType paramName defaultType =
|
||||
case (Map.lookup paramName bindingsMap, defaultType) of
|
||||
(Nothing, Just t) -> (t, Set.empty)
|
||||
(Nothing, Just t) -> (t, (Set.empty, []))
|
||||
(Nothing, Nothing) ->
|
||||
error $ "instantiation " ++ show orig ++
|
||||
" is missing a type parameter: " ++ paramName
|
||||
(Just (Left t), _) -> prepareTypeIdents paramName t
|
||||
(Just (Left t), _) -> prepareTypeExprs x paramName t
|
||||
(Just (Right e), _) ->
|
||||
-- Some types are parsed as expressions because of the
|
||||
-- ambiguities of defined type names.
|
||||
case exprToType e of
|
||||
Just t -> prepareTypeIdents paramName t
|
||||
Just t -> prepareTypeExprs x paramName t
|
||||
Nothing ->
|
||||
error $ "instantiation " ++ show orig
|
||||
++ " has expr " ++ show e
|
||||
|
|
|
|||
|
|
@ -109,9 +109,20 @@ module f_2; o_nodef #(.T(logic [1:0]), .U(logic), .b(1), .a(0)) x(); endmodule
|
|||
module f_3; o_nodef #(0, logic [1:0], logic [2:0], 1) x(); endmodule
|
||||
module f_4; o_nodef #(.T(logic [1:0]), .U(logic), .b(0), .a(1)) x(); endmodule
|
||||
|
||||
function automatic integer square;
|
||||
input integer inp;
|
||||
return inp ** 2;
|
||||
endfunction
|
||||
|
||||
localparam type SomeT = logic [square(integer'(3)):0] ;
|
||||
localparam type OtherT = enum SomeT { A, B, C, D };
|
||||
|
||||
module p_1; p #(logic [1:0], logic [2:0]) x(); endmodule
|
||||
module p_2; p x(); endmodule
|
||||
module p_3; localparam W = 2; p #(logic [W:0], logic [W:0]) x(); endmodule
|
||||
module p_4; parameter W = 2; p #(logic [$clog2(W):0], logic [$clog2(W):0]) x(); endmodule
|
||||
module p_5; parameter W = 2; p #(logic [$unsigned(W):0], logic [$unsigned(W):0]) x(); endmodule
|
||||
module p_6; parameter W = 2; p #(logic [$signed(W):0], logic [$signed(W):0]) x(); endmodule
|
||||
module p_7; parameter W = 2; p #(logic [square(W):0], logic [square(W):0]) x(); endmodule
|
||||
module p_8; p #(OtherT) x(); endmodule
|
||||
module p_9; p #(SomeT, OtherT) x(); endmodule
|
||||
|
|
|
|||
|
|
@ -48,5 +48,11 @@ module top;
|
|||
$display("p 001 00000000000000000000000000000010 3");
|
||||
$display("p 000 00000000000000000000000000000001 3");
|
||||
$display("p 001 00000000000000000000000000000010 3");
|
||||
$display("p 00000 00000000000000000000000000000001 5");
|
||||
$display("p 00001 00000000000000000000000000000010 5");
|
||||
$display("p 0000000000 00000000000000000000000000000001 10");
|
||||
$display("p 1 00000000000000000000000000000010 1");
|
||||
$display("p 0000000000 00000000000000000000000000000001 10");
|
||||
$display("p 0000000001 00000000000000000000000000000010 10");
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue