;------------------------------------------------------------------------- ; ; Transistor stacks ; ; (c) 1996 California Institute of Technology ; Department of Computer Science ; Pasadena, CA 91125. ; ; Permission to use, copy, modify, and distribute this software ; and its documentation for any purpose and without fee is hereby ; granted, provided that the above copyright notice appear in all ; copies. The California Institute of Technology makes no representations ; about the suitability of this software for any purpose. It is ; provided "as is" without express or implied warranty. Export of this ; software outside of the United States of America may require an ; export license. ; ; $Id: stack.scm,v 1.1.1.1 2000/03/29 18:35:58 rajit Exp $ ; ;------------------------------------------------------------------------- (define stack.p ()) (define stack.n ()) (define stack.tallp ()) (define stack.talln ()) (letrec ( (flush-left-contacts 0) ; # of contacts that were placed ; flush left in the middle of a ; stack ;------------------------------------------------------------------------ ; The height of the transistor stack, assuming that the poly wires were ; not jogged and that there were no contacts in the middle of the ; stack. ;------------------------------------------------------------------------ (height-raw (lambda (num-transistors type) (+ (+ (* (- num-transistors 1) (+ (drc.min-spacing "poly") (drc.min-width "poly")) ) (* 2 (drc.min-overhang (string-append "gate-" (string-append type "diff") ) ) ) ) (drc.min-width "poly") ) ) ) ;------------------------------------------------------------------------ ; The height of the transistor stack ;------------------------------------------------------------------------ (height (lambda (num-transistors type) (+ (height-raw num-transistors type) (* flush-left-contacts (- (+ (* 2 (drc.min-spacing "contact-gate")) (drc.min-width "contact") ) (drc.min-spacing "poly") ) ) ) ) ) ;------------------------------------------------------------------------ ; Draw a poly wire. The wire jogs around contacts and is spaced so that ; there all the diffusion between the contact/poly/poly is squished out. ; Returns the new position of "dx" ;------------------------------------------------------------------------ (draw-poly (lambda (name dx y fullwidth a0 a1 a2 a3) (let* ((cur (getbox)) (nx (+ (car cur) dx)) (cury (cadr cur)) ) (begin (if (>? dx a2) (begin (box (car cur) cury (+ (car cur) fullwidth) (+ cury a3)) (paint "poly") ) (begin (box (car cur) cury (+ nx a0) (+ cury a3)) (paint "poly") (box (+ nx a1) (- cury y) (+ nx a0) cury) (paint "poly") (box (+ nx a1) (- cury y) (+ (car cur) fullwidth) (+ (- cury y) a3) ) (paint "poly") ) ) (eval (cons 'box cur)) (if (positive? (string-length name)) (label.draw name "poly") () ) (box (car cur) (+ cury a0) (car cur) (+ cury a0)) (+ dx a0) ) ) ) ) ;------------------------------------------------------------------------ ; Draw a contact. Placed in the "notch" of a poly wire if possible, or ; placed flush left. Returns the new "dx" value. ;------------------------------------------------------------------------ (draw-contact (lambda (name dx y a0 a1 a2 a3 a4 a5 yinc newdx type lastcontact big) (let* ((cur (getbox)) (nx (+ (car cur) dx)) (cury (cadr cur)) ) (begin (if (>? dx a0) (begin (set! flush-left-contacts (+ flush-left-contacts (if lastcontact 0 1)) ) (box (+ (car cur) a4) (+ (- cury a5) a1) (+ (+ (car cur) a4) a2) (+ (- cury a5) a3) ) (paint type) (if (positive? (string-length name)) (label.draw name type) () ) (box (car cur) (+ cury y) (car cur) (+ cury y)) (if lastcontact big newdx) ) (begin (box (+ nx a1) (+ (- (- cury y) a5) a1) (+ nx a3) (+ (- (- cury y) a5) a3)) (paint type) (if (positive? (string-length name)) (label.draw name type) () ) (box (car cur) cury (car cur) cury) (if lastcontact dx (+ dx y)) ) ) ) ) ) ) ;------------------------------------------------------------------------ ; Actually draws the stacks. c-name is either "pdc" or "ndc", depending ; on the type of stack. ;------------------------------------------------------------------------ (drawing-aux (let* ( (ca1 (drc.min-spacing "contact-gate")) (ca2 (drc.min-width "contact")) (ca3 (+ ca1 ca2)) (ca4 (drc.min-overhang "poly-gate")) (ca5 (drc.min-spacing "poly")) (ca6 (drc.min-width "poly")) (dxp (drc.min-overhang "pdiff-gate")) (dxn (drc.min-overhang "ndiff-gate")) (y (max 0 (+ ca2 (- (* 2 ca1) ca5)))) ) (lambda (nl gw dx c-name) (if (null? nl) (list dx y) (drawing-aux (cdr nl) gw (if (list? (car nl)) (draw-contact (caar nl) dx y (- (- gw ca1) ca2) ca1 ca2 ca3 ca4 ca5 (+ ca5 ca6) (- (+ ca4 ca3) ca5) c-name (null? (cdr nl)) (+ gw ca4) ) (draw-poly (car nl) dx y (+ gw ca4) (+ ca5 ca6) ca5 (- (- gw (+ ca5 ca6)) (if (=? (string-ref c-name 0) (string-ref "p" 0) ) dxp dxn)) ca6) ) c-name ) ) ) ) ) ;------------------------------------------------------------------------ ; Returns the number of gates in the stack. ;------------------------------------------------------------------------ (count-gates (lambda (l) (if (null? l) 0 (+ (count-gates (cdr l)) (if (list? (car l)) 0 1)) ) ) ) ;------------------------------------------------------------------------ ; Draws the transistor stacks and paints the diffusion layers. ;------------------------------------------------------------------------ (pn (lambda (name-list gate-width type) (let* ((dx-y (begin (box.push (getbox)) (set! flush-left-contacts 0) (if (list? (car name-list)) (begin (box.move 0 (- (drc.min-overhang (string-append "gate-" (string-append type "diff")) ) (+ (drc.min-width "contact") (drc.min-spacing "contact-gate") ) ) ) (draw.layer (string-append type "dc") (drc.min-width "contact") (drc.min-width "contact") ) (if (positive? (string-length (caar name-list))) (label.draw (caar name-list) (string-append type "dc")) () ) (box.move (uminus (drc.min-overhang "gate-poly")) (+ (drc.min-width "contact") (drc.min-spacing "contact-gate") ) ) (drawing-aux (cdr name-list) (+ gate-width (drc.min-overhang "gate-poly") ) gate-width (string-append type "dc") ) ) (begin (box.move (uminus (drc.min-overhang "gate-poly")) (drc.min-overhang "gate-pdiff") ) (drawing-aux name-list (+ gate-width (drc.min-overhang "gate-poly") ) gate-width (string-append type "dc") ) ) ) ) ) (dx (car dx-y)) (y (cadr dx-y)) (strip (+ (- dx (drc.min-overhang "poly-gate")) (drc.min-overhang (string-append type "diff-gate")) )) ) (begin (box.pop) (define ret-box (draw.layer (string-append type "diff") (min strip gate-width) (height (count-gates name-list) type)) ) (if ( stack-desc") ) (pn p-list gate-width "p") ) ) ) ;------------------------------------------------------------------------ ; Draw n-transistor stack, jogging poly to remove diffusion ;------------------------------------------------------------------------ (set! stack.n (lambda (gate-width n-list) (begin (if (and (number? gate-width) (is-a-stack? n-list)) #t (error "Usage: stack.n stack-desc") ) (pn n-list gate-width "n") ) ) ) ;------------------------------------------------------------------------ ; Draw p-transistor stack, straight poly ;------------------------------------------------------------------------ (set! stack.tallp (lambda (gate-width p-list) (begin (if (and (number? gate-width) (is-a-stack? p-list)) #t (error "Usage: stack.tallp stack-desc") ) (pntall p-list gate-width "p") ) ) ) ;------------------------------------------------------------------------ ; Draw n-transistor stack, straight poly ;------------------------------------------------------------------------ (set! stack.talln (lambda (gate-width n-list) (begin (if (and (number? gate-width) (is-a-stack? n-list)) #t (error "Usage: stack.talln stack-desc") ) (pntall n-list gate-width "n") ) ) ) ) )