Merge 87dfed3cdd into b8de0499a9
This commit is contained in:
commit
9892a9503e
78
elab_expr.cc
78
elab_expr.cc
|
|
@ -1983,6 +1983,15 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
} else {
|
||||
// Check if the expression could be resolved. If test_width
|
||||
// failed to find the identifier, expr_type will be NO_TYPE.
|
||||
if (expr->expr_type() == IVL_VT_NO_TYPE) {
|
||||
// Try to elaborate the expression to get a proper error
|
||||
// message about the undefined identifier.
|
||||
NetExpr *tmp = expr->elaborate_expr(des, scope, (unsigned)1, flags);
|
||||
if (tmp) delete tmp;
|
||||
return 0;
|
||||
}
|
||||
use_width = expr->expr_width();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
|
||||
|
|
@ -2380,12 +2389,17 @@ bool calculate_part(const LineInfo*li, Design*des, NetScope*scope,
|
|||
* the net is a struct. If that turns out to be the case, and the
|
||||
* struct is packed, then return a NetExpr that selects the member out
|
||||
* of the variable.
|
||||
*
|
||||
* The word_index parameter is used when the struct is in an unpacked
|
||||
* array - it selects which array word to access before the packed
|
||||
* member selection.
|
||||
*/
|
||||
static NetExpr* check_for_struct_members(const LineInfo*li,
|
||||
Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
const list<index_component_t>&base_index,
|
||||
pform_name_t member_path)
|
||||
pform_name_t member_path,
|
||||
NetExpr*word_index = 0)
|
||||
{
|
||||
const netstruct_t*struct_type = net->struct_type();
|
||||
ivl_assert(*li, struct_type);
|
||||
|
|
@ -2698,7 +2712,7 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
packed_base = 0;
|
||||
}
|
||||
|
||||
NetESignal*sig = new NetESignal(net);
|
||||
NetESignal*sig = new NetESignal(net, word_index);
|
||||
NetExpr *base = packed_base? packed_base : make_const_val(off);
|
||||
NetESelect*sel = new NetESelect(sig, base, use_width, member_type);
|
||||
|
||||
|
|
@ -2706,13 +2720,59 @@ static NetExpr* check_for_struct_members(const LineInfo*li,
|
|||
cerr << li->get_fileline() << ": check_for_struct_member: "
|
||||
<< "Finally, completed_path=" << completed_path
|
||||
<< ", off=" << off << ", use_width=" << use_width
|
||||
<< ", base=" << *base
|
||||
<< endl;
|
||||
<< ", base=" << *base;
|
||||
if (word_index)
|
||||
cerr << ", word_index=" << *word_index;
|
||||
cerr << endl;
|
||||
}
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to elaborate struct member access in an unpacked array.
|
||||
* This handles separating unpacked indices from packed indices,
|
||||
* computing the word index, and calling check_for_struct_members.
|
||||
*/
|
||||
static NetExpr* elaborate_struct_member_access(const PExpr*expr,
|
||||
Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
const pform_name_t&path_head,
|
||||
const pform_name_t&path_tail)
|
||||
{
|
||||
// Separate unpacked indices from packed indices.
|
||||
// check_for_struct_members expects only packed indices.
|
||||
list<index_component_t> all_index = path_head.back().index;
|
||||
list<index_component_t> unpacked_index;
|
||||
for (unsigned idx = 0 ; idx < net->unpacked_dimensions() ; idx += 1) {
|
||||
unpacked_index.push_back(all_index.front());
|
||||
all_index.pop_front();
|
||||
}
|
||||
list<index_component_t>& packed_index = all_index;
|
||||
|
||||
// Compute word index for unpacked array access.
|
||||
NetExpr*word_index = 0;
|
||||
if (net->unpacked_dimensions() > 0) {
|
||||
list<NetExpr*>unpacked_indices_expr;
|
||||
list<long> unpacked_indices_const;
|
||||
indices_flags idx_flags;
|
||||
indices_to_expressions(des, scope, expr,
|
||||
unpacked_index, net->unpacked_dimensions(),
|
||||
false, idx_flags,
|
||||
unpacked_indices_expr, unpacked_indices_const);
|
||||
|
||||
if (idx_flags.variable) {
|
||||
word_index = normalize_variable_unpacked(net, unpacked_indices_expr);
|
||||
} else if (!idx_flags.invalid && !idx_flags.undefined) {
|
||||
word_index = normalize_variable_unpacked(net, unpacked_indices_const);
|
||||
}
|
||||
}
|
||||
|
||||
return check_for_struct_members(expr, des, scope, net,
|
||||
packed_index,
|
||||
path_tail, word_index);
|
||||
}
|
||||
|
||||
static NetExpr* class_static_property_expression(const LineInfo*li,
|
||||
const netclass_t*class_type,
|
||||
perm_string name)
|
||||
|
|
@ -4546,9 +4606,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
|
||||
if (!sr.path_tail.empty()) {
|
||||
if (net->struct_type()) {
|
||||
return check_for_struct_members(this, des, scope, net,
|
||||
sr.path_head.back().index,
|
||||
sr.path_tail);
|
||||
return elaborate_struct_member_access(this, des, scope, net,
|
||||
sr.path_head, sr.path_tail);
|
||||
} else if (dynamic_cast<const netclass_t*>(sr.type)) {
|
||||
return elaborate_expr_class_field_(des, scope, sr, 0, flags);
|
||||
}
|
||||
|
|
@ -4773,9 +4832,8 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope,
|
|||
<< endl;
|
||||
}
|
||||
|
||||
return check_for_struct_members(this, des, scope, sr.net,
|
||||
sr.path_head.back().index,
|
||||
sr.path_tail);
|
||||
return elaborate_struct_member_access(this, des, scope, sr.net,
|
||||
sr.path_head, sr.path_tail);
|
||||
}
|
||||
|
||||
// If this is an array object, and there are members in
|
||||
|
|
|
|||
67
elab_lval.cc
67
elab_lval.cc
|
|
@ -528,9 +528,8 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
bool need_const_idx,
|
||||
bool is_force) const
|
||||
{
|
||||
list<long>prefix_indices;
|
||||
bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices);
|
||||
if (!rc) return false;
|
||||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
|
@ -539,8 +538,66 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb == 0);
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
// First, check if packed prefix indices contain any variable expressions.
|
||||
// Build the list of packed indices (excluding unpacked dimensions).
|
||||
list<index_component_t> packed_index;
|
||||
packed_index = name_tail.index;
|
||||
for (size_t idx = 0 ; idx < reg->unpacked_dimensions() ; idx += 1)
|
||||
packed_index.pop_front();
|
||||
|
||||
// For multi-dimensional packed arrays, check if the prefix indices
|
||||
// (all but the final) contain any non-constant expressions.
|
||||
bool has_variable_prefix = false;
|
||||
if (packed_index.size() > 1) {
|
||||
list<index_component_t>::const_iterator icur = packed_index.begin();
|
||||
for (size_t idx = 0 ; (idx+1) < packed_index.size() ; idx += 1, ++icur) {
|
||||
NetExpr*texpr = elab_and_eval(des, scope, icur->msb, -1, false);
|
||||
if (texpr == 0 || !dynamic_cast<NetEConst*>(texpr)) {
|
||||
has_variable_prefix = true;
|
||||
}
|
||||
delete texpr;
|
||||
if (has_variable_prefix) break;
|
||||
}
|
||||
}
|
||||
|
||||
// If prefix indices are variable, handle using expression-based path.
|
||||
if (has_variable_prefix) {
|
||||
if (need_const_idx) {
|
||||
cerr << get_fileline() << ": error: '" << reg->name()
|
||||
<< "' index must be a constant in this context."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) {
|
||||
ivl_assert(*this, reg->coerced_to_uwire());
|
||||
report_mixed_assignment_conflict_("bit select");
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use collapse_array_exprs to compute the bit offset as an expression.
|
||||
NetExpr*base_expr = collapse_array_exprs(des, scope, this, reg, packed_index);
|
||||
if (base_expr == 0) {
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_bit_: "
|
||||
<< "Variable packed prefix, base_expr=" << *base_expr
|
||||
<< endl;
|
||||
}
|
||||
|
||||
lv->set_part(base_expr, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// All prefix indices are constant. Use the existing code path.
|
||||
list<long>prefix_indices;
|
||||
bool rc = calculate_packed_indices_(des, scope, reg, prefix_indices);
|
||||
if (!rc) return false;
|
||||
|
||||
// Bit selects have a single select expression. Evaluate the
|
||||
// constant value and treat it as a part select with a bit
|
||||
|
|
|
|||
|
|
@ -1212,7 +1212,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
|
|||
|
||||
NetNet*sig = new NetNet(scope, name_, wtype, unpacked_dimensions, type);
|
||||
|
||||
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
|
||||
if (wtype == NetNet::WIRE || wtype == NetNet::UNRESOLVED_WIRE)
|
||||
sig->devirtualize_pins();
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->lexical_pos(lexical_pos_);
|
||||
|
|
|
|||
40
elaborate.cc
40
elaborate.cc
|
|
@ -133,8 +133,26 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
// If this turns out to be an assignment to an unpacked array,
|
||||
// then handle that special case elsewhere.
|
||||
// then handle that special case elsewhere. We need to distinguish:
|
||||
// 1. Whole array assignment: `assign arr = expr` -> elaborate_unpacked_array_
|
||||
// 2. Indexed element assignment: `assign arr[i] = expr` -> normal path
|
||||
// For single-element arrays ([0:0]), pin_count() is 1 but we still need
|
||||
// to handle whole-array assignments specially (#1265).
|
||||
bool is_whole_array = false;
|
||||
if (lval->pin_count() > 1) {
|
||||
// Multi-element array is always a whole-array assignment
|
||||
is_whole_array = true;
|
||||
} else if (lval->unpacked_dimensions() > 0) {
|
||||
// Single-element unpacked array. Check if lval has array indices.
|
||||
const PEIdent* lval_ident = dynamic_cast<const PEIdent*>(pin(0));
|
||||
if (lval_ident && !lval_ident->path().name.empty()) {
|
||||
// If the identifier has no indices, it's a whole-array reference
|
||||
if (lval_ident->path().back().index.empty()) {
|
||||
is_whole_array = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_whole_array) {
|
||||
elaborate_unpacked_array_(des, scope, lval);
|
||||
return;
|
||||
}
|
||||
|
|
@ -774,11 +792,13 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
// Gates can never have variable output ports.
|
||||
// In SystemVerilog, variables can be driven by a single
|
||||
// primitive/gate output (IEEE 1800-2017 6.5). Primitives always
|
||||
// use default (strong) drive strength.
|
||||
if (lval_count > gate_count)
|
||||
lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope, false);
|
||||
lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope, gn_system_verilog());
|
||||
else
|
||||
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope, false);
|
||||
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope, gn_system_verilog());
|
||||
|
||||
// The only way this should return zero is if an error
|
||||
// happened, so for that case just return.
|
||||
|
|
@ -4338,9 +4358,15 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
|
|||
rv = cast_to_int4(rv, lv_width);
|
||||
break;
|
||||
default:
|
||||
/* Don't yet know how to handle this. */
|
||||
ivl_assert(*this, 0);
|
||||
break;
|
||||
/* Cannot cast between these types. */
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Type of task port " << (idx+1)
|
||||
<< " is not compatible with the argument type."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
delete rv;
|
||||
delete lv;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
rv = pad_to_width(rv, lv_width, *this);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
./ivltests/br_gh1112.v:4: error: Unable to bind parameter `value' in `top'
|
||||
1 error(s) during elaboration.
|
||||
|
|
@ -2,8 +2,4 @@
|
|||
./ivltests/br_gh1222.v:6: error: Variable 'rout_ca2' cannot be driven by a primitive or continuous assignment with non-default strength.
|
||||
./ivltests/br_gh1222.v:7: error: Variable 'lout_ca1' cannot be driven by a primitive or continuous assignment with non-default strength.
|
||||
./ivltests/br_gh1222.v:7: error: Variable 'lout_ca2' cannot be driven by a primitive or continuous assignment with non-default strength.
|
||||
./ivltests/br_gh1222.v:12: error: Variable 'rout_gt' cannot be driven by a primitive or continuous assignment with non-default strength.
|
||||
./ivltests/br_gh1222.v:12: error: Failed to elaborate primitive output expression top.rout_gt.
|
||||
./ivltests/br_gh1222.v:13: error: Variable 'lout_gt' cannot be driven by a primitive or continuous assignment with non-default strength.
|
||||
./ivltests/br_gh1222.v:13: error: Failed to elaborate primitive output expression top.lout_gt.
|
||||
12 error(s) during elaboration.
|
||||
8 error(s) during elaboration.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
./ivltests/br_gh716.v:11: error: Type of task port 1 is not compatible with the argument type.
|
||||
1 error(s) during elaboration.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// Test for GitHub issue #1112
|
||||
// $bits() with non-existent identifier should produce an error
|
||||
module top;
|
||||
localparam width = $bits(value); // 'value' doesn't exist - should error
|
||||
initial $display(width);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Test for GitHub issue #1134
|
||||
// Accessing member of packed struct in unpacked array should work
|
||||
typedef struct packed {
|
||||
logic a, b;
|
||||
} test_t;
|
||||
|
||||
module test;
|
||||
// tests[0] = {a:0, b:1}, tests[1] = {a:1, b:0}
|
||||
test_t tests [0:1] = '{'{'b0, 'b1}, '{'b1, 'b0}};
|
||||
wire w0, w1;
|
||||
|
||||
assign w0 = tests[0].a; // Should be 0
|
||||
assign w1 = tests[1].a; // Should be 1
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
if (w0 !== 1'b0) begin
|
||||
$display("FAILED: tests[0].a = %b, expected 0", w0);
|
||||
$finish;
|
||||
end
|
||||
if (w1 !== 1'b1) begin
|
||||
$display("FAILED: tests[1].a = %b, expected 1", w1);
|
||||
$finish;
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// Test for GitHub issue #1170
|
||||
// tgt-sizer should work with SystemVerilog 2012 ($unit scope)
|
||||
module test;
|
||||
logic [7:0] data;
|
||||
assign data = 8'hAA;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Test for GitHub issue #1217
|
||||
// Unpacked array literal parsing
|
||||
module a(output bit b [0:0]);
|
||||
assign b = '{1'b0};
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
wire bit out_b [0:0];
|
||||
|
||||
a dut(.b(out_b));
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
if (out_b[0] !== 1'b0) begin
|
||||
$display("FAILED: out_b[0] = %b, expected 0", out_b[0]);
|
||||
$finish;
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Test for GitHub issue #1220
|
||||
// Assertion failed with uwire multi-dimensional input port
|
||||
module sub(input uwire data [1:0]);
|
||||
initial begin
|
||||
#1;
|
||||
if (data[0] === 1'b0 && data[1] === 1'b1)
|
||||
$display("PASSED");
|
||||
else
|
||||
$display("FAILED: data[0]=%0b data[1]=%0b", data[0], data[1]);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
wire w [1:0];
|
||||
assign w[0] = 1'b0;
|
||||
assign w[1] = 1'b1;
|
||||
|
||||
sub dut(.data(w));
|
||||
endmodule
|
||||
|
|
@ -9,8 +9,8 @@ module top;
|
|||
assign (strong1, strong0) rout_valid = in; // Ok, real cannot be in a concatenation
|
||||
assign (strong1, strong0) {lout_valid1, lout_valid2} = in; // Ok, default strength
|
||||
|
||||
and (rout_gt, in, in); // Gates must drive a net
|
||||
and (lout_gt, in, in); // Gates must drive a net
|
||||
and (rout_gt, in, in); // Ok in SV, variables can be driven by primitives (IEEE 1800-2017 6.5)
|
||||
and (lout_gt, in, in); // Ok in SV, variables can be driven by primitives (IEEE 1800-2017 6.5)
|
||||
|
||||
// When strength is added it should only be for the default strength!
|
||||
udp_inv (rout_udp, in); // A UDP is like a module and can drive a variable
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
// Test for GitHub issue #1224
|
||||
// Packed vs unpacked dimension confusion with byte array
|
||||
module a(output byte b [0:0]);
|
||||
assign b = '{8'd1}; // Should be interpreted as single byte value
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
wire byte out_b [0:0];
|
||||
|
||||
a dut(.b(out_b));
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
if (out_b[0] !== 8'd1) begin
|
||||
$display("FAILED: out_b[0] = %d, expected 1", out_b[0]);
|
||||
$finish;
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// Test for GitHub issue #1265
|
||||
// Single element unpacked array continuous assignment should compile
|
||||
module test(output o1 [0:0], input i1 [0:0]);
|
||||
assign o1 = i1;
|
||||
|
||||
// Verify the assignment works by checking a simple case
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Test for GitHub issue #1267
|
||||
// Wire logic connected to uwire port should not trigger multi-driver error
|
||||
// The uwire semantics apply only to the uwire signal, not to wires connected to it.
|
||||
|
||||
module a(input uwire logic a1);
|
||||
endmodule
|
||||
|
||||
module b();
|
||||
wire logic b1;
|
||||
|
||||
a b_inst(.a1(b1));
|
||||
not not_inst(b1, b1);
|
||||
|
||||
assign b1 = 'b0;
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
// b1 has multiple drivers, which is allowed for wire types
|
||||
// The value will be X due to conflicting drivers
|
||||
$display("b1 = %b (expected X due to conflicting drivers)", b1);
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Test for GitHub issue #1268
|
||||
// Variable (output logic) should be allowed to be driven by primitive gate
|
||||
// Per IEEE 1800-2017 6.5: variables can be written by one port (primitive output)
|
||||
|
||||
module driver(output logic c, input wire d);
|
||||
not b(c, d);
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
wire d = 1'b0;
|
||||
wire c;
|
||||
|
||||
driver dut(.c(c), .d(d));
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
if (c !== 1'b1) begin
|
||||
$display("FAILED: c = %b, expected 1", c);
|
||||
$finish;
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Test for GitHub issue #521
|
||||
// Loop index should be allowed in outer dimension of multi-dimensional packed arrays
|
||||
module test;
|
||||
logic [3:0][3:0] a;
|
||||
|
||||
initial begin
|
||||
a = 0;
|
||||
for (int i=0; i<4; i++)
|
||||
a[i][3] = 1;
|
||||
|
||||
// Each 4-bit sub-array has bit 3 set to 1, so each nibble is 0x8
|
||||
if (a !== 16'h8888) begin
|
||||
$display("FAILED: a = %h, expected 8888", a);
|
||||
$finish;
|
||||
end
|
||||
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Test for GitHub issue #670
|
||||
// Class method can have the same name as the class
|
||||
program main;
|
||||
class test;
|
||||
int value;
|
||||
|
||||
// Method with same name as class - should be valid
|
||||
function void test();
|
||||
$display("test method called");
|
||||
value = 42;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
test tst;
|
||||
|
||||
initial begin
|
||||
tst = new();
|
||||
tst.test();
|
||||
if (tst.value !== 42) begin
|
||||
$display("FAILED: value = %0d, expected 42", tst.value);
|
||||
$finish;
|
||||
end
|
||||
$display("PASSED");
|
||||
end
|
||||
endprogram
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Test for GitHub issue #716
|
||||
// Undimensioned array passed to task expecting single vector should error
|
||||
module test();
|
||||
logic [7:0] mybuf [];
|
||||
|
||||
task t1(output logic [7:0] buffer);
|
||||
buffer = 0;
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
t1(mybuf);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -102,7 +102,7 @@ sub read_regression_list {
|
|||
$args{$tname} = "";
|
||||
}
|
||||
if ($opt ne "std") {
|
||||
$args{$tname} = $opt . $args{$tname};
|
||||
$args{$tname} = $opt . ($args{$tname} ? " " . $args{$tname} : "");
|
||||
}
|
||||
|
||||
$srcpath{$tname} = $fields[2];
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ br_gh477 normal,-g2009 ivltests
|
|||
br_gh478 normal,-g2009 ivltests
|
||||
br_gh498 normal,-g2009 ivltests
|
||||
br_gh508a normal,-g2009 ivltests
|
||||
br_gh521 normal,-g2012 ivltests
|
||||
br_gh527 normal,-g2009 ivltests
|
||||
br_gh530 CO,-g2009 ivltests
|
||||
br_gh540 normal,-g2009 ivltests
|
||||
|
|
@ -222,16 +223,20 @@ br_gh661a normal,-g2009 ivltests
|
|||
br_gh661b normal,-g2009 ivltests
|
||||
br_gh672 normal,-g2009 ivltests
|
||||
br_gh699 CE,-g2009 ivltests
|
||||
br_gh716 CE,-g2012 ivltests gold=br_gh716.gold
|
||||
br_gh756 normal,-g2009 ivltests
|
||||
br_gh782a normal,-g2009 ivltests gold=br_gh782a.gold
|
||||
br_gh782b normal,-g2009 ivltests gold=br_gh782b.gold
|
||||
br_gh800 normal,-g2009 ivltests
|
||||
br_gh801 normal,-g2012 ivltests
|
||||
br_gh801b normal,-g2012 ivltests
|
||||
br_gh1217 normal,-g2012 ivltests
|
||||
br_gh1220 normal,-g2012 ivltests
|
||||
br_gh1222 CE,-g2009 ivltests gold=br_gh1222.gold
|
||||
br_gh1223a normal,-g2009 ivltests
|
||||
br_gh1223b normal,-g2009 ivltests
|
||||
br_gh1223c normal,-g2009 ivltests
|
||||
br_gh1224 normal,-g2012 ivltests
|
||||
br_gh1230 normal,-g2009 ivltests
|
||||
br_ml20171017 normal,-g2009 ivltests
|
||||
br_ml20180227 CE,-g2009 ivltests
|
||||
|
|
@ -989,3 +994,9 @@ partsel_real_idx CE,-g2012 ivltests gold=partsel_real_idx.gold
|
|||
ipsdownsel_real_idx CE,-g2012 ivltests gold=ipsdownsel_real_idx.gold
|
||||
ipsupsel_real_idx CE,-g2012 ivltests gold=ipsupsel_real_idx.gold
|
||||
real_edges CE,-g2012 ivltests gold=real_edges.gold
|
||||
br_gh1112 CE,-g2009 ivltests gold=br_gh1112.gold
|
||||
br_gh670 normal,-g2009 ivltests
|
||||
br_gh1134 normal,-g2012 ivltests
|
||||
br_gh1265 normal,-g2012 ivltests
|
||||
br_gh1267 normal,-g2012 ivltests
|
||||
br_gh1268 normal,-g2012 ivltests
|
||||
|
|
|
|||
|
|
@ -137,3 +137,4 @@ ssetclr2 normal ivltests
|
|||
ssetclr3 normal ivltests
|
||||
synth_if_no_else normal ivltests
|
||||
ufuncsynth1 normal ivltests
|
||||
br_gh1170 CO,-g2012,-tsizer ivltests
|
||||
|
|
|
|||
14
parse.y
14
parse.y
|
|
@ -1582,7 +1582,7 @@ for_step_opt
|
|||
definitions in the func_body to take on the scope of the function
|
||||
instead of the module. */
|
||||
function_declaration /* IEEE1800-2005: A.2.6 */
|
||||
: K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER ';'
|
||||
: K_function lifetime_opt data_type_or_implicit_or_void identifier_name ';'
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
|
|
@ -1602,7 +1602,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
delete[]$4;
|
||||
}
|
||||
|
||||
| K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER
|
||||
| K_function lifetime_opt data_type_or_implicit_or_void identifier_name
|
||||
{ assert(current_function == 0);
|
||||
current_function = pform_push_function_scope(@1, $4, $2);
|
||||
}
|
||||
|
|
@ -1628,7 +1628,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
|
||||
/* Detect and recover from some errors. */
|
||||
|
||||
| K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER error K_endfunction
|
||||
| K_function lifetime_opt data_type_or_implicit_or_void identifier_name error K_endfunction
|
||||
{ /* */
|
||||
if (current_function) {
|
||||
pform_pop_scope();
|
||||
|
|
@ -2442,7 +2442,7 @@ streaming_concatenation /* IEEE1800-2005: A.8.1 */
|
|||
|
||||
task_declaration /* IEEE1800-2005: A.2.7 */
|
||||
|
||||
: K_task lifetime_opt IDENTIFIER ';'
|
||||
: K_task lifetime_opt identifier_name ';'
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
|
|
@ -2469,7 +2469,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
delete[]$3;
|
||||
}
|
||||
|
||||
| K_task lifetime_opt IDENTIFIER '('
|
||||
| K_task lifetime_opt identifier_name '('
|
||||
{ assert(current_task == 0);
|
||||
current_task = pform_push_task_scope(@1, $3, $2);
|
||||
}
|
||||
|
|
@ -2498,7 +2498,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
delete[]$3;
|
||||
}
|
||||
|
||||
| K_task lifetime_opt IDENTIFIER error K_endtask
|
||||
| K_task lifetime_opt identifier_name error K_endtask
|
||||
{
|
||||
if (current_task) {
|
||||
pform_pop_scope();
|
||||
|
|
@ -4468,7 +4468,7 @@ hierarchy_identifier
|
|||
$$->push_back(name_component_t(lex_strings.make($1)));
|
||||
delete[]$1;
|
||||
}
|
||||
| hierarchy_identifier '.' IDENTIFIER
|
||||
| hierarchy_identifier '.' identifier_name
|
||||
{ pform_name_t * tmp = $1;
|
||||
tmp->push_back(name_component_t(lex_strings.make($3)));
|
||||
delete[]$3;
|
||||
|
|
|
|||
|
|
@ -2496,8 +2496,8 @@ extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
|
|||
if (net->pins) {
|
||||
return net->pins[word];
|
||||
} else {
|
||||
// net->pins can be NULL for a virtualized reg array.
|
||||
assert(net->type_ == IVL_SIT_REG);
|
||||
// net->pins can be NULL for a virtualized reg or uwire array.
|
||||
assert(net->type_ == IVL_SIT_REG || net->type_ == IVL_SIT_UWIRE);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ int target_design(ivl_design_t des)
|
|||
// multiple root scopes, we will give isolated numbers for
|
||||
// each and keep then separate.
|
||||
for (unsigned idx = 0 ; idx < nroots ; idx += 1) {
|
||||
// Skip SystemVerilog $unit scope (compilation unit scope)
|
||||
if (ivl_scope_type(roots[idx]) == IVL_SCT_PACKAGE) {
|
||||
continue;
|
||||
}
|
||||
if (ivl_scope_type(roots[idx]) != IVL_SCT_MODULE) {
|
||||
fprintf(stderr, "SIZER: The root scope %s must be a module.\n", ivl_scope_basename(roots[idx]));
|
||||
sizer_errors += 1;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
|
|||
{
|
||||
unsigned idx;
|
||||
ivl_signal_type_t out = IVL_SIT_TRI;
|
||||
int has_tri = 0;
|
||||
int has_uwire = 0;
|
||||
|
||||
for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
|
||||
ivl_signal_type_t stype;
|
||||
|
|
@ -41,14 +43,29 @@ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex)
|
|||
stype = ivl_signal_type(sig);
|
||||
if (stype == IVL_SIT_REG)
|
||||
continue;
|
||||
if (stype == IVL_SIT_TRI)
|
||||
if (stype == IVL_SIT_TRI) {
|
||||
has_tri = 1;
|
||||
continue;
|
||||
}
|
||||
if (stype == IVL_SIT_NONE)
|
||||
continue;
|
||||
if (stype == IVL_SIT_UWIRE) return IVL_SIT_UWIRE;
|
||||
if (stype == IVL_SIT_UWIRE) {
|
||||
has_uwire = 1;
|
||||
continue;
|
||||
}
|
||||
out = stype;
|
||||
}
|
||||
|
||||
/* If both TRI (wire) and UWIRE are in the nexus, return TRI
|
||||
because wire semantics allow multiple drivers. Only return
|
||||
UWIRE if no TRI signals are present. This fixes GitHub #1267
|
||||
where wire logic connected to uwire ports was incorrectly
|
||||
treated as requiring single-driver semantics.
|
||||
TODO: Decide how resolved net types (tri0/tri1/triand/trior)
|
||||
should interact with uwire in a shared nexus. */
|
||||
if (has_uwire && !has_tri)
|
||||
return IVL_SIT_UWIRE;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue