mirror of https://github.com/zachjs/sv2v.git
better support for struct array parameters
This includes support for - parsing dimensioned alias parameters - flattening non-var decls with multiple packed dimensions - converting arrays of structs - inferring struct types for decls with initializations
This commit is contained in:
parent
e82537fa97
commit
4fd7b6c2f2
|
|
@ -41,19 +41,29 @@ convertDescription =
|
||||||
|
|
||||||
-- collects and converts multi-dimensional packed-array declarations
|
-- collects and converts multi-dimensional packed-array declarations
|
||||||
traverseDeclM :: Decl -> State Info Decl
|
traverseDeclM :: Decl -> State Info Decl
|
||||||
traverseDeclM (origDecl @ (Variable dir t ident a me)) = do
|
traverseDeclM (Variable dir t ident a me) = do
|
||||||
|
t' <- traverseDeclM' t ident
|
||||||
|
return $ Variable dir t' ident a me
|
||||||
|
traverseDeclM (Parameter t ident e) = do
|
||||||
|
t' <- traverseDeclM' t ident
|
||||||
|
return $ Parameter t' ident e
|
||||||
|
traverseDeclM (Localparam t ident e) = do
|
||||||
|
t' <- traverseDeclM' t ident
|
||||||
|
return $ Localparam t' ident e
|
||||||
|
|
||||||
|
traverseDeclM' :: Type -> Identifier -> State Info Type
|
||||||
|
traverseDeclM' t ident = do
|
||||||
Info typeDims <- get
|
Info typeDims <- get
|
||||||
let (tf, rs) = typeRanges t
|
let (tf, rs) = typeRanges t
|
||||||
if length rs <= 1
|
if length rs <= 1
|
||||||
then do
|
then do
|
||||||
put $ Info $ Map.delete ident typeDims
|
put $ Info $ Map.delete ident typeDims
|
||||||
return origDecl
|
return t
|
||||||
else do
|
else do
|
||||||
put $ Info $ Map.insert ident rs typeDims
|
put $ Info $ Map.insert ident rs typeDims
|
||||||
let r1 : r2 : rest = rs
|
let r1 : r2 : rest = rs
|
||||||
let rs' = (combineRanges r1 r2) : rest
|
let rs' = (combineRanges r1 r2) : rest
|
||||||
return $ Variable dir (tf rs') ident a me
|
return $ tf rs'
|
||||||
traverseDeclM other = return other
|
|
||||||
|
|
||||||
-- combines two ranges into one flattened range
|
-- combines two ranges into one flattened range
|
||||||
combineRanges :: Range -> Range -> Range
|
combineRanges :: Range -> Range -> Range
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ convertDescription (description @ (Part _ _ _ _ _ _)) =
|
||||||
Part extern kw lifetime name ports (items ++ funcs)
|
Part extern kw lifetime name ports (items ++ funcs)
|
||||||
where
|
where
|
||||||
description' @ (Part extern kw lifetime name ports items) =
|
description' @ (Part extern kw lifetime name ports items) =
|
||||||
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
|
scopedConversion (traverseDeclM structs) traverseModuleItemM
|
||||||
tfArgTypes description
|
traverseStmtM tfArgTypes description
|
||||||
-- collect information about this description
|
-- collect information about this description
|
||||||
structs = execWriter $ collectModuleItemsM
|
structs = execWriter $ collectModuleItemsM
|
||||||
(collectTypesM collectStructM) description
|
(collectTypesM collectStructM) description
|
||||||
|
|
@ -149,15 +149,31 @@ collectTFArgsM (MIPackageItem item) = do
|
||||||
collectTFArgsM _ = return ()
|
collectTFArgsM _ = return ()
|
||||||
|
|
||||||
-- write down the types of declarations
|
-- write down the types of declarations
|
||||||
traverseDeclM :: Decl -> State Types Decl
|
traverseDeclM :: Structs -> Decl -> State Types Decl
|
||||||
traverseDeclM origDecl = do
|
traverseDeclM structs origDecl = do
|
||||||
case origDecl of
|
case origDecl of
|
||||||
Variable _ t x a _ -> do
|
Variable d t x a me -> do
|
||||||
let (tf, rs) = typeRanges t
|
let (tf, rs) = typeRanges t
|
||||||
modify $ Map.insert x (tf $ a ++ rs)
|
modify $ Map.insert x (tf $ a ++ rs)
|
||||||
Parameter t x _ -> modify $ Map.insert x t
|
case me of
|
||||||
Localparam t x _ -> modify $ Map.insert x t
|
Nothing -> return origDecl
|
||||||
return origDecl
|
Just e -> do
|
||||||
|
e' <- convertDeclExpr x e
|
||||||
|
return $ Variable d t x a (Just e')
|
||||||
|
Parameter t x e -> do
|
||||||
|
modify $ Map.insert x t
|
||||||
|
e' <- convertDeclExpr x e
|
||||||
|
return $ Parameter t x e'
|
||||||
|
Localparam t x e -> do
|
||||||
|
modify $ Map.insert x t
|
||||||
|
e' <- convertDeclExpr x e
|
||||||
|
return $ Localparam t x e'
|
||||||
|
where
|
||||||
|
convertDeclExpr :: Identifier -> Expr -> State Types Expr
|
||||||
|
convertDeclExpr x e = do
|
||||||
|
types <- get
|
||||||
|
let (LHSIdent _, e') = convertAsgn structs types (LHSIdent x, e)
|
||||||
|
return e'
|
||||||
|
|
||||||
-- produces a function which packs the components of a struct literal
|
-- produces a function which packs the components of a struct literal
|
||||||
packerFn :: TypeFunc -> ModuleItem
|
packerFn :: TypeFunc -> ModuleItem
|
||||||
|
|
@ -262,6 +278,8 @@ convertAsgn structs types (lhs, expr) =
|
||||||
convertExpr (IntegerVector t sg (r:rs)) (Pattern [(Just "default", e)]) =
|
convertExpr (IntegerVector t sg (r:rs)) (Pattern [(Just "default", e)]) =
|
||||||
Repeat (rangeSize r) [e']
|
Repeat (rangeSize r) [e']
|
||||||
where e' = convertExpr (IntegerVector t sg rs) e
|
where e' = convertExpr (IntegerVector t sg rs) e
|
||||||
|
convertExpr (Struct (Packed sg) fields (_:rs)) (Concat exprs) =
|
||||||
|
Concat $ map (convertExpr (Struct (Packed sg) fields rs)) exprs
|
||||||
convertExpr (Struct (Packed sg) fields (_:rs)) (Bit e _) =
|
convertExpr (Struct (Packed sg) fields (_:rs)) (Bit e _) =
|
||||||
convertExpr (Struct (Packed sg) fields rs) e
|
convertExpr (Struct (Packed sg) fields rs) e
|
||||||
convertExpr (Struct (Packed sg) fields rs) (Pattern [(Just "default", e)]) =
|
convertExpr (Struct (Packed sg) fields rs) (Pattern [(Just "default", e)]) =
|
||||||
|
|
|
||||||
|
|
@ -727,10 +727,10 @@ DeclOrStmt :: { ([Decl], [Stmt]) }
|
||||||
| ParameterDecl(";") { ($1, []) }
|
| ParameterDecl(";") { ($1, []) }
|
||||||
|
|
||||||
ParameterDecl(delim) :: { [Decl] }
|
ParameterDecl(delim) :: { [Decl] }
|
||||||
: ParameterDeclKW DeclAsgns delim { map (uncurry $ $1 (Implicit Unspecified [])) $2 }
|
: ParameterDeclKW DeclAsgns delim { map (uncurry $ $1 (Implicit Unspecified [])) $2 }
|
||||||
| ParameterDeclKW ParamType DeclAsgns delim { map (uncurry $ $1 ($2 )) $3 }
|
| ParameterDeclKW ParamType DeclAsgns delim { map (uncurry $ $1 ($2 )) $3 }
|
||||||
| ParameterDeclKW Identifier DeclAsgns delim { map (uncurry $ $1 (Alias (Nothing) $2 [])) $3 }
|
| ParameterDeclKW Identifier Dimensions DeclAsgns delim { map (uncurry $ $1 (Alias (Nothing) $2 $3)) $4 }
|
||||||
| ParameterDeclKW Identifier "::" Identifier DeclAsgns delim { map (uncurry $ $1 (Alias (Just $2) $4 [])) $5 }
|
| ParameterDeclKW Identifier "::" Identifier Dimensions DeclAsgns delim { map (uncurry $ $1 (Alias (Just $2) $4 $5)) $6 }
|
||||||
ParameterDeclKW :: { Type -> Identifier -> Expr -> Decl }
|
ParameterDeclKW :: { Type -> Identifier -> Expr -> Decl }
|
||||||
: "parameter" { Parameter }
|
: "parameter" { Parameter }
|
||||||
| "localparam" { Localparam }
|
| "localparam" { Localparam }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
typedef struct packed {
|
||||||
|
logic [2:0] a;
|
||||||
|
logic [1:0] b;
|
||||||
|
logic [3:0] c;
|
||||||
|
} foo_s;
|
||||||
|
|
||||||
|
parameter foo_s [1:0] foo = {
|
||||||
|
'{ a: 2, b: 1, c: 0 },
|
||||||
|
'{ a: 1, b: 0, c: 2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
module top;
|
||||||
|
initial begin
|
||||||
|
$display(foo[0]);
|
||||||
|
$display(foo[1]);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
module top;
|
||||||
|
parameter foo_1 = { 3'b010, 2'b01, 4'b0000 };
|
||||||
|
parameter foo_0 = { 3'b001, 2'b00, 4'b0010 };
|
||||||
|
initial begin
|
||||||
|
$display(foo_0);
|
||||||
|
$display(foo_1);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue