`include "discipline.h" `include"constants.h" //-------------------- // dac_dnl_8bit // // - 8 bit DAC DNL 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 DNL found to the output. // // If 'log_to_file' is 1, then the DNL (differential non-linearity) is // recorded and writen to the file. // module dac_dnl_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 dnl[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_dnl; integer max_dnl_code; analog begin @ ( initial_step ) begin tnext = tsettle; max_dnl_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 dnl function just_finished = 0; width_expect = (code_vout[`NUM_CODES-1] - code_vout[0]) / (`NUM_CODES - 1); for (code=0; code < `NUM_CODES-1; code = code+1) begin dnl[code] = (code_vout[code+1] - code_vout[code] - width_expect) / width_expect; if (max_dnl < abs(dnl[code])) begin max_dnl = abs(dnl[code]); max_dnl_code = code; end end $strobe("The maximum dnl measured is %f at code %d",max_dnl, max_dnl_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-1; code=code+1) begin $fstrobe(out_file,"%d\t%f",code,dnl[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