Commit 4fd7b6c2 by Zachary Snow

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
parent e82537fa
...@@ -41,19 +41,29 @@ convertDescription = ...@@ -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 _ _ _ _ _ _)) = ...@@ -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 ...@@ -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) = ...@@ -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)]) =
......
...@@ -729,8 +729,8 @@ DeclOrStmt :: { ([Decl], [Stmt]) } ...@@ -729,8 +729,8 @@ DeclOrStmt :: { ([Decl], [Stmt]) }
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 }
......
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
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
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