FPGARelated.com
Blogs

Modeling Gate Drive Diodes

Jason SachsMarch 11, 20241 comment

This is a short article about how to analyze the diode in some gate drive circuits when figuring out turn-off characteristics — specifically, determining the relationship between gate drive current and gate voltage during turn-off of a power transistor.

Here’s the diode I’m talking about; it’s the one labeled D1:

Just as an example, I’m going to use the following:

  • Gate driver sink resistance (R3 = Rdson of Q2n) = 2.5 Ω
  • R1 = 2.5 Ω
  • R2 = 10 Ω
  • D1 = Nexperia PMEG2005CT with both diodes in parallel to double the current capability.* Rated forward voltage for each diode is 390 mV at 500 mA.

*Can you really put diodes in parallel to double the current capability? Why, yes you can — in some cases. The bad cases are ones where the limitation is thermal, and the negative temperature coefficient of forward voltage means that one will have a slightly lower forward voltage drop and hog more than its share of current, and heat up more than the others, which will lower its forward voltage drop and hog still more current, and heat up more, until the other diodes aren’t carrying much of the current at all, and you’ve just wasted your money putting these extra diodes to try to help. ST Micro has a good application note on current-sharing in diodes. But in this case, we’re dealing with a very short transient, pulling charge out of the MOSFET gate, so the diodes don’t heat up much.

Turn-off current depends on the voltage at the transistor gate, and here I need to use my Thevenin-equivalent kung-fu to analyze the circuit. As long as the diode is conducting, it acts as a voltage source, so we can transform the circuit:

  • from a voltage source \( V_D \) in series with a resistor R1 (first circuit, below) all of which is in parallel with resistor R2
  • to a Norton equivalent \( V_D/R_1 \) in parallel with R1, all of which is in parallel with R2 (second circuit, below) — oh, look, now we have three things all in parallel
  • to a Thevenin equivalent \( \frac{R_2}{R_1+R_2}V_D \) in series with resistor \( R_1 \parallel R_2 = \frac{R_1R_2}{R_1+R_2} \)

Current through the diode is \( I_D = \frac{R_2I-V_D}{R_1+R_2} \) where I is the total current that goes through R3. (You can derive this by equating voltage across both R1 and R2 paths: \( V_D + I_DR_1 = (I - I_D)R_2 \) and then solve for \( I_D \).)

This means our turn-off circuit has resistance R3 = 2.5 Ω from the gate driver IC, with parallel combination R1 || R2 = 2 Ω, and effective diode drop \( \frac{R_2}{R_1+R_2}V_D = \) 0.8 × 390 mV = 312 mV.

Total turn-off equivalent is 4.5 Ω in series with 312 mV.

That’s when the diode is conducting. But at some point, the voltage is low enough that it doesn’t conduct, and we’re left with R2 + R3 = 12.5 Ω. What gate voltage does this point correspond to?

If you guessed 312 mV, you’d be… WRONG!

In this case, it’s when voltage across R2 is the diode voltage \( V_D \), and there’s no current in R1, which occurs at a gate voltage \( V_g = \frac{R_2+R_3}{R_2}V_D \), when the current through R2 and R3 is \( \frac{V_D}{R_2} \). In our example this is Vg = 488 mV at a current of 39mA.

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

V = np.arange(0,1.2,0.001)
I = np.maximum(V/12.5, (V-0.312)/4.5)
fig,ax = plt.subplots()
ax.plot(V,I)
ax.plot(0.488,0.039,'.')
ax.grid()
ax.set_xlabel('Voltage $V_g$, V')
ax.set_ylabel('Current I, A');

Is this good enough?

Improving the model

Well, we can go further with diode modeling than just a fixed voltage source of 390 mV; we could model the diode’s effective series resistance \( R_D \), or we could even use the Shockley diode equation and add a resistance to capture the voltage drop of the diode’s leads:

$$V_D = \frac{nkT}{q} \ln \left(\frac{I_D}{I_S} + 1\right) + R_DI_D$$

except that now we have to figure out \( R_D \) and \( n \) and \( I_S \), and the datasheet doesn’t tell us these.

What we do have is Figure 4 of the datasheet, showing typical forward voltage as a function of current:

Argh! I hate these graphs! The manufacturers have the raw data points and they display these in a graph, and the raw data points are somehow even in the PDF file, but you can’t get them out without having to read the graph visually, which is tedious and error-prone.

In cases like this, I turn to one of my favorite tools, WebPlotDigitizer. First you upload the image, and then mark the axis limits:

Then you digitize whatever points you want:

And then WebPlotDigitizer spits out the values of the points you digitized. Here they are:

raw_points = '''
0.08963965931426074, 0.00010054759620253744
0.14935848438523694, 0.0010043720714643183
0.1855923782485259, 0.003975344939778284
0.24732419742301812, 0.037237294425694956
0.21847128193928808, 0.013312632936170968
0.26409914828565184, 0.06390032297060724
0.2855710853898231, 0.1154419611012017
0.3103980126665211, 0.21956345014850223
0.33321194583970304, 0.34880396975645306
0.360051867219917, 0.52634085723272
0.38957578073815247, 0.7544266820574363
0.4184286962218825, 1.0010676660874334
0.4452686176020966, 1.2456332526505078
0.47210853898231053, 1.4913005277918399
0.4935804760864818, 1.6959164068156412
0.5526283031229526, 2.338851332434253
0.5231043896047172, 2.004451224988414
0.5727582441581132, 2.4941481817309454
'''
points = np.array([[float(num) for num in line.split(',')] 
                   for line in raw_points.splitlines() if line != ''])
