Merge pull request #688 from larsclausen/func-return-queue
Allow queues as return types for functions
This commit is contained in:
commit
fe4891a77d
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -27,11 +27,6 @@ LineInfo::LineInfo()
|
|||
{
|
||||
}
|
||||
|
||||
LineInfo::LineInfo(const LineInfo&that) :
|
||||
file_(that.file_), lineno_(that.lineno_)
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
LineInfo(const LineInfo&that);
|
||||
virtual ~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
|
|
|
|||
13
netmisc.cc
13
netmisc.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue