Skip to content

Instantly share code, notes, and snippets.

@debetimi
Last active August 29, 2015 13:58
Show Gist options
  • Save debetimi/9957853 to your computer and use it in GitHub Desktop.
Save debetimi/9957853 to your computer and use it in GitHub Desktop.
Learning Clojure: Digital Circuits
(ns circuits.core)
(defn wire
"This is a wire. It takes an optional delay
keyword parameter and outputs a map with :i, and :o
which are atoms and :d which represents the delay
in milliseconds. The default delay is 0. When i changes value,
o follows in d number of seconds"
[& {:keys [del] :or {del 0}}]
(let [in (atom 0)
out (atom 0)
delta (* del 1000)
;;Transition is a watch function on the input
;;when the value changes it sets the output the value of the
;;input after delay seconds
transition
(fn [k a old new]
(future
(Thread/sleep delta)
(reset! out new) nil))]
(add-watch in :fn transition)
{:i in, :o out :d delta}))
(defn gate
"creates a logic gate, takes in
bit function and text to display when
logic gate transitions"
[func text]
(fn [a b c & {:keys [del] :or {del 1}}]
(let [i1 (:o a)
i2 (:o b)
o (:i c)
delta (* del 1000)
update
(fn [k a old new]
(future
(Thread/sleep delta)
(println "A" @i1)
(println "B" @i2)
(reset! o (func @i1 @i2))
(println text @o) nil))]
(add-watch i1 (keyword text) update)
(add-watch i2 (keyword text) update)
(reset! o (func @i1 @i2))
{:d delta})))
(defn bit-nand
[a b](case (bit-and a b)
0 1
0))
(def and-gate
(gate bit-and "AND"))
(def or-gate
(gate bit-or "OR"))
(def xor-gate
(gate bit-xor "XOR"))
(def nand-gate
(gate bit-nor "NAND"))
(defn inverter
"This is a logical inverter"
[a output] ())
(def a (wire))
(def b (wire :del 30))
(def c (wire))
(def d (wire))
(def e (wire))
(def f (wire))
;; make some gates add different delays so output is more clear
(def g1 (and-gate a b c :del 5))
(def g2 (or-gate a b d :del 10))
(def g3 (nand-gate a b e :del 15))
(def g4 (xor-gate a b f :del 20))
(println "INIT")
(println "AND" @(:o c))
(println "OR" @(:o d))
(println "NAND" @(:o e))
(println "XOR" @(:o f))
(println "STARTING")
(do
(reset! (:i a) 1)
(reset! (:i b) 1) nil)
INIT
AND 0
OR 0
NAND 1
XOR 0
STARTING
()
A 1
B 0
AND 0
A 1
B 0
OR 1
A 1
B 0
NAND 1
A 1
B 0
XOR 1
A 1
B 1
AND 1
A 1
B 1
OR 1
A 1
B 1
NAND 0
A 1
B 1
XOR 0
starting....
nil
switch 1
a:1
s:1
switch 2
b:1
a:0
s:0
s:1
switch 3
switch 3
a:1
s:0
c1:1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment