📄 emver.hh
字号:
/* * Copyright (c) 2000-2002 moe * * 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 */#ifndef __EMVER_HH#define __EMVER_HH#include <iostream>#include <stdint.h>namespace moe{ //////////////////////////////////////////////////////////////////////// class _UIntN { public: _UIntN(){} ~_UIntN(){} virtual const uint32_t* v() const {} virtual unsigned int n() const {} }; template <uint32_t T> class UIntN : public _UIntN { uint32_t _v[(T+31)>>5]; public: const uint32_t* v() const { return _v; } uint32_t n() const { return T; } virtual ~UIntN(){} UIntN(){} UIntN(bool a) { _v[0]=a; int i; for( i=1;i<((T+31)>>5);i++ ) _v[i]=0; } UIntN(uint32_t a) { _v[0]=a&~(0xFFFFFFFF<<(T&31)); int i; for( i=1;i<((T+31)>>5);i++ ) _v[i]=0; } UIntN(unsigned long a) { _v[0]=a&~(0xFFFFFFFF<<(T&31)); int i; for( i=1;i<((T+31)>>5);i++ ) _v[i]=0; } UIntN(const uint64_t& a) { _v[0]=a; int i=1; if( i>=((T+31)>>5) ) { _v[i-1]&=~(0xFFFFFFFF<<(T&31)); } _v[i++]=a>>32; if( i>=((T+31)>>5) ) { _v[i-1]&=~(0xFFFFFFFF<<(T&31)); return; } for( ;i<((T+31)>>5);i++ ) _v[i]=0; } UIntN(const uint32_t* a) { int i; for( i=0;i<((T+31)>>5);i++ ) _v[i]=a[i]; _v[i-1]&=~(0xffffffff<<(T&31)); } UIntN(const UIntN& a) { int i; for( i=0;i<((T+31)>>5);i++ ) _v[i]=a.v()[i]; _v[i-1]&=~(0xffffffff<<(T&31)); } UIntN(const _UIntN& a) { int i; if( T>a.n() ) { for( i=0;i<((a.n()+31)>>5);i++ ) _v[i]=a.v()[i]; _v[i-1]&=~(0xffffffff<<(a.n()%32)); for( ;i<((T+31)>>5);i++ ) _v[i]=0; } else { for( i=0;i<((T+31)>>5);i++ ) _v[i]=a.v()[i]; _v[i-1]&=~(0xffffffff<<(T&31)); } } //////////////////////////////////// operator uint32_t() const { return _v[0]; } UIntN& operator =(const _UIntN& a) { int i; if( T>a.n() ) { for( i=0;i<((a.n()+31)>>5);i++ ) _v[i]=a.v()[i]; _v[i-1]&=~(0xffffffff<<(a.n()%32)); for( ;i<((T+31)>>5);i++ ) _v[i]=0; } else { for( i=0;i<((T+31)>>5);i++ ) _v[i]=a.v()[i]; _v[i-1]&=~(0xffffffff<<(T&31)); } } //////////////////////////////////// friend std::ostream& operator << (std::ostream& ostr,const UIntN& a) { int i; for( i=a.n()-1;i>=0;i-- ) ostr << ((a._v[i/32]>>(i%32))&1); return ostr; } friend UIntN operator +(const UIntN& a,const UIntN& b) { UIntN r; uint64_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =t =uint64_t(a._v[i])+uint64_t(b._v[i])+(t>>32); return r; } friend UIntN operator -(const UIntN& a,const UIntN& b) { UIntN r; uint64_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =t =uint64_t(a._v[i])-uint64_t(b._v[i])-((t>>32)&1); return r; } friend UIntN operator &(const UIntN& a,const UIntN& b) { UIntN r; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =a._v[i]&b._v[i]; return r; } friend UIntN operator |(const UIntN& a,const UIntN& b) { UIntN r; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =a._v[i]|b._v[i]; return r; } friend UIntN operator ^(const UIntN& a,const UIntN& b) { UIntN r; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =a._v[i]^b._v[i]; return r; } friend UIntN operator ~(const UIntN& a) { UIntN r; unsigned int i; for( i=0;i<(T+31)/32;i++ ) r._v[i] =~a._v[i]; return r; } friend UIntN operator >>(const UIntN& a,const uint32_t b) { UIntN r; uint32_t c=b>>5; uint32_t d=b&31; uint32_t e=32-d; unsigned int i; if( d==0 ) for( i=0;i<(T+31)/32;i++ ) r._v[i] =((i+c+0) < T) ? a._v[i+c] : 0; else for( i=0;i<(T+31)/32;i++ ) { r._v[i] =((i+c+0) < T) ? (a._v[i+c]>>d) : 0; r._v[i] |=((i+c+1) < T) ? (a._v[i+c+1]<<e) : 0; } return r; } friend UIntN operator <<(const UIntN& a,const uint32_t b) { UIntN r; uint32_t c=b>>5; uint32_t d=b&31; uint32_t e=32-d; int i; if( d==0 ) for( i=0;i<(T+31)/32;i++ ) r._v[i] =((i-c-0) >=0) ? a._v[i-c-0] : 0; else for( i=0;i<(T+31)/32;i++ ) { r._v[i] =((i-c-0) >=0) ? (a._v[i-c-0]<<d) : 0; r._v[i] |=((i-c-1) >=0) ? (a._v[i-c-1]>>e) : 0; } return r; } friend bool operator ==(const UIntN& a,const UIntN& b) { unsigned int i; for( i=0;i<(T+31)/32;i++ ) if( a._v[i]!=b._v[i] ) return false; return true; } friend bool operator !=(const UIntN& a,const UIntN& b) { unsigned int i; for( i=0;i<(T+31)/32;i++ ) if( a._v[i]!=b._v[i] ) return true; return false; } friend bool operator <(const UIntN& a,const UIntN& b) { int i; for( i=((T+31)/32)-1;i>=0;i-- ) if( a._v[i]<b._v[i] ) return true; else if( a._v[i]>b._v[i] ) return false; return false; } friend bool operator >(const UIntN& a,const UIntN& b) { int i; for( i=((T+31)/32)-1;i>=0;i-- ) if( a._v[i]>b._v[i] ) return true; else if( a._v[i]<b._v[i] ) return false; return false; } friend bool operator <=(const UIntN& a,const UIntN& b) { int i; for( i=((T+31)/32)-1;i>=0;i-- ) if( a._v[i]<b._v[i] ) return true; else if( a._v[i]>b._v[i] ) return false; return false; } friend bool operator >=(const UIntN& a,const UIntN& b) { int i; for( i=((T+31)/32)-1;i>=0;i-- ) if( a._v[i]>b._v[i] ) return true; else if( a._v[i]<b._v[i] ) return false; return false; } friend bool case_equality(const UIntN& a,const UIntN& b,const UIntN& m) { unsigned int i; for( i=0;i<(T+31)/32;i++ ) if( (a._v[i]&m._v[i])!=(b._v[i]&m._v[i]) ) return false; return true; } friend bool case_inequality(const UIntN& a,const UIntN& b,const UIntN& m) { unsigned int i; for( i=0;i<(T+31)/32;i++ ) if( (a._v[i]&m._v[i])!=(b._v[i]&m._v[i]) ) return true; return false; } friend bool reduction_and(const UIntN& a) { uint32_t t=0xFFFFFFFF; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t &=a.v[i]; return (t==0xFFFFFFFF); } friend bool reduction_nand(const UIntN& a) { uint32_t t=0xFFFFFFFF; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t &=a.v[i]; return !(t==0xFFFFFFFF); } friend bool reduction_or(const UIntN& a) { uint32_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t |=a.v[i]; return (t!=0); } friend bool reduction_nor(const UIntN& a) { uint32_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t |=a.v[i]; return !(t!=0); } friend bool reduction_xor(const UIntN& a) { uint32_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t ^=a.v[i]; t ^=(t>>16); t ^=(t>>8); t ^=(t>>4); t ^=(t>>2); t ^=(t>>1); return (t&1); } friend bool reduction_nxor(const UIntN& a) { uint32_t t=0; unsigned int i; for( i=0;i<(T+31)/32;i++ ) t ^=a.v[i]; t ^=(t>>16); t ^=(t>>8); t ^=(t>>4); t ^=(t>>2); t ^=(t>>1); return !(t&1); } bool index(uint32_t i) { uint32_t c=i>>5; uint32_t d=i&31; return (_v[c]>>d)&1; } friend UIntN Mask(unsigned int w) { UIntN r; unsigned int i; for( i=0;i<(w+31)/32;i++ ) r._v[i] =0xFFFFFFFF; r._v[i-1] =~(0xFFFFFFFF<<(w&31)); return r; } friend UIntN Mask(unsigned int msb,unsigned int lsb) { UIntN r; unsigned int i; return r; } UIntN operator ()(uint32_t m,uint32_t l) const //read { } _UIntN operator ()(uint32_t m,uint32_t l) //write { } UIntN part(uint32_t m,uint32_t l) { UIntN r; uint32_t lc =l>>5; uint32_t lb =l&31; uint32_t ld =32-lb; uint32_t mc =(m-l+1+31)>>5; uint32_t mm =31-(m-l+1+31)&31; unsigned int i; if( lb==0 ) for( i=0;i<mc;i++ ) r._v[i] =((i+lc+0) < T) ? _v[i+lc] : 0; else for( i=0;i<mc;i++ ) { r._v[i] =((i+lc+0) < T) ? (_v[i+lc+0]>>lb) : 0; r._v[i] |=((i+lc+1) < T) ? (_v[i+lc+1]<<ld) : 0; } r._v[mc-1] &=(0xFFFFFFFFUL>>mm); for( ;i<T;i++ ) r._v[i] =0; return r; } }; //////////////////////////////////////////////////////////////////////// // helper functions class EmVer { public: EmVer(){} virtual ~EmVer(){} //////////////////////////////////// inline void Assign(uint64_t& a,uint64_t mask,uint32_t lsb,uint64_t b) { a =(a&(~mask))|((b<<lsb)&mask); } inline void Assign(uint32_t& a,uint32_t mask,uint32_t lsb,uint32_t b) { a =(a&(~mask))|((b<<lsb)&mask); } inline void Assign(uint64_t& a,uint64_t mask,uint64_t b) { a =b&mask; } inline void Assign(uint32_t& a,uint32_t mask,uint32_t b) { a =b&mask; } inline bool Index(uint32_t a,int i) { return ((a>>i)&1); } inline uint32_t Part(uint32_t a,int l,uint32_t m) { return ((a>>l)&m); } inline uint32_t Concat(uint32_t l,uint32_t r,int rw) { return ((l<<rw)|r); } inline uint32_t Repeat(uint32_t repeat,uint32_t concat,int concat_width) { uint32_t r =concat; int i; for( i=1;i<repeat;i++ ) r =(r<<concat_width)|r; return r; } //////////////////////////////////////////////////////////////////////// // unary expression inline bool ReductionAND(uint32_t r,uint32_t m) { return ((r&m)==m); } inline bool ReductionOR(uint32_t r,uint32_t m) { return ((r&m)!=0); } inline bool ReductionXOR(uint32_t r,uint32_t m) { r &=m; r ^=(r>>16); r ^=(r>>8); r ^=(r>>4); r ^=(r>>2); r ^=(r>>1); return (r&1); } inline bool ReductionNAND(uint32_t r,uint32_t m) { return !((r&m)==m); } inline bool ReductionNOR(uint32_t r,uint32_t m) { return !((r&m)==0); } inline bool ReductionNXOR(uint32_t r,uint32_t m) { r &=m; r ^=(r>>16); r ^=(r>>8); r ^=(r>>4); r ^=(r>>2); r ^=(r>>1); return !(r&1); } inline uint32_t SignExt(uint32_t a,uint32_t b) { if( (a&b)!=0 ) return a|b; else return a; } inline uint64_t SignExt(uint64_t a,uint64_t b) { if( (a&b)!=0 ) return a|b; else return a; } inline uint64_t SignExt(uint32_t a,uint64_t b) { if( (uint64_t(a)&b)!=0 ) return uint64_t(a)|b; else return uint64_t(a); } //////////////////////////////////////////////////////////////////////// // binary expression inline uint32_t ArithmeticAdd(uint32_t a,uint32_t b) { return (a+b); } inline uint32_t ArithmeticMinus(uint32_t a,uint32_t b) { return (a+b); } inline uint32_t ArithmeticMultiply(uint32_t a,uint32_t b) { return (a+b); } inline uint32_t ArithmeticDivide(uint32_t a,uint32_t b) { return (a+b); } inline uint32_t ArithmeticModulus(uint32_t a,uint32_t b) { return (a+b); } inline uint32_t BitwiseXOR(uint32_t a,uint32_t b) { return (a^b); } inline bool LogicalEquality(uint32_t a,uint32_t b) { return (a==b); } inline bool CaseEquality(uint32_t a,uint32_t b,uint32_t m) { return ((a&m)==(b&m)); } inline bool CaseInequality(uint32_t a,uint32_t b,uint32_t m) { return ((a&m)!=(b&m)); } //////////////////////////////////// inline bool Index(uint64_t a,int i) { return ((a>>i)&1); } /* inline bool Index(const _UIntN& a,int i) { return ((*(a.v()+(i>>5))>>(i&31))&1); } */ //////////////////////////////////// inline uint64_t Part(uint64_t a,int l,uint64_t m) { return ((a>>l)&m); } //////////////////////////////////// inline uint64_t Concat(uint64_t l,uint64_t r,int rw) { return ((l<<rw)|r); } //////////////////////////////////// inline uint64_t Concat(uint32_t repeat,uint64_t concat,int concat_width) { uint64_t r =concat; int i; for( i=1;i<repeat;i++ ) r =(r<<concat_width)|r; return r; } //////////////////////////////////// inline uint64_t ArithmeticAdd(uint64_t a,uint64_t b) { return (a+b); } //////////////////////////////////// void vcd_dump(std::ostream& str,uint32_t d,int w) { str << 'b'; int i; for( i=w-1;i>=0;i-- ) str << ((d>>i)&1); } void vcd_dump(std::ostream& str,uint64_t d,int w) { str << 'b'; int i; for( i=w-1;i>=0;i-- ) str << ((d>>i)&1); } }; inline int32_t SignExt(uint32_t a,uint32_t b) { if( (a&b)!=0 ) return a|b; else return a; } inline int64_t SignExt(uint64_t a,uint64_t b) { if( (a&b)!=0 ) return a|b; else return a; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -