From dda960dce42e7547a62939e9b10d9f9538350629 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 28 Mar 2022 05:48:58 +0200 Subject: [PATCH 1/5] Use default copy-constructor for LineInfo The LineInfo class defines a copy-constructor, but relies on the default copy-assignment operator. In newer versions of C++ this deprecated and modern compilers generate a warning about this. A class must either use the default copy-constructor and default copy-assignment operator or provide a user defined version of both. Since the current user-defined copy-constructor for LineInfo does the same as the default copy-constructor, remove the custom one and rely on the default constructor. Signed-off-by: Lars-Peter Clausen --- libmisc/LineInfo.cc | 5 ----- libmisc/LineInfo.h | 1 - 2 files changed, 6 deletions(-) diff --git a/libmisc/LineInfo.cc b/libmisc/LineInfo.cc index c0daaff14..753b24970 100644 --- a/libmisc/LineInfo.cc +++ b/libmisc/LineInfo.cc @@ -27,11 +27,6 @@ LineInfo::LineInfo() { } -LineInfo::LineInfo(const LineInfo&that) : - file_(that.file_), lineno_(that.lineno_) -{ -} - LineInfo::~LineInfo() { } diff --git a/libmisc/LineInfo.h b/libmisc/LineInfo.h index ec36aee41..b47f194f0 100644 --- a/libmisc/LineInfo.h +++ b/libmisc/LineInfo.h @@ -34,7 +34,6 @@ class LineInfo { public: LineInfo(); - LineInfo(const LineInfo&that); virtual ~LineInfo(); // Get a fully formatted file/lineno From bcae0304a3903573ecd0a72e26e65e9b5ecf490e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 19 Jan 2022 10:50:52 +0100 Subject: [PATCH 2/5] Set line info on class properties This will allow to generate error messages that point to the right line if there is something wrong or not supported in a class property declaration. Signed-off-by: Lars-Peter Clausen --- pform_pclass.cc | 1 + pform_types.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pform_pclass.cc b/pform_pclass.cc index a129e19be..f922b9df9 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -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); diff --git a/pform_types.h b/pform_types.h index dc4bb8da4..45e312e6f 100644 --- a/pform_types.h +++ b/pform_types.h @@ -336,7 +336,7 @@ struct class_type_t : public data_type_t { std::listbase_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; From c853025305c079272375d358556cae0ca65f52af Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Apr 2022 18:23:41 +0200 Subject: [PATCH 3/5] Allow implicit cast between dynamic array and queue for all expressions Dynamic arrays and queues can be implicitly cast between each other. At the moment this only works if the right hand side is a signal or assignment pattern. But this should be possible for other r-value expression that returns a queue or dynamic array type. E.g. function calls or class properties. Since the expr_type() method is defined for all NetExpr objects we can use that and do not have to cast to NetESignal. Signed-off-by: Lars-Peter Clausen --- netmisc.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/netmisc.cc b/netmisc.cc index e27778361..b2ca68a61 100644 --- a/netmisc.cc +++ b/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(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(pe)) return tmp; // fall through From 27f3fcc5f1c8ec0316a667e2308758bae2392591 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Jan 2022 23:43:59 +0100 Subject: [PATCH 4/5] Allow queue types outside of classes Currently the elaboration function for unpacked array types prints an error for queues that they are not allowed inside classes. And while this error gets triggered when declaring a property with a queue type, it also gets triggered for other places that uses a queue type, e.g. a function return type. The only exception is signals which uses a different internal code path when elaborating queue types. Move the error message, that is class property specific, to the class property elaboration. This also makes sure that the error messages references the line where the property is declared and not the line where the type is declared. Signed-off-by: Lars-Peter Clausen --- elab_scope.cc | 8 ++++++++ elab_type.cc | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index 99a14081d..d6a3bf40a 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -50,6 +50,7 @@ # include "netlist.h" # include "netclass.h" # include "netenum.h" +# include "netqueue.h" # include "parse_api.h" # include "util.h" # include @@ -557,6 +558,13 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) << " Property " << cur->first << " type=" << *tmp << endl; } + + if (dynamic_cast (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); } diff --git a/elab_type.cc b/elab_type.cc index b77138ac3..4471e1b28 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -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(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; From 393c7a3b498b3bc4c95a67693367668401451da5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Apr 2022 18:44:12 +0200 Subject: [PATCH 5/5] Add a regression test for functions with queue return type Check that a queue type is supported for the return type of a function. Make sure that the queue is not cleared in between invocations for non-automatic functions. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_queue_function.v | 41 +++++++++++++++++++++++++++++ ivtest/regress-sv.list | 1 + ivtest/regress-vlog95.list | 1 + 3 files changed, 43 insertions(+) create mode 100644 ivtest/ivltests/sv_queue_function.v diff --git a/ivtest/ivltests/sv_queue_function.v b/ivtest/ivltests/sv_queue_function.v new file mode 100644 index 000000000..9fb52f1eb --- /dev/null +++ b/ivtest/ivltests/sv_queue_function.v @@ -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 diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index e0503d23c..06b392d6e 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -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 diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 7aa9989e8..3f9b3d29b 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -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