`include "discipline.h"
`include"constants.h"


//--------------------
// dac_inl_8bit
//
// -  8 bit DAC INL measurement
//
// vin:		terminal for monitoring DAC output voltages [V,A]
// vd0..vd7:	data lines for DAC [V,A]
//
// INSTANCE parameters
//    vlogic_high = [V]
//    vlogic_low  = [V]
//    tsettle     = time to allow for settling after the data lines are changed
//                  before 'vin' is recorded [s]
//    log_to_file = Whether to log the results to a file; yes or no []
//    filename    = The name of the file in which the results are logged []
//
// MODEL parameters
//    {noneend
//
// Sweeps through all the 256 codes and records the DAC output voltage and
// writes the maximum INL found to the output.
// 
// If 'log_to_file' is 1, then the INL (integral non-linearity) is
// recorded and writen to the file
//

module dac_inl_8bit(vin, vd7, vd6, vd5, vd4, vd3, vd2, vd1, vd0);
electrical vin, vd7, vd6, vd5, vd4, vd3, vd2, vd1, vd0;
parameter real tsettle=200n from (0:inf);
parameter real vlogic_high=5.0;
parameter real vlogic_low=0.0;
parameter integer log_to_file = 0;

`define NUM_DAC_BITS 8
`define NUM_CODES 256

   integer out_file;

   real    vd_val[0:`NUM_DAC_BITS-1];

   real    code_vout[0:`NUM_CODES-1];
   real    inl[0:`NUM_CODES-1];

   integer code_mask[0:`NUM_DAC_BITS-1];
   integer bit, mask;

   integer just_finished; // flag that says measurement finished during
                          //  this evaluation
   integer code;

   real    tnext;

   real    width_expect;

   real    max_inl;
   integer max_inl_code;

 
   analog begin

     @ ( initial_step ) begin
         tnext = tsettle;
         max_inl_code = -1;
         mask = 1;
         for (bit=0; bit < `NUM_DAC_BITS; bit=bit+1) begin
           code_mask[bit] = mask;
         mask = mask * 2;
           vd_val[bit] = vlogic_low;
         end
      end

      @ (timer(tnext)) begin // at a measurement point

         // record the last measured value
         code_vout[code] = V(vin);

         code=code+1;
         if (code < `NUM_CODES) begin
           tnext = tnext + tsettle;
         end else begin			// finished
           code = `NUM_CODES  - 1;
           just_finished = 1;
         end

         // to convert a code into a bit pattern
         for (bit=0;bit<`NUM_DAC_BITS; bit=bit+1) begin
            if (code & code_mask[bit]) begin
               vd_val[bit] = vlogic_high;
            end else begin
               vd_val[bit] = vlogic_low;
            end
         end
      end

      if (just_finished) begin  // calculate the inl function
         just_finished = 0;
         width_expect = (code_vout[`NUM_CODES-1] - code_vout[0])
                        / (`NUM_CODES - 1);
         for (code=0; code < `NUM_CODES; code=code+1) begin
            inl[code] = (code_vout[code] -  code*width_expect)/width_expect;
            if (max_inl < abs(inl[code])) begin
               max_inl = abs(inl[code]);
               max_inl_code = code;
            end
         end

         $strobe("The maximum inl measured is %f at code %d",max_inl,
                  max_inl_code);

         // log the results to a file if desired
         //
         if (log_to_file) begin
            out_file = $fopen( "%C:r.dat" );
            $fstrobe(out_file,"# Generated by Spectre from `%M'");
            for (code=0; code < `NUM_CODES; code=code+1) begin
                $fstrobe(out_file,"%d\t%f\t%g",code,inl[code],code_vout[code]);
            end

            $fclose(out_file);
         end
      end

      V(vd0) <+ vd_val[0];
      V(vd1) <+ vd_val[1];
      V(vd2) <+ vd_val[2];
      V(vd3) <+ vd_val[3];
      V(vd4) <+ vd_val[4];
      V(vd5) <+ vd_val[5];
      V(vd6) <+ vd_val[6];
      V(vd7) <+ vd_val[7];
   end
endmodule







    Source: geocities.com/fudinggeadc/model

               ( geocities.com/fudinggeadc)