Merge branch 'master' of github.com:steveicarus/iverilog

Conflicts:
	vhdlpp/parse_misc.cc
	vhdlpp/vtype.cc
This commit is contained in:
Stephen Williams 2016-07-17 09:36:34 -07:00
commit c37d6ac3ac
8 changed files with 95 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@ -17,11 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "PExpr.h"
# include "pform_types.h"
# include "netlist.h"
# include "netclass.h"
# include "netdarray.h"
# include "netenum.h"
# include "netqueue.h"
# include "netparray.h"
# include "netscalar.h"
# include "netstruct.h"
@ -245,6 +247,16 @@ ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
return res;
}
// Special case: if the dimension is null:nil. this is a queue.
if (cur->second==0 && dynamic_cast<PENull*>(cur->first)) {
cerr << get_fileline() << ": sorry: "
<< "SV queues inside classes are not yet supported." << endl;
des->errors += 1;
ivl_type_s*res = new netqueue_t(btype);
return res;
}
vector<netrange_t> dimensions;
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);

View File

@ -558,7 +558,7 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void)
ivl_assert(*this, ! slice_wids_.empty());
slice_wids_[0] = netrange_width(slice_dims_);
vector<netrange_t>::const_iterator cur = slice_dims_.begin();
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1) {
for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1, cur++) {
slice_wids_[idx] = slice_wids_[idx-1] / cur->width();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2016 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
@ -203,7 +203,7 @@ static NetExpr* make_add_expr(NetExpr*expr, long val)
}
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@ -236,7 +236,7 @@ static NetExpr* make_add_expr(const LineInfo*loc, NetExpr*expr1, NetExpr*expr2)
static NetExpr* make_sub_expr(long val, NetExpr*expr)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@ -254,7 +254,7 @@ static NetExpr* make_sub_expr(long val, NetExpr*expr)
static NetExpr* make_sub_expr(NetExpr*expr, long val)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@ -268,7 +268,7 @@ static NetExpr* make_sub_expr(NetExpr*expr, long val)
/*
* Multiple an existing expression by a signed positive number.
* Multiply an existing expression by a signed positive number.
* This does a lossless multiply, so the arguments will need to be
* sized to match the output size.
*/
@ -277,7 +277,7 @@ static NetExpr* make_mult_expr(NetExpr*expr, unsigned long val)
const unsigned val_wid = ceil(log2((double)val)) ;
unsigned use_wid = expr->expr_width() + val_wid;
verinum val_v (val, use_wid);
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
@ -457,22 +457,37 @@ NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
long loff;
reg->sb_to_slice(indices, sb, loff, lwid);
bool idx_incr = pcur->get_msb() < pcur->get_lsb();
if(pcur->get_lsb() != 0) {
// Adjust the base for the case when the array range does not start from 0
if(idx_incr)
base = make_sub_expr(pcur->get_lsb(), base);
else
base = make_sub_expr(base, pcur->get_lsb());
unsigned min_wid = base->expr_width();
if ((sb < 0) && !base->has_sign()) min_wid += 1;
if (min_wid < num_bits(pcur->get_lsb())) min_wid = pcur->get_lsb();
if (min_wid < num_bits(pcur->get_msb())) min_wid = pcur->get_msb();
base = pad_to_width(base, min_wid, *base);
if ((sb < 0) && !base->has_sign()) {
NetESelect *tmp = new NetESelect(base, 0 , min_wid);
tmp->set_line(*base);
tmp->cast_signed(true);
base = tmp;
}
base = make_mult_expr(base, lwid);
// TODO I do not see any influence of the lines below to the test suite
if(!idx_incr)
base = make_add_expr(base, loff);
if (pcur->get_msb() >= pcur->get_lsb()) {
if (pcur->get_lsb() != 0)
base = make_sub_expr(base, pcur->get_lsb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_add_expr(base, loff);
} else {
if (pcur->get_msb() != 0)
base = make_sub_expr(base, pcur->get_msb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_sub_expr(loff, base);
}
return base;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2016 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
@ -147,13 +147,12 @@ bool prefix_to_slice(const std::vector<netrange_t>&dims,
do {
-- icur;
acc_wid *= pcur->width();
-- pcur;
if (pcur->get_msb() >= pcur->get_lsb())
acc_off += (*icur - pcur->get_lsb()) * acc_wid;
else
acc_off += (pcur->get_lsb() - *icur) * acc_wid;
-- pcur;
} while (icur != prefix.begin());
// Got our final offset.

36
parse.y
View File

@ -5847,7 +5847,23 @@ specify_path_identifiers
delete[]$1;
}
| IDENTIFIER '[' expr_primary ']'
{ list<perm_string>*tmp = new list<perm_string>;
{ if (gn_specify_blocks_flag) {
yywarn(@4, "Bit selects are not currently supported "
"in path declarations. The declaration "
"will be applied to the whole vector.");
}
list<perm_string>*tmp = new list<perm_string>;
tmp->push_back(lex_strings.make($1));
$$ = tmp;
delete[]$1;
}
| IDENTIFIER '[' expr_primary polarity_operator expr_primary ']'
{ if (gn_specify_blocks_flag) {
yywarn(@4, "Part selects are not currently supported "
"in path declarations. The declaration "
"will be applied to the whole vector.");
}
list<perm_string>*tmp = new list<perm_string>;
tmp->push_back(lex_strings.make($1));
$$ = tmp;
delete[]$1;
@ -5859,7 +5875,23 @@ specify_path_identifiers
delete[]$3;
}
| specify_path_identifiers ',' IDENTIFIER '[' expr_primary ']'
{ list<perm_string>*tmp = $1;
{ if (gn_specify_blocks_flag) {
yywarn(@4, "Bit selects are not currently supported "
"in path declarations. The declaration "
"will be applied to the whole vector.");
}
list<perm_string>*tmp = $1;
tmp->push_back(lex_strings.make($3));
$$ = tmp;
delete[]$3;
}
| specify_path_identifiers ',' IDENTIFIER '[' expr_primary polarity_operator expr_primary ']'
{ if (gn_specify_blocks_flag) {
yywarn(@4, "Part selects are not currently supported "
"in path declarations. The declaration "
"will be applied to the whole vector.");
}
list<perm_string>*tmp = $1;
tmp->push_back(lex_strings.make($3));
$$ = tmp;
delete[]$3;

View File

@ -79,6 +79,7 @@ void pform_class_property(const struct vlltype&loc,
if (! curp->index.empty()) {
list<pform_range_t>*pd = new list<pform_range_t> (curp->index);
use_type = new uarray_type_t(use_type, pd);
FILE_NAME(use_type, loc);
}
pform_cur_class->type->properties[curp->name]

View File

@ -121,7 +121,11 @@ const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
Expression*lef = tmpr->left();
Expression*rig = tmpr->right();
return calculate_subtype_array(loc, base_name, scope,
lef, tmpr->direction(), rig);
lef,
(tmpr->direction() == ExpRange::DOWNTO
? true
: false),
rig);
}
sorrymsg(loc, "Don't know how to handle multiple ranges here.\n");

View File

@ -119,7 +119,10 @@ VTypeArray::VTypeArray(const VType*element, std::list<ExpRange*>*r, bool sv)
for (size_t idx = 0 ; idx < ranges_.size() ; idx += 1) {
ExpRange*curp = r->front();
r->pop_front();
ranges_[idx] = range_t(curp->msb(), curp->lsb(), curp->direction());
ranges_[idx] = range_t(curp->msb(), curp->lsb(),
(curp->direction() == ExpRange::DOWNTO
? true
: false));
}
}