module fullAdder(a,b,c,s,o);
	output s,o;
	input a,b,c;
	wire w1,w2,w3,w4;

	xor #1
		xor1(w1,a,b),
		xor2(s,w1,c);
	and #1
		and1(w2,c,b),
		and2(w3,c,a),
		and3(w4,a,b);
	or #1
		or1(o, w2,w3,w4);

endmodule


module andorcircuit(o,s,a,b);
	output o,s;
	input a,b;

	and #1
		and1(s,a,b);
	or #1
		or1(o,a,b);

endmodule


module carrygenerator(cout,p,g,cin);
	output cout;
	input p,g,cin;
	wire w1,w2,w3;

	or #1
		or1(w1,p,cin);
	and #1
		and1(cout,w1,g);

endmodule


module sumgenerator(s,p,g,a,b,cin);
	output s,p,g;
	input a,b,cin;
	wire w1,w2,w3,w4,w5,w6,w7;
	
	xor #1
		xor1(p,a,b),
		xor2(s,p,cin);
	and #1
		and1(g,a,b);

endmodule


module mux2to1(o,a,b,s);
	output o;
	input a,b,s;
	wire w1,w2,w3;

	not #1
		not1(w1, s);
	and #1
		and1(w2, a, w1), 
		and2(w3, b, s);
	or #1
		or1(o, w2, w3);
	



endmodule


module mux4to1(o,a,b,c,d,s0,s1);
	output o;
	input a,b,c,d,s0,s1;
	wire w1,w2;

	mux2to1
		m1(w1,a,b,s0),
		m2(w2,c,d,s0),
		m3(o,w1,w2,s1);

endmodule


module additionsubtraction(s,cout,p,g,sub,a,b,cin);
	output s,cout,p,g;
	input a,b,cin,sub;
	wire w1,w2;
	
	not #1
		not1(w1,b);
	mux2to1
		m1(w2,w1,b,sub);
	sumgenerator
		sum(s,p,g,a,b,cin);
	carrygenerator
		carry(cout,p,g,cin);
endmodule

module alu(o,set,cout,p,g,a,b,sub,cin,less,op1,op2);
	output o,set,cout,p,g;
	input a,b,cin,op1,op2,sub,less;
	wire w1,w2;

	andorcircuit
		andor(w1,w2,a,b);
	additionsubtraction
		addsub(set,cout,p,g,sub,a,b,cin);
	mux4to1
		m1(o,w1,w2,set,less,op1,op2);

endmodule

