;;;; Part and model definitions.

(part-type 'resistor
           '(t1 t2)
           '(resistance) 
           '((any-model () ()
              (voltage)
              ((kvl
                (= (>> voltage)
                   (- (>> potential t1)
                      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
               (ohm
                (= (>> voltage)
                   (* (>> resistance)
                      (>> current t1)))))))
           '())

(part-type 'open-circuit
           '(t1 t2)
           '() 
           '((any-model () ()
              (voltage)
              ((kvl
                (= (>> voltage)
                   (- (>> potential t1)
                      (>> potential t2))))
               (kcl-1
                (= (dimensioned 0 amperes)
                    (>> current t1)))
               (kcl-2
                (= (dimensioned 0 amperes)
                   (>> current t2))))))
           '())

(part-type 'short-circuit
           '(t1 t2)
           '() 
           '((any-model () ()
              (current)
              ((kvl
                (= (>> potential t1)
                   (>> potential t2)))
	       (kcl
		(= (>> current t2)
		   (- (>> current t1))))
               (= (>> current t1)
                  (>> current)))))
           '())

(part-type 'vccs
           '(sense+ sense- t+ t-)
           '(transconductance)
           '((any-model () ()
              (vsense vout)
              ((kvl-sense
                (= (>> vsense)
                   (- (>> potential sense+)
                      (>> potential sense-))))
               (kcl-sense+
                (= (dimensioned 0 amperes)
                   (>> current sense+)))
               (kcl-sense-
                (= (dimensioned 0 amperes)
                   (>> current sense-)))
               (kvl-out
                (= (>> vout)
                   (- (>> potential t+)
                      (>> potential t-))))
	       (kcl-out
		(= (>> current t-)
		   (- (>> current t+))))
               (control
                (= (>> current t+)
                   (* (>> transconductance)
                      (>> vsense)))))))
           '())

(part-type 'vcvs
           '(sense+ sense- t+ t-)
           '(voltage-transfer-ratio)
           '((any-model () ()
              (vsense vout)
              ((kvl-sense
                (= (>> vsense)
                   (- (>> potential sense+)
                      (>> potential sense-))))
               (kcl-sense+
                (= (dimensioned 0 amperes)
                   (>> current sense+)))
               (kcl-sense-
                (= (dimensioned 0 amperes)
                   (>> current sense-)))
               (kvl-out
                (= (>> vout)
                   (- (>> potential t+)
                      (>> potential t-))))
	       (kcl-out
		(= (>> current t-)
		   (- (>> current t+))))
               (control
                (= (>> vout)
                   (* (>> transfer-ratio)
                      (>> vsense)))))))
           '())

(part-type 'cccs
           '(sense+ sense- t+ t-)
           '(current-transfer-ratio)
           '((any-model () ()
              (vout)
              ((kvl-sense
                (= (>> potential sense+)
                   (>> potential sense-)))
               (kcl-sense
                (= (>> current sense-)
                   (- (>> current sense+))))
               (kvl-out
                (= (>> vout)
                   (- (>> potential t+)
                      (>> potential t-))))
	       (kcl-out
		(= (>> current t-)
		   (- (>> current t+))))
               (control
                (= (>> current t+)
                   (* (>> current-transfer-ratio)
                      (>> current sense+)))))))
           '())

(part-type 'ccvs
           '(sense+ sense- t+ t-)
           '(transresistance)
           '((any-model () ()
              (vout)
              ((kvl-sense
                (= (>> potential sense+)
                   (>> potential sense-)))
               (kcl-sense
                (= (>> current sense-)
                   (- (>> current sense+))))
               (kvl-out
                (= (>> vout)
                   (- (>> potential t+)
                      (>> potential t-))))
	       (kcl-out
		(= (>> current t-)
		   (- (>> current t+))))
               (control
                (= (>> vout)
                   (* (>> transresistance)
                      (>> current sense+)))))))
           '())

