3.3.4 A Simulator for Digital Circuits

論理回路をシミュレート。

  • 導線(wire)同士を関数で繋ぐ感じ。
  • 入力側のwireの持つ値(導線の信号)が変化したときに関数を呼び出して、出力側のwireの信号を変化させる。
  • その際発生する遅延もシミュレートする。
  • 時間軸を一列にとっておいて、after-delayという関数でイベントが起きる順に追加していく。

3.28 (or-gate)

(define (or-gate a1 a2 output)
  (define (or-action-procedure)
    (let ((new-value
           (logical-or (get-signal a1) (get-signal a2))))
      (after-delay or-gate-delay
                   (lambda ()
                     (set-signal! output new-value)))))
  (add-action! a1 or-action-procedure)
  (add-action! a2 or-action-procedure)
  'ok)
(define (logical-or x y)
  (if (or (= x 1) (= y 1)) 1 0))

3.29 (not, andだけでor)

(define (or-gate/nand a1 a2 output)
  (let ((n1 (make-wire))
        (n2 (make-wire))
        (o (make-wire))
        (p (make-wire)))
    (inverter a1 n1)
    (inverter a2 n2)
    (and-gate n1 n2 o)
    (inverter o p)))

この回路の遅延はinverter-delay + and-gate-delay + inverter-delay.

3.30

half-adderの遅延は and-gate-delay + inverter-delay + and-gate-delay, full-adderの遅延は half-adder-delay + half-adder-delay + or-gate-delay なので、そのn倍かな?

3.31

wireにアクションが指定されたとき、必ず最初に一回呼び出すのはなぜか?

初期入力に対する応答が未定義になるため。かな。

3.32

同じ時間に起きるイベントを、追加された順に実行(FIFO)ではなく最後に追加されたものから実行(LIFO)するのはなぜか?

これ分かんなかった。動きをしっかり理解してないからかも。後で調べる。