Python a simulácia elektronických obvodov

2. 5. 2018
Doba čtení: 14 minut

Sdílet

V príspevku ukážeme možnosť využitia Pythonu pre tvorbu prostredia na riešenie simulačných úloh z oblasti elektroniky. Vlastnosti kooperácie programov gschem, gnetlist, ngspice a matplotlib ukážeme na príkladoch.

Úvod

Simulácie elektronických obvodov počítačom sú zviazané s vývojom výpočtovej techniky od jej samého začiatku – od prvých simulácií diferenciálnych rovníc na analógových počítačoch až po súčasné rozsiahle sofistikované simulačné nástroje integrované do vývojových prostredí. Pre bežnú prácu vývojára elektronických obvodov je dostupné množstvo komerčných alebo voľných aplikácií, často s podporou súčiastkovej základne výrobcov, napríklad LTSpice, z oblasti open-source určenej pre Linux môžeme spomenúť:

a ďaľšie. Prevažná väčšina simulačných nástrojov vychádza z klasického viac-menej priemyselného štandardu Spice3f5 doplnených ďaľšími nadstavbami, ako sú databázy modelov, blokové simulácie, rozšírenie zapojení o parazitné komponenty z návrhu plošných spojov, mikropáskových komponentov a pod.

Predmetom tohoto príspevku je tvorba jednoduchého simulačného prostredia pre riešenie špecializovaných úloh z oblasti simulácií elektronických obvodov pomocou skriptov v jazyku Python. Pomocu jednoduchých skriptov sú previazané programy z balíka pre návrh elektronických obvodov gEDA (gschem, gnetlist), simulačný engine (Ngspice, Xyce) a grafický výstup (matplotlib). Príspevok je určený primárne pre pokročilejších uživateľov oboznámených s princípmi a vlastnosťami simulačných nástrojov, pre bežné použitie odporúčame použitie vhodného kompaktného simulačného prostredia, v Linuxe napr. spomenutý vynikajúci Qucs.

Programová podpora simulácií v Linuxe

