Distinguish queue dimensions from `null` expressions
Queue dimensions use a `PENull` expression as an internal marker for `$`.
This also represents a source `null` expression, so declarations such as:
integer value[null:2];
are accepted and elaborated as bounded queues.
Use a dedicated `PEQueueDimension` marker for queue dimensions. This lets
source `null` expressions follow normal range expression validation while
preserving the existing representation of dynamic and fixed dimensions.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
72998c5415
commit
04c21e1982
6
PExpr.h
6
PExpr.h
|
|
@ -635,6 +635,12 @@ class PENull : public PExpr {
|
||||||
unsigned flags) const override;
|
unsigned flags) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Internal marker for the '$' in a queue dimension.
|
||||||
|
class PEQueueDimension : public PExpr {
|
||||||
|
public:
|
||||||
|
void dump(std::ostream&) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class PENumber : public PExpr {
|
class PENumber : public PExpr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -374,9 +374,8 @@ ivl_type_t elaborate_array_type(Design *des, NetScope *scope,
|
||||||
type = elaborate_darray_check_type(des, li, type, "Dynamic array");
|
type = elaborate_darray_check_type(des, li, type, "Dynamic array");
|
||||||
type = new netdarray_t(type);
|
type = new netdarray_t(type);
|
||||||
continue;
|
continue;
|
||||||
} else if (dynamic_cast<PENull*>(lidx)) {
|
} else if (dynamic_cast<PEQueueDimension*>(lidx)) {
|
||||||
// Special case: Detect the mark for a QUEUE declaration,
|
// Special case: Detect the mark for a QUEUE declaration.
|
||||||
// which is the dimensions [null:max_idx].
|
|
||||||
type = elaborate_static_array_type(des, li, type, dimensions);
|
type = elaborate_static_array_type(des, li, type, dimensions);
|
||||||
type = elaborate_queue_type(des, scope, li, type, ridx);
|
type = elaborate_queue_type(des, scope, li, type, ridx);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -1087,7 +1087,7 @@ bool evaluate_range(Design*des, NetScope*scope, const LineInfo*li,
|
||||||
"An unsized dimension is not allowed here." << endl;
|
"An unsized dimension is not allowed here." << endl;
|
||||||
dimension_ok = false;
|
dimension_ok = false;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
} else if (dynamic_cast<PENull*>(range.first)) {
|
} else if (dynamic_cast<PEQueueDimension*>(range.first)) {
|
||||||
cerr << li->get_fileline() << ": error: "
|
cerr << li->get_fileline() << ": error: "
|
||||||
"A queue dimension is not allowed here." << endl;
|
"A queue dimension is not allowed here." << endl;
|
||||||
dimension_ok = false;
|
dimension_ok = false;
|
||||||
|
|
|
||||||
4
parse.y
4
parse.y
|
|
@ -3197,7 +3197,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
||||||
| '[' '$' ']'
|
| '[' '$' ']'
|
||||||
{ // SystemVerilog queue
|
{ // SystemVerilog queue
|
||||||
list<pform_range_t> *tmp = new std::list<pform_range_t>;
|
list<pform_range_t> *tmp = new std::list<pform_range_t>;
|
||||||
pform_range_t index (new PENull,0);
|
pform_range_t index (new PEQueueDimension,0);
|
||||||
pform_requires_sv(@$, "Queue declaration");
|
pform_requires_sv(@$, "Queue declaration");
|
||||||
tmp->push_back(index);
|
tmp->push_back(index);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -3205,7 +3205,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
||||||
| '[' '$' ':' expression ']'
|
| '[' '$' ':' expression ']'
|
||||||
{ // SystemVerilog queue with a max size
|
{ // SystemVerilog queue with a max size
|
||||||
list<pform_range_t> *tmp = new std::list<pform_range_t>;
|
list<pform_range_t> *tmp = new std::list<pform_range_t>;
|
||||||
pform_range_t index (new PENull,$4);
|
pform_range_t index (new PEQueueDimension,$4);
|
||||||
pform_requires_sv(@$, "Queue declaration");
|
pform_requires_sv(@$, "Queue declaration");
|
||||||
tmp->push_back(index);
|
tmp->push_back(index);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
|
||||||
|
|
@ -506,6 +506,11 @@ void PENull::dump(ostream&out) const
|
||||||
out << "null";
|
out << "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PEQueueDimension::dump(ostream&out) const
|
||||||
|
{
|
||||||
|
out << "$";
|
||||||
|
}
|
||||||
|
|
||||||
void PENumber::dump(ostream&out) const
|
void PENumber::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
out << value();
|
out << value();
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,12 @@ typedef std::pair<perm_string, unsigned> pform_ident_t;
|
||||||
* second = 0
|
* second = 0
|
||||||
*
|
*
|
||||||
* [ $ ] -- Queue type
|
* [ $ ] -- Queue type
|
||||||
* first = PENull
|
* first = PEQueueDimension
|
||||||
* second = 0
|
* second = 0
|
||||||
|
*
|
||||||
|
* [ $ : <expr> ] -- Bounded queue type
|
||||||
|
* first = PEQueueDimension
|
||||||
|
* second = <expr>
|
||||||
*/
|
*/
|
||||||
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue