
	/*** 4 Bit ALU  ***/

`include "DEFINE_ALU" 

module alu(reset,clk,s0,s1,s2,in1,in2,cin,f,cout);
input s0,s1,s2,cin,clk,reset;
input [3:0] in1,in2;
output [3:0] f;
output cout;
reg [3:0] temp,temp1,temp2,logi1,logi2,logi3,logi4;
reg t,res;
     adder_4bit a1(.cout(cout),.sum(f),.in1_num(temp1),.in2_num(temp2),.cin(cin),.clock(clk));
     logic_and_or l(.temp(temp),.f(f),.in1(logi1),.in2(logi2),.clock(clk));
        xor1 x1(.c(f[0]),.a(logi3[0]),.b(logi4[0]),.clock(clk));
        xor1 x2(.c(f[1]),.a(logi3[1]),.b(logi4[1]),.clock(clk));
        xor1 x3(.c(f[2]),.a(logi3[2]),.b(logi4[2]),.clock(clk));
        xor1 x4(.c(f[3]),.a(logi3[3]),.b(logi4[3]),.clock(clk));  
     logic_reset res(.reset(reset),.out(f),.carryout(cout),.clock(clk));
		
always @ (posedge clk or reset)
begin
    if (reset==1)
        begin
        temp[0]=cin;
        temp[1]=s0;
        temp[2]=s1;
        temp[3]=s2;
    case (temp)
	`TRANSFER_B_0:
    		begin
    		temp1=in1;temp2=4'b0000;t=1'b0;
    		end
	`INCREMENT:
   		begin
   		temp1=in1;temp2=4'b0000;t=1'b1;
   		end
	`ADD:
   		begin
   		temp1=in1;temp2=in2;t=1'b0;
   		end
	`ADD_CARRY:
   		begin
   		temp1=in1;temp2=in2;t=1'b1;
   		end
	`SUB_BORROW:
   		begin
   		temp1=in1;temp2=~in2;t=1'b0;
   		end
	`SUB:
   		begin
   		temp1=in1;temp2=~in2;t=1'b1;
   		end
	`DECREMENT:
   		begin
   		temp1=in1;temp2=4'b1111;t=1'b0;
   		end
	`TRANSFER_B_1:
   		begin 
   		temp1=in1;temp2=4'b0000;t=1'b0;
   		end
	`XOR_0:
   		begin
   		logi3=in1;logi4=in2;
  		end
	`XOR_1:
  	 	begin
   		logi3=in1;logi4=in2;
   		end
	default:
   		begin
   		logi1=in1;logi2=in2;
   		end
   
    endcase
    end    
end
endmodule 



module logic_and_or(temp,f,in1,in2,clock);
input [3:0] temp,in1,in2;
input clock;
output [3:0] f;
reg f;

always @ (temp or in1 or in2 or clock)
begin
    case (temp)
	`OR_0:
   		begin
   		f=in1|in2;
   		end
	`OR_1:	
   		begin
   		f=in1|in2;
  		end
	`AND_0:
   		begin
   		f=in1&in2;
   		end
	`AND_1:
   		begin
   		f=in1&in2;
   		end
	`NOT_0:
   		begin
   		f=~in1;
   		end
	`NOT_1:
   		begin
   		f=~in1;
   		end
    endcase
end
endmodule

module logic_reset(reset,out,carryout,clock);
input reset,clock;
output carryout;
output [3:0] out;
reg carryout;
reg [3:0] out;
always @ (reset or posedge clock)
   if(reset==1'b0) 
    begin
      out=4'b0000;
      carryout=1'b0;
    end
endmodule


