Merge pull request #688 from larsclausen/func-return-queue

Allow queues as return types for functions
This commit is contained in:
Stephen Williams 2022-04-17 18:34:03 -07:00 committed by GitHub
commit fe4891a77d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 60 additions and 17 deletions

View File

@ -50,6 +50,7 @@
# include "netlist.h"
# include "netclass.h"
# include "netenum.h"
# include "netqueue.h"
# include "parse_api.h"
# include "util.h"
# include <typeinfo>
@ -557,6 +558,13 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
<< " Property " << cur->first
<< " type=" << *tmp << endl;
}
if (dynamic_cast<const netqueue_t *> (tmp)) {
cerr << cur->second.get_fileline() << ": sorry: "
<< "Queues inside classes are not yet supported." << endl;
des->errors++;
}
use_class->set_property(cur->first, cur->second.qual, tmp);
}

View File

@ -241,10 +241,6 @@ ivl_type_t uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
// Special case: if the dimension is null:nil. this is a queue.
if (dynamic_cast<PENull*>(cur->first)) {
cerr << get_fileline() << ": sorry: "
<< "SV queues inside classes are not yet supported." << endl;
des->errors += 1;
// FIXME: Need to set the max size if cur->second is defined
ivl_type_s*res = new netqueue_t(btype, -1);
return res;

View File

@ -0,0 +1,41 @@
// Check that a queue return type is supported for functions
module test;
typedef int Q[$];
// Since this is not an automatic function calling this repeatetly will
// append to the same queue.
function Q f1(int x);
f1.push_back(1 + x);
f1.push_back(2 + x);
endfunction
// Since this function is automatic a new queue will be created each time it
// is called.
function automatic Q f2(int x);
f2.push_back(1 + x);
f2.push_back(2 + x);
endfunction
initial begin
Q a, b, c, d;
a = f1(0);
// `a` should be a copy and not affected by the second call
b = f1(2);
c = f2(0);
d = f2(2);
if (a.size() == 2 && a[0] == 1 && a[1] == 2 &&
b.size() == 4 && b[0] == 1 && b[1] == 2 && b[2] == 3 && b[3] == 4 &&
c.size() == 2 && c[0] == 1 && c[1] == 2 &&
d.size() == 2 && d[0] == 3 && d[1] == 4) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -575,6 +575,7 @@ sv_port_default14 CE,-g2009 ivltests
sv_queue1 normal,-g2009 ivltests
sv_queue2 normal,-g2009 ivltests
sv_queue3 normal,-g2009 ivltests
sv_queue_function normal,-g2009 ivltests
sv_queue_parray normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray.gold
sv_queue_parray_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray_bounded.gold
sv_queue_parray_fail CE,-g2009 ivltests gold=sv_queue_parray_fail.gold

View File

@ -463,6 +463,7 @@ pr3390385b CE,-g2009 ivltests # ++
pr3390385c CE,-g2009 ivltests # ++
pr3390385d CE,-g2009 ivltests # ++
pr3462145 CE,-g2009 ivltests # ++
sv_queue_function CE,-g2009,-pallowsigned=1 ivltests # queue
sv_typedef_darray_base1 CE,-g2009 ivltests # Dyanmic array
sv_typedef_darray_base2 CE,-g2009 ivltests # Dyanmic array
sv_typedef_darray_base3 CE,-g2009 ivltests # Dyanmic array

View File

@ -27,11 +27,6 @@ LineInfo::LineInfo()
{
}
LineInfo::LineInfo(const LineInfo&that) :
file_(that.file_), lineno_(that.lineno_)
{
}
LineInfo::~LineInfo()
{
}

View File

@ -34,7 +34,6 @@
class LineInfo {
public:
LineInfo();
LineInfo(const LineInfo&that);
virtual ~LineInfo();
// Get a fully formatted file/lineno

View File

@ -985,16 +985,17 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
if (tmp == 0) return 0;
ivl_variable_type_t cast_type = ivl_type_base(lv_net_type);
if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != tmp->expr_type())) {
ivl_variable_type_t expr_type = tmp->expr_type();
if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != expr_type)) {
// Catch some special cases.
switch (cast_type) {
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
if (NetESignal*net = dynamic_cast<NetESignal*>(tmp)) {
ivl_variable_type_t type = net->expr_type();
if ((type == IVL_VT_DARRAY) || (type == IVL_VT_QUEUE))
return tmp;
}
if ((expr_type == IVL_VT_DARRAY) || (expr_type == IVL_VT_QUEUE))
return tmp;
// This is needed to handle the special case of `'{}` which
// gets elaborated to NetENull.
if (dynamic_cast<PEAssignPattern*>(pe))
return tmp;
// fall through

View File

@ -86,6 +86,7 @@ void pform_class_property(const struct vlltype&loc,
pform_cur_class->type->properties[curp->name]
= class_type_t::prop_info_t(property_qual,use_type);
FILE_NAME(&pform_cur_class->type->properties[curp->name], loc);
if (PExpr*rval = curp->expr.release()) {
PExpr*lval = new PEIdent(curp->name);

View File

@ -336,7 +336,7 @@ struct class_type_t : public data_type_t {
std::list<PExpr*>base_args;
// This is a map of the properties. Map the name to the type.
struct prop_info_t {
struct prop_info_t : public LineInfo {
inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { }
inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { }
property_qualifier_t qual;