`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
               (
geocities.com/fudinggeadc)