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;
|
||||
};
|
||||
|
||||
// Internal marker for the '$' in a queue dimension.
|
||||
class PEQueueDimension : public PExpr {
|
||||
public:
|
||||
void dump(std::ostream&) const override;
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
|
||||
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 = new netdarray_t(type);
|
||||
continue;
|
||||
} else if (dynamic_cast<PENull*>(lidx)) {
|
||||
// Special case: Detect the mark for a QUEUE declaration,
|
||||
// which is the dimensions [null:max_idx].
|
||||
} else if (dynamic_cast<PEQueueDimension*>(lidx)) {
|
||||
// Special case: Detect the mark for a QUEUE declaration.
|
||||
type = elaborate_static_array_type(des, li, type, dimensions);
|
||||
type = elaborate_queue_type(des, scope, li, type, ridx);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1087,7 +1087,7 @@ bool evaluate_range(Design*des, NetScope*scope, const LineInfo*li,
|
|||
"An unsized dimension is not allowed here." << endl;
|
||||
dimension_ok = false;
|
||||
des->errors += 1;
|
||||
} else if (dynamic_cast<PENull*>(range.first)) {
|
||||
} else if (dynamic_cast<PEQueueDimension*>(range.first)) {
|
||||
cerr << li->get_fileline() << ": error: "
|
||||
"A queue dimension is not allowed here." << endl;
|
||||
dimension_ok = false;
|
||||
|
|
|
|||
4
parse.y
4
parse.y
|
|
@ -3197,7 +3197,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
|||
| '[' '$' ']'
|
||||
{ // SystemVerilog queue
|
||||
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");
|
||||
tmp->push_back(index);
|
||||
$$ = tmp;
|
||||
|
|
@ -3205,7 +3205,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
|||
| '[' '$' ':' expression ']'
|
||||
{ // SystemVerilog queue with a max size
|
||||
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");
|
||||
tmp->push_back(index);
|
||||
$$ = tmp;
|
||||
|
|
|
|||
|
|
@ -506,6 +506,11 @@ void PENull::dump(ostream&out) const
|
|||
out << "null";
|
||||
}
|
||||
|
||||
void PEQueueDimension::dump(ostream&out) const
|
||||
{
|
||||
out << "$";
|
||||
}
|
||||
|
||||
void PENumber::dump(ostream&out) const
|
||||
{
|
||||
out << value();
|
||||
|
|
|
|||
|
|
@ -91,8 +91,12 @@ typedef std::pair<perm_string, unsigned> pform_ident_t;
|
|||
* second = 0
|
||||
*
|
||||
* [ $ ] -- Queue type
|
||||
* first = PENull
|
||||
* first = PEQueueDimension
|
||||
* second = 0
|
||||
*
|
||||
* [ $ : <expr> ] -- Bounded queue type
|
||||
* first = PEQueueDimension
|
||||
* second = <expr>
|
||||
*/
|
||||
typedef std::pair<PExpr*,PExpr*> pform_range_t;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue