OpenCores
URL https://opencores.org/ocsvn/complexarithmetic/complexarithmetic/trunk

Subversion Repositories complexarithmetic

[/] [complexarithmetic/] [trunk/] [cplxopsphasor.sc.h] - Rev 4

Compare with Previous | Blame | View Log

 
#include <systemc.h>
#ifndef _CPLXOPSPHASOR_H_
#define _CPLXOPSPHASOR_H_
 
template<typename T>
class complex
{
    T real, imag;
    /*initialization of the real and imaginal parts of the complex values as 0
    definition of copy constructor and assignment operator*/
public:
    complex() : real(0),imag(0)         
    {
    }
    complex( const T& real_, const T& imag_ ) : real(real_), imag(imag_){}
    complex( const complex& other ) : real(other.real), imag(other.imag){}
    complex& operator = ( const complex& other )
    {
        real = other.real;
        imag = other.imag;
        return *this;
    }
 
    /*definiton of mutators and access member functions*/
    T get_real() const
    {
        return real;
    }
    T get_imag() const
    {
        return imag;
    }
    void set_real( const T& real_ )
    {
        real = real_;
    }
    void set_imag( const T& imag_ )
    {
        imag = imag_;
    }
 
    /*Definition of member operators*/
    complex& operator += ( const complex& other )
    {
        real += other.real;
        imag += other.imag;
        return *this;
    }
    /*Definition of complex aritmetic operators as friend Operators.*/
    friend complex operator + ( const complex& a, const complex& b )  //approved
    {
        complex result;
        result.set_real( a.get_real() + b.get_real() );
        result.set_imag( a.get_imag() + b.get_imag() );
        return result;
    }
    friend complex operator * ( const complex& a, const complex& b )  //approved
    {
        complex result;
        sc_uint<8> areal, aimag, breal, bimag;       //real and imaginary parts of the operands
        sc_uint<16> tempreal,tempimag;               //temporary outputs (16 BITS)
 
        /*complex multiplication of two complex numnbers a and b is defined by
        a*b=(areal*breal-aimag*bimag)+i(areal*bimag+aimag*breal)*/
 
        areal=a.get_real();aimag=a.get_imag();
        breal=b.get_real();bimag=b.get_imag();
        tempreal=areal*breal-aimag*bimag;       
        tempimag=aimag*breal+areal*bimag;
        result.set_real(tempreal);
        result.set_imag(tempimag);
        return result;                              //the result is returned
    }
 
    friend complex operator / ( const complex& a, const complex& b ) //approved
    {
        complex result;
        sc_uint<4> count=0;
        sc_uint<8> areal, aimag, breal, bimag;                                                   //real and imaginary parts of the operands
        sc_uint<8> tempxa=0,tempya=0,tempxb=0,tempyb=0,anglea=0,angleb=0,angleresult,rresult,angle=90,us=128;    //,raparameters to accumulate the temporary results of the operation
//        sc_uint<16> rb;
        areal=a.get_real(); breal=b.get_real(); aimag=a.get_imag(); b.get_imag();                       //read real and imaginary parts of the complex operands
        /*the operands will first be converted from cartesian to polar representation using cordic techniques
       then the operands will be divided as a/b=ra/rb(anglea-angleb) */
        if (areal[7]==1)                    //determination of the initial angular position of the operands
        {
            anglea=180;
        }
        if (breal[7]==1)
        {
            angleb=180;
        }
        while (count<=6)                    //CORDIC vector mode operation for converting 
        {                                   //the operands from cartesian to polar representation
            angle=angle>>1;
			count++;
			tempxa = areal>>count;
            tempya = aimag>>count;
            tempxb = breal>>count;
            tempyb = bimag>>count;
           if ( aimag[7]==1 )              //CORDIC operation for the first operand
            {
                areal=areal-tempya;
                aimag=aimag+tempxa;
                anglea=anglea-angle;
            }
            else //if ( aimag[7]==0 )
            {
                areal=areal+tempya;
                aimag=aimag-tempxa;
                anglea=anglea+angle; 
           }
            if ( bimag[7]==0 )             //CORDIC operation for the second operand
            {
                breal=breal-tempyb;
                bimag=bimag+tempxb;
                angleb=angleb-angle;
            }
            else //if ( bimag[7]==0 )
            {
                breal=breal+tempyb;
                bimag=bimag-tempxb;
                angleb=angleb+angle;
           }
 
        }
        rresult=areal/breal;                      //divide the absolute values
        angleresult=anglea-angleb;          //subtract the polar angles
        count=0;
        sc_uint<8> y=0,tempr,tempy;
		angle=90;
        while (count<=6)                    //CORDIC vector mode operation for converting 
        {                                   //the result from polar to cartesian representation
            count++;
			tempr = rresult>>count;
            tempy = y>>count;
            angle=angle>>1;
            if (angleresult[7]==0)
            {
                rresult=rresult-tempy;
                y=y+tempr;
                angleresult=angleresult-angle;
            }
            else if (angleresult[7]==1)
            {
                rresult=rresult+tempy;
                y=y-tempr;
                angleresult=angleresult+angle;
            }
         }
        result.set_real(rresult);
        result.set_imag(angleresult);
        return result;         
   }
 
