`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