diff --git a/elab_type.cc b/elab_type.cc index eb2803cbf..4c1814909 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -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(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 dimensions; bool bad_range = evaluate_ranges(des, scope, dimensions, *dims); diff --git a/netlist.cc b/netlist.cc index 34b3ebf28..26f45a33b 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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::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(); } } diff --git a/netmisc.cc b/netmisc.cc index 8c6e240c5..b0bf41b98 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -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&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; } diff --git a/nettypes.cc b/nettypes.cc index 2f2e3988f..807956b4b 100644 --- a/nettypes.cc +++ b/nettypes.cc @@ -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&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. diff --git a/parse.y b/parse.y index b7a523963..f4298e9f4 100644 --- a/parse.y +++ b/parse.y @@ -5847,7 +5847,23 @@ specify_path_identifiers delete[]$1; } | IDENTIFIER '[' expr_primary ']' - { list*tmp = new list; + { 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*tmp = new list; + 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*tmp = new list; 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*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*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*tmp = $1; tmp->push_back(lex_strings.make($3)); $$ = tmp; delete[]$3; diff --git a/pform_pclass.cc b/pform_pclass.cc index bd2a7a21a..a3b7df4f0 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -79,6 +79,7 @@ void pform_class_property(const struct vlltype&loc, if (! curp->index.empty()) { list*pd = new list (curp->index); use_type = new uarray_type_t(use_type, pd); + FILE_NAME(use_type, loc); } pform_cur_class->type->properties[curp->name] diff --git a/vhdlpp/parse_misc.cc b/vhdlpp/parse_misc.cc index eefe5296b..09e2f2d8c 100644 --- a/vhdlpp/parse_misc.cc +++ b/vhdlpp/parse_misc.cc @@ -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"); diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 64e94ef46..9ea22c72a 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -119,7 +119,10 @@ VTypeArray::VTypeArray(const VType*element, std::list*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)); } }