Skip to content

Commit 592a7da

Browse files
committed
Add implementation of exercise 3-30
1 parent 3261b0f commit 592a7da

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
习题完成情况:
2626
- 章节一: 43/46
2727
- 章节二: 88/97
28-
- 章节三: 29/82
28+
- 章节三: 30/82
2929
- 章节四: TODO
3030
- 章节五: TODO
3131
* 运行

chapter3/adder.rkt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
(or-gate c1 c2 c-out))
2121
'ok)
2222

23+
(provide half-adder full-adder)
24+
2325
(module+ test
2426
(require rackunit)
2527

chapter3/exercise3-30.rkt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#lang racket
2+
(require "digital-circuit.rkt")
3+
(require "sicp-compat.rkt")
4+
(require "adder.rkt")
5+
(require "after-delay.rkt")
6+
7+
;;; 延迟分析
8+
;;; 全加器延迟是 2 and-gate-delay + 1 or-gate delay
9+
;;; n位的级联进位加法器就是 n * (2 * and-gate-delay + or-gate-delay)
10+
(define (ripple-carry-adder a-list b-list s-list c-out)
11+
(define (iter a-wires b-wires s-wires c-in)
12+
(if (null? a-wires)
13+
'done
14+
(let ((a (car a-wires))
15+
(b (car b-wires))
16+
(s (car s-wires))
17+
(next-carry (if (null? (cdr a-wires))
18+
c-out
19+
(make-wire))))
20+
(full-adder a b c-in s next-carry)
21+
(iter (cdr a-wires) (cdr b-wires) (cdr s-wires) next-carry))))
22+
(let ((c-in (make-wire)))
23+
(set-signal! c-in 0)
24+
(iter a-list b-list s-list c-in)))
25+
26+
(module+ test
27+
(require rackunit)
28+
29+
(define (make-wire-list n)
30+
(if (= n 0)
31+
'()
32+
(cons (make-wire) (make-wire-list (- n 1)))))
33+
34+
(define (get-wire-list-signal wires)
35+
(if (null? wires)
36+
'()
37+
(cons (get-signal (car wires))
38+
(get-wire-list-signal (cdr wires)))))
39+
40+
(define (set-wire-signals! wires values)
41+
(if (or (null? wires) (null? values))
42+
'done
43+
(begin
44+
(set-signal! (car wires) (car values))
45+
(set-wire-signals! (cdr wires) (cdr values)))))
46+
47+
(test-case "Test for ripple-carry-adder, 5 + 3 = 8"
48+
(let ((a-wires (make-wire-list 4))
49+
(b-wires (make-wire-list 4))
50+
(s-wires (make-wire-list 4))
51+
(c-wire (make-wire)))
52+
(ripple-carry-adder a-wires b-wires s-wires c-wire)
53+
54+
;; Using little-endian bit order (LSB first)
55+
;; 5 = 0101 in binary -> (1 0 1 0) in little-endian
56+
;; 3 = 0011 in binary -> (1 1 0 0) in little-endian
57+
;; 8 = 1000 in binary -> (0 0 0 1) in little-endian
58+
(set-wire-signals! a-wires (list 1 0 1 0))
59+
(set-wire-signals! b-wires (list 1 1 0 0))
60+
(propagate)
61+
(check-equal? (get-wire-list-signal s-wires) (list 0 0 0 1))
62+
(check-equal? (get-signal c-wire) 0)
63+
))
64+
65+
(test-case "Test for ripple-carry-adder, 9 + 10 = 19"
66+
(let ((a-wires (make-wire-list 4))
67+
(b-wires (make-wire-list 4))
68+
(s-wires (make-wire-list 4))
69+
(c-wire (make-wire)))
70+
(ripple-carry-adder a-wires b-wires s-wires c-wire)
71+
72+
;; Using little-endian bit order (LSB first)
73+
;; 9 = 1001 in binary -> (1 0 0 1) in little-endian
74+
;; 10 = 1010 in binary -> (0 1 0 1) in little-endian
75+
;; 19 = 10011 in binary -> (1 1 0 0 1) in little-endian
76+
;; 19 = 16 + 3 = 0b10000 + 0b0011
77+
(set-wire-signals! a-wires (list 1 0 0 1))
78+
(set-wire-signals! b-wires (list 0 1 0 1))
79+
(propagate)
80+
;; 1 1 0 0 in little-endian
81+
(check-equal? (get-wire-list-signal s-wires) (list 1 1 0 0))
82+
;; 0b10000
83+
(check-equal? (get-signal c-wire) 1)
84+
))
85+
)

0 commit comments

Comments
 (0)