Indexed part selects cannot use real values

This commit is contained in:
Cary R 2023-07-09 12:24:39 -07:00
parent 095e6daa0a
commit fdb9465329
8 changed files with 284 additions and 10 deletions

View File

@ -4146,10 +4146,10 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope,
wid = wid_c ? wid_c->value().as_ulong() : 0;
if (wid == 0) {
cerr << index_tail.lsb->get_fileline() << ": error: "
"Indexed part widths must be constant and greater than zero."
"Indexed part select width must be an integral constants greater than zero."
<< endl;
cerr << index_tail.lsb->get_fileline() << ": : "
"This part width expression violates the rule: "
"This width expression violates that rule: "
<< *index_tail.lsb << endl;
des->errors += 1;
flag = false;
@ -5365,12 +5365,20 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
// Use the part select width already calculated by test_width().
unsigned long wid = min_width_;
perm_string name = peek_tail_name(path_);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Calculate part select "
<< "[" << *base << "+:" << wid << "] from range "
<< name << "[" << *base << "+:" << wid << "] from range "
<< "[" << par_msv << ":" << par_lsv << "]." << endl;
perm_string name = peek_tail_name(path_);
if (base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for " << name << "[" << *base << "+:" << wid
<< "] cannot be a real value." << endl;
des->errors += 1;
return 0;
}
// Handle the special case that the base is constant. In this
// case, just precalculate the entire constant result.
@ -5445,12 +5453,20 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
// Use the part select width already calculated by test_width().
unsigned long wid = min_width_;
perm_string name = peek_tail_name(path_);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Calculate part select "
<< "[" << *base << "-:" << wid << "] from range "
<< name << "[" << *base << "-:" << wid << "] from range "
<< "[" << par_msv << ":" << par_lsv << "]." << endl;
perm_string name = peek_tail_name(path_);
if (base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for " << name << "[" << *base << "-:" << wid
<< "] cannot be a real value." << endl;
des->errors += 1;
return 0;
}
// Handle the special case that the base is constant. In this
// case, just precalculate the entire constant result.
@ -5931,6 +5947,13 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
NetESignal*net, NetScope*,
bool need_const) const
{
if (net->sig()->data_type() == IVL_VT_STRING) {
cerr << get_fileline() << ": error: Cannot take the index part "
"select of a string ('" << net->name() << "')." << endl;
des->errors += 1;
return 0;
}
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
if (!rc)
@ -5941,6 +5964,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
// Use the part select width already calculated by test_width().
unsigned long wid = min_width_;
if (base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for " << net->sig()->name() << "[" << *base
<< "+:" << wid << "] cannot be a real value." << endl;
des->errors += 1;
return 0;
}
// Handle the special case that the base is constant as
// well. In this case it can be converted to a conventional
// part select.
@ -6063,6 +6094,13 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
NetESignal*net, NetScope*,
bool need_const) const
{
if (net->sig()->data_type() == IVL_VT_STRING) {
cerr << get_fileline() << ": error: Cannot take the index part "
"select of a string ('" << net->name() << "')." << endl;
des->errors += 1;
return 0;
}
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices);
if (!rc)
@ -6073,6 +6111,14 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
// Use the part select width already calculated by test_width().
unsigned long wid = min_width_;
if (base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for " << net->sig()->name() << "[" << *base
<< "-:" << wid << "] cannot be a real value." << endl;
des->errors += 1;
return 0;
}
// Handle the special case that the base is constant as
// well. In this case it can be converted to a conventional
// part select.

View File

@ -814,6 +814,13 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
index_component_t::ctype_t use_sel,
bool need_const_idx) const
{
if (lv->sig()->data_type() == IVL_VT_STRING) {
cerr << get_fileline() << ": error: Cannot index part select assign to a string ('"
<< lv->sig()->name() << "')." << endl;
des->errors += 1;
return false;
}
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices);
ivl_assert(*this, rc);
@ -832,6 +839,21 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
if (base && base->expr_type() == IVL_VT_REAL) {
cerr << get_fileline() << ": error: Indexed part select base "
"expression for ";
cerr << lv->sig()->name() << "[" << *base;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] cannot be a real value." << endl;
des->errors += 1;
return 0;
}
ivl_select_type_t sel_type = IVL_SEL_OTHER;
// Handle the special case that the base is constant. For this

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2022 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2023 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -234,9 +234,11 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1, true);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of "
<< sig->name()
<< " must be a constant in this context." << endl;
cerr << get_fileline() << ": error: Indexed part select "
"base expression must be a constant integral value "
"in this context." << endl;
cerr << get_fileline() << ": : This expression "
"violates that rule: " << *index_tail.msb << endl;
des->errors += 1;
return 0;
}

