1 ;;; gEDA - GPL Electronic Design Automation
3 ;;; Copyright (C) 2003, 2005-2010 Dan McMahill
5 ;;; This program is free software; you can redistribute it and/or modify
6 ;;; it under the terms of the GNU General Public License as published by
7 ;;; the Free Software Foundation; either version 2 of the License, or
8 ;;; (at your option) any later version.
10 ;;; This program is distributed in the hope that it will be useful,
11 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;;; GNU General Public License for more details.
15 ;;; You should have received a copy of the GNU General Public License
16 ;;; along with this program; if not, write to the Free Software
17 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ;; --------------------------------------------------------------------------
20 ;; This is gnetlist backend for the SWITCAP switched capacitor
21 ;; simulator. This backend was written by Dan McMahill
22 ;; 'mcmahill at alum dot mit dotedu' who used the SPICE backend by
23 ;; S. Gieltjes as a starting point.
25 ;; The following is needed to make guile 1.8.x happy.
26 (use-modules (ice-9 rdelim))
28 ;; ----------------------------------------------------------------------------
29 ;; Utility functions used by this netlister
30 ;; ----------------------------------------------------------------------------
32 ;; This procedure takes a net name as determined by gnetlist and
33 ;; modifies it to be a valid SWITCAP net name.
35 (define switcap:map-net-names
37 (let ((rx (make-regexp "^unnamed_net"))
40 ;; XXX we should use a dynamic regexp based on the current value
41 ;; for the unnamed net base string.
44 ;; Change "GND" to "0"
45 ((string=? net-name "GND") (set! net-alias "0"))
46 ;; remove the 'unnamed_net' part
47 ((regexp-exec rx net-name) (set! net-alias (substring net-name 11)))
51 ;; Truncate to 7 characters
52 (if (> (string-length net-alias) 7)
53 (set! net-alias (substring net-alias 0 7))
55 ;; Convert to all upper case
56 (string-upcase net-alias)
62 ;; This procedure takes a refdes as determined by gnetlist and
63 ;; modifies it to be a valid SWITCAP refdes. In particular,
64 ;; we need to make sure that
66 ;; - the first character is correct for the component type
68 ;; - we do not exceed 8 characters. Note the 8 comes from
69 ;; the first character which denotes component type plus
70 ;; 7 for the unique identifier part.
72 ;; - we are all caps (switcap is not case sensitive)
74 (define switcap:map-refdes
76 (let ((refdes-alias refdes)
79 ;; Convert to all upper case
80 (string-upcase refdes-alias)
82 ;; Make sure the first character is correct for
83 ;; this component type
85 ( (string=? (get-device refdes) "SWITCAP-switch")
86 (if (not (string=? (substring refdes-alias 0 1) "S"))
87 (set! refdes-alias (string-append "S" refdes-alias))))
89 ( (string=? (get-device refdes) "SWITCAP-capacitor")
90 (if (not (string=? (substring refdes-alias 0 1) "C"))
91 (set! refdes-alias (string-append "C" refdes-alias))))
93 ( (string=? (get-device refdes) "SWITCAP-vcvs")
94 (if (not (string=? (substring refdes-alias 0 1) "E"))
95 (set! refdes-alias (string-append "E" refdes-alias))))
97 ( (string=? (get-device refdes) "SWITCAP-vsrc")
98 (if (not (string=? (substring refdes-alias 0 1) "V"))
99 (set! refdes-alias (string-append "V" refdes-alias))))
103 ;; Truncate to 8 characters (1 for the first character and
104 ;; 7 for the identifier)
105 (if (> (string-length refdes-alias) 8)
106 (set! refdes-alias (substring refdes-alias 0 8))
109 ;; set to #t for debugging
112 (display "(switcap:map-refdes ")
115 (display refdes-alias )
126 ;; Given a reference designator, pin number, and output port
127 ;; write out the net name
129 (define switcap:write-pin-net
130 (lambda (package pin port)
131 (display (gnetlist:alias-net (car (gnetlist:get-nets package pin))) port)
136 ;; Given a reference designator, attribute name, and output port
137 ;; write out the attribute with warnings if the attribute has
140 (define switcap:write-attrib
141 (lambda (package attrib port)
142 (let ((val (gnetlist:get-package-attribute package attrib)))
143 (if (string=? val "unknown")
145 (display "*** WARNING ***\n")
146 (display "Required attribute \"")
148 (display "\" is not set on component \"")
150 (display "\". Please correct this.\n\n")
156 ;; ----------------------------------------------------------------------------
157 ;; Individual component netlist functions
158 ;; ----------------------------------------------------------------------------
165 ;; C### (N1 N2) value;
168 (define switcap:write-cap
169 (lambda (package port)
171 ;; Write out the refdes
173 (display (gnetlist:alias-refdes package) port)
176 ;; Write out the nodes
177 ;; Write out the nodes
179 (switcap:write-pin-net package "1" port)
181 (switcap:write-pin-net package "2" port)
185 (switcap:write-attrib package "value" port)
199 (define switcap:write-switch
200 (lambda (package port)
202 ;; Write out the refdes
204 (display (gnetlist:alias-refdes package) port)
207 ;; Write out the nodes
209 (switcap:write-pin-net package "1" port)
211 (switcap:write-pin-net package "2" port)
215 (switcap:write-attrib package "clock" port)
222 ;; voltage controlled voltage source
226 ;; E### (OUTP OUTM INP INM) gain;
229 (define switcap:write-vcvs
230 (lambda (package port)
232 ;; Write out the refdes
234 (display (gnetlist:alias-refdes package) port)
237 ;; Write out the nodes
239 (switcap:write-pin-net package "1" port)
241 (switcap:write-pin-net package "2" port)
243 (switcap:write-pin-net package "3" port)
245 (switcap:write-pin-net package "4" port)
249 (switcap:write-attrib package "gain" port)
263 (define switcap:write-vsrc
264 (lambda (package port)
266 ;; Write out the refdes
268 (display (gnetlist:alias-refdes package) port)
271 ;; Write out the nodes
273 (switcap:write-pin-net package "1" port)
275 (switcap:write-pin-net package "2" port)
283 ;; Timing block -- clock definition
287 ;; CLOCK clock_name period (phi_start phi_stop)
290 (define switcap:write-clock
291 (lambda (package port)
293 (display " CLOCK " port)
294 (display (string-append package " ") port)
295 (switcap:write-attrib package "PERIOD" port)
297 (switcap:write-attrib package "PSTART" port)
299 (switcap:write-attrib package "PSTOP" port)
300 (display ");\n" port)
304 ;; Timing block -- master clock period
308 ;; PERIOD clock_period;
311 (define switcap:write-timing
312 (lambda (package port)
314 (display " PERIOD " port)
315 (switcap:write-attrib package "PERIOD" port)
328 ;; Can only have 64 characters in the title
329 ;; XXX - need to truncate to 64 chars
330 (define switcap:write-title
331 (lambda (package port)
333 (display "TITLE:" port)
334 (switcap:write-attrib package "TITLE" port)
337 (display ";\n\n" port)
345 ;; OPTIONS; OPT1; OPT2; ...; END;
347 ;; valid options are:
353 (define switcap:write-options
354 (lambda (package port)
356 (display "OPTIONS; " port)
357 (switcap:write-attrib package "OPTIONS" port)
360 (display " END;\n\n" port)
366 ;; For now, we only support writing the analysis blocks in a file
367 ;; and including that via a switcap-analysis-1.sym instantiation
369 (define switcap:write-analysis
370 (lambda (package port)
371 (display "/* reading analysis from \"" port)
372 (let ((fname (switcap:write-attrib package "file" port)))
373 (display "\" */ \n" port)
374 (switcap:cat-file (open-input-file fname) port)
377 (define switcap:cat-file
380 (set! line (read-line ip))
381 (if (not (eof-object? line))
384 (switcap:cat-file ip op)
389 ;; ----------------------------------------------------------------------------
390 ;; Netlist functions for each of the blocks in the switcap netlist
391 ;; ----------------------------------------------------------------------------
395 ;; Switcap netlist header
397 (define switcap:write-top-header
399 (display "/* Switcap netlist produced by gnetlist (part of gEDA) */\n" port)
400 (display "/* See http://www.geda.seul.org for more information. */\n" port)
401 (display "/* Switcap backend written by Dan McMahill */\n" port)
402 (display "\n\n" port)
407 ;; The main TITLE and OPTIONS block dispatcher
409 (define switcap:write-title-block
412 (let ((package (car ls)))
414 ( (string=? (get-device package) "SWITCAP-options")
415 (switcap:write-options package port))
416 ( (string=? (get-device package) "SWITCAP-title")
417 (switcap:write-title package port))
419 (switcap:write-title-block port (cdr ls)) ))))
422 ;; The main TIMING block dispatcher
424 (define switcap:write-timing-block
427 (let ((package (car ls)))
429 ( (string=? (get-device package) "SWITCAP-clock")
430 (switcap:write-clock package port))
431 ( (string=? (get-device package) "SWITCAP-timing")
432 (switcap:write-timing package port))
434 (switcap:write-timing-block port (cdr ls)) ))))
437 ;; The main CIRCUIT block netlist dispatcher.
439 (define switcap:write-netlist
442 (let ((package (car ls)))
444 ( (string=? (get-device package) "SWITCAP-switch")
445 (switcap:write-switch package port))
446 ( (string=? (get-device package) "SWITCAP-capacitor")
447 (switcap:write-cap package port))
448 ( (string=? (get-device package) "SWITCAP-vcvs")
449 (switcap:write-vcvs package port))
450 ( (string=? (get-device package) "SWITCAP-vsrc")
451 (switcap:write-vsrc package port))
453 (switcap:write-netlist port (cdr ls)) ))))
456 ;; The main ANALYSIS block dispatcher
458 (define switcap:write-analysis-block
461 (let ((package (car ls)))
463 ( (string=? (get-device package) "SWITCAP-analysis")
464 (switcap:write-analysis package port))
466 (switcap:write-analysis-block port (cdr ls)) ))))
469 ;; ----------------------------------------------------------------------------
470 ;; Switcap netlist generation -- top level
471 ;; ----------------------------------------------------------------------------
473 (lambda (output-filename)
474 (let ((port (open-output-file output-filename)))
476 ;; initialize the net-name aliasing
477 (gnetlist:build-net-aliases switcap:map-net-names all-unique-nets)
479 ;; initialize the refdes aliasing
480 (gnetlist:build-refdes-aliases switcap:map-refdes packages)
482 (switcap:write-top-header port)
483 (switcap:write-title-block port packages)
484 (display "TIMING;\n" port)
485 (switcap:write-timing-block port packages)
486 (display "END;\n\n" port)
487 (display "CIRCUIT;\n" port)
488 (switcap:write-netlist port packages)
489 (display "END;\n\n" port)
490 (switcap:write-analysis-block port packages)
491 (display "\n\n/* End of SWITCAP netlist */\n" port)
492 (display "END;\n" port)
493 (close-output-port port))))
496 ;; --------------------------------------------------------------------------