1. Introduction
Le programme SPICE (Simulated Program with Integrated Circuit Emphasis) effectue des simulations de circuits électroniques analogiques. La version de référence (spice 2g6, 1983) est écrite en fortran. Une version plus récente (spice 3, 1985) est écrite en C. De nombreux logiciels commerciaux de simulation utilisent le moteur de calcul de SPICE, en ajoutant des fonctions supplémentaires.
On s’intéresse ici aux versions libres de spice, ngspice et SpiceOpus, qui reposent sur spice3f5. Ces deux programmes lisent un fichier texte comportant une description du circuit et différentes commandes. La commande PLOT permet de tracer des courbes mais ne permet pas d’exporter sous forme de fichier. La commande PRINT permet d’exporter les résultats dans un fichier texte. Nous utiliserons une fonction python permettant de lire les fichiers produits par PRINT.
Le présent document explique le principe d’utilisation de SPICE (ngspice) à travers un exemple simple. Seules les fonctions les plus courantes sont décrites.
2. Description du circuit
On considère comme exemple le circuit suivant :
Il faut tout d’abord numéroter les nœuds du circuit, en attribuant le numéro 0 à la masse. Ce circuit comporte 3 nœuds (sans compter la masse).
Une source de tension est définie par la syntaxe suivante :
Vxxx N1 N2
Le nom commence par V et xxx est un nom qui permet d’identifier la source s’il y en a plusieurs. N1 et N2 sont les deux nœuds de la source : la tension appliquée est par convention VN1-VN2.
Une resistance est définie par :
Rxxx N1 N2 VALEUR
La valeur est donnée en Ω. Pour entrer une valeur très petite ou très grande, on peut utiliser un des multiples définis dans le tableau suivant :
Symbole | Facteur |
T | 1E12 |
G | 1E9 |
MEG | 1E6 |
K | 1E3 |
M | 1E-3 |
U | 1E-6 |
N | 1E-9 |
P | 1E-12 |
F | 1E-15 |
La syntaxe des capacités et des inductances est similaire, avec des noms commençant respectivement par C et L.
Voici la description du circuit précédent avec des valeurs numériques pour les composants passifs :
V1 1 0 R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 0 10
La description de ce circuit n’est pas tout à fait complète. Il faut encore préciser le type de source de tension, qui dépend du type d’analyse que l’on souhaite effectuer.
3. Analyse en continu
Pour faire une analyse en continu, il faut ajouter l’option DC aux sources. Par exemple, une source appliquant une tension continue de 1 volt sera définie par :
V1 1 0 DC 1V
Le symbole V accolé à 1 n’est pas pris en compte par SPICE : il est ajouté pour rendre le code plus lisible.
L’analyse en continu est définie par la commande .DC. les commandes sont précédées d’un point. On peut aussi placer toutes les commandes (sans les points) entre les deux commandes .CONTROL et .ENDC.
La commande .DC effectue en fait un balayage de tensions ou de courants continus, c’est-à-dire ayant une valeur constante. Voici sa syntaxe minimale :
.DC SRC1 START1 STOP1 INC1
SRC1 désigne la source (de tension ou de courant) dont on veut faire varier la valeur. START1 est la valeur de départ, STOP1 la valeur finale et INC1 l’incrément.
La description du circuit et les commandes se placent dans un fichier .cir. Voici le fichier .cir complet pour le circuit précédent, avec une analyse DC :
Circuit RLC V1 1 0 DC R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 0 10 .CONTROL DC V1 0 10 1 PLOT V(2) .ENDC .END
La première ligne est le nom du circuit. La dernière ligne doit être .END. La commande PLOT a été ajoutée.
Pour traiter ce fichier avec ngspice, ouvrir ngspice depuis une console puis exécuter
source circuit-RLC-1.cir
La courbe tracée est la tension du nœud 2 en fonction de la tension balayée (v-sweep), qui est ici la tension de la source V1. Dans le cas présent, la courbe obtenue est linéaire car le circuit est linéaire.
Pour récupérer les données dans python (ou dans Mathematica), nous allons remplacer la commande PLOT par la commande PRINT, en redirigeant la sortie vers un fichier :
Circuit RLC V1 1 0 DC R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 0 10 .CONTROL DC V1 0 10 1 PRINT V(2) > export-2.txt .ENDC .END
Dans ce cas, on peut exécuter le fichier avec ngspice sans ouvrir la console ngspice (mode batch avec l’option -b) :
Le fichier texte obtenu contient une colonne pour v-sweep, une colonne pour v(2). La fonction python lectureSpicePrint.py décrite dans Lecture des sorties SPICE avec Python permet de lire ce fichier (dans certains cas les valeurs exportées sont complexes).
from lectureSpicePrint import lectureSpicePrint from matplotlib.pyplot import * data = lectureSpicePrint("export-2.txt") V1 = data["v-sweep"] V2 = data["v(2)"]
Voici le tracé de V2 en fonction de V1 :
figure(figsize=(6,6)) plot(V1,V2) xlabel("V1 (V)") ylabel("V2 (V)") grid()
4. Analyse en régime sinusoïdal
Pour effectuer une analyse fréquentielle en régime sinusoïdal, il faut déclarer une source en mode AC, avec la syntaxe suivante :
Vxxx N1 N2 AC (AMP) (PHASE)
Les paramètres entre parenthèses sont facultatifs. AMP est l’amplitude de la source sinusoïdal (en V ou en A). Sa valeur par défaut est 1. Ce paramètre est sans importance pour les circuits linéaires. PHASE est la phase de la source, nulle par défaut.
L’analyse est définie par la commande .AC, dont la syntaxe est :
.AC BALAYAGE NB_POINTS FSTART STOP
FSTART et la fréquence de départ, FSTOP la fréquence d’arrivée (en Hertz). Il y a trois types de balayage :
- DEC : balayage par décade, avec NB_POINTS points par décade.
- OCT : balayage par octave, avec NP_POINTS par octave.
- LIN : balayage linéaire, avec NP_POINTS sur toute la plage de fréquence.
Voici le fichier .cir pour une analyse fréquentielle de 100 Hz à 100 kHz :
Circuit RLC V1 1 0 AC 1 R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 0 10 .CONTROL AC DEC 100 100 100K PRINT VDB(2) VP(2) > export-3.txt .ENDC .END
Dans ce cas, les données exportées sont la tension du nœud 2 en décibel et la phase en radian. Si le nœud est la sortie d’un filtre, on obtient directement le gain en décibel car l’entrée a une amplitude de 1. La phase obtenue est le déphasage par rapport à l’entrée puisque celle-ci a une phase de 0.
On peut aussi exporter la tension sous forme de nombres complexes, avec :
PRINT V(2)
Le tracé du diagramme de Bode directement dans ngspice est obtenu avec les commandes :
PLOT VDB(2) PLOT VP(2)
Voici le tracé du diagramme de Bode en python :
data = lectureSpicePrint("export-3.txt") freq = data["frequency"] gdb = data["vdb(2)"] phi = data["vp(2)"] figure(figsize=(10,10)) subplot("211") plot(freq,gdb) xscale('symlog') xlabel('f (Hz)') ylabel('GdB') grid() subplot("212") plot(freq,phi) xscale('symlog') xlabel('f (Hz)') ylabel('phi (rad)') grid()
Dans certains cas, la grandeur que l’on veut étudier est un courant. Pour obtenir le courant dans une branche, il faut ajouter une source de tension DC de tension nulle dans cette branche. Voici par exemple comment obtenir le courant dans l’inductance :
Circuit RLC V1 1 0 AC 1 R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 4 10 VIL 4 0 DC 0 .CONTROL AC DEC 100 100 100K PRINT I(VIL) > export-4.txt .ENDC .END
La source VIL a été ajoutée entre la résistance R et la masse, pour obtenir le courant dans cette branche. La syntaxe I(Vxxx) permet d’obtenir le courant traversant une source de tension. La sortie en décibel et en phase ne fonctionne pas sur ngspice pour le courant; on doit donc exporter la tension sous forme de nombres complexes. Le calcul du gain et du déphasage se fait sans difficulté avec python :
import numpy data = lectureSpicePrint("export-4.txt") freq = data["frequency"] iL = data["i(vil)"] gdb = 20*numpy.log10(numpy.absolute(iL)) phi = numpy.angle(iL) figure(figsize=(10,10)) subplot("211") plot(freq,gdb) xscale('symlog') xlabel('f (Hz)') ylabel('GdB') grid() subplot("212") plot(freq,phi) xscale('symlog') xlabel('f (Hz)') ylabel('phi (rad)') grid()
5. Analyse transitoire
L’analyse transitoire, appelée plus généralement analyse temporelle, consiste à obtenir les tensions en fonction du temps. Pour cela, il faut définir précisément les signaux temporels délivrés par les sources. Les différents types de signaux sont :
- PULSE : source à impulsion, utilisée en particulier pour les réponses à échelon et les répondes impulsionnelles.
- SIN : source sinusoïdale, éventuellement à décroissance exponentielle.
- EXP : source exponentielle.
- PWL : source linéaire par intervalle.
- SFFM : source sinusoïdale avec modulation de fréquence.
Nous allons décrire en détail la source PULSE. Consulter SPICE pour les autres sources.
La syntaxe d’une source à impulsion est :
Vxxx N1 N2 PULSE(V1 V2 TD TR TF PW PER)
Les paramètres sont :
- V1 : valeur minimale.
- V2 : valeur maximale.
- TD : délai après l’instant zéro.
- TR : temps de montée.
- TF : temps de descente.
- PW : largeur de l’impulsion.
- PER : période de répétition de l’impulsion, qui doit être supérieure à PW.
L’analyse transitoire est obtenue avec la commande .TRAN, dont voici la syntaxe :
.TRAN PAS TSTOP
PAS est le pas de temps, TSTOP le temps final.
Il peut être nécessaire de préciser certaines conditions initiales. Pour cela, on utilise la commande .IC. On peut aussi ajouter l’option IC à certains composants.
Voyons comment obtenir la réponse à un échelon avec le circuit étudié :
Circuit RLC V1 1 0 PULSE(0 1 0 0 0 10M 20M) R1 1 2 10K C1 2 0 100N L1 2 3 10M R 3 4 10 VIL 4 0 DC 0 .CONTROL IC V(2)=0 TRAN 1U 20M PRINT V(2) > export-5.txt .ENDC .END
data = lectureSpicePrint("export-5.txt") time = data["time"]*1000 V2 = data["v(2)"] figure(figsize=(15,5)) plot(time,V2) xlabel("t (ms)") ylabel("V2 (V)") grid()