`include "opcodes.v" `timescale 100ps / 10ps module control( data, alu_function, update_z, enable_Acc, load_Acc, enable_X, load_X, enable_S, load_S, enable_PC, load_PC, inc_PC, sel_PC, load_MAR, enable_reg, memory_write, zflag, clock, not_reset ); input [15:0] data; output [3:0] alu_function; output memory_write; output update_z; output enable_Acc, load_Acc; output enable_X, load_X; output enable_S, load_S; output enable_PC, load_PC, inc_PC, sel_PC; output load_MAR; output enable_reg; input zflag, clock, not_reset; reg [1:0] state; wire [1:0] phase; wire fetch, op_fetch, execute; reg [11:0] Program_Counter; reg [15:0] Instruction_Register; reg [11:0] operand; wire [11:0] opcode; wire [3:0] inst_type; wire [1:0] src_field, dest_field; wire [3:0] alu_field; wire [3:0] addressing_mode; wire branch; assign fetch = ( state == 1 ); assign op_fetch = ( state == 2 ) && (addressing_mode != `INHERENT); assign execute = (( state == 2 ) && (addressing_mode == `INHERENT)) || (( state == 2 ) && (addressing_mode == `IMMEDIATE)) || (( state == 2 ) && (addressing_mode == `PC_RELATIVE)) || ( state == 3 ); assign opcode = Instruction_Register[15:4]; assign inst_type = Instruction_Register[15:12]; assign src_field = Instruction_Register[11:10]; assign dest_field = Instruction_Register[9:8]; assign alu_field = Instruction_Register[7:4]; assign addressing_mode = Instruction_Register[3:0]; assign memory_write = (inst_type == `store_inst) & (execute); assign branch = (execute) && ((opcode ==`BA) || ((opcode ==`BEQ) && (zflag == 1)) || ((opcode ==`BNE) && (zflag == 0))); assign alu_function = (execute && (inst_type == `alu_inst))? alu_field : (execute && (inst_type == `load_inst))? alu_field : (op_fetch && (addressing_mode == `DIRECT)) ? `justB : `AaddB; assign update_z = (execute && (inst_type == `alu_inst)); assign load_Acc = execute && (dest_field == `ACCn) && ((inst_type == `alu_inst) || (inst_type == `load_inst)); assign load_X = execute && (dest_field == `Xn) && ((inst_type == `alu_inst) || (inst_type == `load_inst)); assign load_S = execute && (dest_field == `Sn) && ((inst_type == `alu_inst) || (inst_type == `load_inst)); assign load_PC = branch; assign load_MAR = (op_fetch) && ((addressing_mode == `DIRECT) || (addressing_mode == `INDEXED)); assign enable_Acc = !enable_X && !enable_S && !enable_PC; assign enable_X = (execute && (src_field == `Xn)) || (op_fetch && (addressing_mode == `INDEXED)); assign enable_S = execute && (src_field == `Sn); assign enable_PC = execute && (src_field == `PCn); assign inc_PC = (fetch) || (op_fetch); assign sel_PC = (fetch) || (op_fetch); assign enable_reg = memory_write; always @(posedge clock) begin if (state == 1) begin Instruction_Register <= data; state <= 2; end else if ((state == 2) && ((addressing_mode == `DIRECT) || (addressing_mode == `INDEXED))) begin state <= 3; end else // execute cycle begin state <= 1; end end always @(not_reset) if (!not_reset) begin assign state = 0; assign Instruction_Register = 0; end else begin deassign state; deassign Instruction_Register; end endmodule