2014-07-23 22:39:29 +02:00
|
|
|
#ifndef IVL_verinum_H
|
|
|
|
|
#define IVL_verinum_H
|
1998-11-04 00:28:49 +01:00
|
|
|
/*
|
2014-02-25 21:39:21 +01:00
|
|
|
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
1998-11-04 00:28:49 +01:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-08-29 03:41:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-11-04 00:28:49 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# include <string>
|
|
|
|
|
|
2003-01-30 05:23:25 +01:00
|
|
|
# include "config.h"
|
2001-01-16 03:44:17 +01:00
|
|
|
#ifdef HAVE_IOSFWD
|
|
|
|
|
# include <iosfwd>
|
|
|
|
|
#else
|
|
|
|
|
class ostream;
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-06-14 21:13:43 +02:00
|
|
|
using namespace std;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
/*
|
2003-01-30 17:23:07 +01:00
|
|
|
* Numbers in Verilog are multibit strings, where each bit has 4
|
1998-11-04 00:28:49 +01:00
|
|
|
* possible values: 0, 1, x or z. The verinum number is store in
|
|
|
|
|
* little-endian format. This means that if the long value is 2b'10,
|
|
|
|
|
* get(0) is 0 and get(1) is 1.
|
|
|
|
|
*/
|
|
|
|
|
class verinum {
|
|
|
|
|
|
|
|
|
|
public:
|
2002-06-03 06:04:24 +02:00
|
|
|
enum V { V0 = 0, V1, Vx, Vz };
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
verinum();
|
2015-10-22 11:45:31 +02:00
|
|
|
explicit verinum(const string&str);
|
1999-05-13 06:02:09 +02:00
|
|
|
verinum(const V*v, unsigned nbits, bool has_len =true);
|
2015-10-22 11:45:31 +02:00
|
|
|
explicit verinum(V, unsigned nbits =1, bool has_len =true);
|
2006-08-08 07:11:37 +02:00
|
|
|
verinum(uint64_t val, unsigned bits);
|
2010-11-01 22:37:06 +01:00
|
|
|
verinum(double val, bool);
|
1998-11-04 00:28:49 +01:00
|
|
|
verinum(const verinum&);
|
1999-05-13 06:02:09 +02:00
|
|
|
|
2000-12-10 23:01:35 +01:00
|
|
|
// Create a signed number, with an unspecified number of bits.
|
2006-08-08 07:11:37 +02:00
|
|
|
explicit verinum(int64_t val);
|
2000-12-10 23:01:35 +01:00
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
// Copy only the specified number of bits from the
|
|
|
|
|
// source. Also mark this number as has_len.
|
|
|
|
|
verinum(const verinum&, unsigned bits);
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
~verinum();
|
1999-05-13 06:02:09 +02:00
|
|
|
verinum& operator= (const verinum&);
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2014-11-02 13:37:32 +01:00
|
|
|
// Number of stored bits in this number.
|
1998-11-04 00:28:49 +01:00
|
|
|
unsigned len() const { return nbits_; }
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
// A number "has a length" if the length was specified fixed
|
|
|
|
|
// in some way.
|
2011-02-26 23:59:52 +01:00
|
|
|
bool has_len(bool flag) { has_len_ = flag; return has_len_; }
|
1999-05-13 06:02:09 +02:00
|
|
|
bool has_len() const { return has_len_; }
|
|
|
|
|
|
2000-01-07 04:45:49 +01:00
|
|
|
bool has_sign(bool flag) { has_sign_ = flag; return has_sign_; }
|
|
|
|
|
bool has_sign() const { return has_sign_; }
|
|
|
|
|
|
2011-01-24 01:21:54 +01:00
|
|
|
// A number "is single" if it comes from a SystemVerilog 'N bit vector
|
|
|
|
|
bool is_single(bool flag) { is_single_ = flag; return is_single_; }
|
|
|
|
|
bool is_single() const { return is_single_; }
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
// A number is "defined" if there are no x or z bits in its value.
|
|
|
|
|
bool is_defined() const;
|
2003-04-03 06:30:00 +02:00
|
|
|
bool is_zero() const;
|
2008-03-25 23:17:47 +01:00
|
|
|
bool is_negative() const;
|
1999-05-13 06:02:09 +02:00
|
|
|
|
|
|
|
|
// A number is "a string" if its value came directly from
|
2003-01-30 17:23:07 +01:00
|
|
|
// an ASCII description instead of a number value.
|
1999-05-13 06:02:09 +02:00
|
|
|
bool is_string() const { return string_flag_; }
|
|
|
|
|
|
1999-11-06 17:00:17 +01:00
|
|
|
// Comparison for use in sorting algorithms.
|
|
|
|
|
bool is_before(const verinum&that) const;
|
|
|
|
|
|
2014-11-02 13:37:32 +01:00
|
|
|
// Number of significant bits in this number.
|
|
|
|
|
unsigned significant_bits() const;
|
|
|
|
|
|
2013-02-25 21:32:56 +01:00
|
|
|
// Convert 4-state to 2-state
|
|
|
|
|
void cast_to_int2();
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
// Individual bits can be accessed with the get and set
|
|
|
|
|
// methods.
|
|
|
|
|
V get(unsigned idx) const;
|
|
|
|
|
V set(unsigned idx, V val);
|
2012-12-20 20:02:29 +01:00
|
|
|
void set(unsigned idx, const verinum&val);
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
V operator[] (unsigned idx) const { return get(idx); }
|
|
|
|
|
|
2014-02-28 21:39:14 +01:00
|
|
|
// Return the value as a native unsigned integer. If the value is
|
|
|
|
|
// larger than can be represented by the returned type, return
|
|
|
|
|
// the maximum value of that type. If the value has any x or z
|
|
|
|
|
// bits or has zero width, return the value 0.
|
2006-08-08 07:11:37 +02:00
|
|
|
uint64_t as_ulong64() const;
|
2014-02-28 21:39:14 +01:00
|
|
|
unsigned as_unsigned() const;
|
1998-11-04 00:28:49 +01:00
|
|
|
unsigned long as_ulong() const;
|
2014-02-28 21:39:14 +01:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
signed long as_long() const;
|
2008-01-15 19:54:04 +01:00
|
|
|
double as_double() const;
|
1998-11-04 00:28:49 +01:00
|
|
|
string as_string() const;
|
2008-07-31 23:05:27 +02:00
|
|
|
private:
|
|
|
|
|
void signed_trim();
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
V* bits_;
|
|
|
|
|
unsigned nbits_;
|
1999-05-13 06:02:09 +02:00
|
|
|
bool has_len_;
|
2000-01-07 04:45:49 +01:00
|
|
|
bool has_sign_;
|
2011-01-24 01:21:54 +01:00
|
|
|
bool is_single_;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
// These are some convenience flags that help us do a better
|
|
|
|
|
// job of pretty-printing values.
|
|
|
|
|
bool string_flag_;
|
|
|
|
|
};
|
|
|
|
|
|
2008-03-26 05:35:08 +01:00
|
|
|
/*
|
|
|
|
|
* This returns the sign bit of the verinum value. If the value is
|
|
|
|
|
* unsigned, then return an implicit sign bit of 0. Otherwise, return
|
|
|
|
|
* the high bit.
|
|
|
|
|
*/
|
|
|
|
|
inline verinum::V sign_bit(const verinum&val)
|
|
|
|
|
{
|
|
|
|
|
if (val.has_sign())
|
|
|
|
|
return val.get(val.len()-1);
|
|
|
|
|
else
|
|
|
|
|
return verinum::V0;
|
|
|
|
|
}
|
|
|
|
|
|
2006-06-02 06:48:49 +02:00
|
|
|
/* Return a verinum that has the same value as the input, but is at
|
|
|
|
|
least as wide as the requested width. This may involve sign
|
|
|
|
|
extension, if the value is signed. */
|
|
|
|
|
extern verinum pad_to_width(const verinum&, unsigned width);
|
|
|
|
|
|
2011-02-26 23:59:52 +01:00
|
|
|
/* Return a verinum that has the same value as the input, but is
|
|
|
|
|
exactly the requested width. This may involve sign extension,
|
|
|
|
|
if the value is signed. The returned verinum will have fixed
|
|
|
|
|
width. */
|
|
|
|
|
extern verinum cast_to_width(const verinum&, unsigned width);
|
|
|
|
|
|
2003-04-14 05:40:21 +02:00
|
|
|
/* Return a verinum that is minimal. That is, it has only the length
|
|
|
|
|
needed to accurately represent the contained value, signed or not. */
|
|
|
|
|
extern verinum trim_vnum(const verinum&);
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1998-11-11 01:01:51 +01:00
|
|
|
extern ostream& operator<< (ostream&, const verinum&);
|
|
|
|
|
extern ostream& operator<< (ostream&, verinum::V);
|
|
|
|
|
|
2008-05-09 18:16:11 +02:00
|
|
|
inline verinum::V bit4_z2x(verinum::V bit)
|
|
|
|
|
{ return bit<2? bit : verinum::Vx; /* Relies on V0 and V1 being <2 */}
|
|
|
|
|
|
2006-06-01 05:54:51 +02:00
|
|
|
extern verinum::V operator ~ (verinum::V l);
|
2001-01-02 04:23:40 +01:00
|
|
|
extern verinum::V operator | (verinum::V l, verinum::V r);
|
|
|
|
|
extern verinum::V operator & (verinum::V l, verinum::V r);
|
2003-10-26 05:54:56 +01:00
|
|
|
extern verinum::V operator ^ (verinum::V l, verinum::V r);
|
2001-01-02 04:23:40 +01:00
|
|
|
|
1999-10-23 01:57:53 +02:00
|
|
|
extern verinum::V operator == (const verinum&left, const verinum&right);
|
|
|
|
|
extern verinum::V operator <= (const verinum&left, const verinum&right);
|
2001-02-09 06:44:23 +01:00
|
|
|
extern verinum::V operator < (const verinum&left, const verinum&right);
|
1998-11-04 00:28:49 +01:00
|
|
|
|
2001-02-10 21:29:39 +01:00
|
|
|
inline verinum::V operator > (const verinum&left, const verinum&right)
|
|
|
|
|
{ return right < left; }
|
|
|
|
|
|
|
|
|
|
inline verinum::V operator >= (const verinum&left, const verinum&right)
|
|
|
|
|
{ return right <= left; }
|
|
|
|
|
|
2002-06-03 06:04:24 +02:00
|
|
|
inline verinum::V operator != (const verinum&left, const verinum&right)
|
|
|
|
|
{ return (left == right)? verinum::V0 : verinum::V1; }
|
|
|
|
|
|
2003-04-14 05:40:21 +02:00
|
|
|
|
2014-02-25 21:39:21 +01:00
|
|
|
/* These are arithmetic operators. If any operand is unsized, they
|
|
|
|
|
generally work to produce results that do not overflow. That means
|
|
|
|
|
the result may expand or contract to hold the bits needed to hold
|
|
|
|
|
the operation results accurately. It is up to the caller to truncate
|
|
|
|
|
or pad if a specific width is expected. If all operands are sized,
|
|
|
|
|
the normal Verilog rules for result size are used. */
|
|
|
|
|
extern verinum operator - (const verinum&right);
|
2003-04-14 05:40:21 +02:00
|
|
|
extern verinum operator + (const verinum&left, const verinum&right);
|
|
|
|
|
extern verinum operator - (const verinum&left, const verinum&right);
|
|
|
|
|
extern verinum operator * (const verinum&left, const verinum&right);
|
|
|
|
|
extern verinum operator / (const verinum&left, const verinum&right);
|
|
|
|
|
extern verinum operator % (const verinum&left, const verinum&right);
|
|
|
|
|
|
2006-07-31 05:50:17 +02:00
|
|
|
extern verinum pow(const verinum&left, const verinum&right);
|
|
|
|
|
|
2004-02-17 07:52:55 +01:00
|
|
|
extern verinum operator<< (const verinum&left, unsigned shift);
|
|
|
|
|
extern verinum operator>> (const verinum&left, unsigned shift);
|
|
|
|
|
|
2005-12-07 05:04:23 +01:00
|
|
|
extern verinum concat(const verinum&left, const verinum&right);
|
|
|
|
|
|
2003-04-14 05:40:21 +02:00
|
|
|
/* Bitwise not returns the ones complement. */
|
2014-02-25 21:39:21 +01:00
|
|
|
extern verinum operator ~ (const verinum&left);
|
2000-02-23 05:43:43 +01:00
|
|
|
|
2014-07-23 22:39:29 +02:00
|
|
|
#endif /* IVL_verinum_H */
|