diff --git a/elab_expr.cc b/elab_expr.cc index a7327475d..91d2a9a2a 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -655,6 +655,14 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, des->errors += 1; } + if (rep->value().is_negative()) { + cerr << get_fileline() << ": error: Concatenation repeat " + << "may not be negative (" << rep->value().as_long() + << ")." << endl; + des->errors += 1; + return 0; + } + repeat = rep; } diff --git a/elab_net.cc b/elab_net.cc index 65365bf3d..ab3b40334 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -1578,6 +1578,14 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, return 0; } + if (erep->value().is_negative()) { + cerr << get_fileline() << ": error: Concatenation repeat " + << "may not be negative (" << erep->value().as_long() + << ")." << endl; + des->errors += 1; + return 0; + } + repeat = erep->value().as_ulong(); delete etmp; diff --git a/verinum.cc b/verinum.cc index d7ed2a25a..0f9907389 100644 --- a/verinum.cc +++ b/verinum.cc @@ -429,6 +429,11 @@ bool verinum::is_zero() const return true; } +bool verinum::is_negative() const +{ + return (bits_[nbits_-1] == V1) && has_sign(); +} + verinum pad_to_width(const verinum&that, unsigned width) { if (that.len() >= width) diff --git a/verinum.h b/verinum.h index f400a1a5c..29477f7d2 100644 --- a/verinum.h +++ b/verinum.h @@ -71,6 +71,7 @@ class verinum { // A number is "defined" if there are no x or z bits in its value. bool is_defined() const; bool is_zero() const; + bool is_negative() const; // A number is "a string" if its value came directly from // an ASCII description instead of a number value.