View File

@ -0,0 +1,54 @@
./ivltests/ipsdownsel_real_idx.v:13: error: Indexed part select base expression for in[+ridx-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:13: error: Unable to elaborate r-value: in[ridx-:'sd1]
./ivltests/ipsdownsel_real_idx.v:14: error: Indexed part select base expression for in[0.500000-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:14: error: Unable to elaborate r-value: in[0.500000-:'sd1]
./ivltests/ipsdownsel_real_idx.v:15: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:15: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:15: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:16: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:16: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:17: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:17: error: Indexed part select base expression must be a constant integral value in this context.
./ivltests/ipsdownsel_real_idx.v:17: : This expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:18: error: Indexed part select base expression must be a constant integral value in this context.
./ivltests/ipsdownsel_real_idx.v:18: : This expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:19: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:19: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:19: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:20: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:20: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:26: error: Indexed part select base expression for in[+ridx-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:27: error: Indexed part select base expression for in[0.500000-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:28: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:28: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:28: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:29: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:29: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:30: error: Indexed part select base expression for vlvb[+ridx-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:31: error: Indexed part select base expression for vlcb[0.500000-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:32: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:32: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:32: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:33: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:33: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:34: error: Indexed part select base expression for pval[+ridx-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:35: error: Indexed part select base expression for pval[0.500000-:1] cannot be a real value.
./ivltests/ipsdownsel_real_idx.v:36: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:36: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:36: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:37: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:37: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:38: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsdownsel_real_idx.v:39: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsdownsel_real_idx.v:40: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsdownsel_real_idx.v:40: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:40: : This width expression violates that rule: ridx
./ivltests/ipsdownsel_real_idx.v:40: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsdownsel_real_idx.v:41: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsdownsel_real_idx.v:41: : This width expression violates that rule: 0.500000
./ivltests/ipsdownsel_real_idx.v:41: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsdownsel_real_idx.v:42: error: Cannot index part select assign to a string ('strvb').
./ivltests/ipsdownsel_real_idx.v:43: error: Cannot index part select assign to a string ('strcb').
./ivltests/ipsdownsel_real_idx.v:44: error: Cannot index part select assign to a string ('strvw').
./ivltests/ipsdownsel_real_idx.v:45: error: Cannot index part select assign to a string ('strcw').
39 error(s) during elaboration.

View File

@ -0,0 +1,54 @@
./ivltests/ipsupsel_real_idx.v:13: error: Indexed part select base expression for in[+ridx+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:13: error: Unable to elaborate r-value: in[ridx+:'sd1]
./ivltests/ipsupsel_real_idx.v:14: error: Indexed part select base expression for in[0.500000+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:14: error: Unable to elaborate r-value: in[0.500000+:'sd1]
./ivltests/ipsupsel_real_idx.v:15: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:15: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:15: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:16: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:16: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:17: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:17: error: Indexed part select base expression must be a constant integral value in this context.
./ivltests/ipsupsel_real_idx.v:17: : This expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:18: error: Indexed part select base expression must be a constant integral value in this context.
./ivltests/ipsupsel_real_idx.v:18: : This expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:19: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:19: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:19: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:20: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:20: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:26: error: Indexed part select base expression for in[+ridx+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:27: error: Indexed part select base expression for in[0.500000+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:28: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:28: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:28: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:29: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:29: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:30: error: Indexed part select base expression for vlvb[+ridx+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:31: error: Indexed part select base expression for vlcb[0.500000+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:32: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:32: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:32: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:33: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:33: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:34: error: Indexed part select base expression for pval[+ridx+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:35: error: Indexed part select base expression for pval[0.500000+:1] cannot be a real value.
./ivltests/ipsupsel_real_idx.v:36: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:36: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:36: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:37: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:37: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:38: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsupsel_real_idx.v:39: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsupsel_real_idx.v:40: error: A reference to a net or variable (`ridx') is not allowed in a constant expression.
./ivltests/ipsupsel_real_idx.v:40: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:40: : This width expression violates that rule: ridx
./ivltests/ipsupsel_real_idx.v:40: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsupsel_real_idx.v:41: error: Indexed part select width must be an integral constants greater than zero.
./ivltests/ipsupsel_real_idx.v:41: : This width expression violates that rule: 0.500000
./ivltests/ipsupsel_real_idx.v:41: error: Cannot take the index part select of a string ('sval').
./ivltests/ipsupsel_real_idx.v:42: error: Cannot index part select assign to a string ('strvb').
./ivltests/ipsupsel_real_idx.v:43: error: Cannot index part select assign to a string ('strcb').
./ivltests/ipsupsel_real_idx.v:44: error: Cannot index part select assign to a string ('strvw').
./ivltests/ipsupsel_real_idx.v:45: error: Cannot index part select assign to a string ('strcw').
39 error(s) during elaboration.

View File

@ -0,0 +1,47 @@
module top;
parameter pval = 7;
string sval, strvb, strcb, strvw, strcw;
real ridx;
integer in;
reg cavb, cacb, cavw, cacw;
reg vvb, vcb, vvw, vcw;
reg pvb, pcb, pvw, pcw;
reg svb, scb, svw, scw;
integer calvb, calcb, calvw, calcw;
integer vlvb, vlcb, vlvw, vlcw;
assign cavb = in[ridx-:1];
assign cacb = in[0.5-:1];
assign cavw = in[1-:ridx];
assign cacw = in[1-:0.5];
assign calvb[ridx-:1] = 1'b1;
assign calcb[0.5-:1] = 1'b1;
assign calvw[1-:ridx] = 1'b1;
assign calcw[1-:0.5] = 1'b1;
initial begin
in = 7;
ridx = 0.5;
sval = "ABC";
vvb = in[ridx-:1];
vcb = in[0.5-:1];
vvw = in[1-:ridx];
vcw = in[1-:0.5];
vlvb[ridx-:1] = 1'b1;
vlcb[0.5-:1] = 1'b1;
vlvw[1-:ridx] = 1'b1;
vlcw[1-:0.5] = 1'b1;
pvb = pval[ridx-:1];
pcb = pval[0.5-:1];
pvw = pval[1-:ridx];
pcw = pval[1-:0.5];
svb = sval[ridx-:1];
scb = sval[0.5-:1];
svw = sval[1-:ridx];
scw = sval[1-:0.5];
strvb[ridx-:1] = "a";
strcb[0.5-:1] = "a";
strvw[1-:ridx] = "a";
strcw[1-:0.5] = "a";
end
endmodule

View File

@ -0,0 +1,47 @@
module top;
parameter pval = 7;
string sval, strvb, strcb, strvw, strcw;
real ridx;
integer in;
reg cavb, cacb, cavw, cacw;
reg vvb, vcb, vvw, vcw;
reg pvb, pcb, pvw, pcw;
reg svb, scb, svw, scw;
integer calvb, calcb, calvw, calcw;
integer vlvb, vlcb, vlvw, vlcw;
assign cavb = in[ridx+:1];
assign cacb = in[0.5+:1];
assign cavw = in[1+:ridx];
assign cacw = in[1+:0.5];
assign calvb[ridx+:1] = 1'b1;
assign calcb[0.5+:1] = 1'b1;
assign calvw[1+:ridx] = 1'b1;
assign calcw[1+:0.5] = 1'b1;
initial begin
in = 7;
ridx = 0.5;
sval = "ABC";
vvb = in[ridx+:1];
vcb = in[0.5+:1];
vvw = in[1+:ridx];
vcw = in[1+:0.5];
vlvb[ridx+:1] = 1'b1;
vlcb[0.5+:1] = 1'b1;
vlvw[1+:ridx] = 1'b1;
vlcw[1+:0.5] = 1'b1;
pvb = pval[ridx+:1];
pcb = pval[0.5+:1];
pvw = pval[1+:ridx];
pcw = pval[1+:0.5];
svb = sval[ridx+:1];
scb = sval[0.5+:1];
svw = sval[1+:ridx];
scw = sval[1+:0.5];
strvb[ridx+:1] = "a";
strcb[0.5+:1] = "a";
strvw[1+:ridx] = "a";
strcw[1+:0.5] = "a";
end
endmodule

View File

@ -996,4 +996,6 @@ br_gh840a CE,-g2012 ivltests
br_gh840b CE,-g2012 ivltests
bitsel_real_idx CE,-g2012 ivltests gold=bitsel_real_idx.gold
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