Commit f84dd701 by Zachary Snow

fix handling of hierarchical references with type parameters

- wait for hierarchical references within an instance's type parameters
  to be resolved before instantiating the module
- references to a module's top-level named scopes are now correctly
  renamed when creating new type parameter modules
parent 82228f67
...@@ -149,13 +149,25 @@ convert files = ...@@ -149,13 +149,25 @@ convert files =
where where
Part attrs extern kw ml m p items = part Part attrs extern kw ml m p items = part
m' = moduleInstanceName m typeMap m' = moduleInstanceName m typeMap
items' = map (traverseDecls rewriteDecl) items items' = map (traverseExprs rewriteExpr) $
map (traverseDecls rewriteDecl) items
rewriteDecl :: Decl -> Decl rewriteDecl :: Decl -> Decl
rewriteDecl (ParamType Parameter x _) = rewriteDecl (ParamType Parameter x _) =
ParamType Localparam x (fst $ typeMap Map.! x) ParamType Localparam x (fst $ typeMap Map.! x)
rewriteDecl other = other rewriteDecl other = other
additionalParamItems = concatMap makeAddedParams $ additionalParamItems = concatMap makeAddedParams $
Map.toList $ Map.map snd typeMap Map.toList $ Map.map snd typeMap
rewriteExpr :: Expr -> Expr
rewriteExpr (orig @ (Dot (Ident x) y)) =
if x == m
then Dot (Ident m') y
else orig
rewriteExpr other =
traverseExprTypes rewriteType $
traverseSinglyNestedExprs rewriteExpr other
rewriteType :: Type -> Type
rewriteType =
traverseNestedTypes $ traverseTypeExprs rewriteExpr
makeAddedParams :: (Identifier, IdentSet) -> [ModuleItem] makeAddedParams :: (Identifier, IdentSet) -> [ModuleItem]
makeAddedParams (paramName, identSet) = makeAddedParams (paramName, identSet) =
...@@ -235,7 +247,7 @@ exprToType _ = Nothing ...@@ -235,7 +247,7 @@ exprToType _ = Nothing
-- checks where a type is sufficiently resolved to be substituted -- checks where a type is sufficiently resolved to be substituted
isSimpleType :: Type -> Bool isSimpleType :: Type -> Bool
isSimpleType typ = isSimpleType typ =
(not $ typeHasQueries typ) && (not $ typeIsUnresolved typ) &&
case typ of case typ of
IntegerVector{} -> True IntegerVector{} -> True
IntegerAtom {} -> True IntegerAtom {} -> True
...@@ -246,17 +258,19 @@ isSimpleType typ = ...@@ -246,17 +258,19 @@ isSimpleType typ =
Union _ fields _ -> all (isSimpleType . fst) fields Union _ fields _ -> all (isSimpleType . fst) fields
_ -> False _ -> False
-- returns whether a top-level type contains any dimension queries -- returns whether a top-level type contains any dimension queries or
typeHasQueries :: Type -> Bool -- hierarchical references
typeHasQueries = typeIsUnresolved :: Type -> Bool
not . null . execWriter . collectTypeExprsM typeIsUnresolved =
getAny . execWriter . collectTypeExprsM
(collectNestedExprsM collectUnresolvedExprM) (collectNestedExprsM collectUnresolvedExprM)
where where
collectUnresolvedExprM :: Expr -> Writer [Expr] () collectUnresolvedExprM :: Expr -> Writer Any ()
collectUnresolvedExprM (expr @ PSIdent{}) = tell [expr] collectUnresolvedExprM PSIdent{} = tell $ Any True
collectUnresolvedExprM (expr @ CSIdent{}) = tell [expr] collectUnresolvedExprM CSIdent{} = tell $ Any True
collectUnresolvedExprM (expr @ DimsFn{}) = tell [expr] collectUnresolvedExprM DimsFn {} = tell $ Any True
collectUnresolvedExprM (expr @ DimFn {}) = tell [expr] collectUnresolvedExprM DimFn {} = tell $ Any True
collectUnresolvedExprM Dot {} = tell $ Any True
collectUnresolvedExprM _ = return () collectUnresolvedExprM _ = return ()
prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet) prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet)
......
module Module;
parameter int S;
parameter type T;
T x = '1;
initial $display("Module %0d: %b, %0d", S, Module.x, $bits(T));
endmodule
module top;
parameter ONE = 1;
logic [ONE*7:ONE*0] x;
if (1) begin : blk
localparam W = ONE * 3;
typedef logic [W-1:$bits(x)] T;
T x;
end
Module #(1, logic [$bits(x)-1:0]) m1();
Module #(2, logic [$bits(blk.x)-1:0]) m2();
Module #(3, logic [top.blk.W-1:0]) m3();
endmodule
module Module;
parameter S = 0;
parameter T = 0;
wire [T-1:0] x = 1'sb1;
initial $display("Module %0d: %b, %0d", S, Module.x, T);
endmodule
module top;
parameter ONE = 1;
wire [ONE*7:ONE*0] x;
if (1) begin : blk
localparam W = ONE * 3;
wire [W-1:$bits(x)] x;
end
Module #(1, 8) m1();
Module #(2, 7) m2();
Module #(3, 3) m3();
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