;;; The following generic sources must be given a voltage and current
;;; for each model specified.

(part-type 'voltage-source
           '(t1 t2)
           '()
           '((any-model () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1)))))))
           '())

(part-type 'current-source
           '(t1 t2)
           '()
           '((any-model () ()
              (current)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (current-source
		(= (>> current)
		   (>> current t1))))))
           '())

(part-type 'dc-voltage-source
           '(t1 t2)
           '(strength)
           '((bias () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (voltage-source
		(= (>> voltage) (>> strength)))))
             ((incremental impedance) () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (shorted
		(= (>> voltage)
		   (dimensioned 0 volts)))))
	     (else () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1)))))))
           '())

(part-type 'voltage-signal-source
           '(t1 t2)
           '(strength)
           '(((incremental impedance) () ()
              (voltage)
	      ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (voltage-source
		(= (>> voltage) (>> strength)))))
             (else () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (shorted
		(= (>> voltage)
		   (dimensioned 0 volts))))))
           '())

(part-type 'capacitor
           '(t1 t2)
           '(capacitance)
           '((bias () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (opened
		(= (>> current t1)
		   (dimensioned 0 amperes)))))
             (incremental () ()
              (voltage)
              ((kvl
		(= (>> potential t1)
		   (>> potential t2)))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (shorted
		(= (>> voltage)
		   (dimensioned 0 volts)))))
             (impedance () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (s-plane
		(= (>> current t1)
		   (* (* (>> capacitance) *s*)
		      (>> voltage))))))
             (total () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (capacitor
		(= (>> current t1)
		   (* (>> capacitance)
		      (derivative (>> voltage))))))))
           '())

(part-type 'inductor
           '(t1 t2)
           '(inductance)
           '((bias () ()
              (voltage)
              ((kvl
		(= (>> potential t1)
		   (>> potential t2)))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (shorted
		(= (>> voltage)
		   (dimensioned 0 volts)))))
             (incremental () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (opened
		(= (>> current t1)
		   (dimensioned 0 amperes)))))
             (impedance () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (s-plane
		(= (>> voltage)
		   (* (* (>> inductance) *s*)
		      (>> current t1))))))
             (total () ()
              (voltage)
              ((kvl
		(= (>> voltage)
		   (- (>> potential t1)
		      (>> potential t2))))
               (kcl
		(= (>> current t2)
		   (- (>> current t1))))
	       (inductor
		(= (>> voltage)
		   (* (>> inductance)
		      (derivative (>> current t1))))))))
           '())

(define (*s* s) s)			; an identity function.

(part-type 'npn-bjt                     ; type name
           '(collector base emitter)    ; terminals
           '(beta I0)                   ; global parameters
           '((bias
              ()                        ; model-specific nodes
              ()                        ; model-specific parts
              (vbe vce vthreshold vsat) ; model-specific parameters
              ((kvl-ce                  ; model-specific relations
                (= (>> vce)
                   (- (>> potential collector)
                      (>> potential emitter))))
               (kvl-be
                (= (>> vbe)
                   (- (>> potential base)
                      (>> potential emitter))))
               (kcl
                (= (+ (>> current collector)
                      (>> current base))
                   (- (>> current emitter))))
	       (operation
		(try
		 (cutoff
		  (= (>> current collector) 
		     (dimensioned 0 amperes)))
		 (amplifying
		  (and (> (>> current collector)
			  (dimensioned 0 amperes))
		       (> (>> vce) (>> vsat))))
		 (switched-on
		  (and (> (>> current collector)
			  (dimensioned 0 amperes))
		       (<= (>> vce) (>> vsat))))))
               (beta-heuristic
                (try
		 (beta-infinite
		  (= (>> current base) 0))
                 (beta-finite
		  (= (>> current collector)
		     (* (>> beta)
			(>> current base))))))
               (vbe-heuristic
                (try
		 (emitter-follows
		  (= (>> vbe) (>> vthreshold)))
		 (exponential
		  (= (>> current collector)
		     (* (>> I0)
			(- (exp (* q/kT (>> vbe))) 1))))))
               (beta-typical
                (= (>> beta) 100))
               (I0-typical
                (= (>> I0) (dimensioned 1e-12 amperes)))
               (vthreshold-typical
                (= (>> vthreshold) (dimensioned 6/10 volts)))
               (vsat-typical
                (= (>> vsat) (dimensioned 0.2 volts)))))
             (incremental
	      ()                      ; model-specific nodes
              ((rpi resistor base   emitter) ; model-specific parts
               (source  vccs  base  emitter  collector emitter))
              ()                        ; model-specific parameters
              ((gm*rpi=beta             ; model-specific relations
                (= (* (>> transconductance source)
                      (>> resistance rpi))
                   (>> beta)))))
	     (else () () () ()))
           '((gm=q/kT*IC		; intermodel relations
              (= (:> (transconductance source) incremental)
                 (* (:> (current collector) bias) q/kT))
	      (bias incremental))))

