Commit 5080265e by Zachary Snow

typedef, multipack, and struct conversions scope substitutions

parent 80d75d2a
...@@ -76,20 +76,6 @@ traverseDeclM decl = do ...@@ -76,20 +76,6 @@ traverseDeclM decl = do
_ -> return () _ -> return ()
traverseDeclExprsM traverseExprM decl traverseDeclExprsM traverseExprM decl
-- rewrite an expression so that any constant identifiers it contains
-- unambiguously refer refer to currently visible constant declarations so it
-- can be substituted elsewhere
scopeExpr :: Expr -> ST Expr
scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr'
case details of
Just (accesses, _, _) -> return $ accessesToExpr accesses
_ -> return expr'
scopeType :: Type -> ST Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
-- substitute hierarchical references to constants -- substitute hierarchical references to constants
traverseExprM :: Expr -> ST Expr traverseExprM :: Expr -> ST Expr
traverseExprM (expr @ (Dot _ x)) = do traverseExprM (expr @ (Dot _ x)) = do
......
...@@ -54,7 +54,8 @@ traverseDeclM other = traverseDeclExprsM traverseExprM other ...@@ -54,7 +54,8 @@ traverseDeclM other = traverseDeclExprsM traverseExprM other
traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type
traverseTypeM t a ident = do traverseTypeM t a ident = do
insertElem ident (t, a) tScoped <- scopeType t
insertElem ident (tScoped, a)
t' <- case t of t' <- case t of
Struct pk fields rs -> do Struct pk fields rs -> do
fields' <- flattenFields fields fields' <- flattenFields fields
...@@ -83,7 +84,8 @@ traverseModuleItemM (Instance m p x rs l) = do ...@@ -83,7 +84,8 @@ traverseModuleItemM (Instance m p x rs l) = do
then return rs then return rs
else do else do
let t = Implicit Unspecified rs let t = Implicit Unspecified rs
insertElem x (t, []) tScoped <- scopeType t
insertElem x (tScoped, [])
let r1 : r2 : rest = rs let r1 : r2 : rest = rs
return $ (combineRanges r1 r2) : rest return $ (combineRanges r1 r2) : rest
traverseExprsM traverseExprM $ Instance m p x rs' l traverseExprsM traverseExprM $ Instance m p x rs' l
......
...@@ -34,6 +34,8 @@ module Convert.Scoper ...@@ -34,6 +34,8 @@ module Convert.Scoper
, accessesToExpr , accessesToExpr
, replaceInType , replaceInType
, replaceInExpr , replaceInExpr
, scopeExpr
, scopeType
, insertElem , insertElem
, injectItem , injectItem
, injectDecl , injectDecl
...@@ -178,6 +180,22 @@ replaceInExpr' replacements other = ...@@ -178,6 +180,22 @@ replaceInExpr' replacements other =
traverseExprTypes (replaceInType' replacements) $ traverseExprTypes (replaceInType' replacements) $
traverseSinglyNestedExprs (replaceInExpr' replacements) other traverseSinglyNestedExprs (replaceInExpr' replacements) other
-- rewrite an expression so that any identifiers it contains unambiguously refer
-- refer to currently visible declarations so it can be substituted elsewhere
scopeExpr :: Monad m => Expr -> ScoperT a m Expr
scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr'
case details of
Just (accesses, _, _) -> return $ accessesToExpr accesses
_ -> return expr'
scopeType :: Monad m => Type -> ScoperT a m Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
{-# INLINABLE scopeExpr #-}
{-# INLINABLE scopeType #-}
class ScopePath k where class ScopePath k where
toTiers :: Scopes a -> k -> [Tier] toTiers :: Scopes a -> k -> [Tier]
......
...@@ -111,11 +111,11 @@ traverseDeclM decl = do ...@@ -111,11 +111,11 @@ traverseDeclM decl = do
Variable d t x a e -> do Variable d t x a e -> do
let (tf, rs) = typeRanges t let (tf, rs) = typeRanges t
when (isRangeable t) $ when (isRangeable t) $
insertElem x (tf $ a ++ rs) scopeType (tf $ a ++ rs) >>= insertElem x
let e' = convertExpr t e let e' = convertExpr t e
return $ Variable d t x a e' return $ Variable d t x a e'
Param s t x e -> do Param s t x e -> do
insertElem x t scopeType t >>= insertElem x
let e' = convertExpr t e let e' = convertExpr t e
return $ Param s t x e' return $ Param s t x e'
ParamType{} -> return decl ParamType{} -> return decl
......
...@@ -74,19 +74,6 @@ insertType ident typ = do ...@@ -74,19 +74,6 @@ insertType ident typ = do
typ' <- scopeType typ typ' <- scopeType typ
insertElem ident typ' insertElem ident typ'
-- rewrite an expression so that any identifiers it contains unambiguously refer
-- refer to currently visible declarations so it can be substituted elsewhere
scopeExpr :: Expr -> ST Expr
scopeExpr expr = do
expr' <- traverseSinglyNestedExprsM scopeExpr expr
>>= traverseExprTypesM scopeType
details <- lookupElemM expr'
case details of
Just (accesses, _, _) -> return $ accessesToExpr accesses
_ -> return expr'
scopeType :: Type -> ST Type
scopeType = traverseNestedTypesM $ traverseTypeExprsM scopeExpr
-- convert TypeOf in a ModuleItem -- convert TypeOf in a ModuleItem
traverseModuleItemM :: ModuleItem -> ST ModuleItem traverseModuleItemM :: ModuleItem -> ST ModuleItem
traverseModuleItemM = traverseModuleItemM =
......
...@@ -24,11 +24,13 @@ traverseTypeOrExprM (Left (TypeOf (Ident x))) = do ...@@ -24,11 +24,13 @@ traverseTypeOrExprM (Left (TypeOf (Ident x))) = do
details <- lookupElemM x details <- lookupElemM x
return $ case details of return $ case details of
Nothing -> Left $ TypeOf $ Ident x Nothing -> Left $ TypeOf $ Ident x
Just (_, _, UnknownType) -> Left $ TypeOf $ Ident x
Just (_, _, typ) -> Left typ Just (_, _, typ) -> Left typ
traverseTypeOrExprM (Right (Ident x)) = do traverseTypeOrExprM (Right (Ident x)) = do
details <- lookupElemM x details <- lookupElemM x
return $ case details of return $ case details of
Nothing -> Right $ Ident x Nothing -> Right $ Ident x
Just (_, _, UnknownType) -> Right $ Ident x
Just (_, _, typ) -> Left typ Just (_, _, typ) -> Left typ
traverseTypeOrExprM other = return other traverseTypeOrExprM other = return other
...@@ -70,9 +72,10 @@ traverseDeclM decl = do ...@@ -70,9 +72,10 @@ traverseDeclM decl = do
>>= traverseDeclTypesM traverseTypeM >>= traverseDeclTypesM traverseTypeM
case decl' of case decl' of
Variable{} -> return decl' Variable{} -> return decl'
Param{} -> return decl' Param _ _ x _ ->
insertElem x UnknownType >> return decl'
ParamType Localparam x t -> do ParamType Localparam x t -> do
traverseTypeM t >>= insertElem x traverseTypeM t >>= scopeType >>= insertElem x
return $ CommentDecl $ "removed localparam type " ++ x return $ CommentDecl $ "removed localparam type " ++ x
ParamType{} -> return decl' ParamType{} -> return decl'
CommentDecl{} -> return decl' CommentDecl{} -> return decl'
...@@ -86,6 +89,7 @@ traverseTypeM (Alias st rs1) = do ...@@ -86,6 +89,7 @@ traverseTypeM (Alias st rs1) = do
rs1' <- mapM traverseRangeM rs1 rs1' <- mapM traverseRangeM rs1
return $ case details of return $ case details of
Nothing -> Alias st rs1' Nothing -> Alias st rs1'
Just (_, _, UnknownType) -> Alias st rs1'
Just (_, _, typ) -> tf $ rs1' ++ rs2 Just (_, _, typ) -> tf $ rs1' ++ rs2
where (tf, rs2) = typeRanges typ where (tf, rs2) = typeRanges typ
traverseTypeM other = traverseTypeM other =
......
`define DUMP(id) #1 $display(`"id: %b`", arr[0]);
module top;
parameter A = 5;
reg [0:0][A-1:0] arr;
initial arr = 1'sb1;
initial `DUMP(0)
if (1) begin : blk
localparam A = 10;
initial `DUMP(1)
end
initial begin
localparam A = 10;
`DUMP(2)
end
endmodule
`define DUMP(id) #1 $display(`"id: %b`", arr);
module top;
parameter A = 5;
reg [A-1:0] arr;
initial arr = 1'sb1;
initial `DUMP(0)
if (1) begin : blk
localparam A = 10;
initial `DUMP(1)
end
initial begin : foo
localparam A = 10;
`DUMP(2)
end
endmodule
`define DUMP(id) \
begin \
x = 1'sb1; \
$display(`"id: access a=%b b=%b`", x.a, x.b); \
x = '{ a: 1'sb1, b: 1'sbz }; \
$display(`"id: literal x=%b`", x); \
end
module top;
parameter A = 2;
parameter B = 3;
struct packed {
logic [A-1:0] a;
logic [B-1:0] b;
} x;
initial `DUMP(0)
if (1) begin : blk
localparam A = 10;
localparam B = 11;
initial `DUMP(1)
end
initial begin
localparam A = 10;
localparam B = 11;
`DUMP(2)
end
endmodule
`define DUMP(id) \
begin \
x = 1'sb1; \
$display(`"id: access a=%b b=%b`", x[0+:A], x[A+:B]); \
x = { {A {1'sb1}}, {B {1'sbz}} }; \
$display(`"id: literal x=%b`", x); \
end
module top;
parameter A = 2;
parameter B = 3;
reg [A+B-1:0] x;
initial `DUMP(0)
if (1) begin : blk
localparam _A = 10;
localparam _B = 11;
initial `DUMP(1)
end
initial begin : foo
localparam _A = 10;
localparam _B = 11;
`DUMP(2)
end
endmodule
`define DUMP(id) \
$display(`"id: $bits(T) = %0d, $left(T) = %0d, $right(T) = %0d`", \
$bits(T), $left(T), $right(T))
module top;
parameter A = 1;
parameter B = 2;
parameter ONE = 1;
typedef logic [A:B] T;
initial `DUMP(X1);
if (1) begin : blk
localparam A = ONE * 3;
localparam B = ONE * 4;
initial `DUMP(X2);
if (1) begin : nest
typedef logic [A:B] T;
initial `DUMP(Y0);
end
end
initial begin
localparam A = ONE * 5;
localparam B = ONE * 6;
`DUMP(X3);
begin
localparam type T = logic [A:B];
`DUMP(Z0);
end
end
endmodule
`define DUMP(id, A, B) \
$display(`"id: $bits(T) = %0d, $left(T) = %0d, $right(T) = %0d`", \
A >= B ? A - B + 1: B - A + 1, A, B)
module top;
parameter A = 1;
parameter B = 2;
parameter ONE = 1;
initial `DUMP(X1, A, B);
if (1) begin : blk
localparam _A = ONE * 3;
localparam _B = ONE * 4;
initial `DUMP(X2, A, B);
if (1) begin : nest
initial `DUMP(Y0, _A, _B);
end
end
initial begin : foo
localparam _A = ONE * 5;
localparam _B = ONE * 6;
`DUMP(X3, A, B);
`DUMP(Z0, _A, _B);
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