SystemVerilog: support locator methods on class queue properties
Enable queue locator elaboration for class properties typed as queues (not only dynamic arrays), and add regression coverage for class queue property find/unique/min/max behavior. Made-with: Cursor
This commit is contained in:
parent
7cac25cbd1
commit
0cd7205585
44
elab_expr.cc
44
elab_expr.cc
|
|
@ -4050,12 +4050,14 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
return sys_expr;
|
||||
}
|
||||
}
|
||||
if (ptype && ptype->base_type() == IVL_VT_DARRAY) {
|
||||
if (ptype &&
|
||||
(ptype->base_type() == IVL_VT_DARRAY ||
|
||||
ptype->base_type() == IVL_VT_QUEUE)) {
|
||||
NetEProperty*prop = new NetEProperty(search_results.net, pidx, nullptr);
|
||||
prop->set_line(*this);
|
||||
perm_string method_name = search_results.path_tail.back().name;
|
||||
ivl_type_t element_type = ivl_type_element(ptype);
|
||||
ivl_type_t darray_rtype = ptype;
|
||||
ivl_type_t array_rtype = ptype;
|
||||
if (method_name == "size") {
|
||||
if (parms_.size() != 0) {
|
||||
cerr << get_fileline() << ": error: size() method "
|
||||
|
|
@ -4074,7 +4076,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique() for this "
|
||||
cerr << get_fileline() << ": sorry: array unique() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4089,10 +4091,10 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
element_type, array_rtype, method_name);
|
||||
}
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$unique", darray_rtype, 1);
|
||||
"$ivl_queue_method$unique", array_rtype, 1);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
|
|
@ -4104,7 +4106,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array unique_index() for this "
|
||||
cerr << get_fileline() << ": sorry: array unique_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4132,7 +4134,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find() for this "
|
||||
cerr << get_fileline() << ": sorry: array find() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4147,14 +4149,14 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
element_type, array_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find", darray_rtype, 2);
|
||||
"$ivl_queue_method$find", array_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
|
|
@ -4162,7 +4164,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_index() for this "
|
||||
cerr << get_fileline() << ": sorry: array find_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4195,7 +4197,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find_first") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_first() for this "
|
||||
cerr << get_fileline() << ": sorry: array find_first() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4210,14 +4212,14 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
element_type, array_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_first", darray_rtype, 2);
|
||||
"$ivl_queue_method$find_first", array_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
|
|
@ -4225,7 +4227,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find_first_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_first_index() for this "
|
||||
cerr << get_fileline() << ": sorry: array find_first_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4258,7 +4260,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find_last") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_last() for this "
|
||||
cerr << get_fileline() << ": sorry: array find_last() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4273,14 +4275,14 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
element_type, array_rtype, method_name);
|
||||
}
|
||||
NetExpr* cmp = elab_queue_locator_cmp_arg(
|
||||
des, scope, *this, parms_, element_type);
|
||||
if (!cmp)
|
||||
return 0;
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
"$ivl_queue_method$find_last", darray_rtype, 2);
|
||||
"$ivl_queue_method$find_last", array_rtype, 2);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
sys_expr->parm(1, cmp);
|
||||
|
|
@ -4288,7 +4290,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
if (method_name == "find_last_index") {
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array find_last_index() for this "
|
||||
cerr << get_fileline() << ": sorry: array find_last_index() for this "
|
||||
<< "element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4326,7 +4328,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
if (!queue_method_element_is_integral_vec4(element_type)) {
|
||||
cerr << get_fileline() << ": sorry: dynamic array " << method_name
|
||||
cerr << get_fileline() << ": sorry: array " << method_name
|
||||
<< "() for this element type is not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
|
@ -4341,12 +4343,12 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
return elab_queue_locator_with_predicate(
|
||||
des, scope, *this, with_expr_, prop,
|
||||
element_type, darray_rtype, method_name);
|
||||
element_type, array_rtype, method_name);
|
||||
}
|
||||
NetESFunc*sys_expr = new NetESFunc(
|
||||
method_name == "min" ? "$ivl_queue_method$min"
|
||||
: "$ivl_queue_method$max",
|
||||
darray_rtype, 1);
|
||||
array_rtype, 1);
|
||||
sys_expr->set_line(*this);
|
||||
sys_expr->parm(0, prop);
|
||||
return sys_expr;
|
||||
|
|
|
|||
|
|
@ -48,3 +48,4 @@ Regression tests (see ivtest/vvp_tests/*.json and regress-vvp.list):
|
|||
sv_class_darray_prop_locators.v locator methods on class dynamic-array properties.
|
||||
sv_queue_unique_with.v unique()/unique_index() with predicate on queues.
|
||||
sv_darray_unique_with.v unique()/unique_index() with predicate on dynamic arrays.
|
||||
sv_class_queue_prop_locators.v locator methods on class queue properties.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
// Regression: class queue property locator methods.
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do if ((val) !== (exp)) begin $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); failed = 1'b1; end while (0)
|
||||
|
||||
class C;
|
||||
int q[$];
|
||||
endclass
|
||||
|
||||
C c;
|
||||
int r[$];
|
||||
|
||||
initial begin
|
||||
c = new;
|
||||
c.q.push_back(4);
|
||||
c.q.push_back(7);
|
||||
c.q.push_back(2);
|
||||
c.q.push_back(5);
|
||||
c.q.push_back(7);
|
||||
c.q.push_back(1);
|
||||
c.q.push_back(6);
|
||||
c.q.push_back(3);
|
||||
c.q.push_back(1);
|
||||
|
||||
r = c.q.find() with (item > 3);
|
||||
`check(r.size, 5);
|
||||
`check(r[0], 4);
|
||||
`check(r[4], 6);
|
||||
|
||||
r = c.q.find_last_index() with (item < 3);
|
||||
`check(r.size, 1);
|
||||
`check(r[0], 8);
|
||||
|
||||
r = c.q.unique() with (item > 2);
|
||||
`check(r.size, 5);
|
||||
`check(r[0], 4);
|
||||
`check(r[4], 3);
|
||||
|
||||
r = c.q.unique_index() with (item > 2);
|
||||
`check(r.size, 6);
|
||||
`check(r[0], 0);
|
||||
`check(r[5], 7);
|
||||
|
||||
r = c.q.min();
|
||||
`check(r.size, 2);
|
||||
`check(r[0], 1);
|
||||
`check(r[1], 1);
|
||||
|
||||
r = c.q.max();
|
||||
`check(r.size, 2);
|
||||
`check(r[0], 7);
|
||||
|
||||
if (!failed)
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -232,6 +232,7 @@ sv_class_prop_assign_op1 vvp_tests/sv_class_prop_assign_op1.json
|
|||
sv_class_prop_assign_op2 vvp_tests/sv_class_prop_assign_op2.json
|
||||
sv_class_prop_logic vvp_tests/sv_class_prop_logic.json
|
||||
sv_class_darray_prop_locators vvp_tests/sv_class_darray_prop_locators.json
|
||||
sv_class_queue_prop_locators vvp_tests/sv_class_queue_prop_locators.json
|
||||
sv_class_prop_nest_darray1 vvp_tests/sv_class_prop_nest_darray1.json
|
||||
sv_class_prop_nest_obj1 vvp_tests/sv_class_prop_nest_obj1.json
|
||||
sv_class_prop_nest_real1 vvp_tests/sv_class_prop_nest_str1.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type" : "normal",
|
||||
"source" : "sv_class_queue_prop_locators.v",
|
||||
"iverilog-args" : [ "-g2005-sv" ],
|
||||
"vlog95" : {
|
||||
"__comment" : "SystemVerilog class queue property locator methods",
|
||||
"type" : "CE"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue