module: wb_dac
description: Generic nbit dataweight averaged DAC. With mismatch included.
	idac output is updated only on a clk transition to speed up 
	simulation. This takes a swap input which causes the DAC bits 
	to be reversed on a  swap (for timing mismatch correction)
parameters: int dacbits double idac_val double mm double mmstddev
inputs: double residue double clk double_interp phi0 double_interp phi1 double swap 
outputs: double idac 
static_variables: int ptrtmp int ptr int in Vector phase 
	Vector current int i Vector igain double phi0temp double phi1temp 
	int idac_temp double mmon int vect_length IntVector out double tempval
classes: EdgeDetect edge1()
init:
	tempval=0.0;
	idac_temp=0;
	ptr=0;
	ptrtmp=0;
	phi0temp=0.0;
	phi1temp=0.0;
	idac=0.0;
	vect_length=(int)pow(2,dacbits-1)+1;
	out.set_length(vect_length);
	phase.set_length(vect_length);
	current.set_length(vect_length);
	igain.set_length(vect_length);
	if (mm>0.0)
		mmon=1.0;
	else
		mmon=0.0;
	gauss_ran_vector(mmstddev,current.get_length(),igain);
	mul_elem(igain,mmon,igain);
	add(igain,1.0,igain);	
code: 
in=(int)residue;
if (edge1.inp(clk))
{
	ptrtmp = in+ptr > (pow(2,dacbits-1)) ? in+ptr-int((pow(2,dacbits-1))) : in+ptr;
	for (i=1; i<=pow(2,dacbits-1); i++)
 		{
	idac_temp=((ptr<i) && (i<=ptr+in)) ? 1 : ((ptrtmp >= i) && (in+ptr > pow(2,dacbits-1))) ? 1 : 0;
	out.set_elem(i,idac_temp);
		}
	ptr=ptrtmp;
}
if ((phi1 != phi1temp) || (phi0 != phi0temp))
{
	idac=0.0;
	for (i=1; i<=pow(2,dacbits-1); i++)
	{
	if (swap>0.0)
		{
	phase.set_elem(i,(out.get_elem(i) > 0 ? (phi0+1.0)/2.0 : (phi1+1.0)/2.0));
		}
	else
		{
	phase.set_elem(i,(out.get_elem(i) > 0 ? (phi1+1.0)/2.0 : (phi0+1.0)/2.0));
		}
	tempval=phase.get_elem(i)*(-idac_val/(pow(2,dacbits-1)))*igain.get_elem(i);
	current.set_elem(i,tempval);
 	idac += current.get_elem(i);
	}	
	phi1temp=phi1;
	phi0temp=phi0;
}
