0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ngspiceとSKY130を使ってみる(3) 入力容量の測定

Posted at

入力容量の測定にはいくつかの方法が考えられるが、ここでは電流を積分する方法と駆動したゲートの遅延時間が等しくなる容量を探す方法の2通りを示す。
CMOSのゲート容量は並行平板コンデンサーではなく、チャネルの容量であり、またゲート<->ソース・ドレイン間の容量によるミラー容量もあるので、私はプロセス間の差を見る場合には遅延等価容量を比較している。

遅延等価容量

インバータで対象回路を駆動した場合のインバータの遅延時間(場合によっては波形傾きも)と同じインバータで容量を駆動した場合の遅延時間が同じになるような容量を探す方法。
入力波形傾きによって容量が異なる。
最近の先端プロセスではミラー効果などによって、こちらの容量のほうが大きい。
以下のspicedeckでは容量値はout.txtに出力される。

*
.option method=gear tnom=25
*.option autostop

.lib 'sky130.lib.spice' ss

.param vdd=1.8
.param vss=0

vcc vcc 0 dc vdd
vss vss 0 dc vss

.subckt INVD1 I ZN vcc vss vcp vsb
xp1 vcc i zn vcp sky130_fd_pr__pfet_01v8 w=1.12 l=0.15 nf=1 mult=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
xn1 vss i zn vsb sky130_fd_pr__nfet_01v8 w=0.74 l=0.15 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
.ends

.param cload=0.5f
xi00 in  a01 vcc vss vcc vss INVD1
xi01 a01 a02 vcc vss vcc vss INVD1
xi02 a02 a03 vcc vss vcc vss INVD1
xi03 a03 a04 vcc vss vcc vss INVD1

xc00 in  b01 vcc vss vcc vss INVD1
xc01 b01 b02 vcc vss vcc vss INVD1
xc02 b02 b03 vcc vss vcc vss INVD1
ctarg b03 vss cload

.param trf=10p
vin in 0 pwl (0n vss 5n vss '5n+trf' vdd 10n vdd '10n+trf' vss 15n vss)

.print tran v(in) v(a03) v(b03)

.temp 25
*.tran 1p 100n

.control
let error=0.1f
let step=0.1f
let mul=5
let cl=0.5f
let dirc=1
let delay_diff=1n

while delay_diff > error
       alter ctarg cl
       tran 1p 100n

        meas tran r2f_inv
        + trig v(a02) val='0.5*vdd' rise=1 TD=5n
        + targ v(a03) val='0.5*vdd' fall=1 TD=5n
        meas tran f2r_inv
        + trig v(a02) val='0.5*vdd' fall=1 TD=5n
        + targ v(a03) val='0.5*vdd' rise=1 TD=5n
        meas tran r2f_cap
        + trig v(b02) val='0.5*vdd' rise=1 TD=5n
        + targ v(b03) val='0.5*vdd' fall=1 TD=5n
        meas tran f2r_cap
        + trig v(b02) val='0.5*vdd' fall=1 TD=5n
        + targ v(b03) val='0.5*vdd' rise=1 TD=5n

        let inv_avg=(r2f_inv+f2r_inv)/2
        let cap_avg=(r2f_cap+f2r_cap)/2
        let delay_diff=abs(inv_avg-cap_avg)

        print cl inv_avg cap_avg delay_diff > out.txt
        if inv_avg > cap_avg
           echo "Inv > Cap"
           if dirc=1
              echo "1:"
              let dirc = -1
              let mul = mul / 2
              let cl = cl+ mul * step
           else
              let cl=cl + mul*step
           end
        else
           echo "Inv < Cap"
           if dirc=-1
              echo "2:"
              let dirc=1
              let mul=mul/2
              let cl=cl - mul*step
           else
              let cl=cl - mul*step
           end
        end
end
print cl inv_avg cap_avg delay_diff >> out.txt
*print $delay_diff
*wrdata out1.txt cl
.endc

.end

電流を積分する方法

NGSPICEでは.measureで測定する方法と、.control内のmeasで測定する方法の2通りが記述可能なのでそれぞれを示す。

.measureで測定

*
.option method=gear tnom=25
*.option autostop

.lib 'sky130.lib.spice' ss

.param vdd=1.8
.param vss=0

.param pwidth=1.12
.param nwidth=0.74
.param length=0.15

.subckt INVD1 I ZN vcc vss vcp vsb
X0 vcc i zn vcp sky130_fd_pr__pfet_01v8 w='pwidth' l='length' nf=1 mult=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
X1 vss i zn vsb sky130_fd_pr__nfet_01v8 w='nwidth' l='length' nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
.ends

.param trf=2p

vcc vcc 0 dc vdd
vss vss 0 dc vss

vin in vss  pwl(0n vss 1n vss '1n+trf' vdd 2n vdd '2n+trf' vss 3n vss)

xinv in out vcc vss vcc vss INVD1

.print tran i(vin) v(in)
.temp 25
.tran 0.1n 5n

.measure tran i_rise_integ
+ integ i(vin) from=1n to='1n+trf'
.measure tran i_fall_integ
+ integ i(vin) from=2n to='2n+trf'

.measure tran i_rise find i(vin) at='1n+trf/2'
.measure tran i_fall find i(vin) at='2n+trf/2'
.measure tran capa_rise find par('abs(i(vin))*trf/vdd/1e-15') at='1n+trf/2'
.measure tran capa_fall find par('abs(i(vin))*trf/vdd/1e-15') at='2n+trf/2'

.control
run
.endc

.end

.control内のmeasで測定する方法

ngspiceの.control内のmeasは.measureの記述をそのまま使えないケースがいろいろあり、csparamとletで値をあらかじめ計算しておく必要があった。

*
.option method=gear tnom=25
*.option autostop

.lib 'sky130.lib.spice' ss

.param vdd=1.8
.param vss=0
.csparam vdd2={vdd}

.param pwidth=1.12
.param nwidth=0.74
.param length=0.15

.subckt INVD1 I ZN vcc vss vcp vsb
X0 vcc i zn vcp sky130_fd_pr__pfet_01v8 w='pwidth' l='length' nf=1 mult=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
X1 vss i zn vsb sky130_fd_pr__nfet_01v8 w='nwidth' l='length' nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1
.ends

.param trf=2p
.csparam trf2={trf}

vcc vcc 0 dc vdd
vss vss 0 dc vss

vin in vss  pwl(0n vss 1n vss '1n+trf' vdd 2n vdd '2n+trf' vss 3n vss)

xinv in out vcc vss vcc vss INVD1

.print tran i(vin) v(in)
.temp 25
.tran 0.1n 5n

.control
let frm1=1n
let frm2=2n
let to1='1n+$&trf2'
let to2='2n+$&trf2'
tran 0.1n 5n
meas tran i_rise_integ integ i(vin) from=frm1 to=to1
meas tran i_fall_integ integ i(vin) from=frm2 to=to2
let time1=1n+$&trf2/2
let time2=2n+$&trf2/2
let itarg=abs(i(vin))*'$&trf2'/'$&vdd2'/1e-15
meas tran capa_rise find itarg at=time1
meas tran capa_fall find itarg at=time2
.endc

.end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?