diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index b6894e6..9a5388e 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -633,11 +633,12 @@ Dimension :: { Range } : Range { $1 } | "[" Expr "]" { (simplify $ BinOp Sub $2 (Number "1"), Number "0") } -DeclAsgns :: { [(Identifier, Expr)] } +DeclAsgns :: { [(Identifier, Expr, [Range])] } : DeclAsgn { [$1] } | DeclAsgns "," DeclAsgn { $1 ++ [$3] } -DeclAsgn :: { (Identifier, Expr) } - : Identifier "=" Expr { ($1, $3) } +DeclAsgn :: { (Identifier, Expr, [Range]) } + : Identifier "=" Expr { ($1, $3, []) } + | Identifier DimensionsNonEmpty "=" Expr { ($1, $4, $2) } Range :: { Range } : "[" Expr ":" Expr "]" { ($2, $4) } @@ -730,10 +731,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 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 DeclAsgns delim { makeParamDecls $1 (Implicit Unspecified []) $2 } + | ParameterDeclKW ParamType DeclAsgns delim { makeParamDecls $1 ($2 ) $3 } + | ParameterDeclKW Identifier Dimensions DeclAsgns delim { makeParamDecls $1 (Alias (Nothing) $2 $3) $4 } + | ParameterDeclKW Identifier "::" Identifier Dimensions DeclAsgns delim { makeParamDecls $1 (Alias (Just $2) $4 $5) $6 } ParameterDeclKW :: { Type -> Identifier -> Expr -> Decl } : "parameter" { Parameter } | "localparam" { Localparam } @@ -995,4 +996,16 @@ toLHS expr = Just lhs -> lhs Nothing -> error $ "Parse error: cannot convert expression to LHS: " ++ show expr + +makeParamDecls + :: (Type -> Identifier -> Expr -> Decl) + -> Type + -> [(Identifier, Expr, [Range])] + -> [Decl] +makeParamDecls kw t items = + map mapper items + where + (tf, rs) = typeRanges t + mapper (x, e, a) = kw (tf $ a ++ rs) x e + } diff --git a/test/basic/unpacked_localparam.sv b/test/basic/unpacked_localparam.sv new file mode 100644 index 0000000..2955ff2 --- /dev/null +++ b/test/basic/unpacked_localparam.sv @@ -0,0 +1,12 @@ +module top; + localparam logic [7:0] init_val [4] = {8'd0, 8'd8, 8'd10, 8'd200}; + initial begin + integer i, j; + for (i = 0; i < 4; i += 1) begin + $display(init_val[i]); + for (j = 0; j < 8; j += 1) begin + $display(init_val[i][j]); + end + end + end +endmodule diff --git a/test/basic/unpacked_localparam.v b/test/basic/unpacked_localparam.v new file mode 100644 index 0000000..eca1dd1 --- /dev/null +++ b/test/basic/unpacked_localparam.v @@ -0,0 +1,12 @@ +module top; + localparam [31:0] init_val = {8'd0, 8'd8, 8'd10, 8'd200}; + initial begin : foo + integer i, j; + for (i = 0; i < 4; i += 1) begin + $display(init_val[8*i+:8]); + for (j = 0; j < 8; j += 1) begin + $display(init_val[8*i+j]); + end + end + end +endmodule