/* From bbavett: file `/home/bbavett/cs355/pj6/datapath.h' as assignment pj6 */
Define InputAnd16x1 a[15..0] b | z[15..0];
	And aa a[0] b z[0];
	And aa a[1] b z[1];
	And aa a[2] b z[2];
	And aa a[3] b z[3];
	And aa a[4] b z[4];
	And aa a[5] b z[5];
	And aa a[6] b z[6];
	And aa a[7] b z[7];
	And aa a[8] b z[8];
	And aa a[9] b z[9];
	And aa a[10] b z[10];
	And aa a[11] b z[11];
	And aa a[12] b z[12];
	And aa a[13] b z[13];
	And aa a[14] b z[14];
	And aa a[15] b z[15];
Endef;

Define InputAnd16x2 a[15..0] b[15..0] | z[15..0];
	And aa a[0] b[0] z[0];
	And aa a[1] b[1] z[1];
	And aa a[2] b[2] z[2];
	And aa a[3] b[3] z[3];
	And aa a[4] b[4] z[4];
	And aa a[5] b[5] z[5];
	And aa a[6] b[6] z[6];
	And aa a[7] b[7] z[7];
	And aa a[8] b[8] z[8];
	And aa a[9] b[9] z[9];
	And aa a[10] b[10] z[10];
	And aa a[11] b[11] z[11];
	And aa a[12] b[12] z[12];
	And aa a[13] b[13] z[13];
	And aa a[14] b[14] z[14];
	And aa a[15] b[15] z[15];
Endef;

Define InputOr16x4 a[15..0] b[15..0] c[15..0] d[15..0]  | z[15..0];
	Or aa a[0] b[0] c[0] d[0] z[0];
	Or aa a[1] b[1] c[1] d[1] z[1];
	Or aa a[2] b[2] c[2] d[2] z[2];
	Or aa a[3] b[3] c[3] d[3] z[3];
	Or aa a[4] b[4] c[4] d[4] z[4];
	Or aa a[5] b[5] c[5] d[5] z[5];
	Or aa a[6] b[6] c[6] d[6] z[6];
	Or aa a[7] b[7] c[7] d[7] z[7];
	Or aa a[8] b[8] c[8] d[8] z[8];
	Or aa a[9] b[9] c[9] d[9] z[9];
	Or aa a[10] b[10] c[10] d[10] z[10];
	Or aa a[11] b[11] c[11] d[11] z[11];
	Or aa a[12] b[12] c[12] d[12] z[12];
	Or aa a[13] b[13] c[13] d[13] z[13];
	Or aa a[14] b[14] c[14] d[14] z[14];
	Or aa a[15] b[15] c[15] d[15] z[15];
Endef;

Define InputNot16 a[15..0] | z[15..0];
	Not aa a[0] z[0];
	Not aa a[1] z[1];
	Not aa a[2] z[2];
	Not aa a[3] z[3];
	Not aa a[4] z[4];
	Not aa a[5] z[5];
	Not aa a[6] z[6];
	Not aa a[7] z[7];
	Not aa a[8] z[8];
	Not aa a[9] z[9];
	Not aa a[10] z[10];
	Not aa a[11] z[11];
	Not aa a[12] z[12];
	Not aa a[13] z[13];
	Not aa a[14] z[14];
	Not aa a[15] z[15];
Endef;

Define InputDec16x4 sum[15..0] and[15..0] a[15..0] na[15..0] x y | z[15..0];
	Decoder2x4 aa x y | s[3..0];
		InputAnd16x1 aa sum[15..0] s[0] | sumOr[15..0];
		InputAnd16x1 aa and[15..0] s[1] | andOr[15..0];
		InputAnd16x1 aa a[15..0] s[2] | aOr[15..0];
		InputAnd16x1 aa na[15..0] s[3] | naOr[15..0];
		InputOr16x4 aa sumOr[15..0] andOr[15..0] aOr[15..0] naOr[15..0] | z[15..0];
Endef;