(define q/kT (/ :e (* :k 300)))

(part-type 'pnp-bjt                     ; type name
           '(collector base emitter)    ; terminals
           '(beta I0)                   ; global parameters
           '((bias
              ()                        ; model-specific nodes
              ()                        ; model-specific parts
              (vbe vce vthreshold vsat) ; model-specific parameters
              ((kvl-ce                  ; model-specific relations
                (= (>> vce)
                   (- (>> potential collector)
                      (>> potential emitter))))
               (kvl-be
                (= (>> vbe)
                   (- (>> potential base)
                      (>> potential emitter))))
               (kcl
                (= (- (>> current collector))
                   (+ (>> current base)
                      (>> current emitter))))
	       (operation
		(try
		 (cutoff
		  (= (>> current collector) 
		     (dimensioned 0 amperes)))
		 (amplifying
		  (and (< (>> current collector)
			  (dimensioned 0 amperes))
		       (< (>> vce) (>> vsat))))
		 (switched-on
		  (and (< (>> current collector)
			  (dimensioned 0 amperes))
		       (>= (>> vce) (>> vsat))))))
               (beta-heuristic
                (try
		 (beta-infinite
		  (= (>> current base) 0))
                  (beta-finite
		   (= (>> current collector)
		      (* (>> beta)
			 (>> current base))))))
               (vbe-heuristic
                (try
		 (emitter-follows
		  (= (>> vbe) (>> vthreshold)))
		 (exponential
		  (= (>> current collector)
		     (* (- (>> I0))
			(- (exp (* -q/kT (>> vbe))) 1))))))
               (beta-typical
                (= (>> beta) 100))
               (I0-typical
                (= (>> I0) (dimensioned 1e-12 amperes)))
               (vthreshold-typical
                (= (>> vthreshold) (dimensioned -6/10 volts)))
               (vsat-typical
                (= (>> vsat) (dimensioned -0.2 volts)))))
             (incremental
	      ()                      ; model-specific nodes
              ((rpi resistor base   emitter) ; model-specific parts
               (source  vccs     base   emitter   collector emitter))
              ()                        ; model-specific parameters
              ((gm*rpi=beta             ; model-specific relations
                (= (* (>> transconductance source)
                      (>> resistance rpi))
                   (>> beta)))))
	     (else () () () ()))
           '((gm=q/kT*IC		; intermodel relations
              (= (:> (transconductance source) incremental)
                 (* -q/kT (:> (current collector) bias)))
	      (bias incremental))))


(define -q/kT (- q/kT))

