Advertisement
timothy235

sicp-3-3-4-the-digital-circuits-simulator-program

Mar 1st, 2017
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 9.05 KB | None | 0 0
  1. #lang racket
  2. (require racket/mpair)
  3.  
  4. ;; CONSTANTS
  5.  
  6. (define inverter-delay 2)
  7. (define and-gate-delay 3)
  8. (define or-gate-delay 5)
  9.  
  10. ;; LOGIC FUNCTIONS
  11.  
  12. (define (valid-signal? s) (member s '(0 1)))
  13. (define (logical-not s)
  14.   (unless (valid-signal? s) (error "Invalid signal" s))
  15.   (if (zero? s) 1 0))
  16. (define (logical-and s1 s2)
  17.   (unless (valid-signal? s1) (error "Invalid signal" s1))
  18.   (unless (valid-signal? s2) (error "Invalid signal" s2))
  19.   (* s1 s2))
  20. (define (logical-or s1 s2)
  21.   (unless (valid-signal? s1) (error "Invalid signal" s1))
  22.   (unless (valid-signal? s2) (error "Invalid signal" s2))
  23.   (if (positive? (+ s1 s2)) 1 0))
  24.  
  25. ;; LOGIC GATES
  26.  
  27. (define (inverter input output)
  28.   (define (invert-input)
  29.     (define new-value (logical-not (get-signal input)))
  30.     (after-delay inverter-delay
  31.                  (lambda ()
  32.                    (set-signal! output new-value))))
  33.   (add-action! input invert-input)
  34.   'ok)
  35.  
  36. (define (and-gate a1 a2 output)
  37.   (define (and-action-procedure)
  38.     (define new-value (logical-and (get-signal a1) (get-signal a2)))
  39.     (after-delay and-gate-delay
  40.                  (lambda ()
  41.                    (set-signal! output new-value))))
  42.   (add-action! a1 and-action-procedure)
  43.   (add-action! a2 and-action-procedure)
  44.   'ok)
  45.  
  46. (define (or-gate a1 a2 output)
  47.   (define (or-action-procedure)
  48.     (define new-value (logical-or (get-signal a1) (get-signal a2)))
  49.     (after-delay or-gate-delay
  50.                  (lambda ()
  51.                    (set-signal! output new-value))))
  52.   (add-action! a1 or-action-procedure)
  53.   (add-action! a2 or-action-procedure)
  54.   'ok)
  55.  
  56. ;; ADDERS
  57.  
  58. (define (half-adder a b s c)
  59.   (define d (make-wire))
  60.   (define e (make-wire))
  61.   (or-gate a b d)
  62.   (and-gate a b c)
  63.   (inverter c e)
  64.   (and-gate d e s)
  65.   'ok)
  66.  
  67. (define (full-adder a b c-in sum c-out)
  68.   (define s (make-wire))
  69.   (define c1 (make-wire))
  70.   (define c2 (make-wire))
  71.   (half-adder b c-in s c1)
  72.   (half-adder a s sum c2)
  73.   (or-gate c2 c2 c-out)
  74.   'ok)
  75.  
  76. (define (ripple-carry-adder as bs ss c)
  77.   ; The book goes from index n to index 1; we go from n - 1 to 0.
  78.   (unless (= (length as)
  79.              (length bs)
  80.              (length ss))
  81.     (error "Lists must be same length -- RIPPLE-CARRY-ADDER" as bs ss))
  82.   (define zero-wire (make-wire))
  83.   (set-signal! zero-wire 0)
  84.   (define (loop i carry)
  85.     (cond [(< i 0) 'ok]
  86.           [else
  87.             ; use c for the last carry
  88.             (define next-carry (if (zero? i) c (make-wire)))
  89.             (full-adder (list-ref as i)
  90.                         (list-ref bs i)
  91.                         carry
  92.                         (list-ref ss i)
  93.                         next-carry)
  94.             (loop (sub1 i) next-carry)]))
  95.   (loop (sub1 (length as))
  96.         zero-wire))
  97.  
  98. ;; WIRES
  99.  
  100. (define (make-wire)
  101.   (define signal-value 0)
  102.   (define action-procedures empty)
  103.   (define (set-my-signal! new-value)
  104.     (cond [(not (= signal-value new-value))
  105.            (set! signal-value new-value)
  106.            (call-each action-procedures)]
  107.           [else 'done]))
  108.   (define (accept-action-procedure! proc)
  109.     (set! action-procedures (mcons proc action-procedures))
  110.     (proc))
  111.   (define (dispatch m)
  112.     (cond [(eq? m 'get-signal) signal-value]
  113.           [(eq? m 'set-signal!) set-my-signal!]
  114.           [(eq? m 'add-action!) accept-action-procedure!]
  115.           [else (error "Unknown operation -- WIRE" m)]))
  116.   dispatch)
  117.  
  118. (define (call-each procedures)
  119.   (for ([p procedures]) (p))
  120.   'done)
  121.  
  122. (define (get-signal wire)
  123.   (wire 'get-signal))
  124. (define (set-signal! wire new-value)
  125.   ((wire 'set-signal!) new-value))
  126. (define (add-action! wire action-procedure)
  127.   ((wire 'add-action!) action-procedure))
  128.  
  129. ;; QUEUES FROM 3.3.2
  130.  
  131. (define (front-ptr queue) (mcar queue))
  132. (define (rear-ptr queue) (mcdr queue))
  133. (define (set-front-ptr! queue item) (set-mcar! queue item))
  134. (define (set-rear-ptr! queue item) (set-mcdr! queue item))
  135. (define (empty-queue? queue) (null? (front-ptr queue)))
  136. (define (make-queue) (mcons empty empty))
  137. (define (front-queue queue)
  138.   (if (empty-queue? queue)
  139.     (error "FRONT called with an empty queue" queue)
  140.     (mcar (front-ptr queue))))
  141. (define (insert-queue! queue item)
  142.   (define new-pair (mcons item empty))
  143.   (cond [(empty-queue? queue)
  144.          (set-front-ptr! queue new-pair)
  145.          (set-rear-ptr! queue new-pair)
  146.          queue]
  147.         [else
  148.           (set-mcdr! (rear-ptr queue) new-pair)
  149.           (set-rear-ptr! queue new-pair)
  150.           queue]))
  151. (define (delete-queue! queue)
  152.   (cond [(empty-queue? queue)
  153.          (error "DELETE! called with an empty queue" queue)]
  154.         [else
  155.           (set-front-ptr! queue (mcdr (front-ptr queue)))
  156.           queue]))
  157.  
  158. ;; AGENDAS
  159.  
  160. ;; Segments are time, queue pairs.  The queue holds all the actions to be
  161. ;; performed at that time.
  162.  
  163. (define (make-time-segment time queue)
  164.   (mcons time queue))
  165. (define (segment-time s) (mcar s))
  166. (define (segment-queue s) (mcdr s))
  167.  
  168. ;; An agenda is a table of segments sorted by time.  The head of the table is the
  169. ;; current time.
  170.  
  171. (define (make-agenda) (mlist 0))
  172. (define (current-time agenda) (mcar agenda))
  173. (define (set-current-time! agenda time) (set-mcar! agenda time))
  174. (define (segments agenda) (mcdr agenda))
  175. (define (set-segments! agenda segments) (set-mcdr! agenda segments))
  176. (define (first-segment agenda) (mcar (segments agenda)))
  177. (define (rest-segments agenda) (mcdr (segments agenda)))
  178. (define (empty-agenda? agenda) (empty? (segments agenda)))
  179.  
  180. (define (add-to-agenda! time action agenda)
  181.   (define (belongs-before? segments)
  182.     (or (empty? segments)
  183.         (< time (segment-time (mcar segments)))))
  184.   (define (make-new-time-segment time action)
  185.     (define q (make-queue))
  186.     (insert-queue! q action)
  187.     (make-time-segment time q))
  188.   (define (add-to-segments! segments)
  189.     (cond [(= (segment-time (mcar segments)) time)
  190.            (insert-queue! (segment-queue (mcar segments))
  191.                           action)]
  192.           [else
  193.             (define rest-sgmnts (mcdr segments))
  194.             (if (belongs-before? rest-sgmnts)
  195.               (set-mcdr! segments
  196.                          (mcons (make-new-time-segment time action)
  197.                                 (mcdr segments)))
  198.               (add-to-segments! rest-sgmnts))]))
  199.   (define sgmnts (segments agenda))
  200.   (if (belongs-before? sgmnts)
  201.     (set-segments! agenda
  202.                    (mcons (make-new-time-segment time action)
  203.                           sgmnts))
  204.     (add-to-segments! sgmnts)))
  205.  
  206. (define (remove-first-agenda-item! agenda)
  207.   (define q (segment-queue (first-segment agenda)))
  208.   (delete-queue! q)
  209.   (when (empty-queue? q)
  210.     (set-segments! agenda (rest-segments agenda))))
  211.  
  212. (define (first-agenda-item agenda)
  213.   (cond [(empty-agenda? agenda)
  214.          (error "Agenda is empty -- FIRST-AGENDA-ITEM")]
  215.         [else
  216.           (define first-seg (first-segment agenda))
  217.           (set-current-time! agenda (segment-time first-seg))
  218.           (front-queue (segment-queue first-seg))]))
  219.  
  220. ;; after-delay, propagate and probe
  221.  
  222. (define (after-delay delay action)
  223.   (add-to-agenda! (+ delay (current-time the-agenda))
  224.                   action
  225.                   the-agenda))
  226.  
  227. (define (propagate)
  228.   (cond [(empty-agenda? the-agenda)
  229.          'done]
  230.         [else
  231.           (define first-item (first-agenda-item the-agenda))
  232.           (first-item)
  233.           (remove-first-agenda-item! the-agenda)
  234.           (propagate)]))
  235.  
  236. (define (probe name wire)
  237.   (add-action! wire
  238.                (lambda ()
  239.                  (printf "~a ~a  New-value = ~a ~n"
  240.                          name
  241.                          (current-time the-agenda)
  242.                          (get-signal wire)))))
  243.  
  244. ;; TEST
  245.  
  246. ;; Use ripple-carry-adder to add 111 to 001 to get 1000.
  247.  
  248. (define the-agenda (make-agenda))
  249.  
  250. (define a1 (make-wire))
  251. (define a2 (make-wire))
  252. (define a3 (make-wire))
  253. (set-signal! a1 1)
  254. ;; 'done
  255. (set-signal! a2 1)
  256. ;; 'done
  257. (set-signal! a3 1)
  258. ;; 'done
  259. (define as (list a1 a2 a3))
  260.  
  261. (define b1 (make-wire))
  262. (define b2 (make-wire))
  263. (define b3 (make-wire))
  264. (set-signal! b1 0)
  265. ;; 'done
  266. (set-signal! b2 0)
  267. ;; 'done
  268. (set-signal! b3 1)
  269. ;; 'done
  270. (define bs (list b1 b2 b3))
  271.  
  272. (define s1 (make-wire))
  273. (define s2 (make-wire))
  274. (define s3 (make-wire))
  275. (set-signal! s1 0)
  276. ;; 'done
  277. (set-signal! s2 0)
  278. ;; 'done
  279. (set-signal! s3 0)
  280. ;; 'done
  281. (define ss (list s1 s2 s3))
  282.  
  283. (define c (make-wire))
  284.  
  285. (probe 's1 s1)
  286. ;; s1 0  New-value = 0
  287. (probe 's2 s2)
  288. ;; s2 0  New-value = 0
  289. (probe 's3 s3)
  290. ;; s3 0  New-value = 0
  291. (probe 'c c)
  292. ;; c 0  New-value = 0
  293.  
  294. (ripple-carry-adder as bs ss c)
  295. ;; 'ok
  296.  
  297. ;; Note that all the s wires and the c wire now have probe in their
  298. ;; action-procedures lists.  So probe will run any time one of them changes state.
  299.  
  300. (propagate)
  301. ;; s3 8  New-value = 1
  302. ;; s2 8  New-value = 1
  303. ;; s1 8  New-value = 1
  304. ;; s3 16  New-value = 0
  305. ;; s2 32  New-value = 0
  306. ;; c 48  New-value = 1
  307. ;; s1 48  New-value = 0
  308. ;; 'done
  309.  
  310. (probe 's1 s1)
  311. ;; s1 48  New-value = 0
  312. (probe 's2 s2)
  313. ;; s2 48  New-value = 0
  314. (probe 's3 s3)
  315. ;; s3 48  New-value = 0
  316. (probe 'c c)
  317. ;; c 48  New-value = 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement