Commit e6263d6c by Zachary Snow

support function calls within type parameters

parent 5a8801a4
......@@ -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
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