(part-type 'nmos-fet                    ; type name
           '(drain gate source)         ; terminals
           '(k VT ron)			; global parameters
           '((bias
              ()                        ; model-specific nodes
              ()                        ; model-specific parts
              (vgs vds ve)              ; model-specific parameters
              ((kvl-gs                  ; model-specific relations
                (= (>> vgs)
                   (- (>> potential gate)
                      (>> potential source))))
               (kvl-ds
                (= (>> vds)
                   (- (>> potential drain)
                      (>> potential source))))
               (kcl
                (= (>> current source)
                   (- (>> current drain))))
	       (gate-open
		(= (>> current gate)
		   (dimensioned 0 amperes)))
	       (vedef
		(= (>> ve)
		   (- (>> vgs) (>> VT))))
	       (operation
		(try
		 (cutoff
		  (and (< (>> ve) (dimensioned 0 volts))
		       (= (>> current drain) 
			  (dimensioned 0 amperes))))
		 (amplifying
		  (and (and (< (dimensioned 0 volts) (>> ve))
			    (< (>> ve) (>> vds)))
		       (= (>> current drain)
			  (* 1/2 (>> k)
			     (square (>> ve))))))
		 (switched-on		; analog 
		  (and (and (< (dimensioned 0 volts) (>> vds))
			    (< (>> vds) (>> ve)))
		       (= (>> current drain)
			  (* (>> k)
			     (- (>> ve) (/ (>> vds) 2))
			     (>> vds)))))
		 (on			; digital
		  (and (< (dimensioned 0 volts) (>> ve))
		       (= (>> vds)
			  (* (>> ron)
			     (>> current drain)))))))))
             (incremental
	      ()			; model-specific nodes
              (				; model-specific parts
               (src  vccs     gate   source   drain source))
              ()                        ; model-specific parameters
              ()			; model-specific relations
	      )
	     (else () () () ()))
           '((gm=k*ve			; intermodel relations
              (= (:> (transconductance src) incremental)
                 (* (>> k) (:> (ve) bias)))
	      (bias incremental))))

(part-type 'pmos-fet                    ; type name
           '(drain gate source)         ; terminals
           '(k VT ron)			; global parameters
           '((bias
              ()                        ; model-specific nodes
              ()                        ; model-specific parts
              (vgs vds ve)              ; model-specific parameters
              ((kvl-gs                  ; model-specific relations
                (= (>> vgs)
                   (- (>> potential gate)
                      (>> potential source))))
               (kvl-ds
                (= (>> vds)
                   (- (>> potential drain)
                      (>> potential source))))
	       (kcl
                (= (>> current source)
                   (- (>> current drain))))
	       (gate-open
		(= (>> current gate)
		   (dimensioned 0 amperes)))
	       (vedef
		(= (>> ve)
		   (- (>> vgs) (>> VT))))
	       (operation
		(try
		 (cutoff
		  (and (< (dimensioned 0 volts) (>> ve))
		       (= (>> current drain) 
			  (dimensioned 0 amperes))))
		 (amplifying
		  (and (and (< (>> ve) (dimensioned 0 volts))
			    (< (>> vds) (>> ve)))
		       (= (>> current drain)
			  (* -1/2 (>> k)
			     (square (>> ve))))))
		 (switched-on
		  (and (and (< (>> vds) (dimensioned 0 volts))
			    (< (>> ve) (>> vds)))
		       (= (>> current drain)
			  (* -1 (>> k)
			     (- (>> ve) (/ (>> vds) 2))
			     (>> vds)))))
		 (on			; digital
		  (and (< (>> ve) (dimensioned 0 volts))
		       (= (>> vds)
			  (* (>> ron)
			     (>> current drain)))))))))
             (incremental
	      ()			; model-specific nodes
              (				; model-specific parts
               (src vccs     gate   source   drain source))
              ()                        ; model-specific parameters
              ()			; model-specific relations
	      )
	     (else () () () ()))
           '((gm=k*ve			; intermodel relations
              (= (:> (transconductance src) incremental)
                 (* (>> k) (:> (ve) bias)))
	      (bias incremental))))

;(k-typical (= (>> k) 0.002))
;(VT-typical (= (>> VT) (dimensioned 1 volts)))
