`include "opcodes.sv" module control( Function, SelInc, LoadPC, LoadIR, TrisOperand, TrisPC, TrisAcc, Mem_Write, Opcode, Zflag, Clock, nReset ); output [3:0] Function; output SelInc, LoadPC, LoadIR, TrisOperand, TrisPC, TrisAcc; output Mem_Write; input [3:0] Opcode; input Zflag, Clock, nReset; reg state; wire Branch, IncPC; parameter execute_cycle = 0; parameter fetch_cycle = 1; // // Define state machine // always_ff @(posedge Clock, negedge nReset) if (!nReset) state <= 0; // execute_cycle else if (state == fetch_cycle) state <= #20ns execute_cycle; else // execute_cycle state <= #20ns fetch_cycle; // // Generate memory write signal // assign Mem_Write = (Opcode == `STA) && (state == execute_cycle); // // Generate tri-state contol signals for AddressBus and DataBus // assign TrisOperand = (state == execute_cycle); assign TrisPC = (state == fetch_cycle); assign TrisAcc = (Opcode == `STA) && (state == execute_cycle); // // Generate ALU control // assign Function = (state == execute_cycle) ? decodeFn(Opcode) : `FnACC; // // Identify successful control transfers and PC increment // assign Branch = (state == execute_cycle) && ((Opcode ==`JMP) || ((Opcode ==`JMPZ) && (Zflag == 1)) || ((Opcode ==`JMPNZ) && (Zflag == 0)) ); assign IncPC = (state == fetch_cycle); // // Generate PC update multiplexor control signal // assign SelInc = IncPC; // // Generate Register Load Signals // assign LoadIR = (state == fetch_cycle); assign LoadPC = IncPC || Branch; // // Decode Opcode to create ALU Function code // function [3:0] decodeFn; input [3:0] opcode; case (opcode) `LDA : decodeFn = `FnMem; `ADD : decodeFn = `FnADD; `SUB : decodeFn = `FnSUB; `AND : decodeFn = `FnAND; `OR : decodeFn = `FnOR; `NOT : decodeFn = `FnNOT; `LSL : decodeFn = `FnLSL; `LSR : decodeFn = `FnLSR; default : decodeFn = `FnACC; endcase endfunction endmodule