Esempio n. 1
0
   FPge_expr::FPge_expr(Target* _target, int wE, int wF) :
         Operator(_target) {

      ostringstream name;

      name<<"FPge_expr_" <<wE<<"_"<<wF;
      setName(name.str());

      setCopyrightString("Fabrizio Ferrandi (2011-2017)");

      /* Set up the IO signals */

      addFPInput ("X", wE,wF);
      addFPInput ("Y", wE,wF);
      addOutput ("R", 1);

      /*	VHDL code description	*/
      manageCriticalPath(_target->localWireDelay() + _target->lutDelay());
      vhdl << tab << declare("nY",wE+wF+3) << "  <= Y"<< range(wE+wF+2,wE+wF+1) << " & not(Y"<< of(wE+wF) << ") & Y" << range(wE+wF-1,0) << ";" << endl;
      FPAdderSinglePath * value_difference = new FPAdderSinglePath(_target, wE, wF, wE, wF, wE, wF);
      value_difference->changeName(getName()+"value_difference");
      oplist.push_back(value_difference);
      inPortMap  (value_difference, "X", "X");
      inPortMap  (value_difference, "Y", "nY");
      outPortMap (value_difference, "R","valueDiff");
      vhdl << instance(value_difference, "value_difference");
      syncCycleFromSignal("valueDiff");
      setCriticalPath(value_difference->getOutputDelay("R"));

      manageCriticalPath(_target->localWireDelay() + _target->lutDelay());
      vhdl << tab << "R(0) <=   '1' when (valueDiff" << of(wE+wF) << "='0' or (valueDiff" << range(wE+wF+2,wE+wF+1) << " = \"00\")) else '0';" << endl;
   }
