mirror of https://github.com/zachjs/sv2v.git
typedef, multipack, and struct conversions scope substitutions
This commit is contained in:
parent
80d75d2ac0
commit
5080265e4d
|
|
@ -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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
, accessesToExpr
|
, accessesToExpr
|
||||||
, replaceInType
|
, replaceInType
|
||||||
, replaceInExpr
|
, replaceInExpr
|
||||||
|
, scopeExpr
|
||||||
|
, scopeType
|
||||||
, insertElem
|
, insertElem
|
||||||
, injectItem
|
, injectItem
|
||||||
, injectDecl
|
, injectDecl
|
||||||
|
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
>>= 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
|
||||||
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 =
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
`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
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
`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
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
`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
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
`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
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
`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
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
`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
|
||||||
Loading…
Reference in New Issue