Table des matières Mathematica

Lecture des sorties SPICE avec Mathematica

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 print permet d'exporter les résultats dans un fichier texte. La commande plot permet de tracer des courbes. Afin d'obtenir des sorties graphiques de haute qualité, ou d'effectuer différents traitements des données, il peut être utile d'importer dans Mathematica les données exportées par SPICE avec la commande print. Cette page présente une fonction Mathematica faisant cette importation.

2. Fonction Mathematica d'importation

Pour exporter des données dans un fichier texte, la commande spice est : PRINT v1 v2 ... > fichier.txt, où v1 v2 ... sont les noms des vecteurs de données à exporter.

La fonction suivante effectue l'importation des données du fichier, qu'elle renvoit sous forme d'une table associative dont les clés sont les noms des champs. Les listes obtenues contiennent des réels ou des complexes.

lectureSpicePrint.m
(* ::Package:: *)

lectureSpicePrint[fichier_]:=Module[{f,ligne,entete,champs,valeurs,complexes,i,j,data,x,y},
	f = OpenRead[fichier];
	ligne = Read[f,String];
	While[Not[StringMatchQ[ligne,RegularExpression["-+"]]],Print[ligne];ligne=Read[f,String]];
	entete=Read[f,String];
	champs = StringSplit[entete,Whitespace];
	ligne = Read[f,String];
	ligne = Read[f,String];
	valeurs = StringSplit[ligne,Whitespace];
	Print[champs];
	complexes={};
	j=1;
	For[i=1,i<=Length[champs],i=i+1,
		If[StringTake[valeurs[[j]],-1]==",",
			AppendTo[complexes,True];
			j+=2;
			data[champs[[i]]]={};,
			AppendTo[complexes,False];
			j+=1;
			data[champs[[i]]]={};
		];
	];
	Print["complexes = ",complexes];
	While[StringQ[ligne],
		valeurs = StringSplit[ligne,Whitespace];
		j=1;
		For[i=1,i<=Length[champs],i+=1,
			If[complexes[[i]],
				valeurs[[j]]=StringDrop[valeurs[[j]],-1];
				valeurs[[j]]=StringReplace[valeurs[[j]],{","->".";"e"->"*10^"}];
				valeurs[[j+1]]=StringReplace[valeurs[[j+1]],{","->".";"e"->"*10^"}];
				x = ToExpression[valeurs[[j]]];
				y = ToExpression[valeurs[[j+1]]];
				AppendTo[data[champs[[i]]],x+I*y];
				j+=2,
				valeurs[[j]]=StringReplace[valeurs[[j]],{","->".";"e"->"*10^"}];
				x = ToExpression[valeurs[[j]]];
				AppendTo[data[champs[[i]]],x];
				j+=1
			];
		];
		ligne = Read[f,String];
	];
	Return[data];
]   
             

3. Exemple

On considère un circuit RC :

figureA.svgFigure pleine page

Le fichier ci-dessous décrit ce circuit et fait une analyse AC (réponse fréquentielle). Les données exportées sont la tension en décibel et la phase sur le noeud 2.

circuitRC-1.cir
Circuit RC
v1 1 0 dc 0 ac 1
r1 1 2 1k 
c1 2 0 100n
r2 2 0 1MEG
.control
ac dec 10 10Hz 100kHz
print vdb(2) vp(2)> export-1.txt
.endc
.end
            

Voici la commande exécutée :

ngspice -b circuitRC-1.cir

et l'importation des données dans Mathematica avec le tracé des courbes :

Import["lectureSpicePrint.m"];
data = lectureSpicePrint["export-1.txt"];
freq = data["frequency"];
vdb2 = data["vdb(2)"];
vp2 = data["vp(2)"];
            
ListLogLinearPlot[Transpose[{freq,vdb2}],Joined->True,AxesLabel->{"f (Hz)","GdB"}]
figA.pngfigA.pdf
ListLogLinearPlot[Transpose[{freq,vp2}],Joined->True,AxesLabel->{"phi (rad)","GdB"}]
figB.pngfigB.pdf

Faisons une analyse transitoire avec le même circuit :

circuitRC-2.cir
Circuit RC
v1 1 0 dc 1
r1 1 2 1k 
c1 2 0 100n ic=0
r2 2 0 1MEG
.control
tran 1Us 1ms uic
print v(2)> export-2.txt
.endc
.end
            
ngspice -b circuitRC-2.cir
data = lectureSpicePrint["export-2.txt"];
t = data["time"]*1000
v2 = data["v(2)"]
            
ListPlot[Transpose[{t,v2}],Joined->True,AxesLabel->{"t (ms)","v(2)"}]
figC.pngfigC.pdf
Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.