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 ()
|
||||
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
|
||||
traverseExprM :: Expr -> ST Expr
|
||||
traverseExprM (expr @ (Dot _ x)) = do
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ traverseDeclM other = traverseDeclExprsM traverseExprM other
|
|||
|
||||
traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type
|
||||
traverseTypeM t a ident = do
|
||||
insertElem ident (t, a)
|
||||
tScoped <- scopeType t
|
||||
insertElem ident (tScoped, a)
|
||||
t' <- case t of
|
||||
Struct pk fields rs -> do
|
||||
fields' <- flattenFields fields
|
||||
|
|
@ -83,7 +84,8 @@ traverseModuleItemM (Instance m p x rs l) = do
|
|||
then return rs
|
||||
else do
|
||||
let t = Implicit Unspecified rs
|
||||
insertElem x (t, [])
|
||||
tScoped <- scopeType t
|
||||
insertElem x (tScoped, [])
|
||||
let r1 : r2 : rest = rs
|
||||
return $ (combineRanges r1 r2) : rest
|
||||
traverseExprsM traverseExprM $ Instance m p x rs' l
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ module Convert.Scoper
|
|||
, accessesToExpr
|
||||
, replaceInType
|
||||
, replaceInExpr
|
||||
, scopeExpr
|
||||
, scopeType
|
||||
, insertElem
|
||||
, injectItem
|
||||
, injectDecl
|
||||
|
|
@ -178,6 +180,22 @@ replaceInExpr' replacements other =
|
|||
traverseExprTypes (replaceInType' replacements) $
|
||||
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
|
||||
toTiers :: Scopes a -> k -> [Tier]
|
||||
|
||||
|
|
|
|||
|
|
@ -111,11 +111,11 @@ traverseDeclM decl = do
|
|||
Variable d t x a e -> do
|
||||
let (tf, rs) = typeRanges t
|
||||
when (isRangeable t) $
|
||||
insertElem x (tf $ a ++ rs)
|
||||
scopeType (tf $ a ++ rs) >>= insertElem x
|
||||
let e' = convertExpr t e
|
||||
return $ Variable d t x a e'
|
||||
Param s t x e -> do
|
||||
insertElem x t
|
||||
scopeType t >>= insertElem x
|
||||
let e' = convertExpr t e
|
||||
return $ Param s t x e'
|
||||
ParamType{} -> return decl
|
||||
|
|
|
|||
|
|
@ -74,19 +74,6 @@ insertType ident typ = do
|
|||
typ' <- scopeType 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
|
||||
traverseModuleItemM :: ModuleItem -> ST ModuleItem
|
||||
traverseModuleItemM =
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ traverseTypeOrExprM (Left (TypeOf (Ident x))) = do
|
|||
details <- lookupElemM x
|
||||
return $ case details of
|
||||
Nothing -> Left $ TypeOf $ Ident x
|
||||
Just (_, _, UnknownType) -> Left $ TypeOf $ Ident x
|
||||
Just (_, _, typ) -> Left typ
|
||||
traverseTypeOrExprM (Right (Ident x)) = do
|
||||
details <- lookupElemM x
|
||||
return $ case details of
|
||||
Nothing -> Right $ Ident x
|
||||
Just (_, _, UnknownType) -> Right $ Ident x
|
||||
Just (_, _, typ) -> Left typ
|
||||
traverseTypeOrExprM other = return other
|
||||
|
||||
|
|
@ -70,9 +72,10 @@ traverseDeclM decl = do
|
|||
>>= traverseDeclTypesM traverseTypeM
|
||||
case decl' of
|
||||
Variable{} -> return decl'
|
||||
Param{} -> return decl'
|
||||
Param _ _ x _ ->
|
||||
insertElem x UnknownType >> return decl'
|
||||
ParamType Localparam x t -> do
|
||||
traverseTypeM t >>= insertElem x
|
||||
traverseTypeM t >>= scopeType >>= insertElem x
|
||||
return $ CommentDecl $ "removed localparam type " ++ x
|
||||
ParamType{} -> return decl'
|
||||
CommentDecl{} -> return decl'
|
||||
|
|
@ -86,6 +89,7 @@ traverseTypeM (Alias st rs1) = do
|
|||
rs1' <- mapM traverseRangeM rs1
|
||||
return $ case details of
|
||||
Nothing -> Alias st rs1'
|
||||
Just (_, _, UnknownType) -> Alias st rs1'
|
||||
Just (_, _, typ) -> tf $ rs1' ++ rs2
|
||||
where (tf, rs2) = typeRanges typ
|
||||
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