module: dac_rz
parameters: double mismatch int in_max double i_pos_lsb double i_neg_lsb double i_pos_var double i_neg_var double isi
inputs:  double_interp enable double input
outputs:  double out
static_variables:
  int always_pos
  int count 
  int count_last
  int i
  int pos
  int neg
  double i_total
  double i_total_last;
  double i_pos_rms
  double i_neg_rms
classes:  
  Vector i_pos()
  Vector i_neg()
  IntVector last_pos()
  Rand rand_mm("gauss")
  Rand rand_ivar("gauss")
  EdgeDetect enable_pos()
  EdgeDetect enable_neg()
init:
  always_pos = 0;
  last_pos.set_length(in_max+always_pos);
  i_pos.set_length(in_max+always_pos);
  i_neg.set_length(in_max+always_pos);
  for (i = 0; i < in_max+always_pos; i++) {
    i_pos.set_elem(i,i_pos_lsb*(1+mismatch/100*rand_mm.inp()));
    i_neg.set_elem(i,i_neg_lsb*(1+mismatch/100*rand_mm.inp())); 
  }
  i_pos_rms = sqrt(i_pos_var/Ts);
  i_neg_rms = sqrt(i_neg_var/Ts);
  count = 0;
  count_last = 0;
  i_total_last = 0;
code:
  if (enable_pos.inp(enable)) {
    i_total_last = i_total;
    i_total = 0;
    count = count_last;
    for (i = 0; i < in_max; i++) {
      count = count + 1;
      if (count >= in_max) count = 0;
      if (i < input) {
        i_total = i_total + i_pos.get_elem(count)*(1+isi*last_pos.get_elem(count)/100);
        count_last = count;
        last_pos.set_elem(count,1);
        //printf("input = %1.0f: count = %i: i = %i: i_pos.get_elem = %e\n",input,count,i,i_pos.get_elem(count));
      }
      else {
        i_total = i_total + i_neg.get_elem(count)*(1+isi*(1-last_pos.get_elem(count))/100);
        last_pos.set_elem(count,0);
        //printf("input = %1.0f: count = %i: i = %i: i_neg.get_elem = %e\n",input,count,i,i_neg.get_elem(count));
      }
    }
//    for (i = 0; i < always_pos; i++) {
//      i_total = i_total + i_pos.get_elem(in_max+i)*(1+isi/100);
//printf("input = %1.0f: i_total = %e\n",input,i_total);
//    }
    pos = input + always_pos;
    neg = in_max - input;
  }
  out = (i_total+isi/100*i_total_last+sqrt((pos*i_pos_var+neg*i_neg_var)/Ts)*rand_ivar.inp())*(enable/2+0.5);