Vd_digitized = points[:,0]
Id_digitized = points[:,1]
points
array([[8.96396593e-02, 1.00547596e-04],
       [1.49358484e-01, 1.00437207e-03],
       [1.85592378e-01, 3.97534494e-03],
       [2.47324197e-01, 3.72372944e-02],
       [2.18471282e-01, 1.33126329e-02],
       [2.64099148e-01, 6.39003230e-02],
       [2.85571085e-01, 1.15441961e-01],
       [3.10398013e-01, 2.19563450e-01],
       [3.33211946e-01, 3.48803970e-01],
       [3.60051867e-01, 5.26340857e-01],
       [3.89575781e-01, 7.54426682e-01],
       [4.18428696e-01, 1.00106767e+00],
       [4.45268618e-01, 1.24563325e+00],
       [4.72108539e-01, 1.49130053e+00],
       [4.93580476e-01, 1.69591641e+00],
       [5.52628303e-01, 2.33885133e+00],
       [5.23104390e-01, 2.00445122e+00],
       [5.72758244e-01, 2.49414818e+00]])
fig,ax = plt.subplots()
ax.semilogy(Vd_digitized,Id_digitized,'.-')
ax.grid()

Now we can try to fit an equation to it using least-squares analysis. To do so, we need to write a linear equation in terms of unknown coefficients and known basis functions: \( y = a_1u_1 + a_2u_2 + a_3u_3 \ldots \) where the \( a_k \) are the unknown coefficients and the \( u_k \) are the basis functions.

Here we have to stare really hard at the Shockley equation and try to put it in that form:

$$\begin{aligned} V_D &= \frac{nkT}{q} \ln \left(\frac{I_D}{I_S} + 1\right) + R_DI_D \cr &\approx \frac{nkT}{q} \ln \left(\frac{I _ D}{I _ S}\right) + R_DI_D \cr &= \underbrace{-\frac{nkT}{q} \ln I _ S} _ {a _ 1} \times \underbrace{\vphantom{\frac{T}{q} }1} _ { u _ 1 } \quad + \quad \underbrace{\frac{nkT}{q}} _ {a _ 2} \times \underbrace{\vphantom{\frac{T}{q}}\ln I_ D} _ {u _ 2} \quad + \quad \underbrace{\vphantom{\frac{T}{q}}R _ D} _ {a _ 3} \times \underbrace{\vphantom{\frac{T}{q}}I _ D} _ {u _ 3} \end{aligned}$$

So our basis functions are going to be the following, as a function of current \( I_D \):

  • \( u_1 = 1 \) (coefficient \( a_1 \) is a fixed offset, which will tell us something about the scale current \( I_S \) of the diode)
  • \( u_2 = \ln I_D \) (coefficient \( a_2 \) scales the log term in the diode equation)
  • \( u_3 = I_D \) (coefficient \( a_3 \) is a resistance)
basis = np.array([
    Id_digitized*0 + 1,
    np.log(Id_digitized),
    Id_digitized
])
V0, nkTq, Rd = np.linalg.lstsq(basis.T, Vd_digitized, rcond=None)[0]
V0, nkTq, Rd
(0.3315343790147935, 0.02636950191846902, 0.08646010749710412)

That’s 0.332 volts = \( -\frac{nkT}{q} \ln I_S \) offset, \( R_D = \) 86.5 mΩ series resistance (most important at high currents), and \( \frac{nkT}{q} = \)26.4 mV, which corresponds to \( n=1.026 \) since \( \frac{kT}{q} \) = 25.7 V at 25 °C = 298.15 K (see NIST for k and q).

The value for \( I_S = \) 3.466 μA:

Is = np.exp(-V0/nkTq)
Is
3.465530903611563e-06

And here we have all the coefficients for our model \( V_D = I_DR_D + \frac{nkT}{q} \ln \left(\frac{I_D}{I_S}+1\right) \), to see how well it fits our digitized data:

def fVd(Id):
    return Id*R + nkTq*np.log(Id/Is + 1)

fig,ax = plt.subplots(figsize=(10,8))
ax.semilogy(Vd_digitized,Id_digitized,'.')
Idrange = np.logspace(-5,0.5,1000)
Vdrange = fVd(Idrange)
ax.plot(Vdrange,Idrange)
ax.grid()
ax.set_xlabel('Forward voltage $V_D$')
ax.set_ylabel('Diode current $I_D$')
ax.set_title('Modeled vs digitized diode voltage and current: %.4f V at 500 mA'
             % fVd(0.5));

