1998-11-04 00:28:49 +01:00
|
|
|
#ifndef __verinum_H
|
|
|
|
|
#define __verinum_H
|
|
|
|
|
/*
|
2008-01-15 19:54:04 +01:00
|
|
|
* Copyright (c) 1998-2008 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
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
# 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();
|
|
|
|
|
verinum(const string&str);
|
1999-05-13 06:02:09 +02:00
|
|
|
verinum(const V*v, unsigned nbits, bool has_len =true);
|
2001-02-07 03:46:31 +01:00
|
|
|
verinum(V, unsigned nbits =1, bool has_len =true);
|
2006-08-08 07:11:37 +02:00
|
|
|
verinum(uint64_t val, unsigned bits);
|
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
|
|
|
|
|
|
|
|
// Number of significant bits in this number.
|
|
|
|
|
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.
|
|
|
|
|
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_; }
|
|
|
|
|
|
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;
|
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;
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
V operator[] (unsigned idx) const { return get(idx); }
|
|
|
|
|
|
|
|
|
|
|
2006-08-08 07:11:37 +02:00
|
|
|
uint64_t as_ulong64() const;
|
1998-11-04 00:28:49 +01:00
|
|
|
unsigned long as_ulong() const;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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_;
|
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_;
|
|
|
|
|
};
|
|
|
|
|
|
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);
|
|
|
|
|
|
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);
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
/* These are arithmetic operators. These 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. */
|
|
|
|
|
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. */
|
2000-02-23 05:43:43 +01:00
|
|
|
extern verinum v_not(const verinum&left);
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
#endif
|