Esempio n. 2
0
	FixAtan2ByCORDIC::FixAtan2ByCORDIC(Target* target_, int wIn_, int wOut_, map<string, double> inputDelays_) :
 		FixAtan2(target_, wIn_, wOut_, inputDelays_)
	{
		int stage;
		srcFileName="FixAtan2ByCORDIC";
		setCopyrightString ( "Matei Istoan, Florent de Dinechin (2012-...)" );
		useNumericStd_Unsigned();

		ostringstream name;
		name << "FixAtan2ByCORDIC_" << wIn_ << "_" << wOut_ << "_uid" << getNewUId();
		setNameWithFreq( name.str() );
	
		mpfr_t  zatan; 
		mpfr_init2(zatan, 10*wOut);
	
		computeGuardBits();

		//Defining the various parameters according to method


		///////////// VHDL GENERATION
	
		/////////////////////////////////////////////////////////////////////////////
		// 
		//    First range reduction
		//
		/////////////////////////////////////////////////////////////////////////////

		buildQuadrantRangeReduction();

		// No scaling RR: just a copy
		vhdl << tab << declare("XRS", wIn-1) << " <=  XR;" << endl;
		vhdl << tab << declare("YRS", wIn-1) << " <=  YR;" << endl;
		
		int sizeZ=wOut-2+gA; // w-2 because two bits come from arg red 

		////////////////////////////////////////////////////////////////////////////
		// 
		//   	 CORDIC iterations	
		//
		////////////////////////////////////////////////////////////////////////////
		
		// Fixed-point considerations:
		// Y -> 0 and X -> K.sqrt(x1^2+y1^2)
		// Max value attained by X is sqrt(2)*K which is smaller than 2
		
		int zMSB=-1;      // -1 because these two bits have weight 0 and -1, but we must keep the sign
		int zLSB = zMSB-sizeZ+1;
		int sizeX = wIn+gXY;
		int sizeY = sizeX;
		
		
		vhdl << tab << declare("X1", sizeX) << " <= '0' & XRS & " << zg(sizeX-(wIn-1)-1) << ";" <<endl;			
		vhdl << tab << declare("Y1", sizeY) << " <= '0' & YRS & " << zg(sizeY-(wIn-1)-1) << ";" <<endl;			
		stage=1; 
 
		manageCriticalPath( getTarget()->adderDelay(sizeX));
		vhdl << tab << "--- Iteration " << stage << " : sign is known positive ---" << endl;
		vhdl << tab << declare(join("YShift", stage), sizeX) << " <= " << rangeAssign(sizeX-1, sizeX-stage, "'0'") << " & Y" << stage << range(sizeX-1, stage) << ";" << endl;
		vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " 
				 << join("X", stage) << " + " << join("YShift", stage) << " ;" << endl;
		
		vhdl << tab << declare(join("XShift", stage), sizeY) << " <= " << zg(stage) << " & X" << stage << range(sizeY-1, stage) << ";" <<endl;			
		vhdl << tab << declare(join("Y", stage+1), sizeY) << " <= " 
				 << join("Y", stage) << " - " << join("XShift", stage) << " ;" << endl;
		

		//create the constant signal for the arctan
		mpfr_set_d(zatan, 1.0, GMP_RNDN);
		mpfr_div_2si(zatan, zatan, stage, GMP_RNDN);
		mpfr_atan(zatan, zatan, GMP_RNDN);
		mpfr_div(zatan, zatan, constPi, GMP_RNDN);
		mpfr_t roundbit;
		mpfr_init2(roundbit, 30); // should be enough for anybody
		mpfr_set_d(roundbit, 1.0, GMP_RNDN);
		mpfr_div_2si(roundbit, roundbit, wOut, GMP_RNDN); // roundbit is in position 2^-wOut
		
		REPORT(DEBUG, "stage=" << stage << "  atancst=" << printMPFR(zatan));
		
		mpfr_add(zatan, zatan, roundbit, GMP_RNDN);
		vhdl << tab << declare("Z2", sizeZ) << " <= " << unsignedFixPointNumber(zatan, zMSB, zLSB) << "; -- initial atan, plus round bit" <<endl;
		

		for(stage=2; stage<=maxIterations;    stage++, sizeY--){
			// Invariant: sizeX-sizeY = stage-2
			vhdl << tab << "--- Iteration " << stage << " ---" << endl;
			
			manageCriticalPath( getTarget()->localWireDelay(sizeX+1) + getTarget()->adderDelay(max(sizeX,sizeZ)) );
			vhdl << tab << declare(join("sgnY", stage))  << " <= " <<  join("Y", stage)  <<  of(sizeY-1) << ";" << endl;
			
			if(-2*stage+1 >= -wIn+1-gXY) { 
				vhdl << tab << declare(join("YShift", stage), sizeX) 
						 << " <= " << rangeAssign(sizeX-1, sizeX -(sizeX-sizeY+stage), join("sgnY", stage))   
						 << " & Y" << stage << range(sizeY-1, stage) << ";" << endl;
				
				vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " 
						 << join("X", stage) << " - " << join("YShift", stage) << " when " << join("sgnY", stage) << "=\'1\'     else "
						 << join("X", stage) << " + " << join("YShift", stage) << " ;" << endl;
			}
			else {	// autant pisser dans un violon
				vhdl << tab << declare(join("X", stage+1), sizeX) << " <= " << join("X", stage) << " ;" << endl;
			}
			
			vhdl << tab << declare(join("XShift", stage), sizeY) << " <= " << zg(2) << " & X" << stage << range(sizeX-1, sizeX - sizeY + 2) << ";" <<endl;			
			vhdl << tab << declare(join("YY", stage+1), sizeY) << " <= " 
					 << join("Y", stage) << " + " << join("XShift", stage) << " when " << join("sgnY", stage) << "=\'1\'     else "
					 << join("Y", stage) << " - " << join("XShift", stage) << " ;" << endl;
			vhdl << tab << declare(join("Y", stage+1), sizeY-1) << " <= " << join("YY", stage+1) << range(sizeY-2, 0) << ";" <<endl;
			
			
			//create the constant signal for the arctan
			mpfr_set_d(zatan, 1.0, GMP_RNDN);
			mpfr_div_2si(zatan, zatan, stage, GMP_RNDN);
			mpfr_atan(zatan, zatan, GMP_RNDN);
			mpfr_div(zatan, zatan, constPi, GMP_RNDN);
			REPORT(DEBUG, "stage=" << stage << "  atancst=" << printMPFR(zatan));		
			// rounding here in unsignedFixPointNumber()
			vhdl << tab << declare(join("atan2PowStage", stage), sizeZ) << " <= " << unsignedFixPointNumber(zatan, zMSB, zLSB) << ";" <<endl;
			vhdl << tab << declare(join("Z", stage+1), sizeZ) << " <= " 
					 << join("Z", stage) << " + " << join("atan2PowStage", stage) << " when " << join("sgnY", stage) << "=\'0\'      else "
					 << join("Z", stage) << " - " << join("atan2PowStage", stage) << " ;" << endl;
			
		} //end for loop
		
			// Give the time to finish the last rotation
			// manageCriticalPath( getTarget()->localWireDelay(w+1) + getTarget()->adderDelay(w+1) // actual CP delay
			//                     - (getTarget()->localWireDelay(sizeZ+1) + getTarget()->adderDelay(sizeZ+1))); // CP delay that was already added
		
		manageCriticalPath( getTarget()->localWireDelay(wOut+1) + getTarget()->adderDelay(2) );

		vhdl << tab << declare("finalZ", wOut) << " <= Z" << stage << of(sizeZ-1) << " & Z" << stage << range(sizeZ-1, sizeZ-wOut+1) << "; -- sign-extended and rounded" << endl;

		buildQuadrantReconstruction();
	};
