Ejemplo n.º 1
0
def SetOxideParameters(device, region):
    '''
      Sets physical parameters
    '''
    SetUniversalParameters(device, region)
    ds.set_parameter(
        device=device,
        region=region,
        name="Permittivity",
        value=3.9 *
        ds.get_parameter(device=device, region=region, name='Permittivity_0'))
Ejemplo n.º 2
0
def simulate_charge(device, contact, equation, solver_params):
    #charge_factor=1e7 #from F/cm^2 to fF/um^2
    dv = 0.001
    v1 = ds.get_parameter(device=device, name=GetContactBiasName(contact))
    q1 = ds.get_contact_charge(device=device,
                               contact=contact,
                               equation="PotentialEquation")
    v2 = v1 + dv
    ds.set_parameter(name=GetContactBiasName(contact), value=v2)
    ds.solve(**solver_params)
    q2 = ds.get_contact_charge(device=device,
                               contact=contact,
                               equation="PotentialEquation")
    return (v1, (charge_factor * (q2 - q1) / dv))
Ejemplo n.º 3
0
def rampparam(device, region, param, stop, step_size, min_step, solver_params=None, callback=None):
    '''
      Ramps param with assignable callback function
    '''
    start_param=ds.get_parameter(device=device, region=region, name=param)
    if (start_param < stop):
        step_sign=1
    else:
        step_sign=-1
    last_param=start_param
    while(abs(last_param - stop) > min_step):
        print("last end %e %e" % (last_param, stop))
        next_param=last_param + step_sign * step_size
        if next_param < stop:
            next_step_sign=1
        else:
            next_step_sign=-1

        if next_step_sign != step_sign:
            next_param=stop
            print("setting to last param %e" % (stop))
            print("setting next param %e" % (next_param))
        ds.set_parameter(device=device, region=region, name=param, value=next_param)
        try:
            ds.solve(**solver_params)
        except ds.error as msg:
            if str(msg).find("Convergence failure") != 0:
                raise
            ds.set_parameter(device=device, region=region, name=param, value=last_param)
            step_size *= 0.5
            print("setting new step size %e" % (step_size))
            #raise NameError("STOP")
            if step_size < min_step:
                raise RuntimeError("Min step size too small")
            continue
        last_param=next_param
        if callback:
            callback()
Ejemplo n.º 4
0

def format_value(value):
    if isinstance(value, str):
        ret = '"%s"' % value
    elif isinstance(value, float):
        ret = "%g" % value
    else:
        ret = value
    return ret