Štandardné elektronické simulácie sú v Linuxe možné aj v populárnych prostrediach ako sú Kicad alebo gEDA, v tomto príspevku sa budeme ale venovať špecifickým prípadom, kedy

  • proces simulácie je potrebné riadiť nejakým skriptom a priebežne modifikovať parametre simulačného modelu alebo aj celej simulácie (parametrická simulácia, optimalizácia)
  • v simulovanom obvode je potrebné použiť a/alebo naprogramovať špeciálny komponent, nedostupný v štandardnej knižnici (vlastný návrh, parametrický, nelineárny, nestacionárny, vlastnosti závisia od externých dát, naviazaný na simuláciu v inom programe a pod.
  • výsledky simulácie potrebujeme dodatočne spracovať (ukladať do databázy, zobraziť pomocou iných programov, exportovať do špecifických formátov a pod.)

Simulácia obvodov je zvyčajne realizovaná v samostatnom programovom module, ktorý spracuje vstupný netlist, popisujúci zapojenie simulovaného obvodu a vygeneruje súbor s dátami simulácie. Pre Linux je dostupných niekoľko simulačných nástrojov (gnucap, eispice, Ngspice, spiceopus, Xyce), niektoré umožňujú prácu v interaktívnom móde, použitie skriptov a zvyčajne obsahujú aj podporu jednoduchého grafického výstupu. V tomto príspevku ukážeme použitie Pythonu pre riadenie simulácie v simulačnom engine Ngspice resp. Xyce a spracovanie výsledkov simulácie v knižnici matplotlib. S podobnou koncepciou programovej podpory simulácií skriptami v Pythone sa môžeme stretnúť vo viacerých projektoch (PySpice, PyOPUS, ahkab), gSim je založený na minimalistickej koncepcii v súlade so zásadami Unixu / Linuxu.

Programové riadenie simulácie

Programové riadenie simulácie ukážeme na jednoducho príklade parametrickej simulácie. Elementárny RC obvod chceme simulovať vo zvolenom rozsahu parametrov komponentov R a C, Spice k tomuto poskytuje direktívu .PARAMS. V editore gSchem je zapojenie obvodu s definovanými parametrami zobrazené na obrázku:

Vlastnú simuláciu môžeme spustiť štandardným postupom, vygenerovaním netlistu, spustením simulátora v interaktívnom alebo povelovom móde a vykreslením výsledkov. Pomocou Pythonu si môžeme celý postup zjednodušiť:

    from gsim import *                 # skript pre riadenie simulacie

    data, desc = gs('demo_01.sch')     # spustenie simulacie, vrati slovnik s datami
                                       # a metadata (desc) popisujuce simulaciu
    f = data['frequency'].real         # vybratie pozadovanych dat zo slovnika
    v = abs(data['v(out)'])            # data v AC simulacii su komplexne veliciny
    p = angle(data['v(out)']
                                       # ... spracovanie, vykreslenie dat

Komplikovanejšia situácia nastane, ak potrebujeme simuláciu opakovane spúštať s hodnotami parametrov z nejakého rozsahu, napríklad ak potrebujeme zapojenie optimalizovať na základe priebežných výsledkov simulácie. V našom prípade chceme zobraziť charakteristiky obvodu pre zmenu hodnoty odporu R1 v rozsahu 100k až 800k. V niektorých simulačných prostrediach (Qucs) je toto možné pomocou voľby PARAMETER-SWEEP. V Pythone si pomôžeme programovou zmenou parametrov obvodu v cykle. Program je trochu dlhší, ale jeho podstatnú časť zaberá zobrazenie výsledkov na grafe:

    from pylab import *
    from gsim import *

    graph=[subplot(211),subplot(212)]
    g=gSim('demo_01.sch')
    g.netlist()

    for i in arange(100e3, 800e3, 100e3):
        g.setPAR('R',i)
        data, desc = g.sim()

        f = data['frequency'].real
        v = abs(data['v(out)'])
        p = angle(data['v(out)'])

        graph[0].semilogx(f,v, label=str('%3.0fk' %(i/1e3)))
        graph[1].semilogx(f,p, label=str('%3.0fk' %(i/1e3)))

    graph[0].grid()
    graph[0].legend()
    graph[0].set_ylabel('Ampl |K|')

    graph[1].grid()
    graph[1].legend()
    graph[1].set_xlabel('f [Hz]')
    graph[1].set_ylabel('Phase [rad]')
    show()

Štruktúra skriptu gSim

Z vyššie uvedeného príkladu je zrejmý princíp a štruktúra použitia programového riadenia simulácie v Pythone. Skript funguje ako jednoduché lepidlo medzi samostatnými programami, ktoré si vymieňajú dáta prostredníctvom súborov. K samotnej simulácii je v Linuxe potrebné mať nainštalované nasledujúce programy:

  • Python 3.x, SciPy/NumPy, Matplotlib – štandardné verzie z repozitárov
  • ngSpice-27, pre Linux je potrebné skompilovať zo zdrojového kódu podľa postupu uvedenom v súbore INSTALL. Pre podporu blokových simulácií je vhodné kompiláciu konfigurovať s voľbou --enable-xspice.
  • gEDA 1.8.2, táto verzia je štandardne dostupná v repozitároch

Vlastný skript, príklady použitia ako aj základné simulačné knižnice sú dostupné na GitHube . Po rozbalení obsahuje archív adresáre

  • ./py  – skripty gsim pre Python 3.x
  • ./sym  – knižnice simulačných komponentov
  • ./model  – niekoľko vybraných SPICE modelov bežných komponentov (tranzistory, diódy …)
  • ./demo-*  – testovacie príklady pre overenie funkčnosti skriptov
  • ./template  – pripravené vzory pre základné typy simulácií

Samotný proces simulácie je v princípe jednoduchý, najskôr si vytvoríme pracovný adresár a skopírujeme do neho obsah niektorého zo zvoleného typu simulácií z adresáru ./template. V adresári sa nachádzajú súbory colormap  – môžete si upraviť farebné zobrazenie zapojenia, gafrc  – obsahuje cesty k symbolom v adresari ./sym, ktoré sa zobrazia pri výbere v editore gSchem a súbor gschemrc  – môžete parametrizovať parametre editora. Vlastnosti gschem môžete samozrejme nastaviť aj globálne, podrobnosti sú uvedené v dokumentácii.

Počas simulácie skripty vytvárajú pomocné súbory (log, netlisty a pod.), ktoré je možné použiť pre prípadnú kontrolu simulácie, tieto sa ukladajú do adresára  ./temp.

Vytvorenie zapojenia

V editore gSchem vytvoríme zapojenie, ktoré chceme simulovať. Použijeme knižnice určené pre simulácie, tieto obsahujú generické komponenty, ktoré v editore parametrizujeme pomocou hodnoty atribútu value. Reálne komponenty majú zvyčajne iné zapojenie a niekedy iný počet vývodov ako simulačné, napr. výkonové tranzistory majú kolektor vyvedený na dva terminály – TIP127, 1-NB, 2,4-NC, 3-NE, model bipolárneho tranzistora v SPICE má terminály v poradí NC, NB, NE, toto poradie rešpektujú aj modely komponentov dodávané výrobcami.

Poznámka: Je samozrejme možné používať v simulácii aj reprezentácie reálnych komponentov, toto ale zo sebou prináša potrebu udržiavať konzistenciu medzi symbolom – grafickou reprezentáciou komponentu, jeho terminálmi (meno, číslo pinu), simulačným modelom (vstupy a ich poradie) a prípadne aj púzdrom komponentu. Toto sa v praxi ukázalo ako potenciálny zdroj chýb, jednoduchšie a flexibilnejšie je v simulácii použiť generické komponenty a modely konkrétnych typov komponentov definovať v atribúte value.

V parametroch komponentov a zapojení je potrebné dodržiavať konvencie podľa dokumentácie k Spice napr. Qxxxx ako referenciu pre BJT tranzistor, Vxxxx pre napäťové zdroje a pod. To isté platí aj pre jednotky, rezistor s atribútom value=1M5 je 0.0015 Ohm, value=1.5MEG je 1.5*106 Ohm.

Ak potrebujeme nejakú veličinu použiť v simulácii ako parameter, t.j. budeme ju substituovať hodnotou v priamo v zapojení pomocou príkazu .PARAM alebo v rámci pythonovského skriptu, v zapojení obvodu deklarujeme parameter ako value={meno_parametra} (v zložených zátvorkách). V zapojení zároveň môžeme pomenovať aj spoje pomocou atribútu netname=meno_spoja.Tieto mená reprezentujú uzol zapojenia a môžeme ich použiť v odkazoch na veličiny s ktorými sú zviazané.

Príklad zapojenia s definovanými parametrami je zobrazený na nasledujúcom obrázku, zapojenie obsahuje pomenované spoje – priamo atribútom netname spoja (filter) alebo pomocou terminálov (VF, AM, NF). Pri použití symbolu terminálu a jeho pomenovaní editor gschem automaticky označí týmto menom aj prislúchajúci spoj. Spoje s rovnakým menom sú považované za jeden spoj v rámci celého zapojenia. Zapojenie na obrázku obsahuje okrem štandardných Spice komponentov aj blokové komponenty z rozšírenia XSPICE (A1, A3, A4).

Inicializácia simulácie

Simulačný proces začína vytvorením objektu simulácie, ktorému odovzdáme meno súboru, ktorý sme vytvorili v editore zapojení. Pri načítaní súboru sa kontroluje integrita zapojenia, duplicitné alebo nedefinované referencie na komponenty schémy a vytvoria sa zoznamy komponentov a prepojení. Po kontrole sa vygeneruje pomocou programu gnetlist (súčasť balíku gEDA) základný netlist obvodu. Tento sa na základe hodnôt atribútov komponentov modifikuje a dopĺňa napr. o cesty k modelom komponentov a pod.

import sys
sys.path.append('../../py') # nastavenie cesty k gsim

from gsim import *

g=gSim('demo_003.sch')      # nacitanie a kontrola zapojenia
g.netlist()                 # vygenerovanie a modifikacia netlistu

Spustenie simulácie

Vygenerovaný a modifikovaný netlist sa odovzdá simulátoru, ktorý vygeneruje binárny súbor s výsledkami simulácie. Ak sme v zapojení použili symbolické parametre, musíme im definovať hodnotu, táto sa pred simuláciou doplnia v netliste. Skript po úspešnej simulácii preparsuje binárny súbor ( *.raw)s výsledkami a vráti slovník hodnôt, kde klúčom je fyzikálna veličina v tvare reťazca (prúd, napätie …) v uzle zapojenia alebo zdroja (platí pre Ngspice, Xyce používa priamo mená uzlov). Druhou návratovou hodnotou sú metadáta (mená, jednotky a pod.) k zapojeniu a simulácii.

                        # inicializacia parametrov
g.setPAR('am', 0.5)     # hlbka modulacie
g.setPAR('fm', 1000.0)  # modulacna frekvencia
g.setPAR('fc', 100e3)   # nosna frekvencia

data, desc = g.sim()    # simulacia, vygenerovanie binarneho suboru *.raw
                          # data - slovnik so vysledkami simulacie
                          # desc - metadata k vysledkom simulacie, napr.
                          #        zoznam mien premennych, pouzite jednotky a pod.

Zo slovníka hodnôt si potrebné polia s dátami vyberieme pomocou štandardných operácií pre prácu zo slovníkmi a ďalej s nimi pracujeme ako s akoukoľvek inou premennou v Pythone. Pomocou zmeny vybraných parametrov môžeme opakovane spúšťať proces simulácie a napr. na základe výsledkov optimalizovať parametre zapojenia.

Zobrazenie výsledkov

Pre zobrazenie výsledkov simulácie môžeme použiť akúkoľvek knižnicu pre grafický výstup, napr. Matplotlib, prípadne po konverzii dát môžeme použiť špecializované programy pre zobrazenie dát, ako sú napr. gnuplot, GTKWave, Paraview, Veusz a pod.

    t = data['time']*1e3        # extrakcia dat zo slovnika
    vf = data['v(vf)']          # podla mien spojov
    vfilt = data['v(filter)']
    nf = data['v(nf)']

    plot(t, vf, alpha=0.5, label='VF')
    plot(t, vfilt, label='RC')
    plot(t, nf, label='NF')
    xlim(0,t[-1])
    xlabel('Time [ms]')
    ylabel('V')
    legend()
    grid()
    show()

Výsledok simulácie detekcie AM modulovaného a zašumeného signálu.

Použitie rozšírenia XSPICE

XSPICE je užitočné rozšírenie simulátora ngspice o simuláciu zapojení na systémovej úrovni pomocou blokov popísaných matematickým vzťahom. Obsahuje bloky pre analógovú simuláciu, ako aj digitálne bloky pre udalosťami riadenú simuláciu. XSPICE je možné rozširovať aj o vlastné bloky v jazyku C a integrovať ich do simulačného prostredia. Podrobný popis rozšírenia XSPICE je uvedený v dokumentácii k ngspice. Pretože bloky XSPICE používajú inú syntax netlistu ako štandardné Spice, v skripte gSim je implementovaný jednoduchý parser, ktorý expanduje Spice popis bloku do XSPICE. Princíp spracovania netlistu skriptom ukážeme na nasledujúcom jednoduchom príklade:

Generátor netlistu vytvorí zo zapojenia štandardný netlist, ktorého časť vyzerá nasledujúco:

    A1 1 2 S SUMMER_2
    V2 2 0 DC 2V
    V1 1 0 DC 1V
    R1 0 S 1k

Sumátor signálov v XSPICE je pomerene komplexný komponent s možnosťou nastavenia offsetov a zosilnení pre všetky vstupy a výstup a vo všeobecnosti môže mať ľubovolný počet vstupov. Netlist upravený skriptom pre 2-vstupovú verziu komponentu má tvar:

    A1 [1 2] S SUMMER_2_A1
    .MODEL SUMMER_2_A1 SUMMER (
       + in_offset=[ 0.0 0.0]
       + in_gain=[ 1.0 1.0]
       + out_gain=1.0
       + out_offset=0.0)

    V2 2 0 DC 2V
    V1 1 0 DC 1V
    R1 0 S 1k

Súčasťou skriptu gSim je implementácia grafickej reprezentácie a príslušné generátory pre najčastejšie používané typy komponentov definovaných v XSPICE. Nie je samozrejme žiaden problém vytvoriť si vlastnú verziu komponentu a do skriptu doplniť príslušný generátor. Nasledujúce obrázky zobrazujú prehľad komponentov pre analógovú a digitálnu (udalosťami riadenú) simuláciu.

V simulovanom obvode môžu byť použité súčasne oba typy komponentov, len analógovú a digitálnu časť je potrebné oddeliť špeciálnym komponentom, ktorý prevádza napäťové úrovne na logické hodnoty a naopak. Použitie hybridnej simulácie s analógovými a digitálnymi komponentami je ukázané v príkladoch priložených k distribúcii gSim.

Simulačný engine Xyce neobsahuje štandardne blokové komponenty, aké sú v rozšírení XSPICE použitom v Ngspice, umožnuje ale jednoduchú tvorbu vlastných komponentov založených na matematickej reprezentácii pomocou ABM (Analog Behavioral Modeling). Komponenty s ABM môžu byť parametrické dvojpóly alebo z nich môžeme vyskladať vlastné bloky (ako X – Subcircuits), podrobnosti nájde čitateľ v dokumentácii.

Príklady použitia

Prezentované príklady použitia sú výberom z demonštračných príkladov v distribúcii skriptu gSim.

Štandardná simulácia

Ukážka jednoduchej AC simulácie elementárnych RC obvodov. Skript je použitý len na kontrolu integrity zapojenia, parametre simulácie sú definované v zapojení pomocou Spice príkazov.

Výsledok simulácie

Parametrická simulácia

Potrebujeme verifikovať model tranzistoru BC549C podľa katalógových údajov výrobcu. Pre orientačnú validáciu si zobrazíme sieť výstupných charakteristík tranzistora Ic = f(Vce, Ib). Podľa parametrov výrobcu (ON Semiconductor, katalogový list BC549C) by mal byť pri DC hodnotách Ic = 2.0 mA a Vce = 5.0 V prúdový zosilňovací činiteľ hfe v rozsahu hodnôt 420 … 800. Pre simuláciu charkteristík použijeme nasledujúce jednoduché zapojenie:

Pre simuláciu použijeme nasledujúci program:

    import sys
    sys.path.append('../../py')
    import pylab as plt
    from gsim import *

    g=gsim('100_dc_char.sch')
    g.netlist()

    for i in arange(10e-6, 1e-7, -1e-6):
        g.setPAR('IB',i)
        data, param = g.sim()
        ic = -data['i(v1)']*1e3
        vc = data['v(c)']
        plt.plot(vc,ic,'o-',markevery=40,
                 label=r'$'+str('%3.0f' %(i*1e6) )+'\, \mu A$')

    plt.grid(True)
    leg = plt.legend(loc='center right')
    leg.get_frame().set_alpha(0.5)
    plt.ylim(ymin=0.0)
    plt.xlim(0, 6.5)
    plt.xlabel(r'$V_c\,[V]$',fontsize=14)
    plt.ylabel(r'$I_c\,[mA]$',fontsize=14)
    plt.title(r'$I_c=f(I_b, V_c)$',fontsize=14)
    plt.savefig('param_cb.png')
    plt.show()

gSim obsahuje metódy pre úpravu parametrov vygenerovaného netlistu (zmena typu simulácie a jej parametrov, doplnenie a zmazanie komponentov a pod.). Pri potrebe simulácie zapojenia rôznymi typmi simulácii je niekedy jednoduchšie meniť parametre nelistu programovo, ako ich opakovane editovať v grafickom editore.

V našom prípade zo siete simulovaných výstupných charakteristík môžeme určiť, že bázovom prúde tranzistora 4 uA a napätí Vce = 5.0 V bol kolektorový prúd Ic = 2.18 mA, z toho vyplýva, že hodnota prúdového zosilňovacieho činiteľa hfe = 540 spadá do rozsahu stanoveného výrobcom. Vzhľadom k tomu, že na internete sa nachádzajú rôzne knižnice modelov komponentov často neznámeho pôvodu, je vhodné model pred použitím podobným vhodným spôsobom preveriť a porovnať s údajmi výrobcu.

Pretože dáta už máme v prostredí Pythonu, môžeme s nimi pracovať podľa vlastných predstáv, na nasledujúcom obrázku je avantgardnejšie zobrazenie simulovaných výstupných charakteristík v programe ParaView.

Poznámka: Z vyššie uvedených jednoduchých príkladov ešte nemusí byť užitočnosť riadenia a spracovania výsledkov simulácie skriptom zrejmá, táto sa prejaví najmä vtedy, ak potrebujeme v obvode meniť viacej parametrov. Simulačné enginy poskytujú možnosť PARAM-SWEEP s možnosťou súčasnej zmeny jedného alebo viacerých parametrov, výsledky sú ale exportované (príkaz .PRINT) do textového súboru, z ktorého ich musíme pre ďaľšie spracovanie znova načítať. V Pythone si poradie a formu úpravy parametrov obvodu určujeme sami.

XSPICE simulácia

Simulácia pomocou blokov reprezentujúcich matematické operácie umožňuje pristupovať k riešeniu komplexných problémov podobným postupom, aký bol používaný v pradávnych dobách analógových počítačov. Riešenie sústavy diferenciálnych rovníc v integrálnom tvare môžeme jednoducho ‚poskladať‘ z integrátorov, sumátorov a násobičiek. Na nasledujúcom obrázku je uvedené zapojenie zobrazujúce riešenie sústavy diferenciálnych rovníc prvého rádu pre Rösslerov attractor v integrálnom tvare.

„Zapojenie“ sústavy rovníc

Výsledok simulácie, časový a parametrický záznam

Hybridná simulácia

Pre prepojenie analógového a digitálneho prostredia XSPICE používa špeciálne komponenenty DAC_BRIDGE a ADC_BRIDGE. Tieto definujú prevod analógových úrovní na logické signály a naopak. V syntaxi XSPICE je takýto konverzný komponent definovaný nasledovne:

    A20 [11] [G] DAC_BRIDGE_A20
    .MODEL DAC_BRIDGE_A20 DAC_BRIDGE (
       + out_low=0.0
       + out_high=5
       + out_undef=2.5
       + t_rise=1.0e-8
       + t_fall=1.0e-8 )

V nasledujúcom príklade je ukázaný hybridný model generátora sinusového signálu, zloženého z posuvného registra so spätnou väzbou a súčtového zosilňovača s integračným kondenzátorom pre obmedzenie šírky pásma. Hybridný komponent A11 je analógovým napätím riadený generátor digitálneho signálu.

Výsledok simulácie

Záver

V príspevku je stručne popísané použitie skriptov v jazyku Python pre riadenie simulácie pomocou simulačného engine ngspice a ďaľších programov. Použitie samostatných programov s podporou skriptu umožňuje tvorbu špecifickej flexibilnej konfigurácie simulačného prostredia zameraného na riešenie konkrétnych úloh. Zároveň je možné zjednodušiť rutinné aktivity, ako je vytváranie netlistu, použitie špecifických modelov pre XSPICE a ďaľšie.

ict ve školství 24

Nie je možné v krátkom príspevku poukázať na všetky možnosti, ktoré takáto konfigurácia programov poskytuje, niektoré pokročilejšie témy, ako je napr. tvorba vlasných simulačných komponentov (grafická reprezentácia, tvorba modulov , programovanie XSPICE komponentov v C a ich integrácia do simulačného prostredia), použitie ďaľších simulačných engine (Xyce) môžu byť predmetom ďaľších príspevkov, vyjadrite sa prosím v diskusii pod článkom.

Účelom príspevku nebola tvorba manuálu, podrobnejšie informácie je možné nájsť v dokumentácii k príslušným programom. Príspevok pokladajte skôr za inšpiráciu a pomôcku pre riešenie Vašich vlastných úloh ako za finálne riešenie, autori aj po niekoľkých rokoch intenzívneho používania prezentovaných skriptov tieto stále nepokladajú za definitívne verzie

Autor článku

Vyštudoval experimentálnu fyziku na FMFI UK Bratislava a v súčasnej dobe pracuje na Výskumnom centre Žilinskej univerzity. Používa prevažne programovacie jazyky Python a C/C++ pre programovanie mikrokontrolérov (STM) a tvorbu modulov pre Python.

Vyštudoval elektrotechniku na Žilinskej univerzite a v súčasnej dobe pracuje na Katedre multimédií a informačno-komunikačných technológií. Používa programovací jazyk Python a C/C++.