[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-user: [PATCH] for spice-sdb several fixes / cleanups



Greetings,

I've attached some scheme code patches for gnet-spice-sdb.scm. They are up for discussion. :-)

There is a bug related to the file attribute that seems to cause the variable "type" to be bound globally when a file is read in. This obscures another bug in write-ic and write-subcircuit where type is referenced but not localized. The value that the global type ended up with was something like "" and no one noticed when some symbols didn't have type set. In the process of adding a local copy I followed the advice in the comments that the two routines should be combined since they were virtual clones, so everything calls write-ic now.

There is another bug where get-package-attribute sometimes returns a "?" instead of "unknown". This caused workarounds like:

-         ;; sometimes get-package-attribute returns "?" instead of "unknown".  WTF?  This should fix that . . .

-         (if (string-ci=? model-file "?")
-             (set! model-file "unknown"))
-

to appear. I was about to add another one but tried to fix it instead. (Patch 3114991 in gaf patches)


I did a general clean up to write-net-names-on-component that may make it more flexible. The code is about the same length when the debug statements are removed, though I had to add a couple of small utility routines. Calling it would change from this:

-    (spice-sdb:write-net-names-on-component package (length (gnetlist:get-pins package)) port)

to this:

+    (spice-sdb:write-net-names-on-component package port)

I ran make tests and it passes.

Please let me know what you think

	Thanks,
	Clif
diff -ru4 a/src/gnet-spice-sdb.scm b/src/gnet-spice-sdb.scm
--- a/src/gnet-spice-sdb.scm	2010-11-22 20:04:11.000000000 -0800
+++ b/src/gnet-spice-sdb.scm	2010-11-22 19:36:00.000000000 -0800
#
# Here are my utility routines
#
@@ -358,8 +359,40 @@
     (null? (string->list string))
   )
 )
 
