mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Fix multidimensional function return value selects (#5382).
This commit is contained in:
parent
434896d50c
commit
4e4fdd3b66
2
Changes
2
Changes
@ -27,6 +27,7 @@ Verilator 5.029 devel
|
||||
* Improve performance of V3VariableOrder with parallelism (#5406). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix performance of V3Trace when many activity blocks (#5372). [Deniz Güzel]
|
||||
* Fix REALCVT warning on integral timescale conversions (#5378). [Liam Braun]
|
||||
* Fix multidimensional function return value selects (#5382). [Gökçe Aydos]
|
||||
* Fix dot fallback finding wrong symbols (#5394). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix infinite recursion due to recursive functions/tasks (#5398). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix V3Randomize compile error on old GCC (#5403) (#5417). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
@ -40,6 +41,7 @@ Verilator 5.029 devel
|
||||
* Fix associative array next/prev/first/last mis-propagating constants (#5435). [Ethan Sifferman]
|
||||
|
||||
|
||||
|
||||
Verilator 5.028 2024-08-21
|
||||
==========================
|
||||
|
||||
|
@ -1660,6 +1660,17 @@ public:
|
||||
bool same(const AstNode* /*samep*/) const override { return true; }
|
||||
int instrCount() const override { return widthInstrs(); }
|
||||
};
|
||||
class AstParseHolder final : public AstNodeExpr {
|
||||
// A reference to something soon to replace, used in a select at parse time
|
||||
// that needs conversion to pull the upper lvalue later
|
||||
public:
|
||||
AstParseHolder(FileLine* fl)
|
||||
: ASTGEN_SUPER_ParseHolder(fl) {}
|
||||
ASTGEN_MEMBERS_AstParseHolder;
|
||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
bool cleanOut() const override { V3ERROR_NA_RETURN(true); }
|
||||
};
|
||||
class AstParseRef final : public AstNodeExpr {
|
||||
// A reference to a variable, function or task
|
||||
// We don't know which at parse time due to bison constraints
|
||||
|
@ -128,6 +128,23 @@ AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) {
|
||||
return VN_CAST(nrangep, Range);
|
||||
}
|
||||
|
||||
AstNodePreSel* V3ParseGrammar::scrubSel(AstNodeExpr* fromp, AstNodePreSel* selp) VL_MT_DISABLED {
|
||||
// SEL(PARSELVALUE, ...) -> SEL(fromp, ...)
|
||||
AstNodePreSel* subSelp = selp;
|
||||
while (true) {
|
||||
if (VN_IS(subSelp->fromp(), ParseHolder)) break;
|
||||
if (AstNodePreSel* const lowerSelp = VN_CAST(subSelp->fromp(), NodePreSel)) {
|
||||
subSelp = lowerSelp;
|
||||
continue;
|
||||
}
|
||||
subSelp->v3fatalSrc("Couldn't find where to insert expression into select");
|
||||
}
|
||||
AstNode* subSelFromp = subSelp->fromp();
|
||||
subSelFromp->replaceWith(fromp);
|
||||
VL_DO_DANGLING(subSelFromp->deleteTree(), subSelFromp);
|
||||
return selp;
|
||||
}
|
||||
|
||||
AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstNodeRange* nrangep,
|
||||
bool isPacked) {
|
||||
// Split RANGE0-RANGE1-RANGE2
|
||||
|
@ -125,6 +125,7 @@ public:
|
||||
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
|
||||
}
|
||||
AstRange* scrubRange(AstNodeRange* rangep) VL_MT_DISABLED;
|
||||
AstNodePreSel* scrubSel(AstNodeExpr* fromp, AstNodePreSel* selp) VL_MT_DISABLED;
|
||||
AstNodeDType* createArray(AstNodeDType* basep, AstNodeRange* rangep,
|
||||
bool isPacked) VL_MT_DISABLED;
|
||||
AstVar* createVariable(FileLine* fileline, const string& name, AstNodeRange* arrayp,
|
||||
@ -1181,6 +1182,13 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start source_text
|
||||
|
||||
@ -3112,13 +3120,26 @@ rangeList<nodeRangep>: // IEEE: {packed_dimension}
|
||||
| rangeList anyrange { $$ = $1->addNext($2); }
|
||||
;
|
||||
|
||||
// IEEE: select
|
||||
// Merged into more general idArray
|
||||
|
||||
anyrange<nodeRangep>:
|
||||
'[' constExpr ':' constExpr ']' { $$ = new AstRange{$1, $2, $4}; }
|
||||
;
|
||||
|
||||
part_select_rangeList<nodePreSelp>: // IEEE: part_select_range (as used after function calls)
|
||||
part_select_range { $$ = $1; }
|
||||
| part_select_rangeList part_select_range { $$ = GRAMMARP->scrubSel($1, $2); }
|
||||
;
|
||||
|
||||
part_select_range<nodePreSelp>:
|
||||
'[' expr ']'
|
||||
{ $$ = new AstSelBit{$1, new AstParseHolder{$1}, $2}; }
|
||||
| '[' constExpr ':' constExpr ']'
|
||||
{ $$ = new AstSelExtract{$1, new AstParseHolder{$1}, $2, $4}; }
|
||||
| '[' expr yP_PLUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelPlus{$1, new AstParseHolder{$1}, $2, $4}; }
|
||||
| '[' expr yP_MINUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelMinus{$1, new AstParseHolder{$1}, $2, $4}; }
|
||||
;
|
||||
|
||||
packed_dimensionListE<nodeRangep>: // IEEE: [{ packed_dimension }]
|
||||
/* empty */ { $$ = nullptr; }
|
||||
| packed_dimensionList { $$ = $1; }
|
||||
@ -4964,38 +4985,22 @@ expr<nodeExprp>: // IEEE: part of expression/constant_expression/
|
||||
{ $$ = new AstSelMinus{$7, new AstReplicate{$3, $4, $2}, $8, $10}; }
|
||||
// // UNSUP some other rules above
|
||||
//
|
||||
// // IEEE grammar error: function_subroutine_call [ range_expression ]
|
||||
// // should be instead: function_subroutine_call [ part_select_range ]
|
||||
| function_subroutine_callNoMethod
|
||||
{ $$ = $1; }
|
||||
| function_subroutine_callNoMethod '[' expr ']'
|
||||
{ $$ = new AstSelBit{$2, $1, $3}; }
|
||||
| function_subroutine_callNoMethod '[' constExpr ':' constExpr ']'
|
||||
{ $$ = new AstSelExtract{$2, $1, $3, $5}; }
|
||||
| function_subroutine_callNoMethod '[' expr yP_PLUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelPlus{$2, $1, $3, $5}; }
|
||||
| function_subroutine_callNoMethod '[' expr yP_MINUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelMinus{$2, $1, $3, $5}; }
|
||||
| function_subroutine_callNoMethod part_select_rangeList
|
||||
{ $$ = GRAMMARP->scrubSel($1, $2); }
|
||||
// // method_call
|
||||
| ~l~expr '.' function_subroutine_callNoMethod
|
||||
{ $$ = new AstDot{$2, false, $1, $3}; }
|
||||
| ~l~expr '.' function_subroutine_callNoMethod '[' expr ']'
|
||||
{ $$ = new AstSelBit{$4, new AstDot{$2, false, $1, $3}, $5}; }
|
||||
| ~l~expr '.' function_subroutine_callNoMethod '[' constExpr ':' constExpr ']'
|
||||
{ $$ = new AstSelExtract{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' function_subroutine_callNoMethod '[' expr yP_PLUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelPlus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' function_subroutine_callNoMethod '[' expr yP_MINUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelMinus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' function_subroutine_callNoMethod part_select_rangeList
|
||||
{ $$ = GRAMMARP->scrubSel(new AstDot{$2, false, $1, $3}, $4); }
|
||||
// // method_call:array_method requires a '.'
|
||||
| ~l~expr '.' array_methodWith
|
||||
{ $$ = new AstDot{$2, false, $1, $3}; }
|
||||
| ~l~expr '.' array_methodWith '[' expr ']'
|
||||
{ $$ = new AstSelBit{$4, new AstDot{$2, false, $1, $3}, $5}; }
|
||||
| ~l~expr '.' array_methodWith '[' constExpr ':' constExpr ']'
|
||||
{ $$ = new AstSelExtract{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' array_methodWith '[' expr yP_PLUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelPlus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' array_methodWith '[' expr yP_MINUSCOLON constExpr ']'
|
||||
{ $$ = new AstSelMinus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; }
|
||||
| ~l~expr '.' array_methodWith part_select_rangeList
|
||||
{ $$ = GRAMMARP->scrubSel(new AstDot{$2, false, $1, $3}, $4); }
|
||||
//
|
||||
// // IEEE: let_expression
|
||||
// // see funcRef
|
||||
|
@ -34,6 +34,13 @@ module t(/*AUTOARG*/);
|
||||
return 16'hf0ed;
|
||||
endfunction
|
||||
|
||||
int i;
|
||||
typedef int arr_t[1:0][3:0];
|
||||
|
||||
function arr_t valarr();
|
||||
return '{'{1,2,3,4}, '{5,6,7,8}};
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
aa = 8'haa;
|
||||
bb = 8'hbb;
|
||||
@ -84,6 +91,9 @@ module t(/*AUTOARG*/);
|
||||
s8 = q.sum()[11-:8];
|
||||
`checkh(s8, 8'h0e);
|
||||
|
||||
i = valarr()[1][2];
|
||||
$display(i);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user