Example #1
0
def voltage_deductions(in_pins, out_pins, logic_function, active_pin,
                       netlist_pins):
    """ Setup the Supply voltage and Logic Signal as per the logic function """

    in_pins = in_pins.replace(active_pin, '') + ' ' + active_pin

    pos_unate, pins_voltages = truths.Truths(in_pins.split(),
                                             [logic_function]).truth_table()
    # Setting up Power Supplies Voltages
    power_supplies = ['VPWR', 'VDD', 'VPB']
    gnd_supplies = ['VGND', 'VNB', 'VSS']
    power_str = '\n'.join([
        f'V{net} {net} 0 DC {VDD}' for net in power_supplies
        if net in netlist_pins
    ])
    gnd_str = '\n'.join([
        f'V{net} {net} 0 DC 0' for net in gnd_supplies if net in netlist_pins
    ])

    # Setting Up Signal Voltages
    active_pin_voltage = f'V{active_pin} {active_pin} 0 PULSE(0 {VDD} 0 0.01n 0.01n 50ns 100ns)'
    other_pins_voltage = []
    for net, logic in pins_voltages.items():
        if logic == 0:
            other_pins_voltage.append(f'V{net} {net} 0 DC 0')
        elif logic == 1:
            other_pins_voltage.append(f'V{net} {net} 0 DC {VDD}')

    other_pins_vol_str = '\n'.join(other_pins_voltage)

    power_supplies = power_str + '\n' + gnd_str
    signal_supplies = active_pin_voltage + '\n' + other_pins_vol_str

    return power_supplies, signal_supplies, pos_unate
def ngpost_timing(act_out_pin, func, signal_source, active_pin):
    """ Generate ngspice control commands for timing_harness"""
    in_pins = ' '.join(input_pins).replace(active_pin, '') + ' ' + active_pin
    working_func = convert_logical(func)
    pos_unate, pins_voltages = truths.Truths(in_pins.split(),
                                             [working_func]).truth_table()

    extra_alter_source = []
    missing_voltage_source = []

    for in_pin in pins_voltages.keys():
        if pins_voltages[in_pin] == 1: voltage = power_volts
        else: voltage = 0

        if in_pin in signal_sources.keys():
            extra_alter_source.append(
                f'alter @{signal_sources[in_pin]}[PWL] = [ 0 {voltage} ]')
        else:
            missing_voltage_source.append(f'V{in_pin} {in_pin} 0 DC 0')

    extra_alter_source_str = '\n'.join(extra_alter_source)
    # TODO: Shift this text based template to Jinja Templates if necessary
    control_str = \
    f"""let run  = 0 \n 
    shell rm {working_folder}/input_transition.txt
    shell rm {working_folder}/cell_fall.txt
    shell rm {working_folder}/cell_rise.txt
    shell rm {working_folder}/fall_transition.txt
    shell rm {working_folder}/rise_transition.txt
    foreach in_delay {input_transition_time}
    * Initiating Text Files in folder data
    echo "input_transition:$in_delay" >> {working_folder}/input_transition.txt
    echo "input_transition:$in_delay" >> {working_folder}/cell_fall.txt
    echo "input_transition:$in_delay" >> {working_folder}/cell_rise.txt
    echo "input_transition:$in_delay" >> {working_folder}/fall_transition.txt
    echo "input_transition:$in_delay" >> {working_folder}/rise_transition.txt
    * 1.666 to match the slew rate
    let actual_rtime = $in_delay*1.666   

    * Input Vector - Load Cap values(index2)
    foreach out_cap {output_caps}
        reset
        
        * Changing the V2 Supply Rise time as per the Input Rise Time vector
        alter @{signal_source}[pulse] = [ 0 {power_volts} 0 $&actual_rtime $&actual_rtime 50ns 100ns ]
        {extra_alter_source_str}
        * Changing the C1 value as per the foreach list
        alter CLOAD $out_cap
        
        tran 0.01n 300ns
        run

        reset
        * Verification of INPUT RISE TIME
        meas tran ts1 when v({active_pin})={float(power_volts)*0.8} RISE=1 
        meas tran ts2 when v({active_pin})={float(power_volts)*0.2} RISE=1
        meas tran ts3 when v({active_pin})={float(power_volts)*0.8} FALL=1 
        meas tran ts4 when v({active_pin})={float(power_volts)*0.2} FALL=1
        let RISE_IN_SLEW = (ts1-ts2)/{time_unit}
        let FALL_IN_SLEW = (ts4-ts3)/{time_unit}
        echo "actual_rise_slew:$&RISE_IN_SLEW" >> {working_folder}/input_transition.txt
        echo "actual_fall_slew:$&FALL_IN_SLEW" >> {working_folder}/input_transition.txt


        print run
        * Measuring Cell Fall Time @ 50% of VDD({float(power_volts)}V) 
        meas tran tinfall when v({active_pin})={float(power_volts)*0.5} FALL=1 
        meas tran tofall when v({act_out_pin})={float(power_volts)*0.5} FALL=1
        let cfall = (tofall-tinfall)/{time_unit}
        if abs(cfall)>20
            meas tran tinfall when v({active_pin})={float(power_volts)*0.5} Rise=1 
            meas tran tofall when v({act_out_pin})={float(power_volts)*0.5} FALL=1
            let cfall = abs(tofall-tinfall)/{time_unit}
        end
        print cfall
        echo "out_cap:$out_cap:cell_fall:$&cfall" >> {working_folder}/cell_fall.txt

        * Measuring Cell Rise Time @ 50% of VDD({float(power_volts)}V) 
        meas tran tinrise when v({active_pin})={float(power_volts)*0.5} RISE=1 
        meas tran torise when v({act_out_pin})={float(power_volts)*0.5} RISE=1
        let crise = (torise-tinrise)/{time_unit}
        if abs(crise)>20
            meas tran tinrise when v({active_pin})={float(power_volts)*0.5} FALL=1 
            meas tran torise when v({act_out_pin})={float(power_volts)*0.5} RISE=1
            let crise = abs(tinrise-torise)/{time_unit}
        end
        print crise
        echo "out_cap:$out_cap:cell_rise:$&crise" >> {working_folder}/cell_rise.txt

        * Measuring Fall transition Time @ 80-20% of VDD({float(power_volts)}V) 
        meas tran ft1 when v({act_out_pin})={float(power_volts)*0.8} FALL=2 
        meas tran ft2 when v({act_out_pin})={float(power_volts)*0.2} FALL=2
        let fall_tran = (ft2-ft1)/{time_unit}
        print fall_tran
        echo "out_cap:$out_cap:fall_transition:$&fall_tran" >> {working_folder}/fall_transition.txt
        
        * Measuring Rise transition Time @ 20-80% of VDD({float(power_volts)}V) 
        meas tran rt1 when v({act_out_pin})={float(power_volts)*0.8} RISE=2 
        meas tran rt2 when v({act_out_pin})={float(power_volts)*0.2} RISE=2
        let rise_tran = ((rt1-rt2)/{time_unit})
        print rise_tran
        echo "out_cap:$out_cap:rise_transition:$&rise_tran" >> {working_folder}/rise_transition.txt
        let run = run + 1
        * plot a y
    end
    end"""

    return control_str