1000  !*************************************************
1010  !*
1020  !* FILE       :  JRAMP1
1030  !* DESCRIPTION:  Program for JRAMP. using HPSMU.
1040  !*
1070  !* PRODUCT    :  4155,4156
1080  !* REVISION   :  Rev.A.01.04
1090  !*
1100  !*   (c) Copyright Agilent Technologies 1994
1110  !*              All rights reserved.
1120  !*
1130  !*
1140  !*  Customer shall have the personal, non-
1150  !* transferable right to use, copy or modify
1160  !* this SAMPLE PROGRAM for Customer's internal
1170  !* operations.  Customer shall use the SAMPLE
1180  !* PROGRAM solely and exclusively for its own
1190  !* purpose and shall not license, lease, market
1200  !* or distribute the SAMPLE PROGRAM or modification
1210  !* or any part thereof.
1220  !*
1230  !*  Agilent shall not be liable for the quality,
1240  !* performance or behavior of the SAMPLE PROGRAM.
1250  !* Agilent especially disclaims that the operation
1260  !* of the SAMPLE PROGRAM shall be uninterrupted or
1270  !* error free.  This SAMPLE PROGRAM is provided
1280  !* AS IS.
1290  !*
1300  !*  AGILENT DISCLAIMS THE IMPLIED WARRANTIES OF
1310  !* MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1320  !* PURPOSE.
1330  !*
1340  !*  Agilent shall not be liable for any infringement
1350  !* of any patent, trademark copyright or other
1360  !* proprietary rights by the SAMPLE PROGRAM or
1370  !* its use. Agilent does not warrant that the SAMPLE
1380  !* PROGRAM is free from infringements or such
1390  !* right of third parties. However, Agilent will not
1400  !* knowingly infringe or deliver a software that
1410  !* infringes the patent, trademark, copyright or
1420  !* other proprietary right of a third party.
1430  !*
1440  !************************************************************
1450  ASSIGN @Hp4155 TO 800
1460  COM @Hp4155
1470  COM /File_name/ Init_file$[12],Sweep_file$[12],Save_file$[12]
1480  COM /Err/ Err_num(1:6),Err_message$(1:6)[50]
1490  DIM Result_init$[3],Result_sw$[3],Result_fin$[3]
1500  !
1510  Init_hp4155                                 ! Initialize 415x
1520  !
1530  ON INTR 8 CALL Err_check
1540  ENABLE INTR 8;2
1550  !
1560  Test_setting                  ! Set up test parameters etc.
1570  Get_file                      ! LOAD necessary setup files into memory
1580  Init_fin_test("Init",Result_init$)          ! Initial test
1590  Judge(Result_init$,Result_sw$,Result_fin$)  ! Judge initial failure
1600  Ramp_test(Result_sw$,Vbd,Qbd)               ! Ramp test
1610  Init_fin_test("Fin",Result_fin$)            ! Post test
1620  Judge(Result_init$,Result_sw$,Result_fin$)  ! Judge failure status
1630  Final_session                               ! Data save etc.
1640  !
1650  END
1660  !
1670  !
1680 Test_setting:SUB Test_setting
1690    COM /File_name/ Init_file$,Sweep_file$,Save_file$
1700    COM /Para/ Max_q,Max_e,Tox,Vgcomp,Igcomp,Area,Iforce0,Istop,Vuse,Tp
1710    COM /Step/ Step_time,Step_delay_t,Step_keep_t,INTEGER Step_n
1720    COM /Factor/ Fact$[3],REAL Factor
1730    !
1740    Init_file$="JINIT1.MES"    ! Init/Post Measurement Setup File Name
1750    Sweep_file$="JRMP1.MES"    ! Ramp Setup File Name
1760    Save_file$=TIME$(TIMEDATE) ! File Name for saving measurement results
1770    Save_file$="D"&Save_file$[1,2]&Save_file$[4,5]&Save_file$[7,7]&".DAT"
1780    !
1790    Type$="NMOS"               ! Dev type NMOS - P bulk, PMOS -N bulk
1800    Iforce0=1.E-6              ! Initial current (A)
1810    Vuse=5                     ! Vuse (V) (Reference for Init/Post test)
1820    Smu_type=0                 ! SMU type used
1830                               !  0: MP/HP SMU
1840                               !  1: HR SMU
1850    !---------------------------------------------------
1860    !  Allowable current factor :
1870    !      10^(1/10),   10^(1/25),  10^(1/50)
1880    !---------------------------------------------------
1890    Factor=10^(1/10)              ! Current factor
1900    Step_time=.5/(1/LGT(Factor))-.0037    ! Ramp step time
1910    Step_delay_t=Step_time/2              ! Step Delay time
1920    Step_keep_t=Step_time-Step_delay_t    ! Step keep time
1930    !
1940    Max_q=50                   ! Maximum charge (C/cm^2)
1950    Max_e=25*1.E+6             ! Maximum Field (V/cm)
1960    !
1970    Tox=160*1.E-8              ! Oxide Thickness  (cm)
1980    Area=.001                  ! Area of oxide capacitor (cm^2)
1990    Calc_istop                 ! Calculate Istop (A)
2000    Vgcomp=Max_e*Tox           ! Vg compliance (V)
2010    Igcomp=.1                  ! Ig compliance (A)
2020    Tp=1
2030    IF Type$="NMOS" THEN Tp=-1
2040    !
2050    !----- Input parameter check ----------
2060    SELECT Factor
2070    CASE 10^(1/10)
2080      Fact$="L10"
2090    CASE 10^(1/25)
2100      Fact$="L25"
2110    CASE 10^(1/50)
2120      Fact$="L50"
2130    CASE ELSE 
2140      PRINT "Para ERROR : Factor must be any of  10^(1/10),  10^(1/25),  10^(1/50)"
2150    END SELECT 
2160    !
2170  SUBEND
2180    !
2190 Init_hp4155:SUB Init_hp4155
2200    COM @Hp4155
2210    !
2220    CLEAR SCREEN
2230    CLEAR @Hp4155
2240    OUTPUT @Hp4155;"*RST"
2250    OUTPUT @Hp4155;"*CLS"
2260    OUTPUT @Hp4155;":STAT:PRES"
2270    OUTPUT @Hp4155;"*ESE 60;*SRE 32;*OPC?"
2280    ENTER @Hp4155;A
2290    OUTPUT @Hp4155;":DISP:WIND:ALL BST"
2300    OUTPUT @Hp4155;":DISP OFF"
2310    PRINT "   <<< J Ramp Test >>>"
2320  SUBEND
2330    !
2340 Get_file:SUB Get_file
2350    COM @Hp4155
2360    COM /File_name/ Init_file$,Sweep_file$,Save_file$
2370    OUTPUT @Hp4155;":MMEM:COPY '"&Init_file$&"','DISK','MEM1.MES','MEMORY'"
2380    OUTPUT @Hp4155;":MMEM:COPY '"&Sweep_file$&"','DISK','MEM2.MES','MEMORY'"
2390  SUBEND
2400    !
2410 Init_fin_test:SUB Init_fin_test(I_or_f$,Result$)
2420    !-----------------------------------------------
2430    !  Apply 1uA. Checks if oxide is alive.
2440    !  Used for both Initial and Post tests.
2450    !-----------------------------------------------
2460    COM @Hp4155
2470    COM /Para/ Max_q,Max_e,Tox,Vgcomp,Igcomp,Area,Iforce0,Istop,Vuse,Tp
2480    !
2490    IF I_or_f$="Init" THEN
2500      PRINT "[1] Initial Test"
2510    ELSE 
2520      PRINT "[3] Post Test"
2530    END IF 
2540    OUTPUT @Hp4155;":MMEM:LOAD:STAT 0,'MEM1.MES','MEMORY'"
2550    OUTPUT @Hp4155;":PAGE:MEAS:SAMP:CONS:SMU5:SOUR "&VAL$(Tp*Iforce0)
2560    OUTPUT @Hp4155;":PAGE:MEAS:SAMP:SCON:THR "&VAL$(Tp*Vuse)
2570    OUTPUT @Hp4155;":PAGE:GLIS"      ! GRAPHICS page
2580    OUTPUT @Hp4155;":DISP ON"        !
2590    OUTPUT @Hp4155;":DISP OFF"       ! Display lock
2600    OUTPUT @Hp4155;":PAGE:SCON:SING" ! SINGLE measurement
2610    OUTPUT @Hp4155;"*OPC?"           ! Query *OPC
2620    ENTER @Hp4155;A                  !
2630    !
2640    OUTPUT @Hp4155;":TRAC? 'Vm'"     ! Trace maximum voltage
2650    ENTER @Hp4155;Vm                 !
2660    OUTPUT @Hp4155;":DISP ON"        ! Unlock display
2670    OUTPUT @Hp4155;":PAGE:GLIS:GRAP:SCAL:AUTO ONCE"   ! Auto scale
2680    PRINT "     Vmeas= ";Vm;"[V]"
2690    !
2700    IF ABS(Vm)<ABS(Vuse) THEN        ! Judge if failed
2710      Result$="YES"                  ! Initial fail
2720    ELSE 
2730      Result$="NO"                   ! Survive
2740    END IF 
2750  SUBEND
2760    !
2770 Ramp_test:SUB Ramp_test(Result$,Vdb,Qbd)
2780    OPTION BASE 1
2790    COM @Hp4155
2800    COM /Para/ Max_q,Max_e,Tox,Vgcomp,Igcomp,Area,Iforce0,Istop,Vuse,Tp
2810    COM /Step/ Step_time,Step_delay_t,Step_keep_t,INTEGER Step_n
2820    COM /Factor/ Fact$,REAL Factor
2830    DIM Vmeas$[17]
2840    DIM Vg(10000)
2850    REDIM Vg(Step_n+1)
2860    !
2870    PRINT "[2] Ramp Test"
2880    !
2890    OUTPUT @Hp4155;":MMEM:LOAD:STAT 0,'MEM2.MES','MEMORY'"  ! Load Sweep meas file
2900    !
2910    !------ Update setting --------------------------------------------
2920    OUTPUT @Hp4155;":DISP ON"           ! Display unlock
2930    OUTPUT @Hp4155;":PAGE:CHAN:UFUN"
2940    OUTPUT @Hp4155;":PAGE:CHAN:UFUN:DEF 'Time','sec','@INDEX*"&VAL$(Step_time)&"'"
2950    OUTPUT @Hp4155;":PAGE:MEAS:SWE:MENU"
2960    OUTPUT @Hp4155;":PAGE:MEAS:SWE:DELay "&VAL$(Step_delay_t) ! update delay
2970    OUTPUT @Hp4155;":PAGE:MEAS:OSEQ:TRIG:TIME "&VAL$(Step_keep_t) ! keep tim
2980    OUTPUT @Hp4155;":PAGE:MEAS:SWE:VAR1:MODE SING"                ! Mode
2990    OUTPUT @Hp4155;":PAGE:MEAS:SWE:VAR1:SPAC "&Fact$              ! LOG
3000    OUTPUT @Hp4155;":PAGE:MEAS:SWE:VAR1:STAR "&VAL$(Tp*Iforce0)   ! Istart
3010    OUTPUT @Hp4155;":PAGE:MEAS:SWE:VAR1:STOP "&VAL$(Tp*Istop)     ! Istop
3020    OUTPUT @Hp4155;":PAGE:MEAS:SWE:VAR1:COMP "&VAL$(Vgcomp)       ! Vgcomp
3030    !
3040    OUTPUT @Hp4155;":PAGE:DISP:SET:GRAP:Y1:MIN "&VAL$(Tp*Iforce0/10)
3050    OUTPUT @Hp4155;":PAGE:DISP:SET:GRAP:Y1:MAX "&VAL$(Tp*Istop*10)
3060    OUTPUT @Hp4155;":PAGE:DISP:SET:GRAP:Y2:MIN "&VAL$(Tp*0)
3070    OUTPUT @Hp4155;":PAGE:DISP:SET:GRAP:Y2:MAX "&VAL$(Tp*(Vgcomp+1))
3080    OUTPUT @Hp4155;":PAGE:DISP:SET:GRAP:X:MAX "&VAL$((Step_n+1)*Step_time)
3090    IF Tp=-1 THEN
3100      OUTPUT @Hp4155;":PAGE:DISP:ANAL:MARK:POS 'Vg','MIN(Vg)'"
3110    ELSE 
3120      OUTPUT @Hp4155;":PAGE:DISP:ANAL:MARK:POS 'Vg','MAX(Vg)'"
3130    END IF 
3140    !
3150    OUTPUT @Hp4155;":PAGE:GLIS"         ! change the display page to GRAPH
3160    OUTPUT @Hp4155;":DISP ON"           ! Display unlock
3170    OUTPUT @Hp4155;":PAGE:MEAS"         ! change the display page to GRAPH
3180    OUTPUT @Hp4155;":PAGE:SCON:SING"    ! Start SINGLE measurement
3190    REPEAT
3200      OUTPUT @Hp4155;":PAGE:SCON:STAT?" ! Query operation status
3210      ENTER @Hp4155;Stat$               ! Char data returned.
3220    UNTIL Stat$<>"MEAS"
3230    !
3240    !------ Retrieve measured data ------------------------------
3250    OUTPUT @Hp4155;":DATA? 'Vg'"
3260    ENTER @Hp4155;Vg(*)
3270    !
3280    !------ Search breakdown point -------------------------------
3290    I=1
3300    LOOP
3310    EXIT IF Vg(I)=9.91E+307       ! Exit if compliance
3320      IF I=Step_n+1 THEN Result$="NO"             !
3330    EXIT IF I=Step_n+1
3340      I=I+1
3350      IF Tp*(Vg(I-1)*.85-Vg(I))>0 THEN Result$="YES"   ! Judge breakdown
3360    EXIT IF Tp*(Vg(I-1)*.85-Vg(I))>0                   ! Exit if breakdown
3370    END LOOP 
3380    !
3390    OUTPUT @Hp4155;":STAT:MEAS?"        ! Query meas status
3400    ENTER @Hp4155;Meas_stat             ! Decimal data returned
3410    IF Meas_stat>=8 THEN Result$="NO"   ! If compliance
3420    IF Result$="YES" THEN I=I-1
3430    IF Vg(I)=9.91E+307 AND I>1 THEN I=I-1                 !
3440    Xpos=I*Step_time                                      !
3450    OUTPUT @Hp4155;":PAGE:GLIS:MARK ON"                   ! Marker to
3460    OUTPUT @Hp4155;":PAGE:GLIS:MARK:DIR:X "&VAL$(Xpos)    !  proper pos
3470    OUTPUT @Hp4155;":MMEM:STOR:TRAC DEF,'MEM3.DAT','MEMORY'"
3480    OUTPUT @Hp4155;":DISP OFF"                            ! Display lock
3490    !
3500    !------ Check if breakdown occurred -------------------------
3510    !
3520    OUTPUT @Hp4155;":PAGE:DISP:SET:LIST:SEL 'Ig','Vg','Qbdo'"
3530    OUTPUT @Hp4155;":PAGE:GLIS:LIST:MARK:DIR? 'Vg'"    ! Trace marker value
3540    ENTER @Hp4155;Vbd
3550    OUTPUT @Hp4155;":PAGE:GLIS:LIST:MARK:DIR? 'Qbdo'"  ! Trace marker value
3560    ENTER @Hp4155;Qbdo                                  ! Qbd
3570    ! Compensate Qbd
3580    Qbd=ABS(Qbdo+FNCompen(Tp*Iforce0,Istop,I,Fact$,Smu_type))
3590    OUTPUT @Hp4155;":PAGE:CHAN:UFUN:DEF 'Qbd','C','"&VAL$(Qbd)&"'"
3600    !Re-store data to reflect new Qbd
3610    OUTPUT @Hp4155;":MMEM:STOR:TRAC DEF,'MEM3.DAT','MEMORY'"
3620    PRINT "       Vbd = ";Vbd;"[V]"
3630    PRINT "       Qbd = ";Qbd;"[C]"
3640    PRINT "       qbd = ";Qbd/Area;"[C/cm^2]"
3650  SUBEND
3660    !
3670 Judge:SUB Judge(Result_init$,Result_sw$,Result_fin$)
3680    COM @Hp4155
3690    !
3700    DISP 
3710    IF Result_init$="YES" THEN
3720      PRINT "        ### Initial Failure (1) ###"
3730      DISP "         ### Initial Failure (1) ###"
3740      CALL Final_session
3750      STOP
3760    END IF 
3770    !
3780    IF Result_sw$="YES" OR Result_sw$="NO" THEN  ! Check if ramp test was performed or not
3790      OUTPUT @Hp4155;":MMEM:LOAD:TRAC DEF,'MEM3.DAT','MEMORY'"
3800      OUTPUT @Hp4155;":PAGE:GLIS"
3810      OUTPUT @Hp4155;":DISP ON"
3820      OUTPUT @Hp4155;":DISP OFF"
3830    END IF 
3840    !
3850    SELECT Result_sw$
3860    CASE "YES"
3870      IF Result_fin$="YES" THEN
3880        PRINT "      ### Catastrophic Failure (2) ###"
3890        DISP "       ### Catastrophic Failure (2) ###"
3900      ELSE 
3910        PRINT "      ### Noncatastrophic Failure (4) ###"
3920        DISP "       ### Noncatastrophic Failure (4) ###"
3930      END IF 
3940    CASE "NO"
3950      IF Result_fin$="YES" THEN
3960        PRINT "      ### Masked Catastrophic Failure (3) ###"
3970        DISP "       ### Masked Catastrophic Failure (3) ###"
3980      ELSE 
3990        PRINT "      ### Others (5) ###"
4000        DISP "       ### Others (5) ###"
4010      END IF 
4020    END SELECT 
4030  SUBEND
4040    !
4050 Final_session:SUB Final_session
4060    !-------------------------------------------------
4070    ! Save measured results to file then end test
4080    !-------------------------------------------------
4090    COM @Hp4155
4100    COM /File_name/ Init_file$,Sweep_file$,Save_file$
4110    !
4120    OUTPUT @Hp4155;":MMEM:STOR:TRAC DEF,'"&Save_file$&"','DISK'"
4130    OUTPUT @Hp4155;"*OPC?"
4140    ENTER @Hp4155;A
4150    PRINT "--------  Measurement Completed !  ------------"
4160    PRINT "Save Data File Name : ";Save_file$
4170    PRINT "Test End : ";DATE$(TIMEDATE);",";TIME$(TIMEDATE)
4180    OUTPUT @Hp4155;":PAGE:GLIS"
4190    OUTPUT @Hp4155;":DISP ON"
4200  SUBEND
4210    !
4220 Err_check:SUB Err_check
4230    COM @Hp4155
4240    COM /Err/ Err_num(*),Err_message$(*)
4250    INTEGER I,J
4260    !
4270    OUTPUT @Hp4155;":PAGE:SCON:STOP"
4280    I=0
4290    REPEAT
4300      I=I+1
4310      OUTPUT @Hp4155;":SYST:ERR?"
4320      ENTER @Hp4155;Err_num(I),Err_message$(I)
4330    UNTIL Err_num(I)=0
4340    !
4350    IF I=1 THEN
4360      PRINT "No Error"
4370    ELSE 
4380      PRINT 
4390      FOR J=1 TO I-1
4400        PRINT "### ERROR Occurred ###:";Err_num(J);Err_message$(J)
4410        DISP "### ERROR Occurred ###:";Err_num(J);Err_message$(J)
4420      NEXT J
4430      OUTPUT @Hp4155;"DISP ON"
4440      PRINT 
4450      PRINT "              === Test Aborted ==="
4460      STOP
4470    END IF 
4480  SUBEND
4490  !
4500 Calc_istop:SUB Calc_istop
4510    OPTION BASE 1
4520    COM /Para/ Max_q,Max_e,Tox,Vgcomp,Igcomp,Area,Iforce0,Istop,Vuse,Tp
4530    COM /Step/ Step_time,Step_delay_t,Step_keep_t,INTEGER Step_n
4540    COM /Factor/ Fact$,REAL Factor
4550    Step_n=LGT((LGT(Factor)*Max_q*Area)/(Step_time*Iforce0)+1)/LGT(Factor)
4560    Istop=Iforce0*(Factor^Step_n)
4570    Step_n=INT((1/LGT(Factor))*(LGT(Istop)-LGT(Iforce0)))   ! Recalculate # according to 4156's spec.
4580  SUBEND
4590  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4600  ! FUNCTION:
4610  !  FNCompen
4620  ! PARAMETERS:
4630  !  Istart    - Start current setting of the LOG sweep
4640  !  Istop     - Stop current setting of the LOG sweep
4650  !  Steps     - Number of steps to compensate
4660  !  Factor    - Log sweep mode used.
4670  !               "L10": LOG10 sweep
4680  !               "L25": LOG25 sweep
4690  !               "L50": LOG50 sweep
4700  !  Smutype   - Type of SMU used as VAR1 channel.
4710  !               0: MP/HP SMU
4720  !               1: HR SMU
4730  ! OPERATION:
4740  !  Compensate passed Qbd with the time elapsed for
4750  !  the range change operations thru measurement.
4760  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4770  DEF FNCompen(Istart,Istop,Steps,Factor$,Smutype)
4780  OPTION BASE 0
4790  DIM Lastval(0:9)      ! current to compensate
4800  DIM Icompen(0:9)      ! time data for compensation
4810  INTEGER Nn_ranges     ! number of valid Lastval() entry
4820  INTEGER Range_index   ! index to get compensation time data
4830  INTEGER Flag_sign     ! SIGN flag
4840  REAL Rlast_range      ! previous step range
4850  REAL Rcurr_range      ! current step range
4860  REAL Val_last         ! previous step current
4870  REAL Val_curr         ! current step current
4880  REAL Val_step         ! sweep step multiplier
4890  REAL Val_compen       ! calculated compensation value
4900  REAL Lowest           ! minimum range depend on SMU type
4910  !
4920  ! Compensation time data for each range. Data must be
4930  ! largest range first and decending order.
4940  DATA 8.8E-3,8.9E-3,6.7E-3,8.9E-3,5.9E-3,8.4E-3
4950  DATA 5.9E-3,8.6E-3,25.1E-3,27.0E-3,15.0E-3
4960  !
4970  ! Read data into array
4980  READ Icompen(*)
4990  !
5000  SELECT Factor$
5010  CASE "L10"
5020    Val_step=10^(1/10)
5030  CASE "L25"
5040    Val_step=10^(1/25)
5050  CASE "L50"
5060    Val_step=10^(1/50)
5070  CASE ELSE 
5080    Val_step=10^(1/10)  ! assume L10 sweep mode
5090  END SELECT 
5100  !
5110  SELECT Smutype
5120  CASE 0
5130    Lowest=1.E-9      ! 1nA range for MP/HP SMU
5140  CASE 1
5150    Lowest=1.E-11     ! 10pA range for HR SMU
5160  CASE ELSE 
5170    Lowest=1.E-9
5180  END SELECT 
5190  !
5200  Flag_sign=SGN(Istart)
5210  Istart=ABS(Istart)
5220  Istop=ABS(Istop)
5230  Val_last=Istart
5240  Rlast_range=LGT(Val_last)
5250  Nn_ranges=0
5260  IF Steps<2 THEN
5270    RETURN Istart*.0368  ! Nothing to do except 1st step
5280  END IF 
5290  !
5300  FOR I=0 TO Steps-1
5310    Val_curr=Istart*(Val_step^I)
5320    IF Val_curr>Lowest THEN
5330      Rlast_range=LGT(Val_last)
5340      Rcurr_range=LGT(Val_curr)
5350      IF INT(DROUND(-1*Rlast_range,7))<>INT(DROUND(-1*Rcurr_range,7)) THEN
5360          Lastval(Nn_ranges)=Val_last
5370          Nn_ranges=Nn_ranges+1
5380      END IF 
5390    END IF 
5400    Val_last=Val_curr
5410  NEXT I
5420  !
5430  IF Nn_ranges=0 THEN
5440    ! No range change have been done
5450    RETURN Istart*.0368
5460  END IF 
5470  !
5480  Val_compen=0
5490  FOR I=0 TO Nn_ranges-1
5500    ! calculate compensation data array index for the
5510    ! current where range change have done.
5520    Range_index=INT(DROUND(-1*LGT(Lastval(I)),7))-1
5530    Val_compen=Val_compen+Icompen(Range_index)*Lastval(I)
5540  NEXT I
5550  !
5560  RETURN Flag_sign*(Val_compen+Istart*.0368)
5570  FNEND
