
		/***  INSTRUCTION DECODER  ***/

`define READ  2'b00
`define ALU   2'b01
`define WRITE 2'b10
`define IDLE  2'b11 


module decoder(opcode,op1,op2,clk,cin,reset,rdata,adin1,adin2,adout,csn,rwn, addr,s0,s1,s2);

input clk,reset,cin;
input [3:0] op1,op2,adout;
input [2:0] opcode;
output [3:0] adin1,adin2,addr ;
output csn,rwn,s0,s1,s2;
inout [3:0] rdata;
reg [1:0] state;
reg csn,rwn,s0,s1,s2;
reg [3:0] rdatain,adin1,adin2,addr,temp;

// with new instruction, decoder starts giving control signals

always @(opcode or op1 or op2 or cin or reset)
    	state =`READ;

always @(posedge clk) 
begin
	case (state)
	`READ: 
		begin
  		csn=0;
 		rwn=1;
		addr = op1;
	 	state = `ALU;
		end

  	`ALU:
		begin
		s0= opcode[0];
		s1= opcode[1];
		s2= opcode[2];
		adin1=op2;
    		adin2 =rdata;
    		csn=1;
    		state = `WRITE;
		end
      	`WRITE:
		begin
      		csn=0;
      		rwn=0;
		state= `IDLE;
		end
	`IDLE:
		begin
		csn=1;
//waiting for next instruction
 		end
	endcase
end   

assign rdata = temp;

//tristate bus
always @(csn | rwn)
	if (!rwn)
		temp = adout;
	else
		temp = 4'bzzzz;
    
endmodule 

