module SIMCOMP4(CLK, PC, R0, R1, R2, R3, IR, MBR, MAR, IOBR, IOAR);
input CLK;
output R0,R1,R2,R3, PC, IR, MBR, MAR,IOBR, IOAR;
reg [15:0] MBR, IR, R0, R1, R2, R3;
reg [7:0] IOBR;
reg [5:0] PC, MAR,IOAR;
reg [3 :0] state;
reg [15:0] R[0:3];
reg [15:0] Memory [0:63];
parameter load=4'b0011, store=4'b1011, add=4'b0111, jump=4'b0000, in=4'b0100, out=4'b0101;

initial
  begin
  //instructions
  Memory[10]=16'h4001;
  Memory[11]=16'h3104;
  Memory[12]=16'h7040;
  Memory[13]=16'h5002;
  //data
  Memory[5] =16'hA;
  Memory[6] =16'hB;
 // Memory[4] =16'h0737;
  
  PC=10;
  state=0;
 end
always @(posedge CLK) begin
 
 case (state)
   0: begin
       MAR <= PC;
       state =1; 
      end
   1: begin //fetch instruction
       IR    <= Memory[MAR];
       state = 2;
       PC    <=PC +1;
      end
   2: begin //instruction decoding
       MAR <= IR[5:0];
       IOAR<= IR[5:0];
       state=3;
      end
   3: begin //fetch operands
      // load and store deals for reg with index store in IR[9:8]
       state=4;
       case(IR[15:12])
        load : begin 
        if(IR[11]==0) 
          MBR <= Memory[MAR];
        else 
          begin
           if(IR[7]==0)
             MBR <= IR[7:0];
           else
             MBR <= -(~(IR[7:0])+1);
          end
         end
        store: MBR <= R[IR[9:8]];
        jump : begin 
                PC <= MAR;
                state=0; 
               end
        in  : IOBR<= Memory[IOAR];
        out : IOBR<= R[0];
       endcase
      end
   4: begin
       if(IR[15:12]==4'h7) begin//add
        R[IR[11:10]] <= R[IR[9:8]]+R[IR[7:6]];
        state=0;
       end
       else if(IR[15:12]==4'h3) begin//load
        R[IR[9:8]] <= MBR;
        state=0;
       end
       else if(IR[15:12]==4'hB) begin//store
        Memory[MAR] <= MBR;
        state=0;
       end
       else if(IR[15:12]==4'h4)// IN
        begin 
         R[0] [7:0]<= IOBR;
         state=0;
        end
       else if(IR[15:12]==4'h5)// OUT
       begin 
        Memory[IOAR] <= IOBR;
        state=0; 
        end
      end
 endcase
 R0<=R[0]; R1<=R[1];R2<=R[2];R3<=R[3];
 end
endmodule