with open("mos_2d_params.py", "w") as ofh:
    ofh.write('import devsim\n')
    for p in devsim.get_parameter_list():
        v = format_value(devsim.get_parameter(name=p))
        ofh.write('devsim.set_parameter(name="%s", value=%s)\n' % (p, v))
    for i in devsim.get_device_list():
        for p in devsim.get_parameter_list(device=i):
            v = format_value(devsim.get_parameter(device=i, name=p))
            ofh.write(
                'devsim.set_parameter(device="%s", name="%s", value=%s)\n' %
                (i, p, v))

    for i in devsim.get_device_list():
        for j in devsim.get_region_list(device=i):
            for p in devsim.get_parameter_list(device=i, region=j):
                v = format_value(
                    devsim.get_parameter(device=i, region=j, name=p))
                ofh.write(
                    'devsim.set_parameter(device="%s", region="%s", name="%s", value=%s)\n'
Ejemplo n.º 5
0
def createDriftDiffusion(device, region):
    for name, equation in (
        ("PotentialNodeCharge"          , "-ElectronCharge*(Holes -Electrons + NetDoping)"),
      ("PotentialNodeCharge:Electrons", "+ElectronCharge"),
      ("PotentialNodeCharge:Holes"    , "-ElectronCharge"),
    ):
        devsim.node_model(device=device, region=region, name=name, equation=equation)

    devsim.equation(device=device, region=region, name="PotentialEquation", variable_name="Potential", node_model="PotentialNodeCharge",
                    element_model="PotentialEdgeFlux", variable_update="log_damp")

    for name, equation in (
        ("vdiff"              , "(Potential@n0 - Potential@n1)/V_t"),
      ("vdiff:Potential@n0" , "V_t^(-1)"),
      ("vdiff:Potential@n1" , "-V_t^(-1)"),
      ("Bern01"             , "B(vdiff)"),
      ("Bern01:Potential@n0", "dBdx(vdiff)*vdiff:Potential@n0"),
      ("Bern01:Potential@n1", "dBdx(vdiff)*vdiff:Potential@n1"),
      ("Bern10"             , "Bern01 + vdiff"),
      ("Bern10:Potential@n0", "Bern01:Potential@n0 + vdiff:Potential@n0"),
      ("Bern10:Potential@n1", "Bern01:Potential@n1 + vdiff:Potential@n1"),
    ):
        devsim.edge_model(device=device, region=region, name=name, equation=equation)

    Jn      ="ElectronCharge*mu_n*EdgeInverseLength*V_t*(Electrons@n1*Bern10 - Electrons@n0*Bern01)"
    dJndn0  ="simplify(diff( %s, Electrons@n0))" % Jn
    dJndn1  ="simplify(diff( %s, Electrons@n1))" % Jn
    dJndpot0="simplify(diff( %s, Potential@n0))" % Jn
    dJndpot1="simplify(diff( %s, Potential@n1))" % Jn
    for name, equation in (
        ("ElectronCurrent"             , Jn),
      ("ElectronCurrent:Electrons@n0", dJndn0),
      ("ElectronCurrent:Electrons@n1", dJndn1),
      ("ElectronCurrent:Potential@n0", dJndpot0),
      ("ElectronCurrent:Potential@n1", dJndpot1),
    ):
        devsim.edge_model(device=device, region=region, name=name, equation=equation)

    Jp      ="-ElectronCharge*mu_p*EdgeInverseLength*V_t*(Holes@n1*Bern01 - Holes@n0*Bern10)"
    dJpdp0  ="simplify(diff(%s, Holes@n0))" % Jp
    dJpdp1  ="simplify(diff(%s, Holes@n1))" % Jp
    dJpdpot0="simplify(diff(%s, Potential@n0))" % Jp
    dJpdpot1="simplify(diff(%s, Potential@n1))" % Jp

    for name, equation in (
        ("HoleCurrent"             , Jp),
      ("HoleCurrent:Holes@n0"    , dJpdp0),
      ("HoleCurrent:Holes@n1"    , dJpdp1),
      ("HoleCurrent:Potential@n0", dJpdpot0),
      ("HoleCurrent:Potential@n1", dJpdpot1),
    ):
        devsim.edge_model(device=device, region=region, name=name, equation=equation)

    NCharge="-ElectronCharge * Electrons"
    dNChargedn="-ElectronCharge"
    for name, equation in (
        ("NCharge",           NCharge),
      ("NCharge:Electrons", dNChargedn),
    ):
        devsim.node_model(device=device, region=region, name=name, equation=equation)

    PCharge="-ElectronCharge * Holes"
    dPChargedp="-ElectronCharge"
    for name, equation in (
        ("PCharge", PCharge),
      ("PCharge:Holes", dPChargedp),
    ):
        devsim.node_model(device=device, region=region, name=name, equation=equation)


    ni=devsim.get_parameter(device=device, region=region, name="n_i")
    for name, value in (
        ("n1", ni),
      ("p1", ni),
      ("taun", 1e-5),
      ("taup", 1e-5),
    ):
        devsim.set_parameter(device=device, region=region, name=name, value=value)

    USRH="-ElectronCharge*(Electrons*Holes - n_i^2)/(taup*(Electrons + n1) + taun*(Holes + p1))"
    dUSRHdn="simplify(diff($USRH, Electrons))"
    dUSRHdp="simplify(diff($USRH, Holes))"
    for name, equation in (
        ("USRH", USRH),
      ("USRH:Electrons", dUSRHdn),
      ("USRH:Holes", dUSRHdp),
    ):
        devsim.node_model(device=device, region=region, name=name, equation=equation)

    devsim.equation(device=device, region=region, name="ElectronContinuityEquation", variable_name="Electrons",
                    edge_model="ElectronCurrent", variable_update="positive",
                    time_node_model="NCharge", node_model="USRH")

    devsim.equation(device=device, region=region, name="HoleContinuityEquation", variable_name="Holes",
                    edge_model="HoleCurrent", variable_update="positive",
                    time_node_model="PCharge", node_model="USRH")
Ejemplo n.º 6
0
def createSiliconDriftDiffusion(device, region):
    for name, equation in (
        ("PotentialNodeCharge",
         "-ElectronCharge*(Holes -Electrons + NetDoping)"),
        ("PotentialNodeCharge:Electrons", "+ElectronCharge"),
        ("PotentialNodeCharge:Holes", "-ElectronCharge"),
    ):
        devsim.node_model(device=device,
                          region=region,
                          name=name,
                          equation=equation)

    devsim.equation(device=device,
                    region=region,
                    name="PotentialEquation",
                    variable_name="Potential",
                    node_model="PotentialNodeCharge",
                    edge_model="PotentialEdgeFlux",
                    variable_update="log_damp")

    createBernoulli(device, region)
    createElectronCurrent(device, region)
    createHoleCurrent(device, region)

    NCharge = "-ElectronCharge * Electrons"
    dNChargedn = "-ElectronCharge"
    devsim.node_model(device=device,
                      region=region,
                      name="NCharge",
                      equation=NCharge)
    devsim.node_model(device=device,
                      region=region,
                      name="NCharge:Electrons",
                      equation=dNChargedn)

    PCharge = "-ElectronCharge * Holes"
    dPChargedp = "-ElectronCharge"
    devsim.node_model(device=device,
                      region=region,
                      name="PCharge",
                      equation=PCharge)
    devsim.node_model(device=device,
                      region=region,
                      name="PCharge:Holes",
                      equation=dPChargedp)

    ni = devsim.get_parameter(device=device, region=region, name="n_i")
    devsim.set_parameter(device=device, region=region, name="n1", value=ni)
    devsim.set_parameter(device=device, region=region, name="p1", value=ni)
    devsim.set_parameter(device=device, region=region, name="taun", value=1e-5)
    devsim.set_parameter(device=device, region=region, name="taup", value=1e-5)

    USRH = "-ElectronCharge*(Electrons*Holes - n_i^2)/(taup*(Electrons + n1) + taun*(Holes + p1))"
    dUSRHdn = "simplify(diff(%s, Electrons))" % USRH
    dUSRHdp = "simplify(diff(%s, Holes))" % USRH
    devsim.node_model(device=device, region=region, name="USRH", equation=USRH)
    devsim.node_model(device=device,
                      region=region,
                      name="USRH:Electrons",
                      equation=dUSRHdn)
    devsim.node_model(device=device,
                      region=region,
                      name="USRH:Holes",
                      equation=dUSRHdp)

    devsim.equation(device=device,
                    region=region,
                    name="ElectronContinuityEquation",
                    variable_name="Electrons",
                    edge_model="ElectronCurrent",
                    variable_update="positive",
                    time_node_model="NCharge",
                    node_model="USRH")

    devsim.equation(device=device,
                    region=region,
                    name="HoleContinuityEquation",
                    variable_name="Holes",
                    edge_model="HoleCurrent",
                    variable_update="positive",
                    time_node_model="PCharge",
                    node_model="USRH")
Ejemplo n.º 7
0
devsim.set_node_values(device=device, region="bulk", name="Holes",     init_from="IntrinsicHoles")
createSiliconDriftDiffusion(device, "bulk")


createSiliconDriftDiffusionAtContact(device, "bulk", "drain")
createSiliconDriftDiffusionAtContact(device, "bulk", "source")
createSiliconDriftDiffusionAtContact(device, "bulk", "body")

devsim.solve(type="dc", absolute_error=1.0e30, relative_error=1e-5, maximum_iterations=30)

devsim.element_from_edge_model(edge_model="ElectricField", device=device, region="bulk")

devsim.write_devices(file="mos_2d_dd.msh", type="devsim")

with open("mos_2d_params.py", "w", encoding="utf-8") as ofh:
    ofh.write('import devsim\n')
    for p in devsim.get_parameter_list():
        v=repr(devsim.get_parameter(name=p))
        ofh.write('devsim.set_parameter(name="%s", value=%s)\n' % (p, v))
    for i in devsim.get_device_list():
        for p in devsim.get_parameter_list(device=i):
            v=repr(devsim.get_parameter(device=i, name=p))
            ofh.write('devsim.set_parameter(device="%s", name="%s", value=%s)\n' % (i, p, v))

    for i in devsim.get_device_list():
        for j in devsim.get_region_list(device=i):
            for p in devsim.get_parameter_list(device=i, region=j):
                v=repr(devsim.get_parameter(device=i, region=j, name=p))
                ofh.write('devsim.set_parameter(device="%s", region="%s", name="%s", value=%s)\n' % (i, j, p, v))

Ejemplo n.º 8
0
# Copyright 2020 Devsim LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

####
#### info.py
#### print features for this build
####
import devsim
print(devsim.get_parameter(name="info"))

Ejemplo n.º 9
0
def SetSiliconParameters(device, region):
    '''
      Sets Silicon device parameters on the specified region.
    '''

    SetUniversalParameters(device, region)

    ##D. B. M. Klaassen, J. W. Slotboom, and H. C. de Graaff, "Unified apparent bandgap narrowing in n- and p-type Silicon," Solid-State Electronics, vol. 35, no. 2, pp. 125-29, 1992.
    par = {
        'Permittivity':
        11.1 *
        ds.get_parameter(device=device, region=region, name='Permittivity_0'),
        'NC300':
        2.8e19,  # '1/cm^3'
        'NV300':
        3.1e19,  # '1/cm^3'
        'EG300':
        1.12,  # 'eV'
        'EGALPH':
        2.73e-4,  # 'eV/K'
        'EGBETA':
        0,  # 'K'
        'Affinity':
        4.05,  # 'K'
        # Canali model
        'BETAN0':
        2.57e-2,  # '1'
        'BETANE':
        0.66,  # '1'
        'BETAP0':
        0.46,  # '1'
        'BETAPE':
        0.17,  # '1'
        'VSATN0':
        1.43e9,
        'VSATNE':
        -0.87,
        'VSATP0':
        1.62e8,
        'VSATPE':
        -0.52,
        # Arora model
        'MUMN':
        88,
        'MUMEN':
        -0.57,
        'MU0N':
        7.4e8,
        'MU0EN':
        -2.33,
        'NREFN':
        1.26e17,
        'NREFNE':
        2.4,
        'ALPHA0N':
        0.88,
        'ALPHAEN':
        -0.146,
        'MUMP':
        54.3,
        'MUMEP':
        -0.57,
        'MU0P':
        1.36e8,
        'MU0EP':
        -2.23,
        'NREFP':
        2.35e17,
        'NREFPE':
        2.4,
        'ALPHA0P':
        0.88,
        'ALPHAEP':
        -0.146,
        # SRH
        "taun":
        1e-5,
        "taup":
        1e-5,
        "n1":
        1e10,
        "p1":
        1e10,
        # TEMP
        #    "T" : 300
    }

    for k, v in par.items():
        ds.set_parameter(device=device, region=region, name=k, value=v)