Terrific! Now we just add a fudge factor of 390 mV / 356.5 mV to match the worst-case datasheet value (rather than typical behavior) of 390 mV drop at 500 mA at 25 C, and double the current (two diodes in parallel), and… now how do we incorporate in our circuit? We have this equation we derived earlier, stating the diode current as a function of the diode voltage:

$$I_D = \frac{R_2I-V_D}{R_1+R_2}$$

Which is great, except that in order to estimate the voltage drop \( V_D = I_DR_D + \frac{nkT}{q} \ln \left(\frac{I_D}{I_S}+1\right) \) we need to know the current \( I_D \), and now we’ve got to solve these two equations, which is an ugly nonlinear thing. We could solve it in closed-form in terms of the Lambert W-function. But I’d rather just take the diode current \( I_D \) as the independent variable and see what we get:

$$\begin{aligned} V_D &= I_DR_D + \frac{nkT}{q} \ln \left(\frac{I_D}{I_S}+1\right) \cr I &= \frac{I_D(R_1+R_2) + V_D}{R_2} \cr V_g &= IR_3 + V_D + I_DR_1 \end{aligned}$$

We can compare this to our zero-order model (390mV at any positive current) as well as a first-order model with diode resistance Rd = 86.5 mΩ × 390 mV / 356.5 mV = 94.6 mΩ for each diode, and voltage source 390 mV - 0.5 A × Rd = 343 mV:

# Id = np.arange(0,0.4585,0.001)   -- 3V max
Id = np.arange(0,0.633,0.001)  #   -- 4V max
Vd = fVd(Id/2)*390/356.5
# share current between two diodes and
# adjust magnitude to be 390 mV at 500 mA for each diode 
R1,R2,R3 = 2.5,10,2.5
I = (Id*(R1+R2)+Vd)/R2
Vg = I*R3 + Vd + Id*R1

# Now for the zero-order diode model (390mV voltage source)
Rth = R3 + R1*R2/(R1+R2)
Vd0 = 0.390
Vth = Vd0*R2/(R1+R2)
I_approx0 = np.maximum(Vg/(R3+R2), (Vg-Vth)/Rth)
Id_approx0 = np.maximum(0,(R2*I_approx0 - Vd0)/(R1+R2))

# Now for the first-order diode model (343mV voltage source, 94.6 milliohm)
# where the diode resistance is in series with R1
Rd1 = 0.0946/2
Vd1 = 0.343
R1b = R1 + Rd1
Vth = Vd1*R2/(R1b+R2)
I_approx1 = np.maximum(Vg/(R3+R2), (Vg-Vth)/Rth)
Id_approx1 = np.maximum(0,(R2*I_approx1 - Vd1)/(R1b+R2))

fig,ax = plt.subplots(figsize=(10,8))
hl = ax.plot(Vg,I,label='Shockley model')[0]
c = hl.get_color()
ax.plot(Vg,I_approx0,label='390 mV approximation',
        linestyle='--', color=c, linewidth=1.0)
ax.plot(Vg,I_approx1,label='first-order approximation',
        linestyle='-.', color=c)

hl = ax.plot(Vg,Id,label='Diode current, Shockley model')[0]
c = hl.get_color()
ax.plot(Vg,Id_approx0,label='Diode current, 390 mV approximation',
        linestyle='--', color=c, linewidth=1.0)
ax.plot(Vg,Id_approx1,label='Diode current, first-order approximation',
        linestyle='-.', color=c)
Imax, Vgmax = max(I), max(Vg)
ax.set_xlim(0,Vgmax)
ax.set_xticks(np.arange(0,Vgmax,0.2))
ax.set_xticks(np.arange(0,Vgmax,0.1),minor=True)
ax.set_ylim(-0.01*Imax,1.01*Imax)
ax.set_yticks(np.arange(0,Imax,0.05))
ax.set_yticks(np.arange(0,Imax,0.01),minor=True)
ax.grid()
ax.grid(which='minor', linewidth=0.25)
ax.legend()
ax.set_xlabel('Gate voltage, V')
ax.set_ylabel('Current, A')
ax.set_title('Pulldown current $I$ and diode current $I_D$ vs. gate voltage'
            +' (R1 = %.1f \u03A9, R2 = %.1f \u03A9, R3 = %.1f \u03A9)\n' % (R1,R2,R3)
            +'for several approximate models; first-order = %.0f mV + %.1f m\u03A9'
            % (Vd1*1000, Rd1*1000));

Which is good enough? That’s your call. I’d probably go with the first-order approximation, for reasons I’ll explain another time.

Wrapup

We figured out how to create a zero-order approximation of the voltage vs. current characteristic of the diode pulldown circuit, using a fixed diode drop (312 mV) and a Thevenin-equivalent model from the different resistances.

Then we tried to fit the Shockley diode model to voltage and current points digitized from a graph in the datasheet. (WebPlotDigitizer and least-squares analysis saved the day again!)

Then we compared the resulting pulldown currents from the Shockley model, the zero-order approximation, and a first-order approximation taking diode internal series resistance into account.

Stay tuned for how to apply these models!


© 2024 Jason M. Sachs, all rights reserved.



[ - ]
Comment by tcfkatMarch 14, 2024

Excellent article, Jason! Very interesting.

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: