1;;; gEDA - GPL Electronic Design Automation
2;;; gnetlist - gEDA Netlist
3;;; FutureNet2 backend
4;;; Copyright (C) 2003, 2005-2010 Dan McMahill
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.
20
21
22;;; Notes about futurenet2 (.NV2) format pinlists
23;;;
24;;;  - Case does not seem to be preserved so to avoid issues,
25;;;    simply output the netnames in all caps.
26;;;
27;;;  - Netname length is 8 characters max.  +,-, and _ are allowed
28;;;
29;;;  - How are DATA,3 and DATA,4 used?  In one example, DATA,4 is
30;;;    not used.  In the other DATA,3 and DATA,4 are identical and
31;;;    appear to be set to the value (10.0k for example) of the part.
32;;;
33;;;    From Ferenc Marton (martonf at datapress dot hu):
34;;;
35;;;    These get combined in Ranger2 to produce the device
36;;;    description with a "," separating the two entries.
37;;;    DATA,3 is the "device name", max of 5 characters
38;;;    DATA,4 is the "device value", max of 13 characters.
39;;;    We could put the footprint into DATA,4
40;;;
41;;;  - In the "PIN" and "SIG" lines, what are the various fields really
42;;;    doing?
43;;;
44;;;    It seems that for a PIN line, the format is:
45;;;
46;;;    PIN,,<netname>,1-1,5,<net attribute number>,<pinnumber>
47;;;
48;;;    What are the "1-1" and the "5"?  On the <net attribute
49;;;    number> I've seen "23", "25", and "100".  Maybe these
50;;;    indicate signal vs power or some sort of routing preference?
51;;;
52;;;    For a SIG line, the format seems to be:
53;;;
54;;;    SIG,<netname>,1-1,5,<netname>
55;;;
56;;;    What exactly are "1-1" and "5"?  I think maybe the "1-1" part
57;;;    has something to do with sheet number in a multipage schematic.
58;;;
59
60
61;; This procedure takes a net name as determined by gnetlist and
62;; modifies it to be a valid FutureNet2 net name.
63;;
64(define futurenet2:map-net-names
65  (lambda (net-name)
66    (let ((rx (make-regexp "^unnamed_net"))
67	  (net-alias net-name)
68          )
69      ;; XXX we should use a dynamic regexp based on the current value
70      ;; for the unnamed net base string.
71
72      ;; Remove "unnamed_net" and replace with "NET"
73      (if (regexp-exec rx net-name)
74	    (set! net-alias (string-append "NET" (substring net-name 11)))
75	    )
76
77      ;; Truncate to 8 characters
78      (if (> (string-length net-alias) 8)
79	  (set! net-alias (substring net-alias 0 8))
80	  )
81      ;; Convert to all upper case
82      (string-upcase net-alias)
83      )
84    )
85  )
86
87;; This procedure takes a refdes as determined by gnetlist and
88;; modifies it to be a valid FutureNet2 refdes.
89;;
90(define futurenet2:map-refdes
91  (lambda (refdes)
92    (let ((refdes-alias refdes)
93          )
94
95      ;; XXX do we need to truncate to 8 characters
96      ;; like with net names?
97;;      (if (> (string-length refdes-alias) 8)
98;;	  (set! refdes-alias (substring refdes-alias 0 8))
99;;	  )
100
101      ;; Convert to all upper case
102      (string-upcase refdes-alias)
103      )
104    )
105  )
106
107;; write out the pins for a particular component
108(define futurenet2:component_pins
109  (lambda (port package pins)
110    (if (and (not (null? package)) (not (null? pins)))
111	(begin
112	  (let (
113		(pin (car pins)))
114	    ;;  PIN,,NetName,1-1,5,20/23,pinnum
115	    (display "PIN,," port)
116
117	    (display
118	     (gnetlist:alias-net (car (gnetlist:get-nets package pin)))
119	     port)
120
121	    ;; XXX I've seen 20, 23, and 100 in the position where the
122	    ;; "23" is here.  Seems to be a property like signal vs
123	    ;; power net.  Not sure how to support that.
124	    (display ",1-1,5,23," port)
125
126	    (display
127	     (gnetlist:get-attribute-by-pinnumber package pin "pinnumber")
128	     port)
129	    (newline port)
130	    )
131	  (futurenet2:component_pins port package (cdr pins))
132	  )
133	)
134    )
135  )
136
137
138;; write out the components
139(define futurenet2:components
140   (lambda (port packages symcnt)
141      (if (not (null? packages))
142         (begin
143            (let ((pattern (gnetlist:get-package-attribute (car packages)
144                                                           "pattern"))
145	    ;; The above pattern should stay as "pattern" and not "footprint"
146                  (package (car packages)))
147	      (display "(SYM," port)
148	      (display symcnt port)
149
150	      ;; write the reference designator
151	      (display "\nDATA,2," port)
152	      (display (gnetlist:alias-refdes package) port)
153
154	      ;; If there is a "value" attribute, output that.
155	      ;; Otherwise output the "device" attribute (the symbol name).
156	      (display "\nDATA,3," port)
157	      (let
158		  ((val (gnetlist:get-package-attribute package
159							"value")) )
160		(if (string=? val "unknown")
161		    (set! val (gnetlist:get-package-attribute package "device") )
162		    )
163		(display  val port)
164		)
165	      (display "\n" port)
166
167	      ;; write the footprint
168	      (display "DATA,4," port)
169	      (display (gnetlist:get-package-attribute package
170						       "footprint")
171		       port)
172	      (display "\n" port)
173
174	      ;; write the pins
175	      (futurenet2:component_pins port package
176					 (gnetlist:get-pins package))
177
178	      ;; close the part
179	      (display ")\n" port)
180
181	      )
182            (futurenet2:components port (cdr packages) (+ symcnt 1))
183	    )
184	 )
185      )
186   )
187
188;; write out the nets
189(define futurenet2:write-net
190   (lambda (port netnames)
191      (if (not (null? netnames))
192         (let (
193	       (netname (car netnames))
194	       (alias (gnetlist:alias-net (car netnames)))
195	       )
196	   (display "SIG," port)
197	   (display alias port)
198	   (display ",1-1,5," port)
199	   (display alias port)
200	   (newline port)
201	   (futurenet2:write-net port (cdr netnames))
202	   )
203	 )
204      )
205   )
206
207;; The top level netlister for futurenet2
208(define futurenet2
209   (lambda (filename)
210     (newline)
211     (display "---------------------------------\n")
212     (display "gEDA/gnetlist FutureNet2 Backend\n")
213     (display "This backend is EXPERIMENTAL\n")
214     (display "Use at your own risk!\n")
215     (display "\n")
216     (display "You may need to run the output netlist\n")
217     (display "through unix2dos before importing to\n")
218     (display "Ranger2 or other windows based layout tools\n")
219     (display "---------------------------------\n\n")
220
221      (let ((port (open-output-file filename))
222	    (all-nets (gnetlist:get-all-unique-nets "dummy"))
223	    )
224
225	;; initialize the net-name aliasing
226        (gnetlist:build-net-aliases futurenet2:map-net-names all-unique-nets)
227
228	;; initialize the refdes aliasing
229        (gnetlist:build-refdes-aliases futurenet2:map-refdes packages)
230
231	;; write the header
232	(display "PINLIST,2\n" port)
233	(display "(DRAWING,GEDA.PIN,1-1\n" port)
234
235	;; write the components
236	(futurenet2:components port packages 1)
237	(display ")\n" port)
238
239	;; write the nets
240	(futurenet2:write-net port all-nets)
241
242	;; terminating ")"
243	(display ")\n" port)
244
245	;; close netlist
246	(close-output-port port)
247	)
248      )
249   )
250
251