//MiniCPU main file -- actions module miniCPU (Reset, Address, Data_bus, Clock, Read, Write, IO_Req, Mem_Req, State, Dir); output logic [15:0] Address; output logic Read, Write, IO_Req, Mem_Req; //Active-low signals output logic [7:0] State; output logic Dir; //0 = write data from CPU to bus, 1 = CPU read data from bus input logic Reset; input wire Clock; inout wire [7:0] Data_bus; logic [7:0] Next_State; logic [15:0] PC_data_in; logic [15:0] PC; logic [1:0] PC_action; //0 = nothing, 1 = increment, 2 = jump logic [15:0] SP_data_in; logic [15:0] SP; logic [1:0] SP_action; //0 = nothing, 1 = inc, 2 = dec, 3 = new SP logic [7:0] IR_A, IR_B, IR_C, IR_D; logic [7:0] Reg_A, Reg_B, Reg_C, Reg_D; logic Carry_flag, Zero_flag, Minus_flag; logic Carry_out, Zero, Minus; logic [2:0] ALU_op; logic [7:0] ALU_a, ALU_b, ALU_out; logic [7:0] temp; logic [15:0] temp16; logic [7:0] Data_in, Data_out; program_counter U1 (Clock, Reset, PC_action, PC_data_in, PC); miniCPU_next_state U2 (IR_A, State, Carry_flag, Zero_flag, Minus_flag, Next_State); bidirec U3 (Dir, Data_in, Data_out, Data_bus); ALU U4 (ALU_op, ALU_a, ALU_b, Carry_flag, Carry_out, Zero, Minus, ALU_out); stack_pointer U5 (Clock, Reset, SP_action, SP_data_in, SP); always_ff @(negedge Clock) begin if (!Reset) State <= 0; else State <= Next_State; end always_ff @(posedge Clock) begin case (State) //Instruction fetch actions 0: begin Address <= PC; Read <= 0; IO_Req <= 1; Mem_Req <= 0; Write <=1; Dir <= 1; PC_action <= 1; SP_action <= 0; end 1: begin IR_A <= Data_out; PC_action <=0; end 2: begin Mem_Req <= 1; Read <= 1; end 3: begin Address <= PC; Mem_Req <= 0; Read <= 0; IO_Req <=1; Write <=1; Dir <= 1; PC_action <= 1; end 4: begin IR_B <= Data_out; PC_action <=0; end 5: begin Mem_Req <= 1; Read <= 1; end 6: begin Address <= PC; Mem_Req <= 0; Read <= 0; IO_Req <=1; Dir <= 1; PC_action <= 1; end 7: begin IR_C <= Data_out; PC_action <=0; end 8: begin Mem_Req <= 1; Read <= 1; end 9: begin Address <= PC; Mem_Req <= 0; Read <= 0; IO_Req <=1; Write <=1; Dir <= 1; PC_action <= 1; end 10: begin IR_D <= Data_out; PC_action <=0; end 11: begin Mem_Req <= 1; Read <= 1; end //Instruction actions //ADD reg, reg 13: begin ALU_op <= 0; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 14: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //ADC reg, reg 15: begin ALU_op <= 1; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 16: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //SUB reg, reg 17: begin ALU_op <= 2; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 18: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //SBB reg, reg 19: begin ALU_op <= 3; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 20: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //AND reg, reg 21: begin ALU_op <= 4; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 22: begin Zero_flag <= Zero; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //OR reg, reg 23: begin ALU_op <= 5; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 24: begin Zero_flag <= Zero; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //XOR reg, reg 25: begin ALU_op <= 6; case (IR_B [3:2]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase case (IR_B [1:0]) 0: ALU_b <= Reg_A; 1: ALU_b <= Reg_B; 2: ALU_b <= Reg_C; 3: ALU_b <= Reg_D; endcase end 26: begin Zero_flag <= Zero; case (IR_B [3:2]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //NOT reg 27: begin ALU_op <= 6; case (IR_B [1:0]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase end 28: begin Zero_flag <= Zero; case (IR_B [1:0]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //MOV reg, reg 29: begin case (IR_B [1:0]) 0: temp <= Reg_A; 1: temp <= Reg_B; 2: temp <= Reg_C; 3: temp <= Reg_D; endcase end 30: begin case (IR_B [3:2]) 0: Reg_A <= temp; 1: Reg_B <= temp; 2: Reg_C <= temp; 3: Reg_D <= temp; endcase end //MOV reg, value 31: begin case (IR_B [1:0]) 0: Reg_A <= IR_C; 1: Reg_B <= IR_C; 2: Reg_C <= IR_C; 3: Reg_D <= IR_C; endcase end //MOV reg, [memory] 32: begin Address [7:0] <= IR_C; Address [15:8] <= IR_D; Mem_Req <= 0; Read <= 0; Dir <= 1; end 33: begin case (IR_B [1:0]) 0: Reg_A <= Data_out; 1: Reg_B <= Data_out; 2: Reg_C <= Data_out; 3: Reg_D <= Data_out; endcase end 34: begin Mem_Req <= 1; Read <= 1; end //MOV [memory], reg 35: begin Address [7:0] <= IR_C; Address [15:8] <= IR_D; case (IR_B [1:0]) 0: Data_in <= Reg_A; 1: Data_in <= Reg_B; 2: Data_in <= Reg_C; 3: Data_in <= Reg_D; endcase Mem_Req <= 0; Dir <= 0; end 36: Write <= 0; 37: Write <=1; 38: begin Dir <= 1; Mem_Req <= 1; end //PUSH reg -- decrement SP then store 39: SP_action <= 2; 40: SP_action <= 0; 41: begin Address <= SP; case (IR_B [1:0]) 0: Data_in <= Reg_A; 1: Data_in <= Reg_B; 2: Data_in <= Reg_C; 3: Data_in <= Reg_D; endcase Mem_Req <= 0; Dir <= 0; end 42: Write <= 0; 43: Write <= 1; 44: begin Dir <= 1; Mem_Req <= 1; end //POP reg -- fetch then increment SP 45: begin Address <= SP; Mem_Req <= 0; Read <= 0; Dir <= 1; end 46: begin case (IR_B [1:0]) 0: Reg_A <= Data_out; 1: Reg_B <= Data_out; 2: Reg_C <= Data_out; 3: Reg_D <= Data_out; endcase end 47: begin SP_action <= 1; Mem_Req <= 1; Read <= 1; end 48: SP_action <= 0; //JP address 49: begin PC_data_in [7:0] <= IR_B; PC_data_in [15:8] <= IR_C; PC_action <= 2; end 50: PC_action <= 0; //CALL address 51: SP_action <= 2; 52: SP_action <= 0; //Dec SP then store PC_lo 53: begin Address <= SP; Data_in <= PC [7:0]; Mem_Req <= 0; Dir <= 0; end 54: Write <= 0; 55: Write <= 1; 56: begin Dir <= 1; Mem_Req <= 1; end 57: SP_action <= 2; //Dec SP then store PC_hi 58: SP_action <= 0; 59: begin Address <= SP; Data_in <= PC [15:8]; Mem_Req <= 0; Dir <= 0; end 60: Write <= 0; 61: Write <= 1; 62: begin Dir <= 1; Mem_Req <= 1; end 63: begin //Jump to call address PC_data_in [7:0] <= IR_B; PC_data_in [15:8] <= IR_C; PC_action <= 2; end 64: PC_action <= 0; //RET 65: begin Address <= SP; //fetch PC_hi then increment SP Mem_Req <= 0; Read <= 0; Dir <= 1; end 66: PC_data_in [15:8] <= Data_out; 67: begin SP_action <= 1; Mem_Req <= 1; Read <= 1; end 68: SP_action <= 0; 69: begin Address <= SP; //fetch PC_lo then increment SP Mem_Req <= 0; Read <= 0; Dir <= 1; end 70: PC_data_in [7:0] <= Data_out; 71: begin SP_action <= 1; Mem_Req <= 1; Read <= 1; end 72: SP_action <= 0; 73: PC_action <= 2; //Jump to retrieved address 74: PC_action <= 0; //SCF 75: Carry_flag <= 1; //CCF 76: Carry_flag <= 0; //IN reg, [port] 77: begin Address [7:0] <= IR_C; IO_Req <= 0; Read <= 0; Dir <= 1; end 78: begin case (IR_B [1:0]) 0: Reg_A <= Data_out; 1: Reg_B <= Data_out; 2: Reg_C <= Data_out; 3: Reg_D <= Data_out; endcase end 79: begin Mem_Req <= 1; Read <= 1; end //OUT [port], reg 80: begin Address [7:0] <= IR_C; case (IR_B [1:0]) 0: Data_in <= Reg_A; 1: Data_in <= Reg_B; 2: Data_in <= Reg_C; 3: Data_in <= Reg_D; endcase IO_Req <= 0; Dir <= 0; end 81: Write <= 0; 82: Write <=1; 83: begin Dir <= 1; IO_Req <= 1; end //MOV SP, address 84: begin SP_data_in [7:0] <= IR_B; SP_data_in [15:8] <= IR_C; SP_action <= 3; end 85: SP_action <= 0; //INC reg 86: begin ALU_op <= 0; case (IR_B [1:0]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase ALU_b <= 1; end 87: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [1:0]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //DEC reg 88: begin ALU_op <= 2; case (IR_B [1:0]) 0: ALU_a <= Reg_A; 1: ALU_a <= Reg_B; 2: ALU_a <= Reg_C; 3: ALU_a <= Reg_D; endcase ALU_b <= 1; end 89: begin Carry_flag <= Carry_out; Zero_flag <= Zero; Minus_flag <= Minus; case (IR_B [1:0]) 0: Reg_A <= ALU_out; 1: Reg_B <= ALU_out; 2: Reg_C <= ALU_out; 3: Reg_D <= ALU_out; endcase end //MOV reg, [reg pair] 90: begin case (IR_B [0]) 0: begin Address [7:0] <= Reg_B; Address [15:8] <= Reg_A; end 1: begin Address [7:0] <= Reg_D; Address [15:8] <= Reg_C; end endcase Mem_Req <= 0; Read <= 0; Dir <= 1; end 91: begin case (IR_B [2:1]) 0: Reg_A <= Data_out; 1: Reg_B <= Data_out; 2: Reg_C <= Data_out; 3: Reg_D <= Data_out; endcase end 92: begin Mem_Req <= 1; Read <= 1; end //MOV [reg pair],reg 93: begin case (IR_B [0]) 0: begin Address [7:0] <= Reg_B; Address [15:8] <= Reg_A; end 1: begin Address [7:0] <= Reg_D; Address [15:8] <= Reg_C; end endcase case (IR_B [2:1]) 0: Data_in <= Reg_A; 1: Data_in <= Reg_B; 2: Data_in <= Reg_C; 3: Data_in <= Reg_D; endcase Mem_Req <= 0; Dir <= 0; end 94: Write <= 0; 95: Write <=1; 96: begin Dir <= 1; Mem_Req <= 1; end //INC reg pair 97: begin case (IR_B [0]) 0: begin temp16[15:8] <= Reg_A; temp16[7:0] <= Reg_B; end 1: begin temp16[15:8] <= Reg_C; temp16[7:0] <= Reg_D; end endcase end 98: temp16 <= temp16 + 16'h0001; 99: begin case (IR_B [0]) 0: begin Reg_A <= temp16[15:8]; Reg_B <= temp16[7:0]; end 1: begin Reg_C <= temp16[15:8]; Reg_D <= temp16[7:0]; end endcase end //DEC reg pair 100: begin case (IR_B [0]) 0: begin temp16[15:8] <= Reg_A; temp16[7:0] <= Reg_B; end 1: begin temp16[15:8] <= Reg_C; temp16[7:0] <= Reg_D; end endcase end 101: temp16 <= temp16 - 16'h0001; 102: begin case (IR_B [0]) 0: begin Reg_A <= temp16[15:8]; Reg_B <= temp16[7:0]; end 1: begin Reg_C <= temp16[15:8]; Reg_D <= temp16[7:0]; end endcase end endcase end endmodule