Inspired by Prakash Harikumar and some of his search for offset in his ADC amplifiers I brushed off some old material that might be worth sharing… Some of this is not new news, and you would find similar tips-and-tricks in eg. the designer’s guide forums, etc.

## Some background

So the idea is to simulate amplifiers, typically differential amplifiers, or at least amplifiers that uses a reference to compare its input signal with. It could be a comparator, a transconductance amplifier, an operational amplifier, or what have you. In most cases, you have a CMOS differential pair at the input of the amplifier. These two transistors should match very well, the sizes should be equally large. In reality that is not the case due to irregularities in the layout or in the processing steps. Typically, this implies that one of the transistors will “steal” more current from the tail current source in the nominal condition. This net current can be more or less directly translated into an equivalent offset voltage at the input of the amplifier. Quite traditional approach.

See for example the picture below. In this case we have a single-ended-to-differential converter that takes the common-mode signal and the differential signal (in this case both are DC) and combines them to create the vInP and vInN to the amplifier. We have also added the simplest of simplest models as an amplifier: a voltage-controlled voltage source that takes the difference between the two inputs, multiplies them and generates the output voltage:

`vOut = -Acomp x (vInP - vInN)`

We could now model the effect of mismatch as an equivalent voltage source on the positive input of the amplifier. This means that the output voltage will then be:

`vOut = -Acomp x (vInP + vOffset - vInN)`

and if the offset is high, the output of the amplifier will saturate. A regulated loop might solve some of these issues, together with some other tricks, but from a characterization point of view, one is often interested in the true value of the offset.

## How to simulate that?

There are a few ways to simulate and find the offset value. One of them could be to assume that input-referred offset is small enough, such that the output-referred offset (Acomp x vOffset) is small enough to not saturate the amplifier. We could measure the vOut and simply divide by the gain of the amplifier. This is however still troublesome in e.g. Monte Carlo analysis, where also the gain could vary and you have to keep your equations in control to capture all the parameters needed to do the calculations.

Another option is suggested here. In this case I use a shift register in a feedback configuration and a voltage-controlled voltage source at the input of the differential-to-single-ended converter. The feedback will impose a voltage difference between the two input vInP and vInN that will compensate for any offset.

The offset itself (the small blob in the dashed amplifier) is modeled by a veriloga component. It picks up a random value at every run to mimic the effect of e.g. a Monte Carlo analyses. The shift-register, i.e., the SAR DAC, will be clocked by a simulation clock that looks at the output and at every rising clock edge will modify the input to search for equilibrium. Every clock cycle the refinement will improve.

The nice things with this approach are two:

- the offset will be mimicked on the vOffset node at the output of the SAR DAC and can thus be plotted in a Monte Carlo histogram.
- both continuous-time and discrete-time amplifiers / comparators can be tested.

The resulting output offset will be searched for by the algorithm and the output could look something like this:

The green curve is the approximation of the offset and the cyan and orange are the two inputs converging towards a stable value. By measuring in the graph, we find the offset to be around 70 mV.

Something to watch out for is the effect of the limited gain of the amplifier. It will cause non-rail outputs towards the end of the refinement. Due to the limited gain, the difference between the compensated input and the actual offset is now so small that the amplifier is not able to amplify the differences enough. Potentially, the amplifier goes into metastability.

If we have a clue about the gain, we can set the number of clock cycles that we refine our loop with. If we know that the maximum offset error that the loop can compensate for is 1 V and that the output logical levels are 1 V, we quickly can conclude that the DC gain of the amplifier has to be above 2^cycles. If the gain is only 1000, 10 cycles is enough, etc.

Here is the code for the offset voltage source:

`include "constants.vams"

`include "disciplines.vams"

module daisyNoise(PLUS, MINUS);

inout PLUS;

inout MINUS;

electrical PLUS, MINUS;

parameter real sigma = 0 from [0:inf);

real voffset;

integer seed;

analog begin

@(initial_step) begin

// seed = 564; // <-- change and pick a number from the time

voffset = sigma*$random(seed)/2147483648;

end

V(PLUS, MINUS) <+ voffset;

end

`endmodule`

And for the SAR DAC

// VerilogA for daisy, daisySarDac, veriloga

`include "constants.vams"

`include "disciplines.vams"

module daisySarDac(RESET, CLK, DATA, vOut);

input RESET, CLK, DATA;

output vOut;

electrical RESET, CLK, DATA, vOut;

integer count;

parameter real vMin = -1 from (-inf:inf);

parameter real vMax = 1 from (-inf:inf);

parameter real vccr = 1 from (0:inf);

real vRef;

real vLo;

analog begin

// Start by initializing all the parameters

@ ( initial_step )

begin

count = 1;

vLo = vMin;

vRef = vLo + (vMax - vMin)/pow(2, count);

end

// Same should be done during the reset...

@ ( cross(V(RESET) - vccr/2.0, 1, 1.0, RESET.potential.abstol))

begin

count = 1;

vLo = vMin;

vRef = vLo + (vMax - vMin)/pow(2,count);

end

// Every time the clock is rising high, value of data

// should be taken into account.

@ (cross(V(CLK) - vccr/2.0, 1, 1.0, CLK.potential.abstol))

begin

if (V(DATA) > vccr/2.0)

begin

vLo = vRef;

end;

count = count + 1;

// Assume a maximum of 32-bit resolution/accuracy

if (count > 32)

begin

count = 32;

end;

vRef = vLo + (vMax - vMin)/pow(2,count);

end

V(vOut) <+ transition(vRef);

end

endmodule

I am not sure if this makes sense, but could you please elaborate on why you chose to implement one block on VHDL-AMS and the other in VerilogA? Thanks

They are both in veriloga. The VAMS compiler as such does not have to be invoked to run them.

how to find offset , INL DNl in DAC in tanner/mentor graphocs

It was a long time since I worked with both Tanner and Mentor tools I’m afraid. However, Mentor/ELDO can also simulate veriloga blocks and therefore the solution would sort of be the same. Tanner is a bit beyond my expertise.