Exemplo n.º 1
0
CAMLexport int caml_umul_overflow(uintnat a, uintnat b, uintnat * res)
{
#define HALF_SIZE (sizeof(uintnat) * 4)
#define HALF_MASK (((uintnat)1 << HALF_SIZE) - 1)
#define LOW_HALF(x) ((x) & HALF_MASK)
#define HIGH_HALF(x) ((x) >> HALF_SIZE)
  /* Cut in half words */
  uintnat al = LOW_HALF(a);
  uintnat ah = HIGH_HALF(a);
  uintnat bl = LOW_HALF(b);
  uintnat bh = HIGH_HALF(b);
  /* Exact product is:
              al * bl
           +  ah * bl  << HALF_SIZE
           +  al * bh  << HALF_SIZE
           +  ah * bh  << 2*HALF_SIZE
     Overflow occurs if:
        ah * bh is not 0, i.e. ah != 0 and bh != 0
     OR ah * bl has high half != 0
     OR al * bh has high half != 0
     OR the sum al * bl + LOW_HALF(ah * bl) << HALF_SIZE
                        + LOW_HALF(al * bh) << HALF_SIZE overflows.
     This sum is equal to p = (a * b) modulo word size. */
  uintnat p = a * b;
  uintnat p1 = al * bh;
  uintnat p2 = ah * bl;
  *res = p;
  if (ah == 0 && bh == 0) return 0;
  if (ah != 0 && bh != 0) return 1;
  if (HIGH_HALF(p1) != 0 || HIGH_HALF(p2) != 0) return 1;
  p1 <<= HALF_SIZE;
  p2 <<= HALF_SIZE;
  p1 += p2;
  if (p < p1 || p1 < p2) return 1; /* overflow in sums */
  return 0;
#undef HALF_SIZE
#undef HALF_MASK
#undef LOW_HALF
#undef HIGH_HALF
}
Exemplo n.º 2
0
void dh_hw_mult::process_hw_mult()
{
  NN_DIGIT a[2], b, c, t, u;
  //NN_HALF_DIGIT bHigh, bLow, cHigh, cLow;

    while (true)
    {
      if (reset.read() == true){
            state.write(S0_WAIT);
            hw_mult_done.write(false);
        }
      else
        {
          switch(state.read()){

            case S0_WAIT: // wait for enable signal to be asserted
                if (hw_mult_enable.read() == true) {
                  state.write(S1_EXECUTE);
                }
                break;

            case S1_EXECUTE: //multiply the inputs
                // Read inputs  
                /*b = in_data_1.read();
                c = in_data_2.read();*/

                // Original code from NN_DigitMult()... 
                /*bHigh = b_high.read(); //(NN_HALF_DIGIT)HIGH_HALF (b);
                bLow = b_low.read(); //(NN_HALF_DIGIT)LOW_HALF (b);
                cHigh = c_high.read();//(NN_HALF_DIGIT)HIGH_HALF (c);
                cLow = c_low.read(); //(NN_HALF_DIGIT)LOW_HALF (c);*/

                a[0] = a0temp.read();//(NN_DIGIT)bLow * (NN_DIGIT)cLow;
                t = t_temp.read(); //(NN_DIGIT)bLow * (NN_DIGIT)cHigh;
                u = u_temp.read(); //(NN_DIGIT)bHigh * (NN_DIGIT)cLow;
                a[1] = a1temp.read();//(NN_DIGIT)bHigh * (NN_DIGIT)cHigh;
              
                if ((t += u) < u) a[1] += TO_HIGH_HALF (1); //t = t + u < u
                u = TO_HIGH_HALF (t);
              
                if ((a[0] += u) < u) a[1]++;
                a[1] += HIGH_HALF (t);

                state.write(S2_OUTPUT);
              break;

            case S2_OUTPUT: //write to modules output ports, assert done signal

                // Write Outputs
                out_data_low.write(a[0]);
                out_data_high.write(a[1]);

                hw_mult_done.write(true);
                wait();
                
                state.write(S3_FINISH);
              break;

            case S3_FINISH: //check if enable is deasserted, if so deassert done
                if (hw_mult_enable.read() == false)
                    {
                        hw_mult_done.write(false);
                        wait();
                        state.write(S0_WAIT);
                    }
              break;
            }
          }wait();
        } 
      }