Define Adder16 a[15..0] b[15..0] | z[15..0];
	Full_Adder aa ZERO a[0] b[0] | c[0] z[0];
	Full_Adder aa c[0] a[1] b[1] | c[1] z[1];
	Full_Adder aa c[1] a[2] b[2] | c[2] z[2];
	Full_Adder aa c[2] a[3] b[3] | c[3] z[3];
	Full_Adder aa c[3] a[4] b[4] | c[4] z[4];
	Full_Adder aa c[4] a[5] b[5] | c[5] z[5];
	Full_Adder aa c[5] a[6] b[6] | c[6] z[6];
	Full_Adder aa c[6] a[7] b[7] | c[7] z[7];
	Full_Adder aa c[7] a[8] b[8] | c[8] z[8];
	Full_Adder aa c[8] a[9] b[9] | c[9] z[9];
	Full_Adder aa c[9] a[10] b[10] | c[10] z[10];
	Full_Adder aa c[10] a[11] b[11] | c[11] z[11];
	Full_Adder aa c[11] a[12] b[12] | c[12] z[12];
	Full_Adder aa c[12] a[13] b[13] | c[13] z[13];
	Full_Adder aa c[13] a[14] b[14] | c[14] z[14];
	Full_Adder aa c[14] a[15] b[15] | c[15] z[15];
Endef;

Define ALU16 a[15..0] b[15..0] x y | z[15..0] N Z;
	Adder16 ac-ic a[15..0] b[15..0] | sum[15..0];
	InputAnd16x2 aa a[15..0] b[15..0] | and[15..0];
	InputNot16 aa a[15..0] | na[15..0];
	InputDec16x4 be-oe sum[15..0] and[15..0] a[15..0] na[15..0] x y | z[15..0];
	Not aa z[15] nN;
	Not aa nN N;
	Nor bg-og z[15..0] Z;
Endef;
Define Shifter L C R c1 c0 | z;
	Not aa c1 nc1;
	Not aa c0 nc0;
	And aa C nc1 nc0 Cand;
	And aa L nc1 c0 Land;
	And aa R c1 nc0 Rand;
	Or ba Cand Land Rand z;
Endef;

Define SHIFTER16 a[15..0] c[1..0] | s[15..0];
	Shifter aa a[1] a[0] ZERO c[1] c[0] | s[0];
	Shifter ba a[2] a[1] a[0] c[1] c[0] | s[1];
	Shifter ca a[3] a[2] a[1] c[1] c[0] | s[2];
	Shifter da a[4] a[3] a[2] c[1] c[0] | s[3];
	Shifter ea a[5] a[4] a[3] c[1] c[0] | s[4];
	Shifter fa a[6] a[5] a[4] c[1] c[0] | s[5];
	Shifter ga a[7] a[6] a[5] c[1] c[0] | s[6];
	Shifter ha a[8] a[7] a[6] c[1] c[0] | s[7];
	Shifter ia a[9] a[8] a[7] c[1] c[0] | s[8];
	Shifter ja a[10] a[9] a[8] c[1] c[0] | s[9];
	Shifter ka a[11] a[10] a[9] c[1] c[0] | s[10];
	Shifter la a[12] a[11] a[10] c[1] c[0] | s[11];
	Shifter ma a[13] a[12] a[11] c[1] c[0] | s[12];
	Shifter na a[14] a[13] a[12] c[1] c[0] | s[13];
	Shifter oa a[15] a[14] a[13] c[1] c[0] | s[14];
	Shifter pa ZERO a[15] a[14] c[1] c[0] | s[15];
Endef;

Define FFReg16 in[15..0] enable clock clear | out[15..0];
    Not aa clock clk;
    Dff aa enable in[15] clk clear out[15] qNot[15]; Dff aa enable in[14] clk clear out[14] qNot[14];
    Dff aa enable in[13] clk clear out[13] qNot[13]; Dff aa enable in[12] clk clear out[12] qNot[12];
    Dff aa enable in[11] clk clear out[11] qNot[11]; Dff aa enable in[10] clk clear out[10] qNot[10];
    Dff aa enable in[9] clk clear out[9] qNot[9]; Dff aa enable in[8] clk clear out[8] qNot[8];
    Dff aa enable in[7] clk clear out[7] qNot[7]; Dff aa enable in[6] clk clear out[6] qNot[6];
    Dff aa enable in[5] clk clear out[5] qNot[5]; Dff aa enable in[4] clk clear out[4] qNot[4];
    Dff aa enable in[3] clk clear out[3] qNot[3]; Dff aa enable in[2] clk clear out[2] qNot[2];
    Dff aa enable in[1] clk clear out[1] qNot[1]; Dff aa enable in[0] clk clear out[0] qNot[0];
Endef;

Define Const-0 activate | D[15-0];
    Or aa ZERO D[15]; Or aa ZERO D[14]; Or aa ZERO D[13];
    Or aa ZERO D[12]; Or aa ZERO D[11]; Or aa ZERO D[10];
    Or aa ZERO D[9]; Or aa ZERO D[8]; Or aa ZERO D[7];
    Or aa ZERO D[6]; Or aa ZERO D[5]; Or aa ZERO D[4];
    Or aa ZERO D[3]; Or aa ZERO D[2]; Or aa ZERO D[1];
    Or aa ZERO D[0]; 
