refdes_renum: warn of possible number clash with non-conforming values
[geda-gaf/whiteaudio.git] / gnetlist / scheme / gnet-switcap.scm
blob64eefbd25a1546f05271465bcbe23b575a1c7ce7
1 ;;; gEDA - GPL Electronic Design Automation
2 ;;;
3 ;;; Copyright (C) 2003, 2005-2010 Dan McMahill
4 ;;;
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.
9 ;;;
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.
14 ;;;
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
36   (lambda (net-name)
37     (let ((rx (make-regexp "^unnamed_net"))
38           (net-alias net-name)
39           )
40       ;; XXX we should use a dynamic regexp based on the current value
41       ;; for the unnamed net base string.
43       (cond 
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)))
48        (else net-name)
49        )
51       ;; Truncate to 7 characters
52       (if (> (string-length net-alias) 7)
53           (set! net-alias (substring net-alias 0 7))
54           )
55       ;; Convert to all upper case
56       (string-upcase net-alias)
58       )
59     )
60   )
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
75   (lambda (refdes)
76     (let ((refdes-alias refdes)
77           )
79       ;; Convert to all upper case
80       (string-upcase refdes-alias)
82       ;; Make sure the first character is correct for
83       ;; this component type
84       (cond   
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))))
101        )
102       
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))
107           )
109       ;; set to #t for debugging
110       (if #f
111           (let ()
112             (display "(switcap:map-refdes ")
113             (display refdes)
114             (display ") ===> " )
115             (display refdes-alias )
116             (display "\n")
117             )
118           )
120       refdes-alias
121       )
122     )
123   )
125 ;; 
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)
132     )
133   )
135 ;; 
136 ;; Given a reference designator, attribute name, and output port
137 ;; write out the attribute with warnings if the attribute has
138 ;; not been set
140 (define switcap:write-attrib
141   (lambda (package attrib port)
142       (let ((val (gnetlist:get-package-attribute package attrib)))
143         (if (string=? val "unknown") 
144             (begin
145               (display "*** WARNING ***\n")
146               (display "Required attribute \"")
147               (display attrib)
148               (display "\" is not set on component \"")
149               (display package)
150               (display "\".  Please correct this.\n\n")
151               ))
152         (display val port)
153         val
154         )))
156 ;; ----------------------------------------------------------------------------
157 ;; Individual component netlist functions
158 ;; ----------------------------------------------------------------------------
161 ;; capacitor
163 ;; Form is:
165 ;; C### (N1 N2) value;
167 ;; 
168 (define switcap:write-cap
169   (lambda (package port)            
170     ( begin
171       ;; Write out the refdes
172       (display "     " port)
173       (display (gnetlist:alias-refdes package) port)
174       (display " " port)
176       ;; Write out the nodes
177       ;; Write out the nodes
178       (display "(" port)
179       (switcap:write-pin-net package "1" port)
180       (display " " port)
181       (switcap:write-pin-net package "2" port)
182       (display ") " port)
184       ;; Write the value
185       (switcap:write-attrib package "value" port)
186       
187       ;; finish the line
188       (display ";\n" port)
189       )))
192 ;; switch
194 ;; Form is:
196 ;; S### (N1 N2) clk;
198 ;; 
199 (define switcap:write-switch
200   (lambda (package port)            
201     ( begin
202       ;; Write out the refdes
203       (display "     " port)
204       (display (gnetlist:alias-refdes package) port)
205       (display " " port)
207       ;; Write out the nodes
208       (display "(" port)
209       (switcap:write-pin-net package "1" port)
210       (display " " port)
211       (switcap:write-pin-net package "2" port)
212       (display ") " port)
214       ;; Write the clock
215       (switcap:write-attrib package "clock" port)
217       ;; finish the line
218       (display ";\n" port)
219       )))
222 ;; voltage controlled voltage source
224 ;; Form is:
226 ;; E### (OUTP OUTM INP INM) gain;
228 ;; 
229 (define switcap:write-vcvs
230   (lambda (package port)            
231     ( begin
232       ;; Write out the refdes
233       (display "     " port)
234       (display (gnetlist:alias-refdes package) port)
235       (display " " port)
237       ;; Write out the nodes
238       (display "(" port)
239       (switcap:write-pin-net package "1" port)
240       (display " " port)
241       (switcap:write-pin-net package "2" port)
242       (display " " port)
243       (switcap:write-pin-net package "3" port)
244       (display " " port)
245       (switcap:write-pin-net package "4" port)
246       (display ") " port)
248       ;; Write the clock
249       (switcap:write-attrib package "gain" port)
251       ;; finish the line
252       (display ";\n" port)
253       )))
256 ;; voltage source
258 ;; Form is:
260 ;; V### (OUTP OUTM);
262 ;; 
263 (define switcap:write-vsrc
264   (lambda (package port)            
265     ( begin
266       ;; Write out the refdes
267       (display "     " port)
268       (display (gnetlist:alias-refdes package) port)
269       (display " " port)
271       ;; Write out the nodes
272       (display "(" port)
273       (switcap:write-pin-net package "1" port)
274       (display " " port)
275       (switcap:write-pin-net package "2" port)
276       (display ")" port)
278       ;; finish the line
279       (display ";\n" port)
280       )))
283 ;; Timing block -- clock definition
285 ;; Form is:
287 ;; CLOCK clock_name period (phi_start phi_stop)
289 ;; 
290 (define switcap:write-clock
291   (lambda (package port)            
292     ( begin
293       (display "     CLOCK " port)
294       (display (string-append package " ") port)
295       (switcap:write-attrib package "PERIOD" port)
296       (display " (" port)
297       (switcap:write-attrib package "PSTART" port)
298       (display " " port)
299       (switcap:write-attrib package "PSTOP" port)
300       (display ");\n" port)
301       )))
304 ;; Timing block -- master clock period
306 ;; Form is:
308 ;; PERIOD clock_period;
310 ;; 
311 (define switcap:write-timing
312   (lambda (package port)            
313     ( begin
314       (display "     PERIOD " port)
315       (switcap:write-attrib package "PERIOD" port)
317       ;; finish the line
318       (display ";\n" port)
319       )))
322 ;; Title
324 ;; Form is:
326 ;; TITLE: my title;
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)            
332     ( begin
333       (display "TITLE:" port)
334       (switcap:write-attrib package "TITLE" port)
336       ;; finish the line
337       (display ";\n\n" port)
338       )))
341 ;; Options
343 ;; Form is:
345 ;; OPTIONS; OPT1; OPT2; ...; END;
347 ;; valid options are:
348 ;;   WIDTH132
349 ;;   NOLIST
350 ;;   REPORT
351 ;;   NOOVRLAY
352 ;;   GRID
353 (define switcap:write-options
354   (lambda (package port)            
355     ( begin
356       (display "OPTIONS; " port)
357       (switcap:write-attrib package "OPTIONS" port)
359       ;; finish the line
360       (display " END;\n\n" port)
361       )))
364 ;; Analysis block
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)
375       )))
377 (define switcap:cat-file
378   (lambda (ip op)
379     (define line "")
380     (set! line (read-line ip))
381     (if (not (eof-object? line))
382         (begin 
383           (write-line line op)
384           (switcap:cat-file ip op)
385         )
386         (close-port ip))
387     ))
389 ;; ----------------------------------------------------------------------------
390 ;; Netlist functions for each of the blocks in the switcap netlist
391 ;; ----------------------------------------------------------------------------
394 ;; 
395 ;; Switcap netlist header
397 (define switcap:write-top-header
398   (lambda (port)
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)
403     )
404   )
407 ;; The main TITLE and OPTIONS block dispatcher
409 (define switcap:write-title-block
410   (lambda (port ls)
411      (if (not (null? ls))
412       (let ((package (car ls)))
413         (cond   
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))
418           )
419         (switcap:write-title-block port (cdr ls)) ))))  
422 ;; The main TIMING block dispatcher
424 (define switcap:write-timing-block
425   (lambda (port ls)
426      (if (not (null? ls))
427       (let ((package (car ls)))
428         (cond   
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))
433           )
434         (switcap:write-timing-block port (cdr ls)) ))))  
437 ;; The main CIRCUIT block netlist dispatcher.  
439 (define switcap:write-netlist
440   (lambda (port ls)
441      (if (not (null? ls))
442       (let ((package (car ls)))
443         (cond   
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))
452           )
453         (switcap:write-netlist port (cdr ls)) ))))  
456 ;; The main ANALYSIS block dispatcher
458 (define switcap:write-analysis-block
459   (lambda (port ls)
460      (if (not (null? ls))
461       (let ((package (car ls)))
462         (cond   
463           ( (string=? (get-device package) "SWITCAP-analysis")
464               (switcap:write-analysis package port))
465           )
466         (switcap:write-analysis-block port (cdr ls)) ))))  
469 ;; ----------------------------------------------------------------------------
470 ;; Switcap netlist generation -- top level
471 ;; ----------------------------------------------------------------------------
472 (define switcap
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 ;; --------------------------------------------------------------------------