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

Subversion Repositories sxp

[/] [sxp/] [trunk/] [csim/] [alu/] [alu.cc] - Rev 59

Compare with Previous | Blame | View Log

class alu {
  public:
    alu();
    void operation(unsigned op,unsigned a, bool a_vld, unsigned b, bool b_vld);
    unsigned get_ya();
    bool get_ya_vld();
    unsigned get_yb();
    bool get_yb_vld();
 
    unsigned get_a_zflag();
    bool get_a_zflag_vld();
    unsigned get_a_nflag();
    bool get_a_nflag_vld();
    unsigned get_a_vflag();
    bool get_a_vflag_vld();
    unsigned get_a_cflag();
    bool get_a_cflag_vld();
 
    unsigned get_b_zflag();
    bool get_b_zflag_vld();
    unsigned get_b_nflag();
    bool get_b_nflag_vld();
    unsigned get_b_vflag();
    bool get_b_vflag_vld();
    unsigned get_b_cflag();
    bool get_b_cflag_vld();
 
  protected:
 
  private:
    void set_flags();
    unsigned ya;
    bool ya_vld;
    unsigned yb;
    bool yb_vld;
 
    typedef unsigned long long true_long;
    true_long result;
 
    bool a_c, a_c_vld;
    bool a_v, a_v_vld;
    bool a_n, a_n_vld;
    bool a_z, a_z_vld;
 
    bool b_c, b_c_vld;
    bool b_v, b_v_vld;
    bool b_n, b_n_vld;
    bool b_z, b_z_vld;
};
 
alu::alu()
{
  cout << "Init alu \n";
}
 
void alu::operation (unsigned op,unsigned a,bool a_vld,unsigned b,bool b_vld)
{
  unsigned b_se;	// sign extended b 
  unsigned b_n;		// two complement version of b
 
  switch (op) {
  case 0:	// Pass operation
    ya = a;
    ya_vld = a_vld;
    yb = b;
    yb_vld = b_vld;
 
    result = 0ULL;
    a_c = false;
    a_c_vld = true;
    b_c = false;
    b_c_vld = true;
    a_v = false;
    a_v_vld = true;
    b_v = false;
    b_v_vld = true;
    break;
  case 1:	// Add operation
    // Code for ya
    ya_vld = a_vld && b_vld;
    yb_vld = a_vld && b_vld;
    if (a_vld && b_vld) {
      result = (true_long)a + (true_long)b;
      ya = 0x00000000ffffffff & result;
      if ((result >> 32) > 0)
        a_c = true;
      else
        a_c = false;
 
      if (((a>>31) ^ (b>>31)) == 0) {
        if (((a>>31) ^ (ya>>31)) == 0)
          a_v = false;
        else
          a_v = true; 
      }
      else 
        a_v = false;
 
      // Code for yb here
 
      b_se = 0x0000ffff & b;
      if ((b_se>>15) == 1)
        b_se = 0xffff0000 | b_se;
 
      result = (true_long)a + (true_long)b_se;
      yb = 0x00000000ffffffff & result;
      if ((result >> 32) > 0)
        b_c = true;
      else
        b_c = false;
 
      if (((a>>31) ^ (b_se>>31)) == 0) {
        if (((a>>31) ^ (ya>>31)) == 0)
          b_v = false;
        else
          b_v = true; 
      }
      else 
        b_v = false;
 
      a_c_vld = true;
      b_c_vld = true;
 
      a_v_vld = true;
      b_v_vld = true;
    }
    else {
      a_c = false;
      a_c_vld = false;
      a_v = false;
      a_v_vld = false;
 
      b_c = false;
      b_c_vld = false;
      b_v = false;
      b_v_vld = false;
      result = 0ULL;
    }
    break;
  case 2:	// Sub operation
    ya_vld = a_vld && b_vld;
    yb_vld = a_vld && b_vld;
    if (a_vld && b_vld) {
      b_n = 1 + ~b; 
      result = (true_long)a + (true_long)b_n;
      ya = 0x00000000ffffffff & result;
      if ((result >> 32) > 0)
        a_c = true;
      else
        a_c = false;
 
      if (((a>>31) ^ (b_n>>31)) == 0) {
        if (((a>>31) ^ (ya>>31)) == 0)
          a_v = false;
        else
          a_v = true; 
      }
      else 
        a_v = false;
 
      // Code for yb here
 
      b_se = 0x0000ffff & b;
      if ((b_se>>15) == 1)
        b_se = 0xffff0000 | b_se;
      b_se = 1 + ~b_se;		// Two's complement
 
      result = (true_long)a + (true_long)b_se;
      yb = 0x00000000ffffffff & result;
      if ((result >> 32) > 0)
        b_c = true;
      else
        b_c = false;
 
      if (((a>>31) ^ (b_se>>31)) == 0) {
        if (((a>>31) ^ (ya>>31)) == 0)
          b_v = false;
        else
          b_v = true; 
      }
      else 
        b_v = false;
 
      a_c_vld = true;
      b_c_vld = true;
 
      a_v_vld = true;
      b_v_vld = true;
 
    }
    else {
      a_c = false;
      a_c_vld = false;
      a_v = false;
      a_v_vld = false;
 
      b_c = false;
      b_c_vld = false;
      b_v = false;
      b_v_vld = false;
      result = 0ULL;
    }
    break;
  case 3:	// Mult operation
    ya_vld = a_vld && b_vld;
    yb_vld = a_vld && b_vld;
    if (a_vld && b_vld) {
      result = (true_long)a * (true_long)b;
      ya = result >> 32;
      yb = 0x00000000ffffffff & result; 
 
      a_c = false;
      a_c_vld = true;
      b_c = false;
      b_c_vld = true;
      a_v = false;
      a_v_vld = true;
      b_v = false;
      b_v_vld = true;
    }
    else {
      a_c = false;
      a_c_vld = false;
      a_v = false;
      a_v_vld = false;
 
      b_c = false;
      b_c_vld = false;
      b_v = false;
      b_v_vld = false;
      result = 0ULL;
    }
    break;
  case 4:	// AND/OR operation
    ya_vld = a_vld && b_vld;
    yb_vld = a_vld && b_vld;
    if (a_vld && b_vld) {
      ya = a & b;
      yb = a | b;
 
      a_c = false;
      a_c_vld = true;
      b_c = false;
      b_c_vld = true;
      a_v = false;
      a_v_vld = true;
      b_v = false;
      b_v_vld = true;
    }
    else {
      a_c = false;
      a_c_vld = false;
      a_v = false;
      a_v_vld = false;
 
      b_c = false;
      b_c_vld = false;
      b_v = false;
      b_v_vld = false;
      result = 0ULL;
    }
    break;
  case 5:	// XOR / XNOR operation
    ya_vld = a_vld && b_vld;
    yb_vld = a_vld && b_vld;
    if (a_vld && b_vld) {
      ya = a ^ b;
      yb = ~ya;
 
      a_c = false;
      a_c_vld = true;
      b_c = false;
      b_c_vld = true;
      a_v = false;
      a_v_vld = true;
      b_v = false;
      b_v_vld = true;
    }
    else {
      a_c = false;
      a_c_vld = false;
      a_v = false;
      a_v_vld = false;
 
      b_c = false;
      b_c_vld = false;
      b_v = false;
      b_v_vld = false;
      result = 0ULL;
    }
    break;
  case 6:	// Reserved 
    ya_vld = false;
    yb_vld = false;
 
    a_c = false;
    a_c_vld = false;
    a_v = false;
    a_v_vld = false;
 
    b_c = false;
    b_c_vld = false;
    b_v = false;
    b_v_vld = false;
    result = 0ULL;
    break;
  case 7:	// Pass operation
    ya = (a<<16) | (a>>16);
    ya_vld = a_vld;
    yb = (b<<16) | (b>>16);
    yb_vld = b_vld;
    result = 0ULL;
    a_c = false;
    a_c_vld = true;
    b_c = false;
    b_c_vld = true;
    a_v = false;
    a_v_vld = true;
    b_v = false;
    b_v_vld = true;
    break;
  }
  set_flags();
}    
 
