NB. circuit primitives

or =: +.
and =: *.
not =: -.

NB. circuit models

bitOr =: monad define script
('a' ; 'b') =. y.
a or b
)

bitAnd =: monad define script
('a' ; 'b') =. y.
a and b
)

bitNot =: not

NB. half adder

bitHalfAdder =: monad define script
('a' ; 'b') =. y.
bitOr (bitAnd a , bitNot b) , bitAnd (bitNot a) , b
)

bitXor =: bitHalfAdder

bitAdder =: monad define script
('a' ; 'b' ; 'cin') =. y.
t =. bitHalfAdder a , b
g =. bitAnd a , b
p =. bitAnd t , cin
(bitOr g , p) , bitHalfAdder t , cin
)

wireOutput =: monad define script
('pin' ; 'outputs') =. y.
pin from outputs
)

twoBitAdder =: monad define script
('a1' ; 'a0' ; 'b1' ; 'b0') =. y.
t0 =. bitAdder a0 , b0 , 0
t1 =. bitAdder a1 , b1 , wireOutput 0 ; t0
(wireOutput 0 1 ; t1) , wireOutput 1 ; t0
)

fourBitAdder =: monad define script
('a3' ; 'a2' ; 'a1' ; 'a0' ; 'b3' ; 'b2' ; 'b1' ; 'b0') =. y.
t0 =. bitAdder a0 , b0 , 0
t1 =. bitAdder a1 , b1 , wireOutput 0 ; t0
t2 =. bitAdder a2 , b2 , wireOutput 0 ; t1
t3 =. bitAdder a3 , b3 , wireOutput 0 ; t2
(wireOutput 0 1 ; t3) , (wireOutput 1 ; t2) , (wireOutput 1 ; t1) , wireOutput 1 ; t0
)

fourBitAlu =: monad define script
('a3' ; 'a2' ; 'a1' ; 'a0' ; 'b3' ; 'b2' ; 'b1' ; 'b0' ; 'sub') =. y.
t0 =. bitAdder a0 , (bitXor b0 , sub) , sub
t1 =. bitAdder a1 , (bitXor b1 , sub) , wireOutput 0 ; t0
t2 =. bitAdder a2 , (bitXor b2 , sub) , wireOutput 0 ; t1
t3 =. bitAdder a3 , (bitXor b3 , sub) , wireOutput 0 ; t2
(wireOutput 0 1 ; t3) , (wireOutput 1 ; t2) , (wireOutput 1 ; t1) , wireOutput 1 ; t0
)

