Beispiel #1
0
string Operator::use(string name) throw(std::string) {
	ostringstream e;
	e << "ERROR in use(), "; // just in case
	
	if(isSequential()) {
		Signal *s;
		try {
			s=getSignalByName(name);
		}
		catch (string e2) {
			e << endl << tab << e2;
			throw e.str();
		}
		if(s->getCycle() < 0) {
			e << "signal " << name<< " doesn't have (yet?) a valid cycle";
			throw e.str();
		} 
		if(s->getCycle() > currentCycle_) {
			ostringstream e;
			e << "active cycle of signal " << name<< " is later than current cycle, cannot delay it";
			throw e.str();
		} 
		// update the lifeSpan of s
		s->updateLifeSpan( currentCycle_ - s->getCycle() );
		return s->delayedName( currentCycle_ - s->getCycle() );
	}
	else
		return name;
}
Beispiel #2
0
void Operator::syncCycleFromSignal(string name, bool report) throw(std::string) {
	ostringstream e;
	e << "ERROR in syncCycleFromSignal, "; // just in case

	if(isSequential()) {
		Signal* s;
		try {
			s=getSignalByName(name);
		}
		catch (string e2) {
			e << endl << tab << e2;
			throw e.str();
		}

		if( s->getCycle() < 0 ) {
			ostringstream o;
			o << "signal " << name << " doesn't have (yet?) a valid cycle";
		throw o.str();
		} 
		// advance cycle if needed
		if (s->getCycle()>currentCycle_)
			currentCycle_ = s->getCycle();

		if(report)
			vhdl << tab << "----------------Synchro barrier, entering cycle " << currentCycle_ << "----------------" << endl ;
		// automatically update pipeline depth of the operator 
		if (currentCycle_ > pipelineDepth_) 
			pipelineDepth_ = currentCycle_;
	}
}
Beispiel #3
0
int Operator::setClk(std::string name) {
  rmClk();
  if ( Signal *s = getSignalByName(name) ) {
    s->setClk(1);
    return 1;
  }
  return 0;
}
Beispiel #4
0
/* should be only one Clk */
int Operator::rmClk() {
  int cnt = 0;
  std::string clk = getClkName();
  while ( clk.compare("") !=0 )  {
    cnt++;
    getSignalByName(clk)->setClk(0);
    clk = getClkName();
  }
  return cnt;
}
Beispiel #5
0
void Operator::inPortMap(Operator* op, string componentPortName, string actualSignalName) throw(std::string) {
	Signal* formal;
	ostringstream e;
	string name;
	e << "ERROR in inPortMap(), "; // just in case
	
	if(isSequential()) {
		Signal *s;
		try {
			s=getSignalByName(actualSignalName);
		}
		catch (string e2) {
			e << endl << tab << e2;
			throw e.str();
		}
		if(s->getCycle() < 0) {
			ostringstream e;
			e << "signal " << actualSignalName<< " doesn't have (yet?) a valid cycle";
			throw e.str();
		} 
		if(s->getCycle() > currentCycle_) {
			ostringstream e;
			e << "active cycle of signal " << actualSignalName<< " is later than current cycle, cannot delay it";
			throw e.str();
		} 
		// update the lifeSpan of s
		s->updateLifeSpan( currentCycle_ - s->getCycle() );
		name = s->delayedName( currentCycle_ - s->getCycle() );
	}
	else
		name = actualSignalName;

	try {
		formal=op->getSignalByName(componentPortName);
	}
	catch (string e2) {
		e << endl << tab << e2;
		throw e.str();
	}
	if (formal->type()!=Signal::in){
		e << "signal " << componentPortName << " of component " << op->getName() 
		  << " doesn't seem to be an input port";
		throw e.str();
	}

	// add the mapping to the mapping list of Op
	op->portMap_[componentPortName] = name;
}
Beispiel #6
0
	FixComplexKCM::FixComplexKCM(
			Target* target,
			bool signedInput,
			int msb_in, 
			int lsb_in, 
			int lsb_out,
			string constant_re,
			string constant_im
		): 	
			Operator(target),
			signedInput(signedInput),
			msb_in(msb_in),
			lsb_in(lsb_in),
			lsb_out(lsb_out),
			constant_re(constant_re),
			constant_im(constant_im)
	{
		init();
		//For final rounding precision
		int guard_bits = 1;
		double targetUlpError = 1.0;

		// declaring output
		addOutput("ReOut", outputre_width);
		addOutput("ImOut", outputim_width);

		if(mpfr_zero_p(mpfr_constant_im) != 0 && mpfr_zero_p(mpfr_constant_re) != 0)
		{
			vhdl << tab << "ReOut" << " <= " << zg(outputre_width, 0) << ";" <<
				endl;
			vhdl << tab << "ImOut" << " <= " << zg(outputim_width, 0) << ";" <<
				endl;
		}
		else
		{
			int kcmImGuardBits = FixRealKCM::neededGuardBits(
					target,
					input_width,
					targetUlpError,
					constant_im,
					lsb_in,
					lsb_out - guard_bits
				);

			int kcmMImGuardBits = FixRealKCM::neededGuardBits(
					target,
					input_width,
					targetUlpError,
					"-1*" + constant_im,
					lsb_in,
					lsb_out - guard_bits
				);

			int kcmReGuardBits = FixRealKCM::neededGuardBits(
					target,
					input_width,
					targetUlpError,
					constant_re,
					lsb_in,
					lsb_out - guard_bits
				);

			// basic message
			REPORT(INFO,"Declaration of FixComplexKCM\n");

			int guardBits_re = max(kcmReGuardBits, kcmMImGuardBits);
			int guardBits_im = max(kcmReGuardBits, kcmImGuardBits);

			BitHeap* bitheapRe = new BitHeap(
					this,
					guardBits_re + outputre_width + guard_bits
				);
			BitHeap* bitheapIm = new BitHeap(
					this, 
					guardBits_im + outputim_width + guard_bits
				);

			//Add 1/2 ulp
			bitheapIm->addConstantOneBit(0);
			bitheapRe->addConstantOneBit(0);

			//---- Real part computation ------------------------------------------
			new FixRealKCM(
					this,
					target,
					getSignalByName("ReIN"),
					signedInput,
					msb_in,
					lsb_in,
					lsb_out - guard_bits,
					constant_re,
					bitheapRe,
					lsb_out - guardBits_re - guard_bits 
				);

			new FixRealKCM(
					this, 
					target, 
					getSignalByName("ImIN"),
					signedInput,
					msb_in,
					lsb_in,
					lsb_out - guard_bits,
					"-1 * " + constant_im,
					bitheapRe,
					lsb_out - guard_bits - guardBits_re
				);

			//--- Imaginary part computation --------------------------------------

			new FixRealKCM(
					this,
					target,
					getSignalByName("ImIN"),
					signedInput,
					msb_in,
					lsb_in,
					lsb_out - guard_bits,
					constant_re,
					bitheapIm,
					lsb_out - guard_bits - guardBits_im
				);

			new FixRealKCM(
					this, 
					target, 
					getSignalByName("ReIN"),
					signedInput,
					msb_in,
					lsb_in,
					lsb_out - guard_bits,
					constant_im,
					bitheapIm,
					lsb_out - guard_bits - guardBits_im
				);

			//BitHeap management
			bitheapIm->generateCompressorVHDL();
			bitheapRe->generateCompressorVHDL();

			vhdl << "ImOut" << " <= " << 
				bitheapIm->getSumName(
						outputim_width+guardBits_im+guard_bits -1,
						guardBits_im+guard_bits
					) << ";" << endl;

			vhdl << "ReOut" << " <= " << 
				bitheapRe->getSumName(
						outputre_width + guardBits_re + guard_bits - 1,
						guardBits_re+guard_bits
					) << ";" << endl;
		}

	};
Beispiel #7
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;
		}
	
	}