module bitsliceALU(o,cout,zero,p,g,set,a,b,cin,sub,less,op1,op2);
	output [31:0] o;
	output cout,set,zero,less,p,g;
	input [31:0] a,b;
	input cin,sub,op1,op2;
	wire [30:0] wire1;
	wire wireoverflow;

	alu
		a0(o[0],set,wire1[0],p,g,a[0],b[0],sub,cin,less,op1,op2),
		a1(o[1],set,wire1[1],p,g,a[1],b[1],sub,wire1[0],0,op1,op2),
		a2(o[2],set,wire1[2],p,g,a[2],b[2],sub,wire1[1],0,op1,op2),
		a3(o[3],set,wire1[3],p,g,a[3],b[3],sub,wire1[2],0,op1,op2),
		a4(o[4],set,wire1[4],p,g,a[4],b[4],sub,wire1[3],0,op1,op2),
		a5(o[5],set,wire1[5],p,g,a[5],b[5],sub,wire1[4],0,op1,op2),
		a6(o[6],set,wire1[6],p,g,a[6],b[6],sub,wire1[5],0,op1,op2),
		a7(o[7],set,wire1[7],p,g,a[7],b[7],sub,wire1[6],0,op1,op2),
		a8(o[8],set,wire1[8],p,g,a[8],b[8],sub,wire1[7],0,op1,op2),
		a9(o[9],set,wire1[9],p,g,a[9],b[9],sub,wire1[8],0,op1,op2),
		a10(o[10],set,wire1[10],p,g,a[10],b[10],sub,wire1[9],0,op1,op2),
		a11(o[11],set,wire1[11],p,g,a[11],b[11],sub,wire1[10],0,op1,op2),
		a12(o[12],set,wire1[12],p,g,a[12],b[12],sub,wire1[11],0,op1,op2),
		a13(o[13],set,wire1[13],p,g,a[13],b[13],sub,wire1[12],0,op1,op2),
		a14(o[14],set,wire1[14],p,g,a[14],b[14],sub,wire1[13],0,op1,op2),
		a15(o[15],set,wire1[15],p,g,a[15],b[15],sub,wire1[14],0,op1,op2),
		a16(o[16],set,wire1[16],p,g,a[16],b[16],sub,wire1[15],0,op1,op2),
		a17(o[17],set,wire1[17],p,g,a[17],b[17],sub,wire1[16],0,op1,op2),
		a18(o[18],set,wire1[18],p,g,a[18],b[18],sub,wire1[17],0,op1,op2),
		a19(o[19],set,wire1[19],p,g,a[19],b[19],sub,wire1[18],0,op1,op2),
		a20(o[20],set,wire1[20],p,g,a[20],b[20],sub,wire1[19],0,op1,op2),
		a21(o[21],set,wire1[21],p,g,a[21],b[21],sub,wire1[20],0,op1,op2),
		a22(o[22],set,wire1[22],p,g,a[22],b[22],sub,wire1[21],0,op1,op2),
		a23(o[23],set,wire1[23],p,g,a[23],b[23],sub,wire1[22],0,op1,op2),
		a24(o[24],set,wire1[24],p,g,a[24],b[24],sub,wire1[23],0,op1,op2),
		a25(o[25],set,wire1[25],p,g,a[25],b[25],sub,wire1[24],0,op1,op2),
		a26(o[26],set,wire1[26],p,g,a[26],b[26],sub,wire1[25],0,op1,op2),
		a27(o[27],set,wire1[27],p,g,a[27],b[27],sub,wire1[26],0,op1,op2),
		a28(o[28],set,wire1[28],p,g,a[28],b[28],sub,wire1[27],0,op1,op2),
		a29(o[29],set,wire1[29],p,g,a[29],b[29],sub,wire1[28],0,op1,op2),
		a30(o[30],set,wire1[30],p,g,a[30],b[30],sub,wire1[29],0,op1,op2),
		a31(o[31],set,cout,p,g,a[31],b[31],sub,wire1[30],0,op1,op2);

	or #1
		or1(zero,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],o[8],o[9],o[10],o[11],o[12],o[13],o[14],o[15],o[16],o[17],o[18],o[19],o[20],o[21],o[22],o[23],o[24],o[25],o[26],o[27],o[28],o[29],o[30],o[31]);

	nor #1
		n1(wireoverflow,cout,wire1[30]),
		n2(less,wireoverflow,set);

endmodule

module test32bitALU(o,cout,zero,p,g,set,a,b,cin,sub,less,op1,op2);
	input [31:0] o;
	input cout,set,zero,less,p,g;
	output [31:0] a,b;
	output cin,sub,op1,op2;
	reg [31:0] a,b;
	reg cin,sub,op1,op2;
	
	initial
		begin
		$monitor($time,,"a=%d, b=%d, cin=%b, sub=%d, op1=%d, op2=%d, o=%d, cout=%b",a,b,cin,sub,op1,op2,cout,zero);
		$display($time,,"a=%d, b=%d, cin=%b, sub=%d, op1=%d, op2=%d, o=%d, cout=%b",a,b,cin,sub,op1,op2,cout,zero);
		#20	a=2; b=3; cin=0; sub=0; op1=0; op2=1;
		#20	a=1; b=7; cin=0; sub=1; op1=1; op2=0;
		#20
		$display($time,,"a=%d, b=%d, cin=%b, sub=%d, op1=%d, op2=%d, o=%d, cout=%b",a,b,cin,sub,op1,op2,cout,zero);
		end

endmodule
		
	