Endef;

Define Const-1 activate | D[15-0];
    Or aa ZERO D[15]; Or aa ZERO D[14]; Or aa ZERO D[13];
    Or aa ZERO D[12]; Or aa ZERO D[11]; Or aa ZERO D[10];
    Or aa ZERO D[9]; Or aa ZERO D[8]; Or aa ZERO D[7];
    Or aa ZERO D[6]; Or aa ZERO D[5]; Or aa ZERO D[4];
    Or aa ZERO D[3]; Or aa ZERO D[2]; Or aa ZERO D[1];
    Or aa ONE D[0]; 
Endef;


Define Const-N1 activate | D[15-0];
    Or aa ONE D[15]; Or aa ONE D[14]; Or aa ONE D[13];
    Or aa ONE D[12]; Or aa ONE D[11]; Or aa ONE D[10];
    Or aa ONE D[9]; Or aa ONE D[8]; Or aa ONE D[7];
    Or aa ONE D[6]; Or aa ONE D[5]; Or aa ONE D[4];
    Or aa ONE D[3]; Or aa ONE D[2]; Or aa ONE D[1];
    Or aa ONE D[0]; 
Endef;


Define DataPath mir[31..0] mbr[15..0] Phase [1..4] reset | 
	R0[15..0] R1[15..0] R2[15..0] R3[15..0] R4[15..0] R5[15..0] 
	R6[15..0] R7[15..0] R8[15..0] R9[15..0] R10[15..0] R11[15..0]
	R12[15..0] R13[15..0] R14[15..0] R15[15..0]
	A_REG_MUX[15-0] BMUX[15-0] A[15-0] B[15-0] AMUX[15-0] 
	ALUOut[15-0] C[15-0] N Z;
     
     Nand aa mir[20] Phase[4] DecActivate;
     Dec4x16 aa mir[19..16] DecActivate R[15..0];
     
     Mux-mxn aa R15[15..0] R14[15..0] R13[15..0] R12[15..0] 
                R11[15..0] R10[15..0] R9[15..0]  R8[15..0] 
                R7[15..0]  R6[15..0]  R5[15..0]  R4[15..0] 
                R3[15..0]  R2[15..0]  R1[15..0]  R0[15..0] 
                mir[11..8] | A_REG_MUX[15..0];
     
     Mux-mxn aa R15[15..0] R14[15..0] R13[15..0] R12[15..0] 
                R11[15..0] R10[15..0] R9[15..0]  R8[15..0] 
                R7[15..0]  R6[15..0]  R5[15..0]  R4[15..0] 
                R3[15..0]  R2[15..0]  R1[15..0]  R0[15..0] 
                mir[15..12] | BMUX[15..0];
     
     Mux-mxn aa mbr[15..0] A[15..0]  mir[31] | AMUX[15..0];
     
     Not aa Phase[2] LatchActivate;
     Register aa A_REG_MUX[15..0] LatchActivate | A[15..0];
     Register aa BMUX[15..0] LatchActivate | B[15..0];
     
     Not aa reset nReset;
     FFReg16 aa C[15..0] ONE R[0] nReset | R0[15..0];
     FFReg16 aa C[15..0] ONE R[1] nReset | R1[15..0];
     FFReg16 aa C[15..0] ONE R[2] nReset | R2[15..0];
     FFReg16 aa C[15..0] ONE R[3] nReset | R3[15..0];
     FFReg16 aa C[15..0] ONE R[4] nReset | R4[15..0];
     Const-0 aa R[5] | R5[15..0];
     Const-1 aa R[6] | R6[15..0];
     Const-N1 aa R[7] | R7[15..0];
     Register aa C[15..0] R[8] | R8[15..0];
     Register aa C[15..0] R[9] | R9[15..0];
     Register aa C[15..0] R[10] | R10[15..0];
     Register aa C[15..0] R[11] | R11[15..0];
     Register aa C[15..0] R[12] | R12[15..0];
     Register aa C[15..0] R[13] | R13[15..0];
     Register aa C[15..0] R[14] | R14[15..0];
     Register aa C[15..0] R[15] | R15[15..0];
     
     ALU16 aa AMUX[15..0] B[15..0] mir[28..27] | ALUOut[15..0] N Z;
     SHIFTER16 aa ALUOut[15..0] mir[26..25] | C[15..0];
Endef;