void alu::set_flags()
{ 
  if (ya_vld) {
    if ((ya>>31) == 1) 
      a_n = true;
    else 
      a_n = false;
 
    if (ya == 0) 
      a_z = true;
    else
      a_z = false;
 
    a_n_vld = true;
    a_z_vld = true;
  }
  else {
    a_n = false;
    a_n_vld = false;
    a_z = false;
    a_z_vld = false;
  }
 
  if (yb_vld) {
    if ((yb>>31) == 1) 
      b_n = true;
    else
      b_n = false;
 
    if (yb == 0) 
      b_z = true;
    else
      b_z = false;
 
    b_n_vld = true;
    b_z_vld = true;
  }
  else {
    b_n = false;
    b_n_vld = false;
    b_z = false;
    b_z_vld = false;
  }
}
 
unsigned alu::get_ya()
{
  return (ya);
}
 
bool alu::get_ya_vld()
{
  return (ya_vld);
}
 
unsigned alu::get_yb()
{
  return (yb);
}
 
bool alu::get_yb_vld()
{
  return (yb_vld);
}
 
unsigned alu::get_a_zflag()
{
  if (a_z)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_a_zflag_vld()
{
  return (a_z_vld);
}
 
unsigned alu::get_a_nflag()
{
  if (a_n)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_a_nflag_vld()
{
  return (a_n_vld);
}
 
unsigned alu::get_a_vflag()
{
  if (a_v)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_a_vflag_vld()
{
  return(a_v_vld);
}
 
unsigned alu::get_a_cflag()
{
  if (a_c)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_a_cflag_vld()
{
  return (a_c_vld);
}
 
 
unsigned alu::get_b_zflag()
{
  if (b_z)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_b_zflag_vld()
{
  return (b_z_vld);
}
 
unsigned alu::get_b_nflag()
{
  if (b_n)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_b_nflag_vld()
{
  return (b_n_vld);
}
 
unsigned alu::get_b_vflag()
{
  if (b_v)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_b_vflag_vld()
{
  return(b_v_vld);
}
 
unsigned alu::get_b_cflag()
{
  if (b_c)
    return (0x00000001);
  else
    return (0x00000000);
}
 
bool alu::get_b_cflag_vld()
{
  return (b_c_vld);
}
 
 
/*
 *  $Id: alu.cc,v 1.1 2001-10-28 03:27:21 samg Exp $ 
 *  Program  : alu.cc 
 *  Author   : Sam Gladstone
 *  Function : alu behavioral class for SXP 
 *  $Log: not supported by cvs2svn $
 */
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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