/* -----------------------------------------------------------
   Basic circuits made available for the CS355 class project
   ----------------------------------------------------------- */

/* Full adder.
   Syntax: Full_Adder c-in a b | 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;

/* 2x4 Decoder
   Syntax: Decoder2x4 <x,y> c[1..0] | s[3..0];
*/
Define Decoder2x4 c[1..0] | s[3..0];
 Not 1a c[1] not-c1; Not 2a c[0] not-c0;
 And 2a c[1] c[0] s[3];
 And 2b c[1] not-c0 s[2];
 And 2c not-c1 c[0] s[1];
 And 2d not-c1 not-c0 s[0];
Endef;

/* ----------------------------------------------------------
   ResetableReg16: a 16 bit register with reset

   Usage: ResetableReg16 xx in[15-0] load reset | out[15-0];

   Use it for the PC register
   ---------------------------------------------------------- */
Define ResetableReg16 in[15..0] load reset | out[15..0];
     Not aa load  not-ld;
     Not aa reset nr;
     Dff aa ONE in[15] not-ld nr out[15] x15 ;
     Dff aa ONE in[14] not-ld nr out[14] x14 ;
     Dff aa ONE in[13] not-ld nr out[13] x13 ;
     Dff aa ONE in[12] not-ld nr out[12] x12 ;
     Dff aa ONE in[11] not-ld nr out[11] x11 ;
     Dff aa ONE in[10] not-ld nr out[10] x10 ;
     Dff aa ONE in[9] not-ld nr out[9] x9 ;
     Dff aa ONE in[8] not-ld nr out[8] x8 ;
     Dff aa ONE in[7] not-ld nr out[7] x7 ;
     Dff aa ONE in[6] not-ld nr out[6] x6 ;
     Dff aa ONE in[5] not-ld nr out[5] x5 ;
     Dff aa ONE in[4] not-ld nr out[4] x4 ;
     Dff aa ONE in[3] not-ld nr out[3] x3 ;
     Dff aa ONE in[2] not-ld nr out[2] x2 ;
     Dff aa ONE in[1] not-ld nr out[1] x1 ;
     Dff aa ONE in[0] not-ld nr out[0] x0 ;
Endef;

/* ----------------------------------------------------------------
   MyRegister16: a 16 bit register with no reset

   Usage: MyRegister16 xx in[15-0] load reset | out[15-0];
			of the clock "load"

   *** IMPORTANT NOTE: the value is written during the FALL EDGE

   Use it for the other registers, MAR, MBR, A-latch, B-latch of
   your project.
   ---------------------------------------------------------------- */
Define MyRegister16 in[15..0] load | out[15..0];
     Not aa load  not-ld;
     Dff aa ONE in[15] not-ld ONE out[15] x15 ;
     Dff aa ONE in[14] not-ld ONE out[14] x14 ;
     Dff aa ONE in[13] not-ld ONE out[13] x13 ;
     Dff aa ONE in[12] not-ld ONE out[12] x12 ;
     Dff aa ONE in[11] not-ld ONE out[11] x11 ;
     Dff aa ONE in[10] not-ld ONE out[10] x10 ;
     Dff aa ONE in[9]  not-ld ONE out[9] x9 ;
     Dff aa ONE in[8]  not-ld ONE out[8] x8 ;
     Dff aa ONE in[7]  not-ld ONE out[7] x7 ;
     Dff aa ONE in[6]  not-ld ONE out[6] x6 ;
     Dff aa ONE in[5]  not-ld ONE out[5] x5 ;
     Dff aa ONE in[4]  not-ld ONE out[4] x4 ;
     Dff aa ONE in[3]  not-ld ONE out[3] x3 ;
     Dff aa ONE in[2]  not-ld ONE out[2] x2 ;
     Dff aa ONE in[1]  not-ld ONE out[1] x1 ;
     Dff aa ONE in[0]  not-ld ONE out[0] x0 ;
Endef;

/* ----------------------------------------------------------------
   MyRegister8: a 8 bit register with no reset

   Usage: MyRegister8 xx in[7-0] load reset | out[7-0];

   *** IMPORTANT NOTE: the value is written during the FALL EDGE
			of the clock "load"

   Use it for MPC
   ---------------------------------------------------------------- */
Define MyRegister8 in[7..0] load | out[7..0];
     Not aa load  not-ld;
     Dff aa ONE in[7]  not-ld ONE out[7] x7 ;
     Dff aa ONE in[6]  not-ld ONE out[6] x6 ;
     Dff aa ONE in[5]  not-ld ONE out[5] x5 ;
     Dff aa ONE in[4]  not-ld ONE out[4] x4 ;
     Dff aa ONE in[3]  not-ld ONE out[3] x3 ;
     Dff aa ONE in[2]  not-ld ONE out[2] x2 ;
     Dff aa ONE in[1]  not-ld ONE out[1] x1 ;
     Dff aa ONE in[0]  not-ld ONE out[0] x0 ;
Endef;

