diff --git a/Makefile.in b/Makefile.in index 3f0c00377..68e54b744 100644 --- a/Makefile.in +++ b/Makefile.in @@ -111,7 +111,6 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \ net_design.o netclass.o netdarray.o \ netenum.o netparray.o netqueue.o netscalar.o netstruct.o netvector.o \ - make_ivl_type.o \ net_event.o net_expr.o net_func.o \ net_func_eval.o net_link.o net_modulo.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ diff --git a/PWire.h b/PWire.h index f4b792538..dbf27dffd 100644 --- a/PWire.h +++ b/PWire.h @@ -130,6 +130,13 @@ class PWire : public PNamedItem { private: // not implemented PWire(const PWire&); PWire& operator= (const PWire&); + + ivl_type_t elaborate_type(Design*des, NetScope*scope, + const std::vector&packed_dimensions) const; + ivl_type_t elaborate_darray_type(Design*des, NetScope*scope, + const char *darray_type, + const std::vector&packed_dimensions) + const; }; #endif /* IVL_PWire_H */ diff --git a/elab_sig.cc b/elab_sig.cc index 47edb73d8..66275b46b 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -934,6 +934,64 @@ bool test_ranges_eeq(const vector&lef, const vector&rig) return true; } +ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope, + const std::vector&packed_dimensions) const +{ + if (dynamic_cast(set_data_type_) || + dynamic_cast(set_data_type_) || + dynamic_cast(set_data_type_) || + dynamic_cast(set_data_type_) || + dynamic_cast(set_data_type_)) { + ivl_type_t use_type = set_data_type_->elaborate_type(des, scope); + ivl_assert(*this, packed_dimensions.empty()); + return use_type; + } + + // Fallback method. Create vector type. + + ivl_variable_type_t use_data_type = data_type_; + if (use_data_type == IVL_VT_NO_TYPE) { + use_data_type = IVL_VT_LOGIC; + if (debug_elaborate) { + cerr << get_fileline() << ": PWire::elaborate_sig: " + << "Signal " << name_ + << " in scope " << scope_path(scope) + << " defaults to data type " << use_data_type << endl; + } + } + + ivl_assert(*this, use_data_type == IVL_VT_LOGIC || + use_data_type == IVL_VT_BOOL || + use_data_type == IVL_VT_REAL); + + netvector_t*vec = new netvector_t(packed_dimensions, use_data_type); + vec->set_signed(get_signed()); + vec->set_isint(get_isint()); + + return vec; +} + +ivl_type_t PWire::elaborate_darray_type(Design*des, NetScope*scope, + const char *darray_type, + const std::vector&packed_dimensions) + const +{ + ivl_type_t type = elaborate_type(des, scope, packed_dimensions); + + if (dynamic_cast(type) || + dynamic_cast(type) || + dynamic_cast(type) || + dynamic_cast(type)) + return type; + + cerr << get_fileline() << ": Sorry: " + << darray_type << " of type `" << *type + << "` is not yet supported." << endl; + des->errors++; + + // Return something to recover + return new netvector_t(IVL_VT_LOGIC); +} /* * Elaborate a source wire. The "wire" is the declaration of wires, @@ -1100,19 +1158,21 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const // dimensions, then turn this into a dynamic array and // put all the packed dimensions there. if (use_lidx==0 && use_ridx==0) { - ivl_type_t vec = make_ivl_type(data_type_, packed_dimensions, - get_signed()); + ivl_type_t base_type = elaborate_darray_type(des, scope, + "Dynamic array", + packed_dimensions); packed_dimensions.clear(); ivl_assert(*this, netdarray==0); - netdarray = new netdarray_t(vec); + netdarray = new netdarray_t(base_type); continue; } // Special case: Detect the mark for a QUEUE // declaration, which is the dimensions [null:max_idx]. if (dynamic_cast(use_lidx)) { - ivl_type_t vec = make_ivl_type(data_type_, packed_dimensions, - get_signed()); + ivl_type_t base_type = elaborate_darray_type(des, scope, + "Queue", + packed_dimensions); packed_dimensions.clear(); ivl_assert(*this, netdarray==0); long max_idx; @@ -1144,7 +1204,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const } } } else max_idx = -1; - netdarray = new netqueue_t(vec, max_idx); + netdarray = new netqueue_t(base_type, max_idx); continue; } @@ -1213,52 +1273,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const NetNet*sig = 0; - if (class_type_t*class_type = dynamic_cast(set_data_type_)) { - // If this is a class variable, then the class type - // should already have been elaborated. All we need to - // do right now is locate the netclass_t object for the - // class, and use that to build the net. - - ivl_assert(*this, class_type->save_elaborated_type); - netclass_t*use_type = class_type->save_elaborated_type; - - sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type); - - } else if (struct_type_t*struct_type = dynamic_cast(set_data_type_)) { - // If this is a struct type, then build the net with the - // struct type. - ivl_type_s*tmp_type = struct_type->elaborate_type(des, scope); - netstruct_t*use_type = dynamic_cast(tmp_type); - if (debug_elaborate) { - cerr << get_fileline() << ": debug: Create signal " << wtype; - if (use_type->packed()) - cerr << " " << use_type->packed_width() << " bit packed struct "; - else - cerr << " struct <> "; - cerr << name_; - cerr << " in scope " << scope_path(scope) << endl; - } - - sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type); - - } else if (enum_type_t*enum_type = dynamic_cast(set_data_type_)) { - list::const_iterator sample_name = enum_type->names->begin(); - const netenum_t*use_enum = base_type_scope->find_enumeration_for_name(des, sample_name->name); - - if (debug_elaborate) { - cerr << get_fileline() << ": PWire::elaborate_sig: " - << "Create signal " << wtype - << " enumeration " - << name_ << " in scope " << scope_path(scope) - << " with packed_dimensions=" << packed_dimensions - << " and packed_width=" << use_enum->packed_width() << endl; - } - - ivl_assert(*this, packed_dimensions.empty()); - sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_enum); - - - } else if (netdarray) { + if (netdarray) { if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " @@ -1272,76 +1287,18 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const ivl_assert(*this, unpacked_dimensions.empty()); sig = new NetNet(scope, name_, wtype, netdarray); - } else if (dynamic_cast(set_data_type_)) { - - // Signal declared as: string foo; - if (debug_elaborate) { - cerr << get_fileline() << ": " << __func__ << ": " - << "Create signal " << wtype - << " string " - << name_ << " in scope " << scope_path(scope) - << endl; - } - - sig = new NetNet(scope, name_, wtype, unpacked_dimensions, - &netstring_t::type_string); - - } else if (parray_type_t*parray_type = dynamic_cast(set_data_type_)) { - // The pform gives us a parray_type_t for packed arrays - // that show up in type definitions. This can be handled - // a lot like packed dimensions from other means. - - // The trick here is that the parray type has an - // arbitrary sub-type, and not just a scalar bit... - ivl_type_t tmp_type = parray_type->elaborate_type(des, scope); - const netparray_t*use_type = dynamic_cast(tmp_type); - // Should not be getting packed dimensions other than - // through the parray type declaration. - ivl_assert(*this, packed_dimensions.empty()); + } else { + ivl_type_t use_type = elaborate_type(des, scope, + packed_dimensions); if (debug_elaborate) { - cerr << get_fileline() << ": debug: Create signal " << wtype - << " parray=" << use_type->static_dimensions() + cerr << get_fileline() << ": debug: Create signal " + << wtype << " " << *set_data_type_ << " " << name_ << unpacked_dimensions << " in scope " << scope_path(scope) << endl; } sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type); - - - } else { - if (debug_elaborate) { - cerr << get_fileline() << ": PWire::elaborate_sig: " - << "Create vector signal " << wtype - << " data_type=" << data_type_; - if (!packed_dimensions.empty()) { - cerr << " " << packed_dimensions; - } - cerr << " " << name_ << unpacked_dimensions; - cerr << " in scope " << scope_path(scope) << endl; - } - - ivl_variable_type_t use_data_type = data_type_; - if (use_data_type == IVL_VT_NO_TYPE) { - use_data_type = IVL_VT_LOGIC; - if (debug_elaborate) { - cerr << get_fileline() << ": PWire::elaborate_sig: " - << "Signal " << name_ - << " in scope " << scope_path(scope) - << " defaults to data type " << use_data_type << endl; - } - } - - ivl_assert(*this, use_data_type == IVL_VT_LOGIC || - use_data_type == IVL_VT_BOOL || - use_data_type == IVL_VT_REAL); - - netvector_t*vec = new netvector_t(packed_dimensions, use_data_type); - vec->set_signed(get_signed()); - vec->set_isint(get_isint()); - packed_dimensions.clear(); - sig = new NetNet(scope, name_, wtype, unpacked_dimensions, vec); - } if (wtype == NetNet::WIRE) sig->devirtualize_pins(); diff --git a/ivtest/gold/sv_queue_parray.gold b/ivtest/gold/sv_queue_parray.gold new file mode 100644 index 000000000..7cedbd4c8 --- /dev/null +++ b/ivtest/gold/sv_queue_parray.gold @@ -0,0 +1,16 @@ +./ivltests/sv_queue_parray.v:35: Warning: skipping delete(0) on empty queue. +./ivltests/sv_queue_parray.v:39: Warning: pop_front() on empty queue. +./ivltests/sv_queue_parray.v:45: Warning: pop_back() on empty queue. +./ivltests/sv_queue_parray.v:56: Warning: skipping out of range delete(3) on queue of size 3. +./ivltests/sv_queue_parray.v:57: Warning: skipping queue delete() with negative index. +./ivltests/sv_queue_parray.v:58: Warning: skipping queue delete() with undefined index. +./ivltests/sv_queue_parray.v:132: Warning: cannot assign to a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:133: Warning: cannot assign to an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:134: Warning: assigning to queue[4] is outside of size (3). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:137: Warning: cannot assign to a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:139: Warning: cannot assign to an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:141: Warning: assigning to queue[4] is outside of size (3). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:153: Warning: cannot insert at a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:154: Warning: cannot insert at an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray.v:155: Warning: inserting to queue[5] is outside of size (4). 40'b0000000000000000000000000000000000001010 was not added. +PASSED diff --git a/ivtest/gold/sv_queue_parray_bounded.gold b/ivtest/gold/sv_queue_parray_bounded.gold new file mode 100644 index 000000000..9de22b87d --- /dev/null +++ b/ivtest/gold/sv_queue_parray_bounded.gold @@ -0,0 +1,9 @@ +./ivltests/sv_queue_parray_bounded.v:61: Warning: Array pattern assignment has more elements (4) than bounded queue 'q_tst' supports (3). + Only using first 3 elements. +./ivltests/sv_queue_parray_bounded.v:38: Warning: push_back(40'b0000000000000000000000000000000001100100) skipped for already full bounded queue [3]. +./ivltests/sv_queue_parray_bounded.v:45: Warning: push_front(40'b0000000000000000000000000000000000000101) removed 40'b0000000000000000000000000000000000000011 from already full bounded queue [3]. +./ivltests/sv_queue_parray_bounded.v:46: Warning: assigning to queue[3] is outside bound (3). 40'b0000000000000000000000000000000000000011 was not added. +./ivltests/sv_queue_parray_bounded.v:53: Warning: inserting to queue[3] is outside bound (3). 40'b0000000000000000000000000000000000001010 was not added. +./ivltests/sv_queue_parray_bounded.v:54: Warning: insert(1, 40'b0000000000000000000000000000000000000010) removed 40'b0000000000000000000000000000000000000010 from already full bounded queue [3]. +./ivltests/sv_queue_parray_bounded.v:69: Warning: queue is bounded to have at most 3 elements, source has 4 elements. +PASSED diff --git a/ivtest/gold/sv_queue_parray_fail.gold b/ivtest/gold/sv_queue_parray_fail.gold new file mode 100644 index 000000000..8bf76072b --- /dev/null +++ b/ivtest/gold/sv_queue_parray_fail.gold @@ -0,0 +1,10 @@ +./ivltests/sv_queue_parray_fail.v:7: error: queue 'q_vec1' bound must be positive (-1)! +./ivltests/sv_queue_parray_fail.v:8: error: queue 'q_vec2' bound is undefined! +./ivltests/sv_queue_parray_fail.v:9: error: A reference to a wire or reg (`bound') is not allowed in a constant expression. +./ivltests/sv_queue_parray_fail.v:9: error: queue 'q_vec3' bound must be a constant! +./ivltests/sv_queue_parray_fail.v:12: error: size() method takes no arguments +./ivltests/sv_queue_parray_fail.v:13: error: pop_front() method takes no arguments +./ivltests/sv_queue_parray_fail.v:14: error: pop_back() method takes no arguments +./ivltests/sv_queue_parray_fail.v:15: error: push_front() method requires a single argument. +./ivltests/sv_queue_parray_fail.v:16: error: push_back() method requires a single argument. +9 error(s) during elaboration. diff --git a/ivtest/ivltests/sv_darray7.v b/ivtest/ivltests/sv_darray7.v new file mode 100644 index 000000000..d62cf0732 --- /dev/null +++ b/ivtest/ivltests/sv_darray7.v @@ -0,0 +1,54 @@ +// Check that dynamic arrays of packed array types are supported + +module main; + + typedef reg [3:0] T1; + typedef T1 [7:0] T2; + + T2 foo[]; + int idx; + + initial begin + if (foo.size() != 0) begin + $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); + $finish; + end + + foo = new[10]; + if (foo.size() != 10) begin + $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); + $finish; + end + + for (idx = 0 ; idx < foo.size() ; idx += 1) begin + foo[idx] = idx; + end + + $display("foo[7] = %d", foo[7]); + if (foo[7] != 7) begin + $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); + $finish; + end + + $display("foo[9] = %d", foo[9]); + if (foo[9] != 9) begin + $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); + $finish; + end + + for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin + if (foo[idx%10] != (idx%10)) begin + $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); + $finish; + end + end + + foo.delete(); + if (foo.size() != 0) begin + $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); + $finish; + end + + $display("PASSED"); + end +endmodule // main diff --git a/ivtest/ivltests/sv_queue_parray.v b/ivtest/ivltests/sv_queue_parray.v new file mode 100644 index 000000000..a581a5910 --- /dev/null +++ b/ivtest/ivltests/sv_queue_parray.v @@ -0,0 +1,195 @@ +module top; + typedef reg [4:0] T1; + typedef T1 [7:0] T2; + + T2 q_tst [$]; + T2 q_tmp [$]; + T2 elem; + integer idx; + bit passed; + + task automatic check_size(integer size, + string fname, + integer lineno); + if (q_tst.size !== size) begin + $display("%s:%0d: Failed: queue size != %0d (%0d)", + fname, lineno, size, q_tst.size); + passed = 1'b0; + end + endtask + + task automatic check_idx_value(integer idx, + T2 expected, + string fname, + integer lineno); + if (q_tst[idx] != expected) begin + $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", + fname, lineno, idx, expected, q_tst[idx]); + passed = 1'b0; + end + endtask + + initial begin + passed = 1'b1; + + q_tst.delete(0); // Warning: skip delete on an empty queue + check_size(0, `__FILE__, `__LINE__); + check_idx_value(0, 0, `__FILE__, `__LINE__); + + elem = q_tst.pop_front(); // Warning: cannot pop_front() an empty queue + if (elem !== 'X) begin + $display("Failed: pop_front() != 'X (%0d)", elem); + passed = 1'b0; + end + + elem = q_tst.pop_back(); // Warning: cannot pop_back() an empty queue + if (elem !== 'X) begin + $display("Failed: pop_back() != 'X (%0d)", elem); + passed = 1'b0; + end + + q_tst.push_back(2); + q_tst.push_front(1); + q_tst.push_back(3); + q_tst.push_back(100); + q_tst.delete(3); // Should $ work here? + q_tst.delete(3); // Warning: skip an out of range delete() + q_tst.delete(-1); // Warning: skip delete with negative index + q_tst.delete('X); // Warning: skip delete with undefined index + + check_size(3, `__FILE__, `__LINE__); + + if (q_tst[0] !== 1) begin + $display("Failed: element [0] != 1 (%0d)", q_tst[0]); + passed = 1'b0; + end + + if (q_tst[1] !== 2) begin + $display("Failed: element [1] != 2 (%0d)", q_tst[1]); + passed = 1'b0; + end + + if (q_tst[2] !== 3) begin + $display("Failed: element [2] != 3 (%0d)", q_tst[2]); + passed = 1'b0; + end + + if (q_tst[3] !== 'X) begin + $display("Failed: element [3] != 'X (%0d)", q_tst[3]); + passed = 1'b0; + end + + if (q_tst[-1] !== 'X) begin + $display("Failed: element [-1] != 'X (%0d)", q_tst[-1]); + passed = 1'b0; + end + + if (q_tst['X] !== 'X) begin + $display("Failed: element ['X] != 'X (%0d)", q_tst['X]); + passed = 1'b0; + end + + check_idx_value(-1, 0.0, `__FILE__, `__LINE__); + check_idx_value('X, 0.0, `__FILE__, `__LINE__); + + elem = q_tst.pop_front(); + if (elem !== 1) begin + $display("Failed: element pop_front() != 1 (%0d)", elem); + passed = 1'b0; + end + + elem = q_tst.pop_back(); + if (elem !== 3) begin + $display("Failed: element pop_back() != 3 (%0d)", elem); + passed = 1'b0; + end + + check_size(1, `__FILE__, `__LINE__); + + if ((q_tst[0] !== q_tst[$]) || (q_tst[0] !== 2)) begin + $display("Failed: q_tst[0](%0d) != q_tst[$](%0d) != 2", + q_tst[0], q_tst[$]); + passed = 1'b0; + end + + q_tst.delete(); + + check_size(0, `__FILE__, `__LINE__); + + q_tst.push_front(5); + q_tst.push_front(100); + q_tst.push_back(100); + elem = q_tst.pop_back; + elem = q_tst.pop_front; + + check_size(1, `__FILE__, `__LINE__); + check_idx_value(0, 5, `__FILE__, `__LINE__); + + q_tst[0] = 1; + q_tst[1] = 3; + q_tst[1] = 2; + q_tst[2] = 3; + q_tst[-1] = 10; // Warning: will not be added (negative index) + q_tst['X] = 10; // Warning: will not be added (undefined index) + q_tst[4] = 10; // Warning: will not be added (out of range index) + + idx = -1; + q_tst[idx] = 10; // Warning: will not be added (negative index) + idx = 3'b0x1; + q_tst[idx] = 10; // Warning: will not be added (undefined index) + idx = 4; + q_tst[idx] = 10; // Warning: will not be added (out of range index) + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 1, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 3, `__FILE__, `__LINE__); + + q_tst.delete(); + q_tst[0] = 2; + q_tst.insert(1, 4); + q_tst.insert(0, 1); + q_tst.insert(2, 3); + q_tst.insert(-1, 10); // Warning: will not be added (negative index) + q_tst.insert('X, 10); // Warning: will not be added (undefined index) + q_tst.insert(5, 10); // Warning: will not be added (out of range index) + + check_size(4, `__FILE__, `__LINE__); + check_idx_value(0, 1, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 3, `__FILE__, `__LINE__); + check_idx_value(3, 4, `__FILE__, `__LINE__); + + q_tst = '{3, 2, 1}; + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 3, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 1, `__FILE__, `__LINE__); + + q_tmp = '{1, 2}; + q_tst = q_tmp; + q_tmp[0] = 3; + q_tmp[2] = 1; + + check_size(2, `__FILE__, `__LINE__); + check_idx_value(0, 1.0, `__FILE__, `__LINE__); + check_idx_value(1, 2.0, `__FILE__, `__LINE__); + + q_tst[2] = 3; + check_size(3, `__FILE__, `__LINE__); + check_idx_value(2, 3, `__FILE__, `__LINE__); + + q_tst = {1, 2}; + check_size(2, `__FILE__, `__LINE__); + check_idx_value(0, 1, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + + q_tst = '{}; + + check_size(0, `__FILE__, `__LINE__); + + if (passed) $display("PASSED"); + + end +endmodule : top diff --git a/ivtest/ivltests/sv_queue_parray_bounded.v b/ivtest/ivltests/sv_queue_parray_bounded.v new file mode 100644 index 000000000..a2ba3751b --- /dev/null +++ b/ivtest/ivltests/sv_queue_parray_bounded.v @@ -0,0 +1,80 @@ +module top; + typedef reg [4:0] T1; + typedef T1 [7:0] T2; + + T2 q_tst [$:2]; + T2 q_tmp [$]; + bit passed; + + task automatic check_size(integer size, + string fname, + integer lineno); + if (q_tst.size !== size) begin + $display("%s:%0d: Failed: queue size != %0d (%0d)", + fname, lineno, size, q_tst.size); + passed = 1'b0; + end + endtask + + task automatic check_idx_value(integer idx, + T2 expected, + string fname, + integer lineno); + if (q_tst[idx] != expected) begin + $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", + fname, lineno, idx, expected, q_tst[idx]); + passed = 1'b0; + end + endtask + + initial begin + passed = 1'b1; + + check_size(0, `__FILE__, `__LINE__); + + q_tst.push_back(2); + q_tst.push_front(1); + q_tst.push_back(3); + q_tst.push_back(100); // Warning: item not added. + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 1, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 3, `__FILE__, `__LINE__); + + q_tst.push_front(5); // Warning: back item removed. + q_tst[3] = 3; // Warning: item not added. + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 5, `__FILE__, `__LINE__); + check_idx_value(1, 1, `__FILE__, `__LINE__); + check_idx_value(2, 2, `__FILE__, `__LINE__); + + q_tst.insert(3, 10); // Warning: item not added. + q_tst.insert(1, 2); // Warning: back item removed. + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 5, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 1, `__FILE__, `__LINE__); + + q_tst = '{1, 2, 3, 4}; // Warning: items not added. + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 1, `__FILE__, `__LINE__); + check_idx_value(1, 2, `__FILE__, `__LINE__); + check_idx_value(2, 3, `__FILE__, `__LINE__); + + q_tmp = '{4, 3, 2, 1}; + q_tst = q_tmp; // Warning not all items copied + q_tmp[0] = 5; + + check_size(3, `__FILE__, `__LINE__); + check_idx_value(0, 4, `__FILE__, `__LINE__); + check_idx_value(1, 3, `__FILE__, `__LINE__); + check_idx_value(2, 2, `__FILE__, `__LINE__); + + if (passed) $display("PASSED"); + + end +endmodule : top diff --git a/ivtest/ivltests/sv_queue_parray_fail.v b/ivtest/ivltests/sv_queue_parray_fail.v new file mode 100644 index 000000000..2d5c046d1 --- /dev/null +++ b/ivtest/ivltests/sv_queue_parray_fail.v @@ -0,0 +1,19 @@ +module top; + typedef reg [4:0] T1; + typedef T1 [7:0] T2; + + int bound = 2; + T2 q_vec [$]; + T2 q_vec1 [$:-1]; + T2 q_vec2 [$:'X]; + T2 q_vec3 [$:bound]; + + initial begin + $display(q_vec.size(1)); + $display(q_vec.pop_front(1)); + $display(q_vec.pop_back(1)); + q_vec.push_front(1, 2); + q_vec.push_back(1, 2); + $display("FAILED"); + end +endmodule : top diff --git a/ivtest/ivltests/unp_array_typedef.v b/ivtest/ivltests/unp_array_typedef.v index bbb0377a5..73c3c3311 100644 --- a/ivtest/ivltests/unp_array_typedef.v +++ b/ivtest/ivltests/unp_array_typedef.v @@ -43,7 +43,8 @@ module unp_array_typedef(); real_unparray real_unparr; int_darray int_darr; int_unparray int_unparr; - word_darray word_darr; + // TODO at the moment dynamic arrays of struct are not supported + // word_darray word_darr; word_unparray word_unparr; initial begin diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index f5a39d697..278d6a3fa 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -453,6 +453,7 @@ sv_darray4 normal,-g2009 ivltests sv_darray5 normal,-g2009 ivltests sv_darray5b normal,-g2009 ivltests sv_darray6 normal,-g2009 ivltests +sv_darray7 normal,-g2009 ivltests sv_darray_args1 normal,-g2009 ivltests sv_darray_args2 normal,-g2009 ivltests sv_darray_args2b normal,-g2009 ivltests @@ -514,6 +515,9 @@ sv_port_default14 CE,-g2009 ivltests sv_queue1 normal,-g2009 ivltests sv_queue2 normal,-g2009 ivltests sv_queue3 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 sv_queue_real normal,-g2009,-pfileline=1 ivltests gold=sv_queue_real.gold sv_queue_real_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_real_bounded.gold sv_queue_real_fail CE,-g2009 ivltests gold=sv_queue_real_fail.gold diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index a18da3562..dfc00dbfd 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -312,6 +312,7 @@ sv_darray4 CE,-g2009,-pallowsigned=1 ivltests sv_darray5 CE,-g2009,-pallowsigned=1 ivltests sv_darray5b CE,-g2009,-pallowsigned=1 ivltests sv_darray6 CE,-g2009,-pallowsigned=1 ivltests # Also string +sv_darray7 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args1 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args2 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args2b CE,-g2009,-pallowsigned=1 ivltests @@ -588,6 +589,9 @@ sv_queue_string_fail CE,-g2009 ivltests sv_queue_vec CE,-g2009,-pallowsigned=1 ivltests sv_queue_vec_bounded CE,-g2009,-pallowsigned=1 ivltests sv_queue_vec_fail CE,-g2009,-pallowsigned=1 ivltests +sv_queue_parray CE,-g2009, ivltests +sv_queue_parray_bounded CE,-g2009, ivltests +sv_queue_parray_fail CE,-g2009, ivltests test_forgen CE,-g2009,ivltests/forgen.vhd ivltests test_gxor CE,-g2009,-pallowsigned=1,ivltests/gxor.vhd ivltests test_varray1 CE,-g2009,-pallowsigned=1,ivltests/varray1.vhd ivltests diff --git a/make_ivl_type.cc b/make_ivl_type.cc deleted file mode 100644 index 963a5eace..000000000 --- a/make_ivl_type.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -# include "nettypes.h" -# include "netscalar.h" -# include "netvector.h" - -ivl_type_t make_ivl_type(ivl_variable_type_t vt, - const std::vector&packed_dimensions, - bool signed_flag, bool isint_flag) -{ - netvector_t*vec; - - if (packed_dimensions.size() > 0) { - vec = new netvector_t(packed_dimensions, vt); - vec->set_signed(signed_flag); - return vec; - } - - switch (vt) { - case IVL_VT_REAL: - return &netreal_t::type_real; - case IVL_VT_STRING: - return &netstring_t::type_string; - default: - vec = new netvector_t(packed_dimensions, vt); - vec->set_signed(signed_flag); - vec->set_isint(isint_flag); - return vec; - } -} diff --git a/tgt-vvp/eval_object.c b/tgt-vvp/eval_object.c index 0da8caa62..c38b432bd 100644 --- a/tgt-vvp/eval_object.c +++ b/tgt-vvp/eval_object.c @@ -28,18 +28,7 @@ void darray_new(ivl_type_t element_type, unsigned size_reg) ivl_variable_type_t type = ivl_type_base(element_type); if ((type == IVL_VT_BOOL) || (type == IVL_VT_LOGIC)) { - // bool objects are vectorable, but for now only support - // a single dimensions. - assert(ivl_type_packed_dimensions(element_type) <= 1); - if (ivl_type_packed_dimensions(element_type) == 1) { - int msb, lsb; - msb = ivl_type_packed_msb(element_type, 0); - lsb = ivl_type_packed_lsb(element_type, 0); - wid = msb>=lsb ? msb - lsb : lsb - msb; - wid += 1; - } else { - wid = 1; - } + wid = width_of_packed_type(element_type); signed_char = ivl_type_signed(element_type) ? "s" : ""; } else { // REAL or STRING objects are not packable.