`timescale 1ns / 1ps module ControlUnit( input wire [3:0] instIn, input wire functBit, output reg [3:0] aluOut, output reg [2:0] FU, output reg addi, output reg mem, dataMemEn, output reg RegEn, output reg halt, output reg link, output reg [1:0] bank, output reg js); always @(instIn, functBit)begin case(instIn) 4'b0000: // Halt/NOP begin halt <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; // Disable Branching addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0001: // Load Byte begin aluOut <= 4'b0000; mem <= 1'b1; dataMemEn <= 1'b0; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching addi <= 1'b0; halt <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0010: // Store Byte begin aluOut <= 4'b0000; mem <= 1'b0; dataMemEn <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0011: // Link begin halt <= 1'b0; RegEn <= 1'b0; FU <= 3'b001; addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b1; bank <= 2'b10; js <= 1'b0; end 4'b0100: // Zero begin aluOut <= 4'b1011; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0101: // Add/Subtract if(functBit == 1) begin // Subtract aluOut <= 4'b0001; RegEn <= 1'b0; FU <= 3'b001; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end else begin // Add aluOut <= 4'b0000; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0110: // Add Immediate begin aluOut <= 4'b1010; addi <= 1'b1; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0111: // Set if Less Than begin aluOut <= 4'b1001; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1000: // Jump to Register begin aluOut <= 4'b0000; FU <= 3'b000; RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1001: // Jump Forward begin aluOut <= 4'b0000; FU <= 3'b010; RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1010: // Bank Load/Bank Store begin halt <= 1'b0; RegEn <= !functBit; FU <= 3'b001; // Disable Branching addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= {functBit,functBit}; js <= 1'b0; end 4'b1011: // Jump Backward begin aluOut <= 4'b0000; FU <= 3'b010; RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b1; end 4'b1100: // Branch if Zero begin aluOut <= 4'b1010; FU <= 3'b110; RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1101: // NOR begin aluOut <= 4'b0011; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1110: // OR/AND if(functBit == 1) // AND begin aluOut <= 4'b0100; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end else // OR begin aluOut <= 4'b0010; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1111: // Shift Right Logical/Shift Left Logical if(functBit == 1) // Shift Right Logical begin aluOut <= 4'b0110; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end else // Shift Left Logical begin aluOut <= 4'b0101; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end default: begin halt <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end endcase end endmodule module ControlUnit_tb(); reg [3:0] instruction; reg functionB; wire [3:0] aluOutput; wire [2:0] FetchUnit; wire addImmediate, memory, RegEnable; ControlUnit ControlUnit0( .instIn(instruction), .functBit(functionB), .aluOut(aluOutput), .FU(FetchUnit), .addi(addImmediate), .mem(memory), .RegEn(RegEnable) ); initial begin functionB = 1'b0; instruction = 4'b0101; #5 functionB = 1'b1; #5 functionB = 1'b0; instruction = 4'b1110; #5 functionB = 1'b1; #5 functionB = 1'b0; instruction = 4'b1111; #5 functionB = 1'b1; #5 instruction = 4'b0111; #5 instruction = 4'b0110; #5 instruction = 4'b1001; #5 instruction = 4'b1100; #5 instruction = 4'b1000; #5 instruction = 4'b0001; #5 instruction = 4'b0010; #5 $finish; end endmodule