    friend complex pol2car ( const complex& a)//approved
    {
        complex result;
        sc_int <4> count=0;
        sc_uint <8> r,angle;                 //absolute value and polar angle of the operand
        sc_uint <8> tempr,tempy,tempangle=90,y; //temporary values for polar to cartesian operation
        r=a.get_real();
        angle=a.get_imag();
         while (count<6) //count= 1; count < 7; count++)  //Cordic operation for polar to cartesian transformation
        {
            count++;
			tempr = r >>count;
            tempy = y >>count;
            tempangle=tempangle>>1;
            if (angle[7]==0)
            {
                r=r-tempy;
                y=y+tempr;
                angle=angle-tempangle;
            }
            else if (angle[7]==1)
            {
                r=r+tempy;
                y=y-tempr;
                angle=angle+tempangle;
            }
        }
        result.set_real(r);
        result.set_imag(y);
        return (result);
    }
 
    friend complex sqrt ( const complex& a)	//approved
    {    //sqrt(x+iy)==1/2sqrt(2)[sqrt(sqrt(x^2+y^2)+x)+isgn(y)sqrt(sqrt(x^2+y^2)-x)].
        complex result;
        int cnt=0;//,cnt1=1;
        sc_uint<8> tempabs, tempreal, tempimag, sgn, areal, aimag, abs, base1, base2, sqrt1,sqrt2;//ra,
        sc_uint<8> tempareal,tempaimag;
		areal=a.get_real();
        aimag=a.get_imag();
        abs=a.get_real();
        while (cnt<6)        //CORDIC vector mode to evaluate the absolute value of a
        {
            cnt++;           
            tempareal = areal >>cnt;
            tempaimag = aimag >>cnt;   
            if ( aimag[7]==1)
            {
                abs=abs-tempaimag;
                aimag=aimag+tempabs;
            }
            if ( aimag[7]==0)
            {
                abs=abs+tempaimag;
                aimag=aimag-tempabs;                
            }
        }
        tempreal=abs+a.get_real();                  //sqrt(x^2+y^2)+x
        tempimag=abs-a.get_real();                  //sqrt(x^2+y^2)-x
        sqrt1=0;base1=8;sqrt2=0;base2=8;        
        for (cnt= 0; cnt < 2; cnt++)//while (cnt1<5)                             //evaluating the temporary square roots using numeric techniques
        {                                           //sqrt(sqrt(x^2+y^2)+x),sqrt(sqrt(x^2+y^2)-x)
                 sqrt1 = base1 + sqrt1;
                if  ( (base1 * base1) > tempreal )
                {
                        sqrt1 = base1 - sqrt1 ;     // base should not have been added, so we substract again
                }
                base1>>1 ;                        // shift 1 digit to the right = divide baimag 2
                sqrt2 = base2 + sqrt2 ;
                if  ( (sqrt2 * sqrt2) > tempimag )
                {
                        sqrt2 = base2 - sqrt2 ;    
                }
                base2>>1 ;                        
        }
        sqrt1=sqrt1>>1;                             //multiply the tmeporary results with 0.5 instead of 0.7
        sqrt2=sqrt2>>1;                             //1/2*sqrt(2)=
        sqrt2[7]=aimag[7];                          //apply the sign of the imaginary part
        result.set_real(sqrt1);
        result.set_imag(sqrt2);
        return result;
    }
 
    friend complex operator - ( const complex& a, const complex& b )//approved
    {
        complex result;
        result.set_real( a.get_real() - b.get_real() );
        result.set_imag( a.get_imag() - b.get_imag() );
        return result;
    }
 
    friend complex conj ( const complex& a )//approved
    {
        complex result;
		sc_uint<8> tempa,tempb;
		tempa=a.get_imag();
		tempb=tempa;
		tempb[7]=!tempa[7];
        result.set_real( a.get_real());
        result.set_imag( tempb);
        return result;
    }
    /*
     * Predicate operators
 
     */
    friend bool operator == ( const complex& a, const complex& b )
    {
        return ( (a.get_real() == b.get_real()) && (a.get_real() == b.get_real()) );
    }
    friend bool operator != ( const complex& a, const complex& b )
    {
        return ( ! (a == b) );
    }
};
 
 
 
#endif
 
 
 
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.