module Controller(L_R0,L_R1,L_R2,L_R3,L_PC,Inc_PC, Sel_Bus1,L_IR,L_ADD_R,L_R_Y,L_R_Z,Sel_Bus2,write, zero,instruction,nclk,rst); //็‹€ๆ…‹ parameter S_idle=0,S_fet1=1,S_fet2=2,S_dec=3, S_ex1=4,S_rd1=5,S_rd2=6,S_wr1=7,S_wr2=8, S_br1=9,S_br2=10,S_halt=11; //ๆŒ‡ไปค parameter NOP=0,ADD=1,SUB=2,AND=3,NOT=4, RD=5,WR=6,BR=7,BRZ=8; output reg L_R0,L_R1,L_R2,L_R3,L_PC,Inc_PC, L_IR,L_ADD_R,L_R_Y,L_R_Z,write; output reg[2:0]Sel_Bus1; output reg [1:0]Sel_Bus2; input zero,nclk,rst; input [7:0]instruction; reg [15:0]Con_out; reg [3:0]PS,NS; reg err_flag; wire [1:0]src=instruction[3:2]; wire [1:0]dest=instruction[1:0]; wire [3:0]opcode=instruction[7:4]; always@(posedge nclk) begin if(rst==1)PS<=0; else PS<=NS; end always@(PS,opcode,src,dest,zero) begin L_R0=0; L_R1=0; L_R2=0; L_R3=0; L_PC=0; Inc_PC=0; Sel_Bus1=0; L_IR=0; L_ADD_R=0; L_R_Y=0; L_R_Z=0; Sel_Bus2=0; write=0; err_flag=0; case(PS) S_idle: NS=S_fet1; S_fet1: begin NS=S_fet2; Sel_Bus1=3'b100;//Sel_PC Sel_Bus2=2'b01;//Sel_Bus1 L_ADD_R=1; end S_fet2: begin NS=S_dec; Sel_Bus2=2'b10;//Sel_Mem L_IR=1; Inc_PC=1; end S_dec: begin case(opcode) NOP:NS=S_fet1; ADD,SUB,AND:begin NS=S_ex1; Sel_Bus2=2'b01;//Sel_Bus1 L_R_Y=1; case(src) 0: Sel_Bus1=3'b000;//R0 1: Sel_Bus1=3'b001;//R1 2: Sel_Bus1=3'b010;//R2 3: Sel_Bus1=3'b011;//R3 default err_flag=1; endcase end//ADD,SUB,AND NOT:begin NS=S_fet1; L_R_Z=1; Sel_Bus2=2'b00;//Sel_ALU case(src) 0: Sel_Bus1=3'b000;//R0 1: Sel_Bus1=3'b001;//R1 2: Sel_Bus1=3'b010;//R2 3: Sel_Bus1=3'b011;//R3 default err_flag=1; endcase case(dest) 0: L_R0=1; 1: L_R1=1; 2: L_R2=1; 3: L_R3=1; default err_flag=1; endcase end//NOT RD: begin NS=S_rd1; Sel_Bus1=3'b100;//Sel_PC Sel_Bus2=3'b001;//Sel_Bus1 L_ADD_R=1; end//RD WR: begin NS=S_wr1; Sel_Bus1=3'b100;//Sel_PC Sel_Bus2=3'b001;//Sel_Bus1 L_ADD_R=1; end//WR BR: begin NS=S_br1; Sel_Bus1=3'b100;//Sel_PC Sel_Bus2=3'b001;//Sel_Bus1 L_ADD_R=1; end//BR BRZ:begin if(zero==1)begin NS=S_br1; Sel_Bus1=3'b100;//Sel_PC Sel_Bus2=3'b001;//Sel_Bus1 L_ADD_R=1; end else begin NS=S_fet1; Inc_PC=1; end end//BRZ default NS=S_halt; endcase//opcode end S_ex1: begin NS=S_fet1; L_R_Z=1; Sel_Bus2=2'b00;//Sel_ALU case(dest) 0: begin Sel_Bus1=3'b000;L_R0=1;end 1: begin Sel_Bus1=3'b001;L_R1=1;end 2: begin Sel_Bus1=3'b010;L_R2=1;end 3: begin Sel_Bus1=3'b011;L_R3=1;end default err_flag=1; endcase end S_rd1: begin NS=S_rd2; Inc_PC=1; Sel_Bus2=2'b10;//Sel_Mem L_ADD_R=1; end S_wr1: begin NS=S_wr2; Inc_PC=1; Sel_Bus2=2'b10;//Sel_Mem L_ADD_R=1; end S_rd2: begin NS=S_fet1; Sel_Bus2=2'b10;//Sel_Mem case(dest) 0: L_R0=1; 1: L_R1=1; 2: L_R2=1; 3: L_R3=1; default err_flag=1; endcase end S_wr2: begin NS=S_fet1; write=1; case(src) 0: Sel_Bus1=3'b000;//R0 1: Sel_Bus1=3'b001;//R1 2: Sel_Bus1=3'b010;//R2 3: Sel_Bus1=3'b011;//R3 default err_flag=1; endcase end S_br1: begin NS=S_br2; Sel_Bus2=2'b10;//Sel_Mem L_ADD_R=1; end S_br2: begin NS=S_fet1; Sel_Bus2=2'b10;//Sel_Mem L_PC=1; end S_halt: NS=S_halt; default NS=S_idle; endcase end endmodule