+
+;;----------------------------------------------------------
+;;  This returns a list of all the integers from start to
+;;  stop. It is similar to perl's range operator '..'
+;;----------------------------------------------------------
+(define range
+  (lambda (start stop)
+    (if (<= start stop) (cons start (range (1+ start) stop)) '())
+  )
+)
+
+
+;;----------------------------------------------------------
+;;  This is a simple version of filter-map from SRFI-1 in
+;;  that it only accepts one list. It takes a function and
+;;  applies it to each element of the list and builds a new
+;;  list out of all the non-false results.
+;;----------------------------------------------------------
+(define spice-sdb:filter-map
+  (lambda (fcn lst)
+    (if (null? lst) '() 
+      (let ((result (fcn (car lst))))
+	(if result
+          (cons result (spice-sdb:filter-map fcn (cdr lst)))
+	  (spice-sdb:filter-map fcn (cdr lst))
+	)
+      )
+    )
+  )
+)
+
+
 ;;----------------------------------------------------------
 ;; Given a filename, open the file, get the first line,
 ;; and see if it is a .MODEL or .SUBCKT file.  
 ;; Returns either ".MODEL" or ".SUBCKT" or "OTHER"
#
# Changes from the write-net-names-on-component cleanup
#
@@ -598,9 +630,9 @@
       (display "* begin vccs expansion, g<name>\n" port)
           ;; implement the controlled current source
           ;; the user should create a refdes label beginning with a g
       (display (string-append package " ") port)
-      (spice-sdb:write-net-names-on-component package (length (gnetlist:get-pins package)) port)
+      (spice-sdb:write-net-names-on-component-new package port)
        (display  (string-append (spice-sdb:component-value package) "\n")  port)
           ;; implement the voltage measuring current source
           ;; imagine yourself copying the voltage of a voltage source with an internal
           ;; impedance, spice starts complaining about unconnected nets if this current
@@ -621,9 +653,9 @@
       (display "* begin vcvs expansion, e<name>\n" port)
           ;; implement the controlled voltage source
           ;; the user should create a refdes label beginning with an e
       (display (string-append package " ") port)
-      (spice-sdb:write-net-names-on-component package (length (gnetlist:get-pins package)) port)
+      (spice-sdb:write-net-names-on-component-new package port)
       (display (string-append (gnetlist:get-package-attribute package "value") "\n" ) port)
           ;; implement the voltage measuring current source
           ;; imagine yourself copying the voltage of a voltage source with an internal
           ;; impedance, spice starts complaining about unconnected nets if this current
@@ -647,9 +679,9 @@
     ( begin
       (display "* begin nullor expansion, e<name>\n" port)
           ;; implement the controlled voltage source
       (display (string-append "E-" package " ") port)
-      (spice-sdb:write-net-names-on-component package (length (gnetlist:get-pins package)) port)
+      (spice-sdb:write-net-names-on-component-new package port)
       (display (string-append (gnetlist:get-package-attribute package "value") "\n" ) port)
           ;; implement the voltage measuring current source
           ;; imagine yourself copying the voltage of a voltage source with an internal
           ;; impedance, spice starts complaining about unconnected nets if this current
#
# Fixing and combining write-ic and write-subcircuit
#
@@ -774,124 +806,40 @@
 
 
 ;;----------------------------------------------------------------
 ;;  spice-sdb:write-ic
-;;  This writes out a valid ic line.
+;;  This writes out a valid ic or subcircuit line.
 ;;  The algorithm is as follows:
-;;  1.  Figure out what type of model goes with this part from 
+;;  1.  Figure out what type of model goes with this part from
 ;;      file-info-list.  If it isn't listed, look for a MODEL attribute.
 ;;      If MODEL attribute is attached, write out SPICE card, and then
 ;;      write out .MODEL on next line.
-;;      If no MODEL attribute is attached, just write out what litte 
+;;      If no MODEL attribute is attached, just write out what little 
 ;;      we know.  Then return
 ;;  2.  If the model-name is in the file-info-list, get the associated
 ;;      file-type.  Compare it against the component's refdes.  If model-type 
-;;      == .SUBCKT and refdes doesn't begin with X, prepend an X to the refdes.
+;;      is .MODEL or .SUBCKT and refdes doesn't begin with a U or X
+;;      respectively, prepend the correct prefix to the refdes.
 ;; 3.   Print out the rest of the line.     
 ;;
 ;;----------------------------------------------------------------
 (define spice-sdb:write-ic
   (lambda (package file-info-list port)
 
-    (debug-spew (string-append "Found ic.  Refdes = " package "\n"))
-
     ;; First do local assignments
-    (let ((model-name (gnetlist:get-package-attribute package "model-name"))
+    (let ((first-char (string (string-ref package 0)))  ;; extract first char of refdes
+	  (model-name (gnetlist:get-package-attribute package "model-name"))
 	  (model (gnetlist:get-package-attribute package "model"))
 	  (value (gnetlist:get-package-attribute package "value"))
+          (type  (gnetlist:get-package-attribute package "type"))
 	  (model-file (gnetlist:get-package-attribute package "file"))
 	  (list-item (list))
 	 )   ;; end of local assignments
 
-    ;; First, if model-name is empty, we use value attribute instead.
-    ;; We do this by sticking the contents of "value" into "model-name".
-      (if (string=? model-name "unknown")
-	  (set! model-name value))
-      
-    ;; Now get item from file-info-list using model-name as key
-      (set! list-item (spice-sdb:get-file-info-list-item model-name file-info-list))
-
-    ;; check to see if list-item is null.
-      (if (null? list-item)
-
-    ;; list-item is null.  Evidently, we didn't discover any files holding this model.  
-    ;; Instead we look for model attribute
-	  (if (not (string=? model "unknown"))             
-	    (begin                                     ;; model attribute exists -- write out card and model.
-	      (debug-spew "Model info not found in model file list, but model attribute exists.  Write out spice card and .model line..\n") 
-              (spice-sdb:write-component-no-value package port)
-              (display (string-append model-name "\n" ) port)
-	      (display (string-append ".MODEL " model-name " " type " (" model ")\n") port)
-	    )
-	    (begin                                     ;; no model attribute either.  Just write out card.
-	      (debug-spew "Model info not found in model file list.  No model attribute either.  Just write what we know.\n")
-              (spice-sdb:write-component-no-value package port)
-              (display (string-append model-name "\n" ) port)
-	    )
-	  )   ;; end if (not (string=? . . . .
-
-    ;; list-item is not null.  Therefore we process line depending upon contents of list-item
-	  (let ((file-type (caddr list-item)) )
-	   (cond 
-	      ;; ---- file holds a model ----
-	      ((string=? file-type ".MODEL") 
-	       (begin
-		(debug-spew (string-append "Found .MODEL with model-file and model-name for " package "\n")) 
-                 (spice-sdb:write-prefix package "U" port)  ;; this appends an "U" to the refdes since we have a .model
-                 (spice-sdb:write-component-no-value package port)
-                 (display (string-append model-name "\n" ) port)
-		(debug-spew "We'll handle the file contents later . . .\n")
-	       ))
-
-	      ;; ---- file holds a subcircuit ----
-	      ((string=? file-type ".SUBCKT") 
-	       (begin
-		 (debug-spew (string-append "Found .SUBCKT with model-file and model-name for " package "\n")) 
-                 (spice-sdb:write-prefix package "X" port)  ;; this appends an "X" to the refdes since we have a .subckt
-                 (spice-sdb:write-component-no-value package port)
-                 (display (string-append model-name "\n" ) port)
-		 (debug-spew "We'll handle the file contents later . . .\n")
-	       ))
-	   )  ;; close of inner cond
-	 )   ;; end of inner let
-       )  ;; end of if (null? list-item
-
-  ) ;; end of outer let
- )
-)
-
-
-;;----------------------------------------------------------------
-;;  spice-sdb:write-subcircuit
-;;  This writes out a valid subcircuit line.
-;;  The algorithm is as follows:
-;;  1.  Figure out what type of model goes with this part from 
-;;      file-info-list.  If it isn't listed, look for a MODEL attribute.
-;;      If MODEL attribute is attached, write out SPICE card, and then
-;;      write out .MODEL on next line.
-;;      If no MODEL attribute is attached, just write out what little 
-;;      we know.  Then return.
-;;  2.  If the model-name is in the file-info-list, get the associated
-;;      file-type.  Compare it against the component's refdes.  If model-type 
-;;      == .MODEL and refdes doesn't begin with U, prepend an U to the refdes.
-;; 3.   Print out the rest of the line.     
-;;
-;;  Note:  This is basically a clone of write-ic.  I can probably just
-;;         eliminate this fcn and call write-ic for all U or X refdeses.
-;;         Maybe on the next revision?
-;;----------------------------------------------------------------
-(define spice-sdb:write-subcircuit
-  (lambda (package file-info-list port)
-
-    (debug-spew (string-append "Found subcircuit.  Refdes = " package "\n"))
-
-    ;; First do local assignments
-    (let ((model-name (gnetlist:get-package-attribute package "model-name"))
-	  (model (gnetlist:get-package-attribute package "model"))
-	  (value (gnetlist:get-package-attribute package "value"))
-	  (model-file (gnetlist:get-package-attribute package "file"))
-	  (list-item (list))
-	 )   ;; end of local assignments
+      (cond
+        ((string=? first-char "U") (debug-spew (string-append "Found ic.  Refdes = " package "\n")))
+        ((string=? first-char "X") (debug-spew (string-append "Found subcircuit.  Refdes = " package "\n")))
+      )
 
     ;; First, if model-name is empty, we use value attribute instead.
     ;; We do this by sticking the contents of "value" into "model-name".
       (if (string=? model-name "unknown")
@@ -909,9 +857,11 @@
 	    (begin                                     ;; model attribute exists -- write out card and model.
 	      (debug-spew "Model info not found in model file list, but model attribute exists.  Write out spice card and .model line..\n") 
               (spice-sdb:write-component-no-value package port)
               (display (string-append model-name "\n" ) port)
-	      (display (string-append ".MODEL " model-name " " type " (" model ")\n") port)
+	      (display (string-append ".MODEL " model-name " ") port)
+	      (if (not (string=? type "unknown")) (display (string-append type " ") port))  ;; If no type then just skip it.
+	      (display (string-append "(" model ")\n") port)
 	    )
 	    (begin                                     ;; no model attribute either.  Just write out card.
 	      (debug-spew "Model info not found in model file list.  No model attribute either.  Just write what we know.\n")
               (spice-sdb:write-component-no-value package port)
@@ -925,9 +875,9 @@
 	      ;; ---- file holds a model ----
 	      ((string=? file-type ".MODEL") 
 	       (begin
 		(debug-spew (string-append "Found .MODEL with model-file and model-name for " package "\n")) 
-                 (spice-sdb:write-prefix package "U" port)  ;; this prepends an "U" to the refdes if needed
+                 (spice-sdb:write-prefix package "U" port)  ;; this prepends an "U" to the refdes if needed, since we have a .model
                  (spice-sdb:write-component-no-value package port)
                  (display (string-append model-name "\n" ) port)
 		(debug-spew "We'll handle the file contents later . . .\n")
 	       ))
@@ -935,9 +885,9 @@
 	      ;; ---- file holds a subcircuit ----
 	      ((string=? file-type ".SUBCKT") 
 	       (begin
 		 (debug-spew (string-append "Found .SUBCKT with model-file and model-name for " package "\n")) 
-                 (spice-sdb:write-prefix package "X" port)  ;; this appends an "X" to the refdes if needed
+                 (spice-sdb:write-prefix package "X" port)  ;; this prepends an "X" to the refdes if needed, since we have a .subckt
                  (spice-sdb:write-component-no-value package port)
                  (display (string-append model-name "\n" ) port)
 		 (debug-spew "We'll handle the file contents later . . .\n")
 	       ))
#
# The new write-net-names-on-component
# I left the old one in for comparisons sake.
#
@@ -1293,17 +1247,63 @@
   )
 )
 
 
+;;--------------------------------------------------------------------
+;; Given a refdes and port, this writes out the nets
+;; attached to the component's pins.  This is used to write out
+;; non-slotted parts.  Call it with a component refdes and port.
+;;--------------------------------------------------------------------
+(define spice-sdb:write-net-names-on-component-new
+  (lambda (refdes port)
+    
+;; get-net-name -- helper function. Called with pinseq, returns net name,
+;; unless net name is "ERROR_INVALID_PIN" then it returns false.
+    (define get-net-name
+      (lambda (pin)
+        (set! pin (number->string pin))
+
+;; -------  Super debug stuff  --------
+          (if #f
+	    (begin
+	      (debug-spew "  In write-net-names-on-component. . . . \n")
+	      (debug-spew (string-append "     pin-name = " pin "\n"))
+	      (debug-spew (string-append "     pinnumber = " (gnetlist:get-attribute-by-pinseq refdes pin "pinnumber") "\n"))
+	      (debug-spew (string-append "     pinseq = " (gnetlist:get-attribute-by-pinseq refdes pin "pinseq")))
+	      (if (not (string=? pin (gnetlist:get-attribute-by-pinseq refdes pin "pinseq")))
+		(debug-spew " <== INCONSISTANT!\n")
+		(debug-spew "\n") )
+	      (debug-spew (string-append "     netname = " (car (spice-sdb:get-net refdes (gnetlist:get-attribute-by-pinseq refdes pin "pinnumber"))) "\n"))
+	  )) ;; if #T for super debugging
+;; ------------------------------------- 
+
+	(set! pin (car (spice-sdb:get-net refdes (gnetlist:get-attribute-by-pinseq refdes pin "pinnumber"))))
+	(if (string=? pin "ERROR_INVALID_PIN")
+	  (begin
+	    (debug-spew (string-append "For " refdes ", found pin with no pinseq attribute.  Ignoring. . . .\n"))
+	    #f)  ;; begin
+	  pin)  ;; if
+      )
+    )  ;; define get-net-name
+
+    ;; First do local assignments
+    (let ((netnames (spice-sdb:filter-map get-net-name (range 1 (length (gnetlist:get-pins refdes)))))
+         )  ;; let
+      (display (string-join netnames " " 'suffix) port)     ;; write out nets.
+    )  ;; let
+  )
+)
+
+
 ;;-------------------------------------------------------------------
 ;; Write the refdes and the net names connected to pins on this component.
 ;; No return, and no component value is written, or extra attribs.
 ;; Those are handled later.
 ;;-------------------------------------------------------------------
 (define spice-sdb:write-component-no-value
   (lambda (package port)
     (display (string-append package " ") port)  ;; write component refdes
-    (spice-sdb:write-net-names-on-component package (length (gnetlist:get-pins package)) port)
+    (spice-sdb:write-net-names-on-component-new package port)
   )
 )


#
# Other changes part of the write-ic consolidation
#
@@ -1493,10 +1492,10 @@
 ;;            in this case so that the spice simulator will barf if the user
 ;;            has been careless.)
 ;;      U? -- Invokes write-ic. This provides the opportunity for a component
 ;;            model to be instantiated.
-;;      X? -- Invokes write-subcircuit.  This provides the opportunity for a component
-;;            model to be instantiated. 
+;;      X? -- Invokes write-ic.  This provides the opportunity for a component
+;;            subcircuit to be instantiated. 
 ;;      V? -- Invokes write-independent-voltage-source
 ;;      I? -- Invokes write-independent-current-source
 ;;      Otherwise, it just outputs the refdes, the attached nets, and the 
 ;;      value of the "value" attribute.
@@ -1512,9 +1512,9 @@
        ((string=? first-char "M") (spice-sdb:write-transistor-diode package #f "<unknown>" (list) port))
        ((string=? first-char "U") (spice-sdb:write-ic package file-info-list port))
        ((string=? first-char "V") (spice-sdb:write-independent-voltage-source package port))
        ((string=? first-char "I") (spice-sdb:write-independent-current-source package port))
-       ((string=? first-char "X") (spice-sdb:write-subcircuit package file-info-list port))
+       ((string=? first-char "X") (spice-sdb:write-ic package file-info-list port))
        (else 
        (display (string-append "Found unknown component.  Refdes = " package "\n"))
         (spice-sdb:write-component-no-value package port)
         ;; write component value, if components have a label "value=#"
#
# Hopefully if patch 3114991 is accepted then this will no longer be nessasary
#
@@ -1646,12 +1644,8 @@
 	  (set! model (gnetlist:get-package-attribute package "model-name") )
 	  (set! value (gnetlist:get-package-attribute package "value") )
 	  (set! model-file (gnetlist:get-package-attribute package "file") )
 
-	  ;; sometimes get-package-attribute returns "?" instead of "unknown".  WTF?  This should fix that . . .
-	  (if (string-ci=? model-file "?")
-	      (set! model-file "unknown"))
-
 	  ;; Now run a series of checks to see if we should stick this file into the file-info-list
 	  ;; Check to see if "file" attribute is non-empty
 	  (if (not (string-ci=? model-file "unknown"))
 	      (begin 

_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user