/* 4-bit ALU: made from 4   1-bit-ALU circuit

   sel1 = '8'  sel0 = '9'

   sel1 = 0, sel0 = 0 -> Add a, b carry_in
   sel1 = 0, sel0 = 1 -> Not a
   sel1 = 1, sel0 = 0 -> a Or b
   sel1 = 1, sel0 = 1 -> a AND b
*/

/* Full adder.
   Syntax: Full_Adder a b c_in | c_out s;
   Effect: Adds binary numbers a + b with carry.
*/
Define Full_Adder CarryIn a b | CarryOut Sum;
  Xor aa    a b       x;
  Xor ab    x CarryIn Sum;
  And bb    a b       y;
  And cb    CarryIn x z;
  Or  bc-cc y z       CarryOut;
Endef;

Define One_Bit_ALU  a b c_in s[1..0] | z c_out;
 /* ========================
    Compute all outputs
    ======================== */
 Full_Adder aa a b c_in | c_outX Out_Sum;
 Not aa a Out_Not;
 And aa a b Out_And;
 Or  aa a b Out_Or;

 /* =============================
    Select the desired output
    ============================= */
 Mux ab s[1] s[0] |  Out_Or  Out_And  Out_Not  Out_Sum | z ;
 Not ab s[1] ns1;
 Not ab s[0] ns0;
 And ab ns1  ns0  c_outX  c_out;

Endef;



/* Main */
One_Bit_ALU ch a0 b0 ZERO control1 control0 | z0 c1;
One_Bit_ALU cg a1 b1 c1   control1 control0 | z1 c2;
One_Bit_ALU cf a2 b2 c2   control1 control0 | z2 c3;
One_Bit_ALU ce a3 b3 c3   control1 control0 | z3 c_out;

/* Number a */
Switch ae a0 '0' ZERO;
Switch ad a1 '1' ZERO;
Switch ac a2 '2' ZERO;
Switch ab a3 '3' ZERO;

/* Number b */
Switch ak b0 '4' ZERO;
Switch aj b1 '5' ZERO;
Switch ai b2 '6' ZERO;
Switch ah b3 '7' ZERO;

/* Probes */
Probe ca c_out;
Probe eh z0;
Probe eg z1;
Probe ef z2;
Probe ee z3;

/* Controls */
Switch ea control1 '8' ZERO;
Switch eb control0 '9' ZERO;


