`include "opcodes.v" `define execute_cycle 0 `define fetch_cycle 1 `timescale 100ps / 10ps module control( data, address, control, memory_write, zflag, clock, not_reset ); input [15:0] data; output [11:0] address; output [3:0] control; output memory_write; input zflag, clock, not_reset; reg state; reg [11:0] Program_Counter; reg [15:0] Instruction_Register; wire [11:0] operand; wire [3:0] opcode; wire branch; assign operand = Instruction_Register[11:0]; assign opcode = Instruction_Register[15:12]; assign memory_write = (opcode == `STA) & (state == `execute_cycle); assign address = (state == `fetch_cycle) ? Program_Counter : operand; assign control = (state == `fetch_cycle) ? `NOP : opcode; assign branch = (state == `execute_cycle) && ((control ==`JMP) || ((control ==`JMPZ) && (zflag == 1)) || ((control ==`JMPNZ) && (zflag == 0))); always @(posedge clock) begin if (state == `fetch_cycle) begin Instruction_Register <= data; state <= `execute_cycle; end else // execute cycle begin state <= `fetch_cycle; end if (branch) Program_Counter <= operand; else if (state == `fetch_cycle) Program_Counter <= Program_Counter + 1; end always @(not_reset) if (!not_reset) begin assign Program_Counter = 0; assign state = 0; assign Instruction_Register = 0; end else begin deassign Program_Counter; deassign state; deassign Instruction_Register; end endmodule