/* 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
    ======================== */
 And 1a a b Out_And;
 Or  1a a b Out_Or;
 Not 1a a   Out_Not;
 Full_Adder 1a a b c_in | c_out1 Out_Sum;

 /* =============================
    Select the desired output
    ============================= */
 Dec 2a ONE s[1] s[0] | l3 l2 l1 l0;
 And 2c l3 Out_And  Out_And1;
 And 2c l2 Out_Or   Out_Or1;
 And 2c l1 Out_Not  Out_Not1;
 And 2c l0 Out_Sum  Out_Sum1;

 And 2c l0 c_out1   c_out;        /* cout for adder */

 /* =================================
    Collect the desired output to z
    ================================= */
 Or  2c Out_And1 Out_Or1 Out_Not1 Out_Sum1 z;
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;


