; In LISP, load this file with
;   (load 'test.scm)
;
; Then run this predicate to build circuitry:
;   (makefacet)
;
; And run this predicate to list the objects in a subarea of the current facet:
;   (listobjects)

(display "To build facets, type: (makefacet)") (newline)

(define makefacet
    (lambda ()
	; create a facet called "tran-contact" in the current library
	(define myfacet (newnodeproto 'tran-contact (curlib)))

	; get pointers to the "P-Transistor" and "Metal-1-Polysilicon-1-Con" primitives
	(define tran (getnodeproto 'P-Transistor))
	(define contact (getnodeproto 'Metal-1-Polysilicon-1-Con))

	; get default sizes of these primitives
	(define tlowx  (getval tran 'lowx))
	(define thighx (getval tran 'highx))
	(define tlowy  (getval tran 'lowy))
	(define thighy (getval tran 'highy))
	(define clowx  (getval contact 'lowx))
	(define chighx (getval contact 'highx))
	(define clowy  (getval contact 'lowy))
	(define chighy (getval contact 'highy))

	; get pointer to Polysilicon arc and its default width
	(define arctype (getarcproto 'Polysilicon-1))
	(define width (getval arctype 'nominalwidth))

	; create the transistor and the contact to its left
	(define c1 (newnodeinst contact clowx chighx clowy chighy 0 0 myfacet))
	(define t1 (newnodeinst tran (+ tlowx 8000) (+ thighx 8000) tlowy thighy 0 0 myfacet))

	; get the transistor's left port coordinates
	(define tport (getportproto tran 'p-trans-poly-left))
	(define tpos (portposition t1 tport))

	; get the contacts's only port coordinates
	(define cport (getval contact 'firstportproto))
	(define cpos (portposition c1 cport))

	; run a wire between the primitives
	(newarcinst arctype width 0 t1 tport (vector-ref tpos 0) (vector-ref tpos 1)
	    c1 cport (vector-ref cpos 0) (vector-ref cpos 1) myfacet)

	; make ports from the transistor
	(newportproto myfacet t1 (getportproto tran 'p-trans-diff-top) 'topdiff)
	(newportproto myfacet t1 (getportproto tran 'p-trans-diff-bottom) 'botdiff)

	; create a facet called "two-trans"
	(define higherfacet (newnodeproto 'two-trans (curlib)))

	; get pointer to the "tran-contact" facet
	(define t-c (getnodeproto 'tran-contact))

	; get size of this facet
	(define lowx  (getval t-c 'lowx))
	(define highx (getval t-c 'highx))
	(define lowy  (getval t-c 'lowy))
	(define highy (getval t-c 'highy))

	; create the two facet instances, one above the other
	(define o1 (newnodeinst t-c lowx highx lowy highy 0 0 higherfacet))
	(define o2 (newnodeinst t-c lowx highx (+ lowy 10000) (+ highy 10000)
		0 0 higherfacet))

	; get pointer to P-Diffusion arc and its default width
	(define darctype (getarcproto 'P-Active))
	(define dwidth (getval darctype 'nominalwidth))

	; get the bottom facet's top port
	(define lowport (getportproto myfacet 'topdiff))
	(define lowpos (portposition o1 lowport))

	; get the top facet's bottom port
	(define highport (getportproto myfacet 'botdiff))
	(define highpos (portposition o2 highport))

	; run a wire between the primitives
	(newarcinst darctype dwidth 0
	    o1 lowport (vector-ref lowpos 0) (vector-ref lowpos 1)
	    o2 highport (vector-ref highpos 0) (vector-ref highpos 1) higherfacet)
    )
)

(define listobjects
    (lambda ()
	(define myfacet (getval (curlib) 'curnodeproto))
	(define key (initsearch 2000 10000 -3000 3000 myfacet))
	(do
	    (
		(object (nextobject key) (nextobject key))
	    )
	    ((null? object))

	    (define type (getval object 'entrytype))
	    (if (= type 1)
		(format #t "Found ~s node~%"
		    (describenode (getval object 'entryaddr))
		)
		(format #t "Found ~s arc~%"
		    (getval
			(getval (getval object 'entryaddr) 'proto)
		    'protoname)
		)
	    )
	)
    )
)

(define describenode
    (lambda (node)
	(define proto (getval node 'proto))
	(if (= (getval proto 'index) 0)
	    (getval (getval proto 'cell) 'cellname)
	    (getval proto 'primname)
	)
    )
)
