Hi <@U01819B63HP> I tried the new functions to cal...
# xschem
s
Hi @Stefan Schippers I tried the new functions to calculate and graph the 4 standard DC errors (zero scale error, full scale error, INL and DNL) for a 2-bit DAC with range -3.3V to +3.3V. Below the result, which is very near the desired result. Questions/FB: • For readability declaring a constant variable upfront to use in the graph would improve readability greatly (eg. n=2, LSB = FS / 2^n). • Reusing signals after they are created would also be useful, eg. compute the ZSE signal and than remove that from the FSE and finally remove the FSE from the output signal. • The DNL and INL calculation seems to be correct INL(t) = OUT(t) - IDEAL(t) and DNL(t)=INL(t) - prev INL(t). I graph two variants. The first one is the raw DNL/INL which is unstable for about 1 ns after switching. The second one marked with INL* and DNL* use a trigger signal to to signify when the output is stable. I wonder if I can do this without a trigger signal? • I use
.measure
to average sample DAC output at the start (after it stabilized) and the very end. I then use those measurements to calculate two constants, the offset (zero scale) and gain (full scale) errors. The zero scale error is straightforward: averaging the sampled output for a short (100p) period after it stabilized and subtract it from the expected value. The full scale is a little more tricky. The averaged sampled output (duration 100p) at the end has correct values during the measurement period and has invalid value (=0) otherwise. Subtracting from start and 3 LSB to get the full scale error will results in incorrect calculation at all points except the end period. I tried to use del() (eg.
start 19.9n del() end - 3 LSB * -
) but that didnt work. With another trigger signal, that is high when in the end period, I can create a correct FSE result shown in FSE*. Any suggestion how to the FSE calculation better?
s
I have some problems understanding exactly what you need. What are START and END signals? are the 4 DAC outputs 1.65V, 0V, -1.65V, -3.3V ? There is a
ravg()
function that takes a waveform , a time window and calculates the running average over that time window, that is from
current time
to
current time - time window
. Can this function be helpful?
"Ravg; v(out) 10n ravg()"
Reusing already computed expressions is not possible currently . I will look into that, but it's not super quick to do 🙂
s
@Stefan Schippers The 4 DAC outputs for this 2-bit DAC are indeed 1.65 V (code 11), 0 V (code 10) -1.65 V (code 01) and -3.3 V (code 00). The START and END signals are badly named. More fitting names would be something like First10samples_Output_Average and Last10samples_Output_Average or OutHeadAvg and OutTailAvg. The two signals are captured using
.measure tran end avg v(out) from=19.9n to=20.0n
. All signals are (forcefully) sampled every 10ps using
.options output initial interval=0.01e-9
so the average (should) range over 10 samples. I need OutHeadAvg to calculate the Zero Scale error. I need both OutHeadAvg and OutTailAvg to calculate the Full Scale error (see https://www.analog.com/en/education/education-library/data-conversion-handbook.html) I have not used
ravg()
before, does it replace
.measure avg
? So I can use it with from and to eg.
OutTailAvg; v(out) 19.9n 20.n ravg()
I am already quite happy with the automated error calculation using the new prev() function. The trigger signal workaround (eg. multiply any signal with the trigger signal which is either 1 or 0) works nicely. My current result is shown below
The 4 DC errors are 0 or very near 0 in the regions where it stable (after about 2 ns)
s
You are a power user!!
😁 1
If you realize some other function is useful (and doable) let me know, if possible prepare a super simple testbench so i can test directly on it...
Running average gives at any 'x' point the average of the signal calculated in the interval (x-w, x], where w is the ravg() window parameter. In following picture the running average power is calculated from instantaneous power. A window exactly equal to 2 wave periods is given so after 2 periods the ravg() indicates the exact average power. "running average supply power; i(vcurrvpp) vpp * 100u ravg()"
So i guess if you apply this function to an error signal (actual - expected) and filter this signal thru the ravg with some sampling window you get a good averaged estimate of the error.
s
I will let you know if a good function comes to mind and I will explore the use of ravg. Doing things post-simulation in xschem is much more efficient than re-running the sim every time to correct my .measure statement. I am nearly done with pre-layout design and simulation and wrote an extensive write-up on github about creating 1-10-bit DACs using all the lessons learned here. It will be made open as soon as post-layout is done. Thanks for making Xschem!
s
I think a .measure should be run last, if you have verified your results using xschem wave processing capabilities, then you have probably all the data to write a working .measure statement. xschem operates on sampled data produced by the simulator, may be the simulator .measure will be more accurate. If you find considerable discrepancies (even after reducing the output timestep) let me know.