;; -*- Mode:LISP; Package:USER; Readtable:CL; Base:10 -*- ;; Bobp, 10/86 ;; grid-locs for iop ;; checks: ;; plausible combinations of input, output and tri-state pins ;; plausible number of connections ;; each pin connects to at most one node ;; compare wirelists: ;; compare two wirelist by comparing in connection-location order ;; does not depend on node names ;; to-do: ;; find duplicate names that aren't XSIG's ;; finish checking loc-list ;; check that each pin connects to at most one node ;; warn that funcs that return node-names lose when name is multiply defined ;; for every node: check that chip-loc and chip-type are consistent ;; compare wirelists by sorting by connections and comparing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defstruct (wl (:type :list)) net ;;net as alist of nodes; ((nodename (conn conn ...)) (nodename ...)) ;; ordered by connection location lengths ;;net as (length node) alist; ((length (nodename (conn ...))) (length ...)) ;; ordered in decreasing length locations ;;alist of (loc chip-type) ;; ordered by location net-by-loc) ;;net as alist of locs; ((loc (conn node) (conn node) ...) (loc ...)) ;; ordered by location ;; structure of each element of connection-list (defstruct (conn (:type :list)) chip-loc pin-number pin-type pin-name chip-type path) ;; list of pal defstructs (defvar pal-database nil) ;; alist of (chip-loc pal-name) ;; ** typed in by hand ** (defvar pal-locs nil) ;; structure of an element of pal-database (defstruct (pal (:type :list)) name type comment pin-types) ;;(pin-number pin-type) ;; alist of (chip-loc (x-coord y-coord)) ;; generated by (make-grid-loc) (defvar grid-locs) ;; list of chip structs ;; alist of (chip-type pin-struct-list) (defvar chip-database nil) ;; chip-type is alist of (chip-type chip-struct) ;; chip-struct is list of pins ;; alist of (pin-number pin-name pin-type) (defstruct (pin (:type :list)) number name type) (defstruct (chip (:type :list)) type pins ;list of pin structs n-pins programmable-p socket) ;disembodied property list for :programmable-p, :socket-p, :fancy-socket-p ;; set by (redac-parse-k) and (telesys-parse-k) ;; save most recent values here (defvar p-net) (defvar p-locs) (defvar m-net) (defvar m-locs) ;; set by (redac-parse-iop) and (telesys-parse-iop) ;; save most recent values here (defvar iop-net) (defvar iop-locs) ;; set by (process-k-wire-list) and (process-iop-wire-list) ;; saves most recent values here (defvar locs) (defvar net) (defvar lengths) (defvar loc-list) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; save and restore state in qfasl files (defvar forms-to-save '(chip-database pal-database pal-locs grid-locs)) (defun save-all (&optional (dir-path "lm:bobp.k;")) (loop for q in forms-to-save when (and (boundp q) (symeval q)) (save-symbol-value q dir-path))) (defun save-symbol-value (q &optional (dir-path "lm:bobp.k;")) (let ((file (string-append dir-path (symbol-name q)))) (format t "~&~s:" file) (compiler:fasd-symbol-value file q))) (defun restore-all (&optional (dir-path "lm:bobp.k;")) (loop for q in forms-to-save do (let ((file (string-append dir-path (symbol-name q)))) (load file)))) (defun restore-symbol-value (q &optional (dir-path "lm:bobp.k;")) (let ((file (string-append dir-path (symbol-name q)))) (format t "~&~s:" file) (load file))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; parse REDAC style ascii wire-list ; sample format of REDAC style wirelist. ; package location database is ignored ; SIGNAL_NAME PHYLOC - PIN attrib NAME of PART_NM PATH/PAGE ; AD10 UN69 - 7 pin in A10 of CY7C171_25 @MEM_BD/NUBUS/7 ; VCC UA7 - (1) pin bi B2 of SIP_1K @PROC_BD/ALU/1 ; VCC UA29 - B14 supply VCC of WTL2264 @PROC_BD/ALU/2 ; 01234567890123456789012345678901234567890123456789012345678901234567890123456789 ; 1 2 3 4 5 6 7 (defvar redac-proc-file "angel://lmi//khh//falcon//PROC//PROC_BD//LMI_NET.LST") (defvar redac-mem-file "angel://lmi//khh//falcon//PROC//MEM_BD//LMI_NET.LST") (defun redac-parse-k () (multiple-value-setq (p-locs p-net) (redac-parse-file redac-proc-file "P_")) (multiple-value-setq (m-locs m-net) (redac-parse-file redac-mem-file "M_")) (process-k-wire-list p-net m-net p-locs m-locs)) (defvar redac-iop-file "angel://lmi//bobp//iop//LMI_NET.LST") (defun redac-parse-iop () (multiple-value-setq (iop-locs iop-net) (redac-parse-file redac-iop-file "")) (process-iop-wire-list iop-net iop-locs)) ;; read a redac wire-list file ;; return values are loc-list and net-list (defun redac-parse-file (f prefix &aux locs net) (with-open-file (s f) (setq locs (redac-parse-locs s prefix)) (setq net (redac-parse-net s prefix)) (values locs net))) (defun redac-parse-locs (s prefix) (redac-skip-lines s "NONPOLARIZED") (read-record s nil) (loop for l = (read-record s nil) while l until (string= l "") collect (redac-parse-loc-entry l prefix))) ;; first 5 are loc, next 16 are chip-type, rest is path ;; return list of (loc chip-type) (defun redac-parse-loc-entry (l prefix) (list (wintern (string-append prefix (redac-get-field l 0 5))) (wintern (redac-get-field l 5 21)))) (defun redac-parse-net (s prefix) (loop for node = (redac-parse-node s prefix) until (null node) collect node)) (defun redac-parse-node (s pfx &aux node-name) (and (redac-skip-lines s "SIGNAL_NAME") (let ((node-list (loop for l = (read-record s nil) while l until (string= l "") for (name conn) = (redac-parse-wire l pfx) do (setq node-name name) collect conn))) (format t "~a " node-name) (list node-name node-list)))) (defun redac-skip-lines (s pattern) (loop for l = (read-record s nil) unless l (return nil) when (string= l pattern :end1 (string-length pattern)) (return t))) (defun redac-parse-wire (l pfx) (list (wintern (string-append pfx (redac-get-field l 0 14))) ;name (make-conn ;conn :chip-loc (wintern (string-append pfx (redac-get-field l 16 20))) :pin-number (read-from-string (string-trim '(#\( #\)) (redac-get-field l 23 27))) :pin-type (read-from-string (string-subst-char #\- #\space (redac-get-field l 27 34))) :pin-name (wintern (redac-get-field l 35 40)) :chip-type (wintern (redac-get-field l 45 58)) :path (wintern (string-subst-char #\- #\/ (redac-get-field l 61) nil))) )) (defun redac-get-field (l from &optional to) (string-trim '(#\space) (substring l from to))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; parse Telesys style wire-list (defvar telesys-proc-file "angel://lmi//pace//wirelist//p") (defvar telesys-mem-file "angel://lmi//pace//wirelist//m") ; $PACKAGE ; (96DIN100)!DIN96;P1C ; (96DIN100)!DIN96;P1B ; $NETS ; AF0; E6.2 E4.3 E5.3 D6.2 , ; B10.5 B11.5 B12.5 ; AF1; E6.5 E4.4 E5.4 D6.5 , ; B10.11 B11.11 B12.11 (defun telesys-parse-k () (multiple-value-setq (p-locs p-net) (telesys-parse-file telesys-proc-file "P_")) (multiple-value-setq (m-locs m-net) (telesys-parse-file telesys-mem-file "M_")) (process-k-wire-list p-net m-net p-locs m-locs)) ;; read a telesys wire-list file ;; return values are loc-list and net-list (defun telesys-parse-file (f prefix) (with-open-file (s f) (let ((l (read-record s))) (unless (string-equal l "$package") (ferror nil "expected $package, got ~s" l))) (let* ((locs (telesys-parse-locs s prefix)) (net (telesys-parse-nets s prefix))) (values locs net)))) (defun telesys-parse-locs (s prefix) (loop for l = (read-record s nil) while l until (string-equal l "$nets") collect (telesys-parse-loc-entry l prefix))) ;; (pkg-type)!chip-type;loc ;; return list of (loc chip-type) (defun telesys-parse-loc-entry (l prefix) (let ((bang (string-search-char #\! l)) (semi (string-search-char #\; l))) (list (wintern (string-append prefix (substring l (1+ semi)))) (wintern (substring l (1+ bang) semi))))) (defun telesys-parse-nets (s prefix) (loop for l = (read-record s nil) while l until (string-equal l "$end") collect (telesys-parse-net l s prefix))) (defun telesys-parse-net (l1 s prefix &aux node-name) (let ((semi (string-search-char #\; l1))) (setq node-name (wintern (string-append prefix (substring l1 0 semi)))) (setq l1 (substring l1 (1+ semi)))) (let ((net (loop for l = l1 then (read-record s nil) while l for comma = (string-search-char #\, l) append (telesys-parse-net-line (substring l 0 comma) prefix) while comma))) (list node-name net))) (defun telesys-parse-net-line (l prefix) (setq l (string-trim '(#\space) l)) (loop for sp = (string-search-char #\space (string-trim '(#\space) l)) collect (telesys-to-conn (string-trim '(#\space) (substring l 0 sp)) prefix) while sp do (setq l (string-trim '(#\space) (substring l (1+ sp)))))) (defun telesys-to-conn (f prefix) (let ((dot (string-search-char #\. f))) (make-conn :chip-loc (wintern (string-append prefix (substring f 0 dot))) :pin-number (read-from-string (string-trim '(#\( #\)) (substring f (1+ dot))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; print from internal format (defun print-list (net) (loop for node in net (print-node node))) (defun print-node-name (n net) (cond ((symbolp n) (loop for node in (find-nodes n net) (print-node node))) (t (print-node n)))) (defun print-node (node &optional (dont-print-if-huge t)) (format t "~&~a: ~,1,-1f\"" (car node) (compute-length node)) (cond ((and dont-print-if-huge (> (length (cadr node)) 100)) (format t "~&~4t~d connections" (length (cadr node)))) (t (loop for conn in (cadr node) (format t "~&~4tpin ~d of ~a at ~a; ~a, ~a, ~a" ;;pin 3 of 74F00 at UN42; input, A10, path (conn-pin-number conn) (conn-chip-type conn) (conn-chip-loc conn) (conn-pin-type conn) (conn-pin-name conn) (conn-path conn)) (let ((pal-loc (assoc (conn-chip-loc conn) pal-locs))) (when pal-loc (format t " (~s)" (cadr pal-loc)))) (let ((grid-loc (cadr (assoc (conn-chip-loc conn) grid-locs)))) (when grid-loc (format t " (~d,~d)" (car grid-loc) (cadr grid-loc))))) (format t "~&")))) ;;;;;;;;;;;;;;;; ;; make a list of node names (defun node-names (net) (uniq (sort (loop for node in net collect (car node)) 'string-lessp))) ;; make a list of node names, ;; excluding XSIG nodes ;; and with the board prefix stripped (defun name-hack (net) (uniq (sort (loop for (name conn) in net for n = (substring name 2) unless (string-equal n "xsig" :end1 4) collect (wintern n)) 'string-lessp))) ;; make a list of node-names sorted by reversed-strings (defun name-rev (net) (let ((rl (sortcar (loop for n in (node-names net) collect (list (wintern (string-reverse (symbol-name n))) n)) 'string-lessp))) (loop for (rev name) in rl collect name))) ;; make a list of nodes whose count of connections meets a spec (defun find-by-length (net len &optional (pred '=)) (loop for node in net when (funcall pred (length (cadr node)) len) collect node)) ;; make a list of nodes with this name (defun find-nodes (name net) (loop for node in net when (eq name (car node)) collect node)) ;; make a list of nodes that connect to a chip (defun find-nodes-for-chip (loc net) (loop for node in net append (loop for conn in (cadr node) when (eq loc (conn-chip-loc conn)) collect node))) ;; make a list of nodes whose name contains the string (defun find-node-substring (s net) (loop for node in net when (string-search s (car node)) collect node)) ;; make a list of (node connection) for all chip pins (defun flat-conn-list (net) (loop for node in net append (loop for conn in (cadr node) collect (list node conn)))) ;; make a list of all chip locations that are used (defun all-chips (net) (uniq (sort (loop for node in (flat-conn-list net) collect (conn-chip-loc (cadr node))) 'string-lessp))) ;;;;;;;;;;;;;;;; (defun chart-conns (net) (loop for (conns num) in (count-conns net) (format t "~&~d node~:P with ~d connection~:P" num conns))) ;; make alist of (number-of-connections number-of-nodes-with-this-number) (defun count-conns (net) (sortcar (let (ll) (loop for (name conn) in net for count = (length conn) for lp = (assoc count ll) when lp (incf (cadr lp)) else (push (list count 1) ll)) ll) #'< )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; check wire-list by nodes (defun check-wire-list (net) (loop for node in net for err = (check-node node) when err do (format t "~2&~a " err) (print-node node) and collect node)) (defvar random-pin-types '(pin-foo pin-led pin-res)) ; error if none of output, bi or tri ; error if output and any of output, bi or tri (defun check-node (node) (loop for w in (cadr node) for pt = (conn-pin-type w) count (eq pt 'pin-in) into pin-in count (eq pt 'pin-out) into pin-out count (or (eq pt 'pin-tri) (eq pt 'pin-bi)) into pin-bi count (eq pt 'supply) into supply count (eq pt 'pin-conn) into pin-conn count (member pt random-pin-types) into pin-foo finally (cond ((and (zerop pin-foo) (or (> pin-out 2) (and (plusp pin-out) (not (zerop pin-bi))))) (return "Multiple outputs driving")) ((plusp pin-conn) (return nil)) ((or (zerop (+ pin-in pin-bi pin-foo supply)) (<= (length (cadr node)) 1)) (return "No inputs using")) ((and (zerop pin-foo) (zerop pin-out) (zerop pin-bi)) (return "No outputs driving")) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun hack-names (net) (loop for node in net collect (list (wintern (substring (symbol-name (car node)) 2)) (car node)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; make a list of pal locations for each pal name (defconst local-pals "lm:bobp.k.pals;*.*#>") (defconst angel-pals "angel://lmi//khh//falcon//PALS//*.SRC") (defconst iop-pals "angel://lmi//bobp//iop//*.pal") ;; parse all pal equation files in a directory ;; return a list of pal structures (defun parse-pal-directory (&optional (dir-path angel-pals)) (loop for (f) in (cdr (fs:directory-list dir-path)) do (format t "~&~s" (send f :string-for-printing)) (let ((pal (parse-pal-file f))) (let ((p (assoc (pal-name pal) pal-database))) (if p (setf (cdr p) (cdr pal)) (push pal pal-database)))))) (defun parse-pal-file (f) (with-open-file (s f) (parse-pal s))) ;; for all connections to pals in the wirelist, ;; set the pin-type to that indicated for the pal equation in the pal database (defun fix-pal-pins (locs net &optional verbose-p) (loop for (name conns) in net (loop for conn in conns for (loc pal-name) = (assoc (conn-chip-loc conn) pal-locs) when loc do (let* ((pal (assoc pal-name pal-database)) (new-type (cadr (assoc (conn-pin-number conn) (pal-pin-types pal))))) (when (and verbose-p (neq (conn-pin-type conn) new-type)) (format t "~&~s: changing pin ~d of ~s (~s) at ~s from ~s to ~s" name (conn-pin-number conn) (pal-name pal) (pal-type pal) loc (conn-pin-type conn) new-type)) (setf (conn-pin-type conn) new-type) )))) (defun fix-pals (wl) (fix-pal-pins (wl-locations wl) (wl-net wl))) (defun find-pal (name) (loop for pal in pal-database when (string-search name (pal-name pal)) collect pal)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; parse PAL pin types from pal files ; PAL16R4 B PAL DESIGN SPECIFICATION ; CH1_00 KENT HOULT ; CALL HARDWARE CONTROL PAL #1 9/09/86 ; ; C_PROC IR48 IR49 IR50 /TRAP1 RD5 RD6 /FRDEST /WOAR GND ; /OE /HP_DEC /HP_CNT H_WE /PREV_INC /PREV_DEC NC17 /RF_CE RF_SEL VCC ; ; IF(VCC) HP_DEC = /TRAP1 * /IR50 * /IR49 * IR48 ; OPEN ; + TRAP1 * PREV_INC (defun parse-pal (s) (let ((pal (make-pal))) (let ((l (read-record s))) ;pal type is first field of first line (setf (pal-type pal) (read-from-string l))) ; (let ((l (read-record s))) ;pal name is first field of second line ; (setf (pal-name pal) (read-from-string l))) ;;up to next blank line is comment (setf (pal-comment pal) (apply 'string-append (loop for l = (read-pal-record s) until (string= "" l) append (list l " ")))) ;;pal name is first field of second line (setf (pal-name pal) (read-from-string (pal-comment pal))) (let* ((out-lines (loop for l = (read-pal-record s) until (string= "" l) append (list l " "))) (pin-names (parse-pal-pin-names (apply 'string-append out-lines))) (out-list (parse-output-pins-from-equations s))) ;read equations (loop for (pin-num pin-name) in pin-names ;make pin-types list (let ((pin-type (cadr (assoc pin-name out-list)))) (push (list pin-num (or pin-type 'pin-in)) (pal-pin-types pal))))) pal)) (defun read-pal-record (s) (let ((l (read-record s nil))) (when l (string-trim '(#\space #\tab) (substring l 0 (string-search-char #\; l)))))) ;; make a list of (pin-name pin-type) for output pins (defun parse-output-pins-from-equations (s) (loop for l = (read-pal-record s) while l when (string-search-char #\= l) collect (parse-pal-equation l))) ;; return list of pin-name and pin-type (defun parse-pal-equation (l &aux (pin-type 'pin-out)) (setq l (substring l 0 (string-search-char #\= l))) (cond ((and (string= "IF" l :end2 2) (string-search-char #\( l)) (let ((cnd (string-trim '(#\space #\( #\) #\/ #\:) (substring l (string-search-char #\( l) (string-search-char #\) l))))) (unless (string= cnd "VCC") (setq pin-type 'pin-bi)))) ((string-search-char #\: l) (setq pin-type 'pin-bi))) (setq l (substring l (or (string-search-char #\) l) 0))) (list (wintern (string-trim '(#\space #\) #\/ #\: #\=) l)) pin-type)) ;; make a list of (pin-number pin-name) (defun parse-pal-pin-names (line) (loop for pin from 1 for sp = (string-search-char #\space line) while sp collect (let ((field (string-trim '(#\space #\/) (substring line 0 sp)))) (list pin (wintern field))) do (setq line (string-trim '(#\space) (substring line (1+ sp)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; wirelist tracer ... ; pick a signal name ; display all connections for that node ; click on a connection to get menu of other signals connected to that chip ; pick a chip and display all connections ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; trace-length measurer ;; for each chip location ;; compute a grid position for the boards hinged by the P4-P5 connectors ;; for each node ;; compute the minimum rectangle that contains all points ;(defun make-m-rows () ; (with-output-to-string (*standard-output*) ; (loop for i from 16 by 14 ; for c from #\a to #\j ; (format t "(m_~c ~d) " c i)))) (defun make-row-locs (st-row end-row first-row row-inc pfx) (loop for row from st-row to end-row for i from first-row by row-inc collect (list (wintern (format nil "~a~c" pfx row)) i))) (defconst p-row-locs '((p_a 16) (p_b 26) (p_c 36) (p_d 46) (p_e 58) (p_f 70) (p_g 84) (p_h 96) (p_i 106) (p_j 120) (p_k 134) (p_l 148))) (defconst m-row-locs-raw '((m_a 16) (m_b 30) (m_c 44) (m_d 58) (m_e 72) (m_f 86) (m_g 100) (m_h 114) (m_i 128) (m_j 142))) (defconst m-row-base (+ 154 148)) (defconst m-row-locs (loop for (name x) in m-row-locs-raw collect (list name (- m-row-base x)))) (defun make-iop-loc-grid () (setq grid-locs (append ;; A1 .. J33 (make-grid (make-row-locs #\A #\J 14 14 "") 1 33) ;; C25 .. C200, C300 .. C310, C025 .. C099 (make-simple 'C0 25 99 nil nil) (make-simple 'C 25 99 nil nil) (make-simple 'C 100 200 nil nil) (make-simple 'C 300 310 nil nil) ;; JP1 .. JP70 (make-simple 'JP 1 70 nil nil) (make-simple 'R0 1 9 nil nil) (make-simple 'R 10 15 nil nil) (make-simple 'R 50 65 nil nil) ;; CY1 (make-simple 'CY 1 1 nil nil) ;; P1A P1B P1C P2A P2B P2C P3A P3B P3C (make-din-connector 'p1 0 125) (make-din-connector 'p2 0 75) (make-din-connector 'p3 0 25) ;; P4 P5 P6 P7 P8 P9 P10 `(,(make-loc 'p4 150 20) ,(make-loc 'p5 150 35) ,(make-loc 'p6 150 50) ,(make-loc 'p7 150 90) ,(make-loc 'p8 150 140) ,(make-loc 'p9 135 80) ,(make-loc 'p10 135 105)) ;; S02 S03 S04 S05 S06 S07 S08 S09 (make-simple 's0 2 9 nil nil) ;; S1 S10 S11 S12 S13 S14 (make-simple 's 1 1 nil nil) (make-simple 's 10 14 nil nil) ;; SIM1 SIM2 SIM3 SIM4 (make-simple 'sim 1 4 70 90) `(,(make-loc 'simr nil nil)) ;; SW1 SW2 (make-simple 'sw 1 2 150 120) ;; CR01 .. CR03 (make-simple 'cr0 1 3 nil nil) (make-simple 'fet 1 1 nil nil) (make-simple 'led 0 0 150 112) ))) (defun make-k-loc-grid () (setq grid-locs (append ;; P_A1 .. P_L33 (make-grid p-row-locs 1 33) ;; M_A1 .. M_J33 (make-grid m-row-locs 1 33) ;; M_B27A M_B27B M_B27C M_F16A P_H13A (make-grid-aux (assoc 'm_b m-row-locs) 27 #\A #\C) (make-grid-aux (assoc 'm_f m-row-locs) 16 #\A #\A) (make-grid-aux (assoc 'p_h p-row-locs) 13 #\A #\A) ;; M_SIM0 .. M_SIMF (make-sim 'm_sim 0 15) ;; P_R1, M_R1..M_R6 (make-simple 'p_r 1 1 nil nil) (make-simple 'm_r 1 6 nil nil) ;; M_LED1 .. M_LED4 (make-simple 'm_led 1 4 (- m-row-base 140) 130) ;; P_P1A..C etc. (make-din-connector 'p_p5 154 30) (make-din-connector 'p_p4 154 100) (make-din-connector 'p_p1 0 110) (make-din-connector 'm_p5 (- m-row-base 146) 30) (make-din-connector 'm_p4 (- m-row-base 146) 100) (make-din-connector 'm_p1 m-row-base 110) )) nil) (defun make-loc (name x y) `(,(wintern name) (,x ,y))) (defun make-grid (row-list start-col end-col) (loop for (row-name x) in row-list append (loop for col from start-col to end-col collect (make-loc (format nil "~a~d" row-name col) x (fix (* (1- col) 4.5)))))) (defun make-grid-aux (name-x col from-c to-c) (loop for c from from-c to to-c collect (make-loc (format nil "~a~d~c" (car name-x) col c) (cadr name-x) (* (1- col) 4)))) (defun make-din-connector (name x y) (loop for row from #\A to #\C collect (make-loc (format nil "~a~c" name row) x y))) (defun make-simple (name first last x y) (loop for n from first to last collect (make-loc (format nil "~a~d" name n) x y))) (defun make-sim (name first last) (loop for sim from first to last collect (make-loc (format nil "~a~x" name sim) (- m-row-base 3 (* sim 3)) 32))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun compute-length (node &optional (verbose-p nil)) (multiple-value-bind (x-min y-min x-max y-max) (loop for conn in (cadr node) for (loc (x y)) = (assoc (conn-chip-loc conn) grid-locs) when x minimize x into x-min when y minimize y into y-min when x maximize x into x-max when y maximize y into y-max unless loc (format t "~&~s not defined for ~a" (conn-chip-loc conn) (car node)) finally (return (values x-min y-min x-max y-max))) (when verbose-p (format t "~&~s: x: ~d-~d, y: ~d-~d" (car node) x-min x-max y-min y-max)) (+ (abs (- x-min x-max)) (abs (- y-min y-max))))) (defun len-errs (net) (loop for node in net append (length-error node))) (defun length-error (node) (loop for conn in (cadr node) unless (assoc (conn-chip-loc conn) grid-locs) collect node)) ;; make an alist of (min-length node) (defun compute-lengths (net) (sortcar (loop for node in net collect (list (compute-length node) node)) '>)) ;;;;;;;;;;;;;;;; (defun find-by-loc (loc net) (uniq (sort (loop for node in net append (loop for conn in (cadr node) when (eq loc (conn-chip-loc conn)) collect (car node))) 'string-lessp) 'equal)) ;; change all conn-chip-loc refs of old to new (defun change-loc (old new net) (loop for (name conns) in net (loop for conn in conns when (eq old (conn-chip-loc conn)) do (format t "~&~s:" name) (setf (conn-chip-loc conn) new)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; non-critical bus lines to exclude from long-length output (defconst bus-list '(p_ir p_mpc p_outreg p_mfi p_mfo p_mfio m_mmfio m_bnu_ad vcc gnd)) (defconst iop-bus-list '(a backsw bvam d db fbad fbda hdb ia id mad madr md pd qa sd sdbi sdbo so va vadr vam vd virq vmeint)) (defun print-by-lengths (lengths &optional silent-p (bl bus-list) (min 0) (max 100)) (setq min (fix (* 10 min)) max (fix (* 10 max))) (loop for (len node) in lengths when (and (not (exclude-p (car node) bl)) (>= len min) (<= len max)) do (if silent-p (format t "~&~6,1,-1f\": ~a" len (car node)) (print-node node)))) (defun print-busses (lengths &optional (bl bus-list)) (let ((ex-list (sortcar (mapcar 'list bl) 'string-lessp))) (loop for (len node) in lengths for base-name = (wintern (alpha-part (car node))) for ex = (assoc base-name ex-list) when ex (push (list (car node) len) (cdr ex))) (let ((bus-out (sortcar (loop for ex in ex-list collect (let ((lens (sortcar (cdr ex) 'hairy-lessp))) (loop for (name len) in lens minimize len into min maximize len into max finally (return (list max min (car (first lens)) (caar (last lens))))))) '>))) (loop for (max min first last) in bus-out (format t "~&max=~4,1,-1f\" min=~4,1,-1f\": ~a..~a" max min first last))))) (defun exclude-p (name list) (memq (wintern (alpha-part name)) list)) (defun alpha-part (str) (substring str 0 (string-search-set "0123456789" str))) (defun print-len-greater (lengths) (loop for i from 0 to 36 (format t "~&~d longer than ~f" (length (len-compare lengths #'> (* i 10))) i))) (defun len-compare (lengths func lim) (loop for (len name) in lengths when (funcall func len lim) collect name)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; general transformation stuff ;; given the wirelists for the two boards, ;; do the top-level merge and processing stuff ;; return node-net list (defun process-k-wire-list (p-net m-net p-locs m-locs) (format t "~&processing locations:") (setq locs (process-locations p-locs m-locs)) (format t "~& merging wirelists:") (setq net (merge-boards p-net m-net)) (format t "~&processing net-list:") (setq net (process-net-list locs net)) (format t "~&computing lengths:") (setq lengths (compute-lengths net)) (format t "~&creating location-heirarchy net:") (setq loc-list (make-loc-list locs net)) (make-wl :net net :lengths lengths :locations locs :net-by-loc loc-list)) ;; given the wirelists for the iop board, ;; do the top-level processing stuff ;; return node-net list (defun process-iop-wire-list (iop-net iop-locs) (format t "~&processing locations:") (setq locs (process-locations iop-locs nil)) (format t "~&processing net-list:") (setq net (process-net-list locs iop-net)) (format t "~&computing lengths:") (setq lengths (compute-lengths net)) (format t "~&creating location-heirarchy net:") (setq loc-list (make-loc-list locs net)) (make-wl :net net :lengths lengths :locations locs :net-by-loc loc-list)) (defun process-locations (p-locs m-locs) (uniq (sortcar (append p-locs m-locs) 'string-lessp) 'equal)) (defun process-net-list (locs net) (format t "~& setting pin types from chip-database:") (fix-pin-types locs net) (format t "~& updating pal pin-types:") (fix-pal-pins locs net) (format t "~& sorting nodes by connection location:") (sort-net-by-loc net)) ;; splice together both wirelists ;; join through connectors ;; concatenate (defun merge-boards (pnet mnet) (merge-boards-by-connectors pnet mnet) (splice-nodes (assoc 'p_vcc pnet) (assoc 'm_vcc mnet) 'vcc) (splice-nodes (assoc 'p_gnd pnet) (assoc 'm_gnd mnet) 'gnd) (append (remove-empty-nodes pnet) (remove-empty-nodes mnet))) ;; splice a pair of nodes together ;; add second node's connections to first node (defun splice-nodes (n1 n2 &optional newname) (rplacd (last (cadr n1)) (cadr n2)) (setf (cadr n2) nil) (unless (string-equal (car n1) (car n2) :start1 2 :start2 2) (format t "~&splicing ~a and ~a" (car n1) (car n2))) (when newname (setf (car n1) newname))) ;; delete empty nodes leftover from splices (defun remove-empty-nodes (net) (loop for node in net when (cadr node) collect node)) ;;;;;;;;;;;;;;;; ; build list of nodes that include connectors p4 and p5 ; sort by connector and pin number ; compare node names for each side ; step lists for both boards and splice nodes ;; merge the P and M board wire-lists by splicing together ;; the nodes on either side of the inter-board connectors (defun merge-boards-by-connectors (pnet mnet) (loop for q in '(p4a p4b p4c p5a p5b p5c) (let ((p (wintern (string-append "P_" (symbol-name q)))) (q (wintern (string-append "M_" (symbol-name q))))) (merge-by-locs (make-pin-node-alist pnet p) (make-pin-node-alist mnet q))))) ;; given (pin-number node) alists for two locations, ;; splice together the nodes for corresponding pins (defun merge-by-locs (l1 l2) (loop for p1 in l1 for p2 = (assoc (car p1) l2) when p2 (splice-nodes (cadr p1) (cadr p2)))) ;; make an alist of (pin-number node) for the connections to a chip (defun make-pin-node-alist (net loc) (sortcar (loop for node in net append (loop for conn in (cadr node) when (eq loc (conn-chip-loc conn)) collect (list (conn-pin-number conn) node))) 'pin-lessp)) ;; make an alist of (pin-number node-name) for the connections to a chip (defun make-pin-nodename-alist (net loc) (sortcar (loop for node in net append (loop for conn in (cadr node) when (eq loc (conn-chip-loc conn)) collect (list (conn-pin-number conn) (car node)))) 'pin-lessp)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; check that each pin connects to at most one node ; make list of (conn node) ; sort by conn-chip-loc and conn-pin-number ;; make location-heirarchy form of net list. ;; make alist of (loc (conn node) (conn node) ...) ;; for all connections at each loc. ;; naive method results in list too big to sort. (defun make-loc-list (locs net) (let ((ll (uniq (sortcar (loop for (loc) in locs collect (list loc)) 'string-lessp) 'equal))) ;;build node list for each element of ll (loop for node in net (loop for conn in (cadr node) for loc = (assoc (conn-chip-loc conn) ll) when loc (push (list conn node) (cdr loc)))) ;;already sorted by loc, ;;now sort each loc by pins (loop for l in ll (setf (cdr l) (uniq (sortcar (cdr l) 'conn-lessp) 'conn-equal))) ll)) ;; print errors visible in location-heirarchy net. (defun check-loc-list (loc-list) (loop for l in loc-list (loop for (conn node) in (cdr l) and for last-conn = nil then conn and for last-node = nil then node when (eq (conn-pin-number conn) (conn-pin-number last-conn)) (format t "~&~a pin=~d: ~a ~a" (car l) (conn-pin-number conn) (car node) (car last-node)) ))) (defun print-ll-elt (elt) (format t "~&~s:" (car elt)) (loop for (conn node) in (cdr elt) (format t "~&~4tpin ~2d: ~14s ~s" (conn-pin-number conn) (car node) conn))) (defun print-loc-list (ll) (loop for l in ll (format t "~&loc=~a" (car l)) (loop for (conn node) in (cdr l) (format t "~&~8tpin=~2d ~a" (conn-pin-number conn) (car node))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; update pin-name and pin-type attributes of all connections (defun fix-pin-types (locs net) (loop for node in net (loop for conn in (cadr node) (unless (conn-chip-type conn) (setf (conn-chip-type conn) (cadr (assoc (conn-chip-loc conn) locs)))) (set-pin-type conn) (fix-pin-type conn)))) (defun fix-pins (wl) (fix-pin-types (wl-locations wl) (wl-net wl))) ;; set pin types from database if not already set (defun set-pin-type (conn) (let ((chip (assoc (conn-chip-type conn) chip-database))) (when chip (let ((pin (assoc (conn-pin-number conn) (chip-pins chip)))) (setf (conn-pin-type conn) (pin-type pin)) (setf (conn-pin-name conn) (pin-name pin)))))) (defconst out-that-should-be-bi '(74ALS534 |27512|)) (defconst bi-that-should-be-in '(RED_LED)) (defconst in-that-should-be-bi nil) (defconst resistors '(res_10 res_220 res_330 rs10_1k rs8_220_330 res_10k res_1k cap_0.1uf)) (defconst connectors '(con50 din96 conn96 db25f jumper_no jumper_3p jumper_nc)) ;; fix pin-type errors in chip database (defun fix-pin-type (conn) (let ((chip-type (conn-chip-type conn)) (pin-type (conn-pin-type conn))) (cond-every ((member chip-type connectors) (setf (conn-pin-type conn) 'pin-conn)) ((member chip-type resistors) (setf (conn-pin-type conn) 'pin-res)) ((and (eq pin-type 'pin-out) (member chip-type out-that-should-be-bi)) (setf (conn-pin-type conn) 'pin-bi)) ((and (eq pin-type 'pin-bi) (member chip-type bi-that-should-be-in)) (setf (conn-pin-type conn) 'pin-in)) ((and (eq pin-type 'pin-in) (member chip-type in-that-should-be-bi)) (setf (conn-pin-type conn) 'pin-bi)) ((and (member chip-type '(|68010| |AM7990|)) (or (string= "A" (alpha-part (conn-pin-name conn))) (string= "R_W~" (conn-pin-name conn)))) (setf (conn-pin-type conn) 'pin-bi)) ((and (eq chip-type '|74LS693|) (member (conn-pin-name conn) '(QA QB QC QD))) (setf (conn-pin-type conn) 'pin-bi)) ((and (eq chip-type '|MB87030|) (or (string= "SDBO" (alpha-part (conn-pin-name conn))))) (setf (conn-pin-type conn) 'pin-out)) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; build chip-attribute database from verbose wirelist (defun make-chip-database (net) (setq chip-database nil) (loop for node in net (loop for conn in (cadr node) (add-chip-pin-info (conn-chip-type conn) (make-pin :number (conn-pin-number conn) :name (conn-pin-name conn) :type (conn-pin-type conn))))) (loop for chip in chip-database (setf (chip-pins chip) (sortcar (chip-pins chip) 'pin-lessp))) (setq chip-database (sortcar chip-database 'pin-lessp)) nil) (defun add-pin-info (chip pin) (let ((p (assoc (pin-number pin) (chip-pins chip)))) (if p (setf (cdr p) (cdr pin)) (push pin (chip-pins chip))))) (defun add-chip-pin-info (chip-type pin) (let ((chip (assoc chip-type chip-database))) (unless chip (setq chip (make-chip :type chip-type)) (push chip chip-database)) (add-pin-info chip pin))) (defun count-chip-pins (chip) (let ((n-pins (loop for pin in (chip-pins chip) when (numberp (pin-number pin)) maximize (pin-number pin) into np else count t into bad finally (return (if (plusp bad) (list (length (chip-pins chip))) np))))) n-pins)) ;(putprop (locf (chip-plist (car chip-database))) t :programmable-p) (defun print-chip-database () (loop for chip in chip-database (format t "~2&~a: ~d pins; socket: ~a, prog: ~a" (chip-type chip) (chip-n-pins chip) (chip-socket chip) (chip-programmable-p chip)) (loop for pin in (chip-pins chip) (format t "~&~4t~3d ~6a ~6a" (pin-number pin) (pin-name pin) (pin-type pin))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; build chip-location database from existing verbose wirelist ;; not used anymore: locs are now read from wirelist files ;; (defun make-loc-database (net &aux locs) (loop for node in net (loop for conn in (cadr node) do (let ((l (assoc (conn-chip-loc conn) locs))) (if l (setf (cadr l) (conn-chip-type conn)) (push (list (conn-chip-loc conn) (conn-chip-type conn)) locs))))) (uniq (sortcar locs 'string-lessp) 'equal)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; create net heirarchy ordered by locations of connections ;; this makes it possible to compare wirelists strictly ;; based on nets and connections, completely ignoring the node names. (defun sort-net-by-loc (net) (sort (loop for node in net collect (list (car node) (uniq (sort (copylist (cadr node)) 'conn-lessp) 'equal))) 'conn-list-lessp :key 'cadr)) ;; compare two lists of connections ;; return non-nil if first comes before second (defun conn-list-lessp (cl1 cl2) (loop for c1 = cl1 then (cdr c1) for c2 = cl2 then (cdr c2) unless (or c1 c2) ;;if both exhausted, they were equal return nil unless c1 ;;if c1 exhausted, it precedes return t unless c2 ;;if c2 exhausted, it precedes return nil unless (conn-equal (car c1) (car c2)) ;;if equal, try next elt return (conn-lessp (car c1) (car c2)))) ;; compare two lists of connections ;; return non-nil if they are equal (defun conn-list-equal (cl1 cl2) (loop for c1 = cl1 then (cdr c1) for c2 = cl2 then (cdr c2) unless (or c1 c2) return t unless (and c1 c2) return nil always (conn-equal (car cl1) (car cl2)))) ;; compare two wire-lists ;; lists must already be sorted in connection-location order ;; as prepared by (sort-net-by-loc) (defun compare-wire-lists (net1 net2) (loop for (na1 cl1) = (car net1) for (na2 cl2) = (car net2) while (and net1 net2) when (conn-list-equal cl1 cl2) do (pop net1) (pop net2) else do (let ((lp (conn-list-lessp cl1 cl2))) (cond (lp (format t "~&~16a~16@t~d conns" na1 (length cl1)) (pop net1)) (t (format t "~&~16@t~16a~d conns" na2 (length cl2)) (pop net2))) ))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun uniq (l &optional (pred 'eq)) (loop for q in l and for last = nil then q unless (funcall pred q last) collect q)) (defun dup (l &optional (pred 'eq) (accessor #'(lambda (x) x))) (uniq (loop for q in l and for last = nil then q when (funcall pred (funcall accessor q) (funcall accessor last)) collect (funcall accessor q)) pred)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun conn-lessp (c1 c2) (if (eq (conn-chip-loc c1) (conn-chip-loc c2)) (pin-lessp (conn-pin-number c1) (conn-pin-number c2)) (string-lessp (conn-chip-loc c1) (conn-chip-loc c2)))) (defun conn-equal (c1 c2) (loop for i below 5 for e1 = c1 then (cdr e1) for e2 = c2 then (cdr e2) always (equal (car e1) (car e2)))) (defun pin-lessp (p1 p2) (if (numberp p1) (if (numberp p2) (< p1 p2) t) (if (numberp p2) nil (string-lessp p1 p2)))) (defconst num-set "0123456789") ;; same as string-lessp, except that if non-numeric characters all match, ;; numeric character substring is compared in numeric instead of string order. (defun hairy-lessp (p1 p2) (let ((n1 (string-search-set num-set p1)) (n2 (string-search-set num-set p2)) (r1 (string-reverse-search-set num-set p1)) (r2 (string-reverse-search-set num-set p2))) (cond ((and n1 (eq n1 n2) (string= p1 p2 :end1 n1 :end2 n2) (string= p1 p2 :start1 (1+ r1) :start2 (1+ r2))) (< (read-from-string (substring p1 n1 (1+ r1))) (read-from-string (substring p2 n2 (1+ r2))))) (t (string-lessp p1 p2))))) ;;;;;;;;;;;;;;;; (defun wintern (str) (intern (string-trim '(#\space #\tab) (string-upcase str)) 'user)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun read-record (&optional (stream *standard-input*) (eof-error-p t) eof-value recursive-p options) "like read-line but accepts CR or LF as delimiter" (declare (values line eof-flag)) (declare (ignore recursive-p)) (multiple-value-bind (string eof-flag delimiter) (read-delimited-string '(#.(char-int #\Newline) #.(char-int 13) #.(char-int #\End)) stream eof-error-p options) (if (and eof-flag (zerop (length string))) (values eof-value t) (when (and (instancep stream) (operation-handled-p stream :rubout-handler)) (send stream :tyo delimiter)) (values string eof-flag)))) ;;;; (defun count-elts (l) (loop for q in l when (consp q) sum (count-elts q) else sum 1)) (defun invalidate-chip-type (net) (loop for node in net (loop for conn in (cadr node) (setf (conn-chip-type conn) nil) (setf (conn-pin-type conn) nil) (setf (conn-pin-name conn) nil)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; print all nodes in net order ; (print-list (wl-net wl)) ; print one node ; (print-node ; print nodes of given name ; (print-node-name ; make list of nodes of given name ; (find-nodes ; make list of nodes whose name contains given string ; (find-node-substring ; make list of nodes whose length matches a spec ; (find-by-length ; perform input/output connection checks on wire-list ; (check-wire-list ; compare two wire-lists by comparing in connection-location order ; (compare-wire-lists ; build pal database from files in directory ; (parse-pal-directory ; update connection pin types from pal database ; (fix-pal-pins net ; find pal definition whose name contains given string ; (find-pal ; print by wire-lengths ; (print-by-lengths ; print min and max lengths of specified busses ; (print-busses ; print by number of connections ; (chart-conns (wl-net wl)) ; check for different nodes connecting to same pins ; (check-loc-list ; print each loc and name of node connecting to each pin ; (print-loc-list (wl-net-by-loc wl)) ; print name of nodes connecting to each pin for a loc of a loc-list element ; (print-ll-elt ; print chip pin-type database ; (print-chip-database (defun check-all (wl) (check-wire-list (wl-net wl)) (check-loc-list (wl-net-by-loc wl))) (defun print-all (wl) (print-by-lengths (wl-lengths wl) nil bus-list 10.0) (print-busses (wl-lengths wl)) (chart-conns (wl-net wl))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun find-bad-conns (net) (uniq (loop for node in net append (loop for conn in (cadr node) when (or (null (conn-pin-type conn)) (null (conn-pin-name conn))) collect node)) 'equal)) (defconst k-pal-locs '((P_F18 CH1_00) (P_F17 CH2_00) (P_F16 CH3_00) (P_H17 CLOCK00) (M_J16 FDEST100) (M_J17 FDEST200) (P_F23 FDEST300) (M_J18 FMSRC00) (P_L11 ICCE00) (P_K11 ICSEQ00) (P_K13 ICWE00) (M_C1 MCAS00) (M_H11 MCHK00) (M_A1 MRAS00) (M_B1 MRAS00) (M_C30 PAT0000) (M_C28 NUERR00) (M_C29 NUMAS00) (M_E33 NUMR00) (M_E31 NUSLV100) (M_E32 NUSLV200) (M_G11 PARITY00) (P_K4 PCINC00) (P_K3 PCINC00) (P_K2 PCINC00) (P_K1 PCINC00) (P_H10 PCMUX00) (M_G10 PREQ00) (P_E10 REGS00) (M_G33 SPY00) (M_C23 STAT00) (M_I15 TRAP00) (M_G9 TRAPMD00))) (defconst iop-pal-locs '((a11 vmecon) ;16r4a (a14 intreg) ;22v10 (b27 vmereqarb) ;22v10 (b26 wbyte) ;16l8a (c17 vmedec) ;20l8a (c14 slvdec) ;20r8a (c25 vbufctl) ;2048a (e6 dmactr) ;16r6a (f9 busctl0) ;22v10 (f8 busctl1) ;16r4a (f7 busctl2) ;16l8a (f6 busctl3) ;20r8a (f5 busctl4) ;20r8a (b2 scsictl0) ;16r8b (b4 scsictl1) ;20l8a (a6 scsictl2) ;20l8a (h29 busarb) ;16l8a (f26 intcon) ;20l8a (no file) (d30 dtcon) ;16r4a (f28 decode) ;20l8a (d23 rfckpal) ;20x10a (d22 dramcon) ;16r4a, dram (d21 dcon2) ;16l8a (no file) (f11 fbctl0) ;16r4b, frame buffer (i14 fbctl1) ;16r8b (g11 fbctl2) ;16r8b (j8 syncgen) ;16r8a )) ;(defun find-pals () ; (loop for q in (wl-locations iop) ; when (memq (cadr q) p) ; collect q)) (defun find-possible-pal (chip) (loop for pal in pal-database when (or (string= chip (pal-type pal)) (string= chip (substring (pal-type pal) 3))) collect pal)) (defun match-pals (wl) (loop for (loc chip-type) in (wl-locations wl) for pals = (find-possible-pal chip-type) when pals count t into n and collect (list loc pals) and do (format t "~&~a: ~a:" loc chip-type) (loop for (xloc xchip-type) in (wl-locations wl) when (and (eq chip-type xchip-type) (neq loc xloc)) (format t " ~a" xloc)) (loop for pal in pals (format t "~&~4t~10a ~a" (pal-name pal) (pal-comment pal))) finally (format t "~&matched ~d locs" n) )) (defmacro ignore-output (body) `(let (r) (with-output-to-string (*standard-output*) (setq r ,body)) r)) (defmacro ignore-return (body) `(progn ,body nil)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; given random list of q's, return an alist of one of ;; each q and the number of occurences of it. ;; (a "parts-list") (defun count-elts (l &optional (pred 'string-lessp)) (let ((elts (sort (copylist l) pred))) (let ((counts (loop for q in (uniq elts) collect (list q 0)))) (loop for q in elts (incf (cadr (assoc q counts)))) counts))) ; returns parts-list alist for a net (defun count-chips (wl) (combine-parts-lists (mapcar 'cdr (wl-locations wl)))) ;; (count-elts (mapcar 'cadr (wl-locations wl)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;(n spare): if more than n, get spare spares (defconst spare-list '((60 100) (45 75) (20 50) (10 25) (5 20) (1 15))) (defun spares-func (n) (or (cadr (ass '>= n spare-list)) 0)) (defun order-func (n) (* 25 (floor (+ n 24) 25))) ;; (print-order-list (make-status-list parts-list inven-list 5 )) ;; (print-order-list (make-status-list parts-list inven-list 15 5 )) ;; given a parts-list, an inventory-list ("parts-list" for current stock), ;; and a number of boards to make, ;; show what we have and what we need. ;; returns list of (chip-type n-each n-required what-we-have what-to-order) (defun make-status-list (parts-list inven-list n-boards &optional (deduct 0)) (format t "~2&To build ~d set~:p" n-boards) (when (plusp deduct) (format t " beyond first ~d" deduct)) (loop for (chip n-each) in parts-list collect (let* ((req (+ (* n-each n-boards) (spares-func n-each))) (have (max 0 (- (or (cadr (assoc chip inven-list)) 0) (* deduct n-each)))) (need (max 0 (- req have)))) (list chip n-each req have (order-func need))))) (defun print-status-list (status-list) (format t "~2&Part-number /Board Req. Have Order") (format t "~&=========== ====== ==== ==== =====") (loop for (chip each req have order) in status-list (format t "~&~16a~8d~8d~8d~8d" chip each req have (if (plusp order) order "")))) ;; given a status-list, ;; print an "order" for the parts that are deficient (defun print-order-list (status-list) (format t "~2&Part-number Count") (format t "~&=========== =====") (loop for (chip each req have order) in status-list (when (plusp order) (format t "~&~16a~d" chip order)))) (defun print-parts-list (parts-list) (format t "~2&Part-number Count") (format t "~&=========== =====") (loop for (chip count) in parts-list (format t "~&~16a~d" chip count))) (defun total-of-parts (parts-list) (loop for (chip count) in parts-list sum count)) (defun combine-parts-lists (&rest parts-lists) (loop for chip-type in (uniq (sort (mapcar 'car (apply 'append parts-lists)) 'string-lessp)) collect (list chip-type (loop for (part count) in (apply 'append parts-lists) when (eq part chip-type) sum (or count 1))))) (defun multiply-parts-list (parts-list n) (loop for (part count) in parts-list collect (list part (* count n)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (print-parts-list (machined-socket-hack parts-list) ;; (print-parts-list (normal-socket-hack parts-list)) ;; all machined for first board, ;; just programmable parts for next four (defun machined-socket-hack (parts-list) (combine-parts-lists (make-socket-list parts-list) (multiply-parts-list (make-socket-list parts-list :machined) 4))) (defun normal-socket-hack (parts-list) (multiply-parts-list (make-socket-list parts-list :default) 4)) (defun make-socket-list (parts-list &optional socket-type) (combine-parts-lists (loop for (chip-type count) in parts-list for chip = (assoc chip-type chip-database) when (if socket-type (eq (chip-socket chip) socket-type) (chip-socket chip)) collect (list (chip-n-pins chip) count)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;