Esempio n. 3
0
	FPSumOf3Squares::FPSumOf3Squares(Target* target, int wE, int wF, int optimize)
		: Operator(target), wE(wE), wF(wF)
	{
		setCopyrightString("F. de Dinechin, Bogdan Pasca (2011)");
		srcFileName="FPSumOf3Squares";
		ostringstream o;
		o << "FPSumOf3Squares_" << wE << "_" << wF;
		if(!optimize)
			o << "_FP";
		setName(o.str());

		addFPInput("X", wE, wF);
		addFPInput("Y", wE, wF);
		addFPInput("Z", wE, wF);
		addFPOutput("R", wE, wF, 2); // This 2 means: we will allow two possible inputs (faithful rounding)

		if(!optimize) {
			//////////////////////////////////////////////////////////////////:
			//            A version that assembles FP operators             //
			//////////////////////////////////////////////////////////////////:

			FPMult* mult = new FPMult(target, wE, wF, wE, wF, wE, wF, 1);
			oplist.push_back(mult);
			FPAddSinglePath* add =  new FPAddSinglePath(target, wE, wF, wE, wF, wE, wF);
			oplist.push_back(add);
		
			inPortMap (mult, "X", "X");
			inPortMap (mult, "Y", "X");
			outPortMap(mult, "R", "X2");
			vhdl << instance(mult, "multx");
		
			inPortMap (mult, "X", "Y");
			inPortMap (mult, "Y", "Y");
			outPortMap(mult, "R", "Y2");
			vhdl << instance(mult, "multy");
		
			inPortMap (mult, "X", "Z");
			inPortMap (mult, "Y", "Z");
			outPortMap(mult, "R", "Z2");
			vhdl << instance(mult, "multz");
		
			syncCycleFromSignal("Z2", false);
			nextCycle(); 
		
			inPortMap (add, "X", "X2");
			inPortMap (add, "Y", "Y2");
			outPortMap(add, "R", "X2PY2");
			vhdl << instance(add, "add1");
		
			syncCycleFromSignal("X2PY2", false);
			nextCycle(); 
		
			inPortMap (add, "X", "X2PY2");
			inPortMap (add, "Y", "Z2");
			outPortMap(add, "R", "X2PY2PZ2");
			vhdl << instance(add, "add2");
		
			syncCycleFromSignal("X2PY2PZ2", false);
			setCriticalPath(add->getOutputDelay("R"));
			vhdl << tab << "R <= X2PY2PZ2;"<<endl;
			outDelayMap["R"]=getCriticalPath();
		}
		else { ////////////////// here comes the FloPoCo version	//////////////////////////:
			// Error analysis
			// 3 ulps(wF+g) in the multiplier truncation
			// Again 2 ulps(wF+g) in the shifter output truncation
			// Normalisation truncation: either 0 (total 5), or 1 ulp(wF+g) but dividing the previous by 2 (total 3.5)
			// Total max 5 ulps, we're safe with 3 guard bits

			// guard bits for a faithful result
			int g=3; 

			// The exponent datapath

			// setCriticalPath( getMaxInputDelays(inputDelays) + target->localWireDelay());
			setCriticalPath(0);

			manageCriticalPath(  target->adderDelay(wE+1) // subtractions 
													 + target->localWireDelay(wE) // fanout of XltY etc
													 + target->lutDelay()         // & and mux
													 );

			//---------------------------------------------------------------------
			// extract the three biased exponents. 
			vhdl << tab << declare("EX", wE) << " <=  X" << range(wE+wF-1, wF) << ";" << endl;
			vhdl << tab << declare("EY", wE) << " <=  Y" << range(wE+wF-1, wF) << ";" << endl;
			vhdl << tab << declare("EZ", wE) << " <=  Z" << range(wE+wF-1, wF) << ";" << endl;
		
			// determine the max of the exponents
			vhdl << tab << declare("DEXY", wE+1) << " <=   ('0' & EX) - ('0' & EY);" << endl;
			vhdl << tab << declare("DEYZ", wE+1) << " <=   ('0' & EY) - ('0' & EZ);" << endl;
			vhdl << tab << declare("DEXZ", wE+1) << " <=   ('0' & EX) - ('0' & EZ);" << endl;
			vhdl << tab << declare("XltY") << " <=   DEXY("<< wE<<");" << endl;
			vhdl << tab << declare("YltZ") << " <=   DEYZ("<< wE<<");" << endl;
			vhdl << tab << declare("XltZ") << " <=   DEXZ("<< wE<<");" << endl;
		
			// rename the exponents  to A,B,C with A>=(B,C)
			vhdl << tab << declare("EA", wE)  << " <= " << endl
				  << tab << tab << "EZ when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "EY when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "EX; " << endl;
			vhdl << tab << declare("EB", wE)  << " <= " << endl
				  << tab << tab << "EX when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "EZ when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "EY; " << endl;
			vhdl << tab << declare("EC", wE)  << " <= " << endl
				  << tab << tab << "EY when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "EX when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "EZ; " << endl;
		
			//---------------------------------------------------------------------
			// Now recompute our two shift values -- they were already computed at cycle 0 but it is cheaper this way, otherwise we have to register, negate and mux them.
			manageCriticalPath(  target->adderDelay(wE-1) );

			vhdl << tab << declare("fullShiftValB", wE) << " <=  (EA" << range(wE-2,0) << " - EB" << range(wE-2,0) << ") & '0' ; -- positive result, no overflow " << endl;
			vhdl << tab << declare("fullShiftValC", wE) << " <=  (EA" << range(wE-2,0) << " - EC" << range(wE-2,0) << ") & '0' ; -- positive result, no overflow " << endl;
	
			double cpfullShiftValC = getCriticalPath();
			//---------------------------------------------------------------------
			Shifter* rightShifterDummy = new Shifter(target,wF+g+2, wF+g+2, Shifter::Right);
			int sizeRightShift = rightShifterDummy->getShiftInWidth(); 

			//-- Manage the shift value of the mantissa of B --------
			manageCriticalPath( target->localWireDelay() + target->lutDelay());
			vhdl<<tab<<declare("shiftedOutB") << " <= "; 
			if (wE>sizeRightShift){
				for (int i=wE-1;i>=sizeRightShift;i--) {
					vhdl<< "fullShiftValB("<<i<<")";
					if (i>sizeRightShift)
						vhdl<< " or ";
				}
				vhdl<<";"<<endl;
			}
			else
				vhdl<<tab<<"'0';"<<endl; 
			
			if (wE>sizeRightShift) {
				manageCriticalPath( target->localWireDelay() + target->lutDelay());
				vhdl<<tab<<declare("shiftValB",sizeRightShift) << " <=  fullShiftValB("<< sizeRightShift-1<<" downto 0)"
					  << " when shiftedOutB='0'"<<endl
					  <<tab << tab << "    else CONV_STD_LOGIC_VECTOR("<<wF+g+1<<","<<sizeRightShift<<") ;" << endl; 
			}else if (wE==sizeRightShift) {
				vhdl<<tab<<declare("shiftValB",sizeRightShift) << " <= fullShiftValB;" << endl ;
			}else { //  wE< sizeRightShift
				vhdl<<tab<<declare("shiftValB",sizeRightShift) << " <= CONV_STD_LOGIC_VECTOR(0,"<<sizeRightShift-wE <<") & fullShiftValB;" <<	endl;
			}
			double cpshiftValB = getCriticalPath();
			
			//-- Manage the shift value of the mantissa of C --------
			manageCriticalPath( target->localWireDelay() + target->lutDelay()); 
			//FIXME possible fixme needed when or does not fit on lut
			vhdl<<tab<<declare("shiftedOutC") << " <= "; 
			if (wE>sizeRightShift){
				for (int i=wE-1;i>=sizeRightShift;i--) {
					vhdl<< "fullShiftValC("<<i<<")";
					if (i>sizeRightShift)
						vhdl<< " or ";
				}
				vhdl<<";"<<endl;
			}
			else
				vhdl<<tab<<"'0';"<<endl; 
		
			setCycleFromSignal("fullShiftValC",cpfullShiftValC);
			if (wE>sizeRightShift) {
				manageCriticalPath( target->localWireDelay() + target->lutDelay());//the mux delay
				vhdl<<tab<<declare("shiftValC",sizeRightShift) << " <= fullShiftValC("<< sizeRightShift-1<<" downto 0)"
					  << " when shiftedOutC='0'"<<endl
					  <<tab << tab << "    else CONV_STD_LOGIC_VECTOR("<<wF+g+1<<","<<sizeRightShift<<") ;" << endl; 
			} else if (wE==sizeRightShift) {
				vhdl<<tab<<declare("shiftValC",sizeRightShift) << " <= fullShiftValC;" << endl ;
			} else 	{ //  wE< sizeRightShift
				vhdl<<tab<<declare("shiftValC",sizeRightShift) << " <= CONV_STD_LOGIC_VECTOR(0,"<<sizeRightShift-wE <<") & fullShiftValC;" <<	endl;
			}

			// Back to cycle 0 for the significand datapath
			setCycle(0);
			//FIXME add inDelayMap for use within hierarchies of components 
			// Square the significands 
#define USE_SQUARER 1
#if  USE_SQUARER
			IntSquarer* mult = new IntSquarer(target,  1+ wF);
#else
			IntMultiplier* mult = new IntMultiplier(target, 1+ wF, 1+ wF);
#endif
			oplist.push_back(mult);
		
			vhdl << tab << declare("mX", wF+1)  << " <= '1' & X" << range(wF-1, 0) << "; " << endl;
		
			inPortMap (mult, "X", "mX");
#if  !USE_SQUARER
			inPortMap (mult, "Y", "mX");
#endif
			outPortMap(mult, "R", "mX2");
			vhdl << instance(mult, "multx");
	
			vhdl << tab << declare("mY", wF+1)  << " <= '1' & Y" << range(wF-1, 0) << "; " << endl;

			inPortMap (mult, "X", "mY");
#if  !USE_SQUARER	
			inPortMap (mult, "Y", "mY");
#endif
			outPortMap(mult, "R", "mY2");
			vhdl << instance(mult, "multy");
		
			vhdl << tab << declare("mZ", wF+1)  << " <= '1' & Z" << range(wF-1, 0) << "; " << endl;
		
			inPortMap (mult, "X", "mZ");
#if  !USE_SQUARER	
			inPortMap (mult, "Y", "mZ");
#endif
			outPortMap(mult, "R", "mZ2");
			vhdl << instance(mult, "multz");

			syncCycleFromSignal("mZ2", false);
			setCriticalPath(mult->getOutputDelay("R"));
			// truncate the three results to wF+g+2
			int prodsize = 2+2*wF;
			vhdl << tab << declare("X2t", wF+g+2)  << " <= mX2" << range(prodsize-1, prodsize - wF-g-2) << "; " << endl;
			vhdl << tab << declare("Y2t", wF+g+2)  << " <= mY2" << range(prodsize-1, prodsize - wF-g-2) << "; " << endl;
			vhdl << tab << declare("Z2t", wF+g+2)  << " <= mZ2" << range(prodsize-1, prodsize - wF-g-2) << "; " << endl;
	
			// Now we have our three FP squares, we rename them to A,B,C with A>=(B,C) 
			// only 3 3-muxes
			manageCriticalPath(target->localWireDelay(wF) + target->lutDelay());  
			vhdl << tab << declare("MA", wF+g+2)  << " <= " << endl
				  << tab << tab << "Z2t when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "Y2t when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "X2t; " << endl;
			vhdl << tab << declare("MB", wF+g+2)  << " <= " << endl
				  << tab << tab << "X2t when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "Z2t when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "Y2t; " << endl;
			vhdl << tab << declare("MC", wF+g+2)  << " <= " << endl
				  << tab << tab << "Y2t when (XltZ='1') and (YltZ='1')  else " << endl
				  << tab << tab << "X2t when (XltY='1') and (YltZ='0')  else " << endl
				  << tab << tab << "Z2t; " << endl;
			
			//Synchronize exponent and significand datapath
			syncCycleFromSignal("shiftValB", cpshiftValB, false);

			// B and C right shifters are the same
			Shifter* rightShifter = new Shifter(target,wF+g+2, wF+g+2, Shifter::Right, inDelayMap("X",target->localWireDelay()+getCriticalPath())); 
			oplist.push_back(rightShifter);

			inPortMap  (rightShifter, "X", "MB");
			inPortMap  (rightShifter, "S", "shiftValB");
			outPortMap (rightShifter, "R","shiftedB");
			vhdl << instance(rightShifter, "ShifterForB");

			inPortMap  (rightShifter, "X", "MC");
			inPortMap  (rightShifter, "S", "shiftValC");
			outPortMap (rightShifter, "R","shiftedC");
			vhdl << instance(rightShifter, "ShifterForC");
		
			// superbly ignore the bits that are shifted out
			syncCycleFromSignal("shiftedB", false);
			setCriticalPath( rightShifter->getOutputDelay("R"));
			
			int shiftedB_size = getSignalByName("shiftedB")->width();
			vhdl << tab << declare("alignedB", wF+g+2)  << " <= shiftedB" << range(shiftedB_size-1, shiftedB_size -(wF+g+2)) << "; " << endl;
			vhdl << tab << declare("alignedC", wF+g+2)  << " <= shiftedC" << range(shiftedB_size-1, shiftedB_size -(wF+g+2)) << "; " << endl;
		
			vhdl << tab << declare("paddedA", wF+g+4)  << " <= \"00\" & MA; " << endl;
			vhdl << tab << declare("paddedB", wF+g+4)  << " <= \"00\" & alignedB; " << endl;
			vhdl << tab << declare("paddedC", wF+g+4)  << " <= \"00\" & alignedC; " << endl;
		
			IntMultiAdder* adder = new IntMultiAdder(target,wF+g+4, 3, inDelayMap("X0", target->localWireDelay() + getCriticalPath() ));
			oplist.push_back(adder);

			inPortMap   (adder, "X0", "paddedA");
			inPortMap   (adder, "X1", "paddedB");
			inPortMap   (adder, "X2", "paddedC");
			inPortMapCst(adder, "Cin", "'0'"); // a 1 would compensate the two truncations in the worst case -- to explore
			outPortMap  (adder, "R","sum");
			vhdl << instance(adder, "adder1");

			syncCycleFromSignal("sum", false);
			setCriticalPath(adder->getOutputDelay("R"));

			manageCriticalPath(target->localWireDelay() + target->lutDelay());
			// Possible 3-bit normalisation, with a truncation
			vhdl << tab << declare("finalFraction", wF+g)  << " <= " << endl
				  << tab << tab << "sum" << range(wF+g+2,3) << "   when sum(" << wF+g+3 << ")='1'    else " << endl
				  << tab << tab << "sum" << range(wF+g+1, 2) <<  "   when (sum" << range(wF+g+3, wF+g+2) << "=\"01\")     else " << endl
				  << tab << tab << "sum" << range(wF+g, 1) <<  "   when (sum" << range(wF+g+3, wF+g+1) << "=\"001\")     else " << endl
				  << tab << tab << "sum" << range(wF+g-1, 0) << "; " << endl;

			// Exponent datapath. We have to compute 2*EA - bias + an update corresponding to the normalisatiobn
			// since (1.m)*(1.m) = xx.xxxxxx sum is xxxx.xxxxxx
			// All the following ignores overflows, infinities, zeroes, etc for the sake of simplicity.
			manageCriticalPath(target->localWireDelay() + target->lutDelay());
			int bias = (1<<(wE-1))-1;
			vhdl << tab << declare("exponentUpdate", wE+1)  << " <= " << endl
				  << tab << tab << "CONV_STD_LOGIC_VECTOR(" << bias-3 << ", "<< wE+1 <<")  when sum(" << wF+g+3 << ")='1'    else " << endl
				  << tab << tab << "CONV_STD_LOGIC_VECTOR(" << bias-2 << ", "<< wE+1 <<")  when (sum" << range(wF+g+3, wF+g+2) << "=\"01\")     else " << endl
				  << tab << tab << "CONV_STD_LOGIC_VECTOR(" << bias-1 << ", "<< wE+1 <<")  when (sum" << range(wF+g+3, wF+g+1) << "=\"001\")     else " << endl
				  << tab << tab << "CONV_STD_LOGIC_VECTOR(" << bias   << ", "<< wE+1 <<")  ; " << endl;
		
			manageCriticalPath( target->localWireDelay() + target->adderDelay(wE+1));
			vhdl << tab << declare("finalExp", wE+1)  << " <= (EA & '0') - exponentUpdate ; " << endl;
			
			IntAdder *roundingAdder = new IntAdder(target, wE +1 + wF);
			oplist.push_back(roundingAdder);
			
			vhdl << tab << declare("roundingOp",wE+1 + wF) << "<= finalExp & finalFraction"<<range(wF+g-1,g)<<";"<<endl;
			
			inPortMap     ( roundingAdder, "X", "roundingOp");
			inPortMapCst  ( roundingAdder, "Y", zg(wE+1+wF));
			inPortMapCst   ( roundingAdder, "Cin", "'1'");
			outPortMap    ( roundingAdder, "R", "expFrac");
			vhdl << tab << instance( roundingAdder, "RoundingAdder"); 
			syncCycleFromSignal("expFrac");
			setCriticalPath( roundingAdder->getOutputDelay("R"));
				
			//TODO 		
			vhdl << tab << declare("rExc",2) << " <= \"01\" when  expFrac"<<of(wE+wF)<<"='0' else \"10\";"<<endl;
			vhdl << tab << "R <= rExc & '0' & expFrac"<<range(wE+1 + wF-2,0)<<";"<<endl;
		}
	
	}