Commit e6263d6c by Zachary Snow

support function calls within type parameters

parent 5a8801a4
...@@ -289,19 +289,22 @@ typeIsUnresolved = ...@@ -289,19 +289,22 @@ typeIsUnresolved =
collectUnresolvedExprM Dot {} = tell $ Any True collectUnresolvedExprM Dot {} = tell $ Any True
collectUnresolvedExprM _ = return () collectUnresolvedExprM _ = return ()
prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet) prepareTypeExprs :: Identifier -> Identifier -> Type -> (Type, (IdentSet, [Decl]))
prepareTypeIdents prefix = prepareTypeExprs instanceName paramName =
runWriter . traverseNestedTypesM runWriter . traverseNestedTypesM
(traverseTypeExprsM $ traverseNestedExprsM prepareExprIdents) (traverseTypeExprsM $ traverseNestedExprsM prepareExpr)
where where
prepareExprIdents :: Expr -> Writer IdentSet Expr prepareExpr :: Expr -> Writer (IdentSet, [Decl]) Expr
prepareExprIdents (e @ (Ident "$unsigned")) = return e prepareExpr (e @ Call{}) = do
prepareExprIdents (e @ (Ident "$signed" )) = return e tell (Set.empty, [decl])
prepareExprIdents (e @ (Ident "$clog2" )) = return e prepareExpr $ Ident x
prepareExprIdents (Ident x) = do where
tell $ Set.singleton x decl = Param Localparam (TypeOf e) x e
return $ Ident $ prefix ++ '_' : x x = instanceName ++ "_sv2v_pfunc_" ++ shortHash e
prepareExprIdents other = return other prepareExpr (Ident x) = do
tell (Set.singleton x, [])
return $ Ident $ paramName ++ '_' : x
prepareExpr other = return other
addedParamName :: Identifier -> Identifier -> Identifier addedParamName :: Identifier -> Identifier -> Identifier
addedParamName paramName var = paramName ++ '_' : var addedParamName paramName var = paramName ++ '_' : var
...@@ -328,7 +331,9 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) = ...@@ -328,7 +331,9 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
else do else do
tell $ Set.singleton (m, resolvedTypes) tell $ Set.singleton (m, resolvedTypes)
let m' = moduleInstanceName 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 where
(paramNames, maybeTypeMap) = info Map.! m (paramNames, maybeTypeMap) = info Map.! m
-- attach names to unnamed parameters -- attach names to unnamed parameters
...@@ -341,20 +346,23 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) = ...@@ -341,20 +346,23 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
else bindings else bindings
-- determine the types corresponding to each type parameter -- determine the types corresponding to each type parameter
bindingsMap = Map.fromList bindingsNamed bindingsMap = Map.fromList bindingsNamed
resolvedTypes = Map.mapWithKey resolveType maybeTypeMap resolvedTypesWithDecls = Map.mapWithKey resolveType maybeTypeMap
resolveType :: Identifier -> Maybe Type -> (Type, IdentSet) 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 = resolveType paramName defaultType =
case (Map.lookup paramName bindingsMap, defaultType) of case (Map.lookup paramName bindingsMap, defaultType) of
(Nothing, Just t) -> (t, Set.empty) (Nothing, Just t) -> (t, (Set.empty, []))
(Nothing, Nothing) -> (Nothing, Nothing) ->
error $ "instantiation " ++ show orig ++ error $ "instantiation " ++ show orig ++
" is missing a type parameter: " ++ paramName " is missing a type parameter: " ++ paramName
(Just (Left t), _) -> prepareTypeIdents paramName t (Just (Left t), _) -> prepareTypeExprs x paramName t
(Just (Right e), _) -> (Just (Right e), _) ->
-- Some types are parsed as expressions because of the -- Some types are parsed as expressions because of the
-- ambiguities of defined type names. -- ambiguities of defined type names.
case exprToType e of case exprToType e of
Just t -> prepareTypeIdents paramName t Just t -> prepareTypeExprs x paramName t
Nothing -> Nothing ->
error $ "instantiation " ++ show orig error $ "instantiation " ++ show orig
++ " has expr " ++ show e ++ " 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 ...@@ -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_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 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_1; p #(logic [1:0], logic [2:0]) x(); endmodule
module p_2; p 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_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_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_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_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; ...@@ -48,5 +48,11 @@ module top;
$display("p 001 00000000000000000000000000000010 3"); $display("p 001 00000000000000000000000000000010 3");
$display("p 000 00000000000000000000000000000001 3"); $display("p 000 00000000000000000000000000000001 3");
$display("p 001 00000000000000000000000000000010 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 end
endmodule 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