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.
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.
(* ::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]; ]
On considère un circuit RC :
Figure pleine pageLe 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.
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.pdf
ListLogLinearPlot[Transpose[{freq,vp2}],Joined->True,AxesLabel->{"phi (rad)","GdB"}]figB.pdf
Faisons une analyse transitoire avec le même circuit :
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.pdf