/* 1 bit ALU  macroc
   Syntax: One_Bit_ALU a b carry_in sel1 sel0 | z carry_out;
   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
*/

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;



/* -------------------
   Carry in
   ------------------- */
Switch 1a c 'c' ZERO;

/* ---------------------------
   a = input 1, b = input 2
   --------------------------- */
Switch 3a a 'a' ZERO;
Switch 4a b 'b' ZERO;

/* -------------------
   Controls
   ------------------- */
Switch 6a y '1' ZERO;
Switch 7a x '0' ZERO;

One_Bit_ALU 2b-5b a b c y x| z c_out;

Probe 3c z;
Probe 1c c_out;

