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
|
||||
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
|
||||
let (tf, rs) = typeRanges t
|
||||
if length rs <= 1
|
||||
then do
|
||||
put $ Info $ Map.delete ident typeDims
|
||||
return origDecl
|
||||
return t
|
||||
else do
|
||||
put $ Info $ Map.insert ident rs typeDims
|
||||
let r1 : r2 : rest = rs
|
||||
let rs' = (combineRanges r1 r2) : rest
|
||||
return $ Variable dir (tf rs') ident a me
|
||||
traverseDeclM other = return other
|
||||
return $ tf rs'
|
||||
|
||||
-- combines two ranges into one flattened range
|
||||
combineRanges :: Range -> Range -> Range
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ convertDescription (description @ (Part _ _ _ _ _ _)) =
|
|||
Part extern kw lifetime name ports (items ++ funcs)
|
||||
where
|
||||
description' @ (Part extern kw lifetime name ports items) =
|
||||
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
|
||||
tfArgTypes description
|
||||
scopedConversion (traverseDeclM structs) traverseModuleItemM
|
||||
traverseStmtM tfArgTypes description
|
||||
-- collect information about this description
|
||||
structs = execWriter $ collectModuleItemsM
|
||||
(collectTypesM collectStructM) description
|
||||
|
|
@ -149,15 +149,31 @@ collectTFArgsM (MIPackageItem item) = do
|
|||
collectTFArgsM _ = return ()
|
||||
|
||||
-- write down the types of declarations
|
||||
traverseDeclM :: Decl -> State Types Decl
|
||||
traverseDeclM origDecl = do
|
||||
traverseDeclM :: Structs -> Decl -> State Types Decl
|
||||
traverseDeclM structs origDecl = do
|
||||
case origDecl of
|
||||
Variable _ t x a _ -> do
|
||||
Variable d t x a me -> do
|
||||
let (tf, rs) = typeRanges t
|
||||
modify $ Map.insert x (tf $ a ++ rs)
|
||||
Parameter t x _ -> modify $ Map.insert x t
|
||||
Localparam t x _ -> modify $ Map.insert x t
|
||||
return origDecl
|
||||
case me of
|
||||
Nothing -> 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
|
||||
packerFn :: TypeFunc -> ModuleItem
|
||||
|
|
@ -262,6 +278,8 @@ convertAsgn structs types (lhs, expr) =
|
|||
convertExpr (IntegerVector t sg (r:rs)) (Pattern [(Just "default", e)]) =
|
||||
Repeat (rangeSize r) [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) e
|
||||
convertExpr (Struct (Packed sg) fields rs) (Pattern [(Just "default", e)]) =
|
||||
|
|
|
|||
|
|
@ -727,10 +727,10 @@ DeclOrStmt :: { ([Decl], [Stmt]) }
|
|||
| ParameterDecl(";") { ($1, []) }
|
||||
|
||||
ParameterDecl(delim) :: { [Decl] }
|
||||
: ParameterDeclKW DeclAsgns delim { map (uncurry $ $1 (Implicit Unspecified [])) $2 }
|
||||
| ParameterDeclKW ParamType DeclAsgns delim { map (uncurry $ $1 ($2 )) $3 }
|
||||
| ParameterDeclKW Identifier DeclAsgns delim { map (uncurry $ $1 (Alias (Nothing) $2 [])) $3 }
|
||||
| ParameterDeclKW Identifier "::" Identifier DeclAsgns delim { map (uncurry $ $1 (Alias (Just $2) $4 [])) $5 }
|
||||
: ParameterDeclKW DeclAsgns delim { map (uncurry $ $1 (Implicit Unspecified [])) $2 }
|
||||
| ParameterDeclKW ParamType DeclAsgns delim { map (uncurry $ $1 ($2 )) $3 }
|
||||
| ParameterDeclKW Identifier Dimensions DeclAsgns delim { map (uncurry $ $1 (Alias (Nothing) $2 $3)) $4 }
|
||||
| ParameterDeclKW Identifier "::" Identifier Dimensions DeclAsgns delim { map (uncurry $ $1 (Alias (Just $2) $4 $5)) $6 }
|
||||
ParameterDeclKW :: { Type -> Identifier -> Expr -> Decl }
|
||||
: "parameter" { Parameter }
|
||||
| "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