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)
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.
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.
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
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)
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
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")
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")
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
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")
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
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")
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
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")
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")
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
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")
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")
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
197 (let ((value (gnetlist:get-package-attribute package "value")))
198 (if (not (string=? value "unknown"))
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))))))