Avoid GNUism '\|' by using extended REs.
[geda-gaf.git] / gnetlist-legacy / scheme / spice-common.scm
blob9450b9b110850ae4efacdac319017284ff34d4bb
1 ;;; gEDA - GPL Electronic Design Automation
2 ;;; gnetlist - gEDA Netlist
3 ;;; Copyright (C) 1998-2014 Ales Hvezda
4 ;;; Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
5 ;;;
6 ;;; This program is free software; you can redistribute it and/or modify
7 ;;; it under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 2 of the License, or
9 ;;; (at your option) any later version.
10 ;;;
11 ;;; This program is distributed in the hope that it will be useful,
12 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;;; GNU General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with this program; if not, write to the Free Software
18 ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 ;;; MA 02111-1301 USA.
21 ;; --------------------------------------------------------------------------
22 ;; Common functions for the SPICE netlist backends `spice' and `spice-sdb'.
23 ;; By S. Gieltjes and others.
24 ;; --------------------------------------------------------------------------
27 ;;---------------------------------------------------------------------
28 ;; write netnames connected to pin-a and pin-b
29 ;;   (currently used by the controlled sources (e, g, f and h)
30 ;;---------------------------------------------------------------------
31 (define spice:write-two-pin-names
32   (lambda (package pin-a pin-b)
33     (display (string-append
34       (car (spice:get-net package (gnetlist:get-attribute-by-pinseq package pin-a "pinnumber"))) " "))
35     (display (string-append
36       (car (spice:get-net package (gnetlist:get-attribute-by-pinseq package pin-b "pinnumber"))) " "))))
39 ;;--------------------------------------------------------------------
40 ;; Given a refdes returns the device associated nets(s) ordered by
41 ;; their pin number,
42 ;; what when not defined?
43 ;;      problem is slotted components e.g. ../examples/singlenet_1.sch
44 ;;--------------------------------------------------------------------
45 (define (spice:write-net-names-on-component refdes)
46   (do ((i 1 (1+ i)))
47       ((> i  (length (gnetlist:get-pins refdes))))
48     (let ((pin-name (number->string i)))
49       (display (car (spice:get-net refdes (gnetlist:get-attribute-by-pinseq refdes pin-name "pinnumber"))))
50       (write-char #\space))))
53 ;;----------------------------------------------------------------
54 ;; write a current controlled voltage source and implement the necessary
55 ;;   current measuring voltage source
56 ;;----------------------------------------------------------------
57 (define spice:write-ccvs
58   (lambda (package)
59     ( begin
60       (display "* begin ccvs expansion, h<name>\n")
61           ;; implement the controlled current source
62           ;; the user should create the refdes label begining with a h
63       (display (string-append package " "))
64       (spice:write-two-pin-names package "1" "2")
65       (display (string-append "Vsense_" package  " " (spice:component-value package) "\n" ))
66           ;; implement the current measuring voltage source
67       (display (string-append "Vsense_" package " "))
68       (spice:write-two-pin-names package "3" "4")
69       (display "dc 0\n")
70           ;; now it is possible to leave the output voltage source unconnected
71           ;; i.e. spice won't complain about unconnected nodes
72       (display (string-append "IOut_" package " "))
73       (spice:write-two-pin-names package "1" "2")
74       (display "dc 0\n")
75       (display "* end ccvs expansion\n"))))
78 ;;-----------------------------------------------------------------------
79 ;; write a current controlled current source and implement the necessary
80 ;;   current measuring voltage source
81 ;;-----------------------------------------------------------------------
82 (define spice:write-cccs
83   (lambda (package)
84     ( begin
85       (display "* begin cccs expansion, f<name>\n")
86           ;; implement the controlled current source
87           ;; the user should create the refdes label begining with a f
88       (display (string-append package " "))
89       (spice:write-two-pin-names package "1" "2")
90       (display (string-append "Vsense_" package " " (gnetlist:get-package-attribute package "value") "\n" ))
91           ;; implement the current measuring voltage source
92       (display (string-append "Vsense_" package " "))
93       (spice:write-two-pin-names package "3" "4")
94       (display "dc 0\n")
95       (display "* end cccs expansion\n"))))
98 ;;-------------------------------------------------------------------------
99 ;; write a voltage controlled current source and implement the necessary
100 ;;   voltage measuring current source
101 ;;-------------------------------------------------------------------------
102 (define spice:write-vccs
103   (lambda (package)
104     ( begin
105       (display "* begin vccs expansion, g<name>\n")
106           ;; implement the controlled current source
107           ;; the user should create a refdes label beginning with a g
108       (display (string-append package " "))
109       (spice:write-net-names-on-component package)
110       (display (string-append (spice:component-value package) "\n"))
111           ;; implement the voltage measuring current source
112           ;; imagine yourself copying the voltage of a voltage source with an internal
113           ;; impedance, spice starts complaining about unconnected nets if this current
114           ;; source is not here.
115       (display (string-append "IMeasure_" package " "))
116       (spice:write-two-pin-names package "3" "4")
117       (display "dc 0\n")
118       (display "* end vccs expansion\n"))))
121 ;;------------------------------------------------------------------------
122 ;; write a voltage controlled voltage source and implement the necessary
123 ;;   voltage measuring current source
124 ;;------------------------------------------------------------------------
125 (define spice:write-vcvs
126   (lambda (package)
127     ( begin
128       (display "* begin vcvs expansion, e<name>\n")
129           ;; implement the controlled voltage source
130           ;; the user should create a refdes label beginning with an e
131       (display (string-append package " "))
132       (spice:write-net-names-on-component package)
133       (display (string-append (gnetlist:get-package-attribute package "value") "\n" ))
134           ;; implement the voltage measuring current source
135           ;; imagine yourself copying the voltage of a voltage source with an internal
136           ;; impedance, spice starts complaining about unconnected nets if this current
137           ;; source is not here.
138       (display (string-append "Isense_" package " "))
139       (spice:write-two-pin-names package "3" "4")
140       (display "dc 0\n")
141           ;; with an output current source it is possible to leave the output voltage source
142           ;; unconnected i.e. spice won't complain about unconnected nodes
143       (display (string-append "IOut_" package " "))
144       (spice:write-two-pin-names package "1" "2")
145       (display "dc 0\n")
146       (display "* end vcvs expansion\n"))))
149 ;;--------------------------------------------------------------------------
150 ;; Create a nullor, make sure it consists of a voltage controlled source
151 ;;--------------------------------------------------------------------------
152 (define spice:write-nullor
153   (lambda (package)
154     (let ((value (gnetlist:get-package-attribute package "value")))
155       (display "* begin nullor expansion, e<name>\n")
156           ;; implement the controlled voltage source
157       (display (string-append "E_" package " "))
158       (spice:write-net-names-on-component package)
159       (display (string-append (if (string=? value "unknown") "1000Meg" value) "\n"))
160           ;; implement the voltage measuring current source
161           ;; imagine yourself copying the voltage of a voltage source with an internal
162           ;; impedance, spice starts complaining about unconnected nets if this current
163           ;; source is not here.
164       (display (string-append "IMeasure_" package " "))
165       (spice:write-two-pin-names package "3" "4")
166       (display "dc 0\n")
167           ;; with an output current source it is possible to leave the output voltage source
168           ;; unconnected i.e. spice won't complain about unconnected nodes
169       (display (string-append "IOut_" package " "))
170       (spice:write-two-pin-names package "1" "2")
171       (display "dc 0\n")
172       (display "* end of nullor expansion\n"))))
175 ;;-------------------------------------------------------------------
176 ;; write all listed and available attributes in the form of <variable>=<value>
177 ;;-------------------------------------------------------------------
178 (define spice:write-list-of-attributes
179   (lambda (package attrib-list)
180     (if (not (null? attrib-list))
181       (let ((attrib (gnetlist:get-package-attribute package (car attrib-list))))
182             ; Is it possible to make no differentiation between upper and lower case?
183             ; That relieves you of mixed case forms e.g. As, AS, as..., they are the
184             ; same attributes, spice3f5 is case insensitive.  And other spice versions?
185         (if (not (string=? attrib "unknown"))
186           (display (string-append  " " (car attrib-list) "=" attrib)))
187         (spice:write-list-of-attributes package (cdr attrib-list))))))
190 ;;-----------------------------------------------------------
191 ;; Given a refdes, returns the device attribute "value" as string
192 ;; Used when "value" is a mandatory attribute.
193 ;; Returns "<no valid attribute . . .>" if not available.
194 ;;-----------------------------------------------------------
195 (define spice:component-value
196   (lambda (package)
197     (let ((value (gnetlist:get-package-attribute package "value")))
198       (if (not (string=? value "unknown"))
199         value
200         "<No valid value attribute found>"))))
202 ;;-----------------------------------------------------------
203 ;; gnet-spice replacement of gnetlist:get-nets, a net labeled "GND" becomes 0
204 ;;-----------------------------------------------------------
205 (define spice:get-net
206   (lambda (refdes pin-name)
207     (let ((net-name (gnetlist:get-nets refdes pin-name)))
208       (cond ((string=? (car net-name) "GND") (cons "0" #t))
209             (else                            (cons (